SECCON Beginners CTF 2024


今回はWeb全部解きました。
reversing
assemble
id=1,2は以下の通りです
mov rax, 0x123
mov rax, 0x123
push rax
id=3から時間がかかりました(アセンブリで調べるとデータセクションを使っているものばかり出てきたので)
push 1869376613 ; elloを入力
push 72; Hを入力
mov rax, 1
mov rdi, 1
mov rsi, rsp
mov rdx, 12 ; pushで8byte積まれるので、Hの8とelloの4で12
syscall
id=4
flag.txtを用意するためにまとめてpushするとエラーとなってしまったので、32bitをpushしてからmovで残り32bit を書き込みました
push 0; ファイル名終端の0x0
push 1734437990; flag
mov DWORD PTR [rsp+4], 1954051118; .txt
mov rax, 2; open
mov rdi, rsp
mov rsi, 2
mov rdx, 0
syscall
mov rax, 0; read
mov rdi, 3
mov rsi, rsp
mov rdx, 55; flagが入り切るまで大きくした
syscall
mov rax, 1; write
mov rdi, 1
mov rsi, rsp
mov rdx, 55
syscall
ctf4b{gre4t_j0b_y0u_h4ve_m4stered_4ssemb1y_14ngu4ge}
cha-ll-enge
cha-ll-engeはLLMに渡して適当な言語に変換させたあと、フラグを出力する関数を書かせて実行することで何も考えずに解くこともできました。
misc
clamre
中身は以下の正規表現が一致するか確認しているだけでした。
^((\x63\x74\x66)(4)(\x62)(\{B)(\x72)(\x33)\3(\x6b1)(\x6e\x67)(\x5f)\3(\x6c)\11\10(\x54\x68)\7\10(\x480)(\x75)(5)\7\10(\x52)\14\11\7(5)\})$
一文字ずつ順に組み立ててflagが得られました
ctf4b{Br34k1ng_4ll_Th3_H0u53_Rul35}
Web
wooorker
?token=tokenを付与してリダイレクトされるため、自身のサーバーのURLを?nextに与えることでtokenを得ることができ、これでflagを取得できます
ctf4b{0p3n_r3d1r3c7_m4k35_70k3n_l34k3d}
ssrforlfi
LFIでflagを環 境変数から取得する問題でした。
/proc/self/environから読むことができますが、os.path.existsで存在するか..が含まれているとDetected LFIとして弾かれてしまいます。
実際の取得がcurlで、その前の確認はos.path.existsであるため、パスの文字列のパース方法の差があるのではと考えました。
Geminiに聞いてみたところ、例えば/は%2Fにすればcurlでは読み込むことができ、pythonからは存在しない扱いにできそうでした。
RFC8089を読むとUNC Stringという表記があり、file://host.example.com/Share/path...と扱うことができることが分かりました。
手元のcurlでfile://localhost/proc/self/environにアクセスするとファイルを読むことができたのでこれを送信してflagが得られました。
https://datatracker.ietf.org/doc/html/rfc8089#appendix-E.3.1
#https://ssrforlfi.beginners.seccon.games/?url=file://localhost/proc/self/environ
ctf4b{1_7h1nk_bl0ck3d_b07h_55rf_4nd_lf1}
double-leaks
配布されたファイルには以下の箇所がありNoSQL Injectionが存在していました。
user = users_collection.find_one(
{"username": username, "password_hash": password_hash}
)
waf関数でregexなどは塞がれていましたが、これはpassword_hashのみに使用されており、username側では可能でした。
