satokictf 2024 writeup

# 誕生日おめでとうございました！！！！お疲れ様でした！！！！

以下writeup

## Web
### MiniBank

FlaskでかかれたWebサイトのコード。
app.pyの
```
@app.route("/")
def index():
    token = request.cookies.get("account")
    if token:
        balance = decode_jwt(token)
        if balance is not None:
            status = determine_status(balance)
            return render_template("index.html", balance=balance, status=status)
```
と

```
def determine_status(balance):
    status = FLAG
    if balance > 0:
        status = "rich"
    if balance <= 0:
        status = "poor"
    return f"You are a {status} person, aren't you?"
```
ここから、cookieにjwtでデータが保存されてそうなのでblanceの値を「0以下」かつ「0超」に書き換えることが出来れば良さそうと分かる。存在するのかそんな値.....？

一旦数学はおいて、jwt改ざんを考える。
```
KEY = str(random.randint(1, 10**6))
def encode_jwt(balance):
    payload = {"balance": balance}
    return jwt.encode(payload, KEY, algorithm="HS256")
```
より、keyは10^6程度の全探索で見つかるため
![MiniBank2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1899463/97670a0c-7cff-9c5b-e2e9-35d3937f4da4.png)
コードを書いて見つける。これでjwt改ざんの準備は整った。
一応https://jwt.io/ を利用して出来てるか確認する。

「0以下」かつ「0超」の値について、pythonではnanを利用すると比較を強制Falseに出来るらしい。試したらできた。
![MiniBank4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1899463/b4a2aabc-8092-8bc5-21cd-404a43e64222.png)
https://jwt.io/ さんでは、float('nan')を値にするのはエラーが起きた？のでpythonコードからペーロードを生成した。
![MiniBank3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1899463/bc95d18e-17ce-163f-67dd-b1756f89b736.png)

生成したjwtをcookieにセットして「/」へリクエストを送るとflagゲット！
![MiniBank1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1899463/805ca9f0-9165-fe55-43a6-f42d3a689761.png)



## Misc
### zzz
「SIGQUIT」信号を出すことが肝だそうです！
私の環境では、「ctrl+4」で出た。OSや設定にもよるのかも！
![zzz1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1899463/2c09ad91-a24f-6cf4-c9ef-baeee60070ba.png)

### HBD
私のつたない理解。自分->apache->バックエンド(go)とリクエストとレスポンスが転々としてる感じ？
ヘッダー部分変更しても意味なくない？と思いつつ色々試してたら出来た。

```
func modify(r *http.Response) error {
	body, err := io.ReadAll(r.Body)
	if err != nil {
		return err
	}

	var b []byte
	if bytes.Contains(body, []byte("HBD!Satoki!")) {
		b = []byte(getFlag())		
	} else {
		b = body
	}

	r.Body = io.NopCloser(bytes.NewReader(b))
	r.Header.Set("Content-Length", strconv.Itoa(len(b)))

	return nil
}
```


![HBD1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1899463/a54f0758-d36f-bba4-f1d1-17d0d7413ae7.png)
![HBD2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1899463/aaf68b8f-dcec-78d6-6551-1338d805a635.png)
```
HBD!Satoki! / HTTP/1.1
Host: 160.251.183.149:8848
Cache-Control: max-age=0
Accept-Language: ja
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.100 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
If-None-Match: "2d-432a5e4a73a80"
If-Modified-Since: Mon, 11 Jun 2007 18:53:14 GMT
Connection: keep-alive
```
![HBD3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1899463/44474394-07fe-ae30-a5d9-b2ab182284d2.png)