チャレンジ一覧
Python自動化 - SQLiteデータベース解析
起動のたびに作られる data.db(SQLite。users / orders / audit_log)を調べます。orders を user_id ごとに SUM(amount) で集計し、合計額が大きい社員の上位3人を求めてください(注文件数が最も多い社員や、1回の注文額が最も大きい社員はおとりで、上位3人には入りません)。audit_log には、全社員に1件ずつ action = 'security_note' の行 "Confidential clearance credential issued to this employee: <16桁16進>" があります。上位3人の credential を、合計額の大きい順に '-' でつないだものが答えです。python3 challenge.py '<答え>' に渡すと、フラグが表示されます。
Python自動化 - カスタム暗号の復号
cipher.txt には独自の暗号でエンコードされたフラグが16進で入っています。暗号化は各バイトに add(鍵加算) -> xor(位置依存) -> rotl(巡回シフト) を適用したものです。この逆変換を Python で実装してフラグを復元してください(仕様は python3 challenge.py で表示)。
Python自動化 - 暗号化ZIPのパスワードクラック
起動のたびに /challenge/secret.zip が作られます。中には flag.txt と readme.txt が入っていて、ZipCrypto で暗号化されています。パスワードは /challenge/wordlist.txt の1語のうしろに2桁の数字(00〜99)を付けたもの(例: sunshine07)で、起動のたびに選び直されます。Python 標準ライブラリの zipfile で候補を総当たりしてパスワードを見つけ、flag.txt を取り出してください。
Web-21. Secure User Searchのブラインドインジェクション
このユーザー検索アプリはユーザー名の存在有無だけを返しますが、直接的な検索結果は表示しません。エラーの発生有無やレスポンスの違いを手がかりに、隠された情報を推測できないか確認してみましょう。
Web-22. Secure Comment BoardのCSPバイパス
このコメント掲示板はContent Security Policy(CSP)で保護されており、スクリプトの実行元を自サイトと信頼済みCDNのみに制限しています。信頼されたCDNの中身まで安全とは限らない点に注目してみましょう。
Web-23. Secure Authentication Systemの型変換の罠
このログインポータルはフォームログイン・JSON API ログイン・検証コードチェックを備えています。管理者アカウントの本当のパスワードは分かりませんが、比較処理の実装次第では回避できるかもしれません。
Web-24. Secure Bankの競合状態を突く
Secure Bankではコイン残高を使ってショップで景品を購入できます。残高チェックと引き落とし処理が別々のステップで行われている場合、その間隙をどう突けるか考えてみましょう。
Web-25. Greeting Card GeneratorのSSTI
このグリーティングカード作成アプリはFlask/Jinja2で作られており、入力したメッセージをそのままテンプレートエンジンでレンダリングしています。テンプレート構文がどこまで実行されてしまうか調べてみましょう。
アルゴリズム - 迷路のBFS最短経路
data.txt の S から E までの最短経路を BFS で求め、UDLR の移動列を challenge.py に入力してください。正しい経路で起動時注入 FLAG が表示されます。
ネットワーク解析 - 802.1Q VLANで分けられた通信
capture.pcapは、スイッチのトランクポートをミラーしてキャプチャした通信で、複数のVLANのフレームが802.1Qタグ付きで混ざっています。どのVLANでも同じ機器からUDP 5140番宛てに MGMT|<断片> の形で文字列が少しずつ送られ、全部が交互に混ざっています。管理VLAN 42の断片だけを届いた順につなげ、フラグを復元してください。
ネットワーク解析 - SNMP情報漏洩
弱いコミュニティ文字列(public)で SNMPv2c を喋る機器の GetResponse をキャプチャしました。配布されるパケットキャプチャ(traffic.pcap)から SNMP(UDP/161)の varbind を解析し、ベンダー独自OIDの値に含まれるフラグを回収してください。
ネットワーク解析 - SSL Stripによる平文認証情報
SSL Strip 攻撃により HTTPS が HTTP に格下げされ、被害者の認証情報が平文で流れた通信をキャプチャしました。配布されるパケットキャプチャ(traffic.pcap)から平文HTTPのPOSTを解析し、ログインのパスワード(フラグ)を抽出してください。
ネットワーク解析 - WebSocketフレームのマスク解除
capture.pcapには、ブラウザとチャットサーバーのWebSocket通信が記録されています。クライアントからサーバーへのフレームは毎回ちがう4バイトの鍵でマスクされています。フレームを解析してマスクを外し、3つのフレームに分割されたメッセージを組み立てて、デプロイ用のトークン(フラグ)を取り出してください。
ネットワーク解析 - 独自プロトコルの解読
独自の簡易バイナリプロトコルで通信するシステムのトラフィックをキャプチャしました。配布されるパケットキャプチャ(traffic.pcap)から、TCPポート9999のフレーム構造を解析し、ペイロードをデコードしてフラグを取得してください。
プログラミング - SQLite証拠データベースの解析
evidence.db は起動のたびに乱数で作られる SQLite データベースです(/challenge にあります。users / sessions / access_log の3表)。trust_score が 80 以上のユーザーのセッションについて、ts がそのセッションの started 〜 ended の範囲内にある event = 'vault' の行を集め、note(6桁の16進)を ts の古い順に - でつないだ文字列を求めてください。その文字列を python3 challenge.py '<答え>' に渡すとフラグが表示されます。
プログラミング - Webスクレイピングとグラフ探索
site.json は起動のたびに乱数で作られるクロール結果です(/challenge にあります)。start と target の URL、各ページの url / links / fragment(Base64 の断片)が入っています。start から links をたどって target へ行く最短経路(一つに決まります)を求め、経路上のページ(start と target を含む)の fragment を経路の順に Base64 デコードして区切りなしでつないだ文字列を求めてください。その文字列を python3 challenge.py '<答え>' に渡すとフラグが表示されます。
プログラミング - ZIPパスワードの復元
secret.zip は起動のたびに作られる、ZipCrypto(従来の PKWARE 暗号)で暗号化された ZIP です(/challenge にあります。同じ場所に wordlist.txt もあります)。パスワードは wordlist.txt のどれか1語の後ろに、2桁の数字(00〜99)を付けたものです。パスワードを見つけて中の note.txt を取り出すと、フラグが書かれています。Python の zipfile は pwd= にパスワードを渡すと ZipCrypto の ZIP を読めます。
プログラミング - パケットログの解析
capture.txt は起動のたびに作られるパケットログです(/challenge にあります)。1行が1つのフローで、flow=<名前> payload_hex=<16進> の形をしています。payload_hex を 0x5A で XOR 復号し、flow=exfil の行を復元するとフラグが現れます。フラグは平文では置かれていません。
プログラミング - マルチスレッド結果の再構築
起動のたびに乱数で作られた並列ジョブの結果ログ worker-results.jsonl を解析します。各 slot は何度も試行されていて、途中で時間切れ(timeout)になったり後の試行に置き換えられたり(superseded)した結果も残っています。最終結果は、slot ごとに status が done のレコードのうち attempt が最大の1件だけです。その result を Base64 デコードし、レコードの worker 番号 N に対する SHA-1(worker-N の文字列) のダイジェストを先頭から繰り返し XOR して復号します。最終結果を slot の昇順につないだ40文字(小文字英数字)が答えです。答えを `python3 challenge.py '<答え>'` に渡すと、正解のときだけフラグが表示されます。
プログラミング - メモリダンプの解析
起動のたびに乱数で作られた合成メモリイメージ memory.img を解析します。先頭のヒープ管理表(先頭8バイト HEAPTBL + NUL・count(uint16)・エントリ(addr: uint32、size: uint16、flags: uint8、すべてリトルエンディアン))で live(flags=1)になっているアドレスの領域だけが現在の値で、解放済みの領域や管理表に載っていない残骸は古いデータです。各領域は `ALLOC:0x<4桁の小文字16進アドレス>:` + 長さ(uint16、リトルエンディアン)+ データで、データは MD5("heap-0x<4桁の小文字16進アドレス>") のダイジェストを繰り返し XOR すると `p<番号>=<4文字>` の断片に復号できます。live の断片を番号の昇順に4文字ずつつないだ40文字(小文字英数字)が答えです。答えを `python3 challenge.py '<答え>'` に渡すと、正解のときだけフラグが表示されます。
プログラミング - 既知平文攻撃
起動のたびに乱数で作られた証拠ファイル ciphertext.b64 と known.txt を解析します。ciphertext.b64 は観測所の報告書を、英小文字だけの短い鍵(長さは不明)で繰り返し XOR して Base64 にしたもので、known.txt は報告書の冒頭部分の平文です。報告書を復号すると `RESULT: unlock-code=...` という行があり、その unlock-code の値(16文字)が答えです。取り消された古いコードも書かれているので取り違えないでください。答えを `python3 challenge.py '<答え>'` に渡すと、正解のときだけフラグが表示されます。
プログラミング - 独自プロトコルの解析
protocol.bin は起動のたびに作られるバイナリのキャプチャです(/challenge にあります)。KINO で始まる長さつきのフレームがいくつか並んでいます。フレームを先頭から順にたどり、type=3 のフレームの payload を 0x23 で XOR 復号するとフラグが現れます。フラグは平文では置かれていません。
プログラミング - 画像ステガノグラフィ
image.pgm は起動のたびに作られるテキスト形式(P2)の PGM 画像です(/challenge にあります)。画素値の最下位ビット(LSB)を先頭から集め、8ビットずつ1バイトにまとめて読むと、NUL(0 のバイト)の手前までがフラグです。フラグは平文では置かれていません。
暗号解析 - RSA共通モジュラス攻撃
2つのシステムが同じRSAの法nを使い回し、公開指数だけを変えていました。同じメッセージを e1 と e2 で暗号化した暗号文 c1, c2 が漏れています(public_keys.txt、ciphertexts.txt)。nは素因数分解できませんが、秘密鍵なしでメッセージを取り戻し、フラグを提出してください。