/* * csaw.c * CSAW CTF Challenge Kernel Module * Jon Oberheide * * This module implements the /proc/csaw interface which can be read * and written like a normal file. For example: * * $ cat /proc/csaw * Welcome to the CSAW CTF challenge. Best of luck! * $ echo "Hello World" > /proc/csaw */ #include #include #include #include #include #include #define MAX_LENGTH 64 MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jon Oberheide"); MODULE_DESCRIPTION("CSAW CTF Challenge Kernel Module"); static struct proc_dir_entry *csaw_proc; int csaw_write(struct file *file, const char __user *ubuf, unsigned long count, void *data) { char buf[MAX_LENGTH]; printk(KERN_INFO "csaw: called csaw_write\n"); /* * We should be safe to perform this copy from userspace since our * kernel is compiled with CC_STACKPROTECTOR, which includes a canary * on the kernel stack to protect against smashing the stack. * * While the user could easily DoS the kernel, I don't think they * should be able to escalate privileges without discovering the * secret stack canary value. */ if (copy_from_user(&buf, ubuf, count)) { printk(KERN_INFO "csaw: error copying data from userspace\n"); return -EFAULT; } return count; } int csaw_read(char *page, char **start, off_t off, int count, int *eof, void *data) { char buf[MAX_LENGTH]; printk(KERN_INFO "csaw: called csaw_read\n"); *eof = 1; memset(buf, 0, sizeof(buf)); strcpy(buf, "Welcome to the CSAW CTF challenge. Best of luck!\n"); memcpy(page, buf + off, MAX_LENGTH); return MAX_LENGTH; } static int __init csaw_init(void) { printk(KERN_INFO "csaw: loading module\n"); csaw_proc = create_proc_entry("csaw", 0666, NULL); csaw_proc->read_proc = csaw_read; csaw_proc->write_proc = csaw_write; printk(KERN_INFO "csaw: created /proc/csaw entry\n"); return 0; } static void __exit csaw_exit(void) { if (csaw_proc) { remove_proc_entry("csaw", csaw_proc); } printk(KERN_INFO "csaw: unloading module\n"); } module_init(csaw_init); module_exit(csaw_exit);