SekaiCTF 2023 感想
ノリで誘われたのでノリでSekaiCTF(Project SEKAI CTF 2023)に参加してきました。
開始時点ですでに48時間のうち24時間が過ぎていましたが何問かは解きました。
ということで雑に書き残しておきます。
解けたやつ
Azusawa’s Gacha World(Reverse)
電子辞書のやりすぎでリバースエンジニアリングに関してはできそうだったのでとりあえずそこから攻めていきました。
dist.zipをダウンロードするとUnityのゲームが出てきます。とりあえずフォルダーの中を見るとil2cppではなくMonoを使用していることがわかるのでAssembly-CSharp.dllをdnSpyに食わせます。
中身を見ていくとGachaManagerクラスが怪しそうなのでリクエストの中身を確認します。このあと私はcurlでリクエストを投げてみたりしていましたが全く必要ありませんでした。
後でゲーム内に100万回目で確定排出と書いてあることに気づき、BepInEx+UnityExplorerを入れてGameStateクラスのpulls変数を999999に書き換えてからガチャを回すと目的のキャラクターが排出されそのリザルト画面に左下にフラグがあるので終了です。30分弱くらいでした。
Guardians of the Kernel(Reverse)
Linuxカーネルとinitramfsがあります。とりあえずGhidraにカーネルを食わせつつ(無意味でしたが)initramfsの中を漁りました。
initramfsの中の/initを見てみるとflag_checker.koという怪しげなモジュールをロードしているのでそれをGhidraにかけます。
ただ取っ掛かりがないのでとりあえずString Searchで怪しい文字列を探します。すると"Unlocked layer 1."や"Unlocked layer 2."といったものが見つかります。device_ioctl()から参照されていることがわかるのでその関数を見に行きます。
Layer1は単純でbufferの中身が"SEKAI{"であることをそのまま検証しているだけです。
Layer3はnバイト目の変換にnバイト目とn+1バイト目を使用しているので、比較に使っている定数から逆変換するにはヌルのバイトから逆方向に1文字ずつ処理すれば良いです。コードを書いても出せますが12文字くらいなので手で解きました。末尾が"SEKAIPL@YER}"であることがわかります。
Layer2が曲者で結果から逆算しようとしても途中で乗算が入ってしまっているためオーバーフローにより必要な値を一意に定めることができません。しかしバッファがヌルを含めて8文字であり全て数字であることを検証しているため、判定部をそのまま持ってきて0~9999999で総当りするプログラムを書きました。結果"6001337"であることがわかります。
ガチャの分から1時間後くらいに終了しました。
I love this world(Misc)
上2つ以外のリバースエンジニアリング系の問題は唐突にレベルが上がって解きづらかったのでその他のジャンルもぶらぶらしつつ様々な問題に中途半端に手を突っ込んでいました。その時に見つけた問題です。
.svpファイルがあります。ソフトはよくわからない(Synthesizer Vですか? 持ってないのでよくわからないです)ですが中身は平文JSONなので読んでみます。
どうやら歌詞やピッチが書いてあるようですが歌詞に対して明らかに発音データが合っていません。歌詞にもフラグとして成立しそうな文字列がありますが問題の方にフラグに日本語は含まれていないと書いてあるため、気合で発音をアルファベットに変換してみるとフラグを含む文字列が得られます。フラグは書き残してないので忘れました。
カーネルの分から実に3時間半後のことでした。
DEF CON Invitation(Forensics)
.emlファイル(電子メールデータ)があります。文面は普通ですが添付されているカレンダーデータ中にあるサイトに飛ぶと地図が出てきます。地図下のオフラインマップをダウンロードするボタンを押すとpngに拡張子偽造しようとした.vbsファイルが出てきます。
.vbsファイルはかなりいらない情報が多いのでいい感じに読み飛ばします。まず必要なのはOwOwO(ewkjunfw)の結果です。ewkjunfwの中身はある画像データのダウンロードURLをHexにしたものでした。
とりあえずそれをダウンロードしますがファイル名にXORedと書いてあります。PNGのmagicと突き合わせて鍵を見つけようとしましたが16Byte程度では規則性が見つけられませんでした。PNGファイルで基本的に値が一致するのはそれくらいのようなのでこの方法では鍵がわかりません。
しばらく悩んでいたのですが、最後のExecuteのところを見る必要がありました。これはあるURLにJSONをPOSTしています。試しにPOSTしてみるとJSONが返ってきて、msgにお前はadminじゃねえというメッセージが入っています。ということでusernameをadminとして送信してみるとなんか鍵が返ってきます。この冒頭部分がさっきXORして計算した結果と一致するのでこれがXORに使用した鍵とわかります。
あとはファイル全体にその鍵でXORをかけて復元しpngを開くと画像にフラグ"SEKAI{so_i_guess_we'll_get_more_better_next_year-_-}"が書かれています。
I love this worldから1時間くらいあとに終わっていますが実際にはI love this worldに手を付ける前から始めています。
解けなかったやつ
こっからは順不同です。強いて言えば問題の添付ファイルの名前順?
Cosmic Ray(Pwn)
実行ファイルがあり、このプログラムのメモリ空間のうち1bitを反転させることができるプログラムです。
チームの他の人がうんうん唸っていた記憶はありました。最終的に私がたどり着いた結論はデータ領域ではなくプログラム領域、それもmain関数のスタックカナリアの部分を無効化すれば良いことに気づきました。jeとjneはちょうどオペコードが1bit違いなのでそこを反転させるとスタックカナリアが「破壊されていないとき」に文句を言ってabortするようになります。
あとはshellcodeを組むだけなのでしょうが実際に攻撃する環境下でのスタックアドレスがわからず戻りアドレスを確定させられなかったのでSIGSEGVを起こさせるのが精一杯でした・・・。
Infected(Forensics)
.pcapngがあります。WordPressに対して攻撃しているっぽいのはわかるんですがどこで攻撃が完了したのかさっぱりわからず・・・。
Scanner Service(Web)
Docker用のファイル一式があります。中のプログラムはrubyで書かれています。
入力を検証してコマンドラインに渡してそうではあるんですが、rubyの標準の文字列->数値変換関数は数字として認識できる文字までで変換をストップしてしまうので実際には検証しきれていません。
そこがポイントであることまではわかりましたが、その前段にシェルで意味を持つ記号類がエスケープされてしまっているのでどう入力を組めば実際の攻撃が可能なのかはわかりませんでした。他のチームメンバーも同じところで詰まっていた気がします。
Text Sender(Pwn)
実行ファイルがあり、メッセージを作成したり送信できるプログラムということになっています。Ghidraに食わせましたがどこが弱いのかよくわかりませんでした。
Conquest of Camelot(Reverse)
実行ファイルがあり、OCamlで書かれているようです。本体の処理部分の位置は分かりましたが非C系言語のネイティブバイナリにありがちなよくわからない関数呼び出しで追いきれませんでした。
Eval Me(Forensics)
.pcapngファイルがありますが、中の通信の大半がTLS通信で見えません。client randomがエクスポートできるような感じですが中の通信と一切合致しませんでした。
SSH(Misc)
.ovpnファイルがありネットワークに接続できます。nmapしてみると10.0.0.1~10.0.0.4がありますが10.0.0.4の22番くらいしか開いていません。後で気づきましたがwiresharkも見るべきだったかもしれません。どこかから10.0.0.4に対してsshしてるかもしれないので。
Teyvat Travel Guide(Reverse)
急に別ゲー出すじゃん。
実行ファイルがあります。48x48のマスの右下まで到達する必要がありそうですが途中に見えない罠がありそこを通ると死んでしまいます。
罠を置いている処理の箇所は見つかったのですが進むたびに更新されているので追うのがめんどくさいです。全探索すれば終わってしまうからPoWがついてるんでしょうね。
と書いて気づきましたがもしかしてバイナリを弄ってPoW無効化してから全探索すればよかったですか?
A letter from the Human Resource Management(Misc)
.txtファイルがあります。Human Resource Managementは持っとらん。
Network Tools(Pwn)
実行ファイルとそのソースコード(rust)があります。main関数は中がunsafeで囲まれており、また他のチームメンバー曰くバッファに対してデータを読みすぎているところがあるということでしたがshellcodeの組み方がわからないので撤退。
Sahuang Flag Checker(Reverse)
実行ファイルがあります。これが地味に厄介でGhidraだとAVX命令周りでディスアセンブルに失敗するところがあるのでまともに読めません。Cutter(radare2のGUIフロントエンド)を使用したらちゃんと読めるんですが逆にデコンパイラの出力が地味に読みづらく追うのを諦めました。
SekaiCTFCorp(Misc)
ウェブサイトのURLがあります。下の方の企業ロゴ(?)のリンクが切れている以外は特に何もありません。多分。それ以外何もわかりませんでした。
感想
簡単な問題しか解けませんでした。Cosmic Rayとかも簡単ではあるっぽいんですが・・・。
CTF筋が足りてない感じがします。まあCTFはちゃんとやったことは今までないですしリバースエンジニアリング系は単純にGhidra力でゴリ押してるのでさもありなんという感じでしょうか。本来定石を押さえておくべきなんでしょうね。
ただ全くできないというわけでもなさそうなので、もしまたやるときがあればもう少しいい感じにしておきたいですね。