チャレンジ一覧
APT攻撃の全ステージを再構築せよ
4つのログ `/challenge/edr_process.log`、`proxy_http.log`、`dns_queries.log`、`dlp_transfer.log` に、APT 攻撃が多数の正規の記録に紛れて残っています。攻撃者のイベントにラベルはありません。端末・ドメイン・ファイル・時刻を手がかりに、侵入から持ち出しまでを再構築し、持ち出されたデータの中にあるフラグを答えてください。 許可済みのペネトレーションテスト(端末 10.20.9.15)も同じ手口で記録されています。実際のインシデントのデータを復元してください。
BitLocker暗号化ドライブをクラックせよ
BitLocker復旧キーの検証を安全なメタデータfixtureで学びます。bitlocker.img は実ボリュームではありません。候補キーのSHA-256を記録済みダイジェストと照合して復旧キーを特定し、そのキーで保護ペイロードを復号してください。
Bitcoinトランザクションに隠されたメッセージを抽出せよ
被害者は身代金をビットコインアドレス `bc1qr4nsmw4r3pay7hzfx0d9cq3vkt8e6m5ljgs2ua` に支払いました。`/home/ctfuser/evidence/transactions.json` は調査期間のトランザクションをオフラインで書き出したものです(ブロックチェーンには接続しません。記録の並びはブロック順ではありません)。 攻撃グループは、資金を動かすたびに、トランザクションの OP_RETURN にメッセージの断片を残します。断片は、そのトランザクションが使った入力のトランザクションID(txid)から SHA-256 で作った鍵で XOR されています。OP_RETURN は取引所・タイムスタンプサービスなどほかの利用者も使っています。身代金の資金の流れを追い、断片をつなげてメッセージ(フラグ)を復元してください。
IoTデバイスファームウェアから秘密鍵を抽出せよ
ネットワークカメラ KNC-CAM-2000 の更新ファイル `/home/ctfuser/evidence/firmware.bin` を解析します(実機には接続しません)。メーカーは rootfs を暗号化して配布し、復号はブートローダーが起動時に行います。ヘッダーとパーティション表の形式は `/home/ctfuser/README.md` にあります。 ファームウェアに入っている root ユーザーの SSH 秘密鍵のコメント欄にフラグがあります。ホスト鍵などほかの鍵や、ブートローダーにあるほかの鍵は、答えではありません。
Python上級 - 並行イベントDAGの因果関係復元
events.jsonlには複数サービスとtraceのイベントがランダム順で混在しています。指定されたauth.failedイベントを根としてparent参照の因果DAGを辿り、到達可能なworker.decryptの断片を論理時刻順に連結してください。
ハイパーバイザーメモリからVM情報を抽出せよ
KVM ホストのメモリダンプ `/home/ctfuser/evidence/kvm_host.dump` を解析します。ゲストは AMD SEV を模した設定でメモリが VM ごとの鍵で暗号化されていますが、このホストは KVM のデバッグビルドで動いており、ゲストの鍵がホスト側の構造体(kvm_sev_info)に残っていました。ダンプの形式とページの暗号化の方式は `/home/ctfuser/README.md` にあります。 対象は DB サーバーの VM `db-prod-02` です。QEMU のプロセスの記録から VM を特定し、VMCS・EPT・kvm_sev_info をたどってゲストのメモリを復号してください。ゲストのメモリ上に残っているシェルの履歴から、復元トークン(restore token)を答えてください。
プログラミング - APTタイムラインの解析
/challenge/events.jsonl は、コンテナの起動のたびに乱数で作り直される、複数のホストから集めたセキュリティログを1つにまとめたものです(行は順不同)。ts は ISO 8601 ですが、収集元によってタイムゾーン(+09:00・-05:00・Z・+00:00)が違うので、UTC にそろえて比べます。rule が phishing-macro のアラートが出たホストが最初の侵害(侵害時刻はそのアラートの時刻)で、remote-logon の src がすでに侵害済みで、かつログオン時刻が src の侵害時刻より後なら、dst もそのログオン時刻に侵害されたとします(ログオンは時刻の順に処理します)。侵害されたホストで、そのホストの侵害時刻より後に起きた upload の chunk(8桁の16進)を、UTC の時刻順に区切りなしでつないだ16進文字列を、python3 challenge.py '<答え>' に渡してください。侵害前の upload や、侵害されていないホストの upload は含めません。正しいときだけフラグが表示されます。
プログラミング - AST静的解析による脆弱性検出
/challenge/corpus/*.py は、コンテナの起動のたびに乱数で作り直されるコードレビュー用の Python ソースです(実行しないでください)。各関数には @audit_id(6桁の16進)が付いています。subprocess.run または subprocess.Popen(import subprocess as sp、from subprocess import run、from subprocess import run as execute のような別名・名前での import を含む)を shell=True で呼び、かつ第1引数が文字列の定数ではない関数が「要修正」です。その audit_id を (ファイル名, 関数の行番号) の順に - でつないだもの(例: 1a2b3c-4d5e6f)を、python3 challenge.py '<答え>' に渡してください。正しいときだけフラグが表示されます。
プログラミング - AWS権限の解析
/challenge/iam.json にはユーザー・グループ・ポリシーが、/challenge/s3_objects.json には S3 オブジェクトの一覧(bucket・key・etag)があり、どちらもコンテナの起動のたびに乱数で作り直されます。ir-analyst に効くポリシー(AttachedTo が user/ir-analyst のものと、ir-analyst が属するグループのもの)を、README.md の規則(* は / を含む任意の文字列、? は任意の1文字、Action は大文字と小文字を区別せず Resource は区別する、適用される Statement に Deny が1つでもあれば拒否、Deny が無く Allow があれば許可、どれも無ければ拒否)で評価してください。ir-analyst が s3:GetObject できるオブジェクトの etag(8桁の16進)を、ARN(arn:aws:s3:::bucket/key)の文字列の昇順に - でつないだものを、python3 challenge.py '<答え>' に渡します。正しいときだけフラグが表示されます。
プログラミング - IoTファームウェアの解析
起動のたびに乱数で作られたネットワークカメラのファームウェアイメージ firmware.bin を解析します(実行コードは含まれません)。形式は、先頭に `KFW2`(4バイト)、パーティション数(uint16)、パーティション表(name: 16バイト(NUL 埋め)、offset・size・crc32: 各 uint32。数値はすべてビッグエンディアン)、本体の順です。CRC32 が一致しないパーティションは壊れているか古いものです。`bootinfo` にはシリアル番号(`serial=...`)が平文で入っており、`config` は設定テキストを zlib で圧縮し、SHA-256(シリアル番号の文字列 + b"config") のダイジェストを繰り返し XOR したものです。名前がちょうど `config` で CRC32 が一致するパーティションに書かれた `admin_token` の値(16進32桁)が答えです。工場出荷時の既定値やバックアップの古い値は、いま有効な値ではありません。答えを `python3 challenge.py '<答え>'` に渡すと、正解のときだけフラグが表示されます。
プログラミング - カバレッジ誘導ファジング
起動のたびに乱数で作られたカバレッジ誘導ファザーの実行記録 coverage-queue.jsonl を解析します(対象プログラムは実行しません)。各行は `{"id": ..., "t": ..., "edges": [{"edge": ..., "hits": ...}, ...]}` の形で、行の順番は処理した順ではありません。エントリを t の昇順に1件ずつ処理し、各 edge のヒット数をバケット(1 / 2 / 3 / 4–7 / 8–15 / 16–31 / 32–127 / 128以上)に分けます。そのエントリの (edge, バケット) の組のうち、それまでに見たことのない組が1つでもあれば、そのエントリをコーパスに保存します(保存したかどうかにかかわらず、組はすべて「見た」ことにして次へ進みます)。保存されたエントリの id を処理した順に `-` でつないだもの(例: `1a2b3c-4d5e6f-...`)が答えです。答えを `python3 challenge.py '<答え>'` に渡すと、正解のときだけフラグが表示されます。
プログラミング - ゼロクリック通信の解析
messages.ndjson は起動のたびに乱数で作られる、メッセージアプリの通信記録です(/challenge にあります)。1行が1つの断片(message_id、frag_index、frag_count、payload_hex)で、断片は複数のメッセージが混ざっています。同じ message_id の断片を frag_index の順につなぎ、SHA256(message_id) の先頭4バイトを鍵に繰り返し XOR で復号すると、TLV(type 1バイト、長さ 2バイト big-endian、値)の並びになります。宣言された長さが残りのバイト数を超える TLV を含むメッセージが、パーサーを狙った攻撃です。攻撃メッセージのその TLV の中にある stage2=<16桁の16進> の値を、message_id の昇順に - でつないだ文字列を python3 challenge.py '<答え>' に渡すとフラグが表示されます(正しい長さの TLV にある stage2= は攻撃ではありません)。
プログラミング - タイミング攻撃データの解析
timings.csv は起動のたびに乱数で作られる、タイミング攻撃の生の測定値です(/challenge にあります)。秘密の16進文字列を1文字ずつ比較するサーバーに対して、各位置(position)で候補の文字(candidate、0〜f)を送ったときの応答時間(sample_us、マイクロ秒)が、各位置・各候補に複数回ずつ記録されています。正しい文字のときだけ応答がわずかに遅くなりますが、測定には雑音があり、ときどき大きな外れ値も混ざります。各位置で本当に遅い候補を選び、position 0 から順につないだ秘密の16進文字列を python3 challenge.py '<答え>' に渡すとフラグが表示されます。
プロセスホロウイング攻撃を検出せよ
Windows ホストのメモリから、プロセス一覧 `process_list.txt`(PEB の見え方)、VAD の一覧 `vad_regions.txt`、プライベートな実行可能領域のダンプ `malfind/` を復元しました。プロセスホロウイングされたプロセスを特定し、そのイメージベースにあるインプラントの設定ブロックからフラグを復元してください。 RWX の領域は、JIT・Defender のスキャン領域・別のプロセスへの DLL 注入など、正規やおとりの領域にも多数あります。設定ブロックは、先頭が `KCFG`、続いて鍵の長さ(1バイト)、鍵、暗号文の長さ(2バイト、リトルエンディアン)、暗号文で、暗号文は鍵を繰り返した XOR です。ほかの領域にも同じ形式のブロックがあります。
改ざんされたタイムスタンプを検出せよ
`/challenge/mft_timeline.csv` は NTFS の `$MFT` から書き出したタイムラインです。各ファイルの `$STANDARD_INFORMATION`(SI)と `$FILE_NAME`(FN)のタイムスタンプと、小さいファイルの常駐データ `resident_data`(16進)を含みます。攻撃者はマルウェア本体のタイムスタンプを SI だけ過去へ書き換えて(timestomping)隠しましたが、FN には本当の作成時刻が残っています。 マルウェアは、自分が置くファイルの常駐データを、そのファイルの本当の作成時刻(`FN_Born`)から作った鍵で暗号化します。鍵ストリームは SHA-256("<FN_Born の文字列そのまま>:<カウンタ>")(カウンタは0から始まる10進の文字列)を順に連結したもので、データと XOR します。同じマルウェアの、timestomp されていない他の検体も残っています。timestomp されたファイルの常駐データを復号してください。
暗号化されたiOSバックアップを復号せよ
暗号化iOSバックアップのパスワード検証を安全なiTunesメタデータfixtureで行います。実iPhoneや実バックアップは使用しません。Manifest.plistのダイジェストと候補パスワードを照合してパスワードを特定し、暗号化されたメッセージデータベースを復号してフラグを探してください。
暗号解析 - RSA e=3ブロードキャスト攻撃
broadcast.jsonには同じ平文をパディングなしRSA・e=3で3つの互いに素なmodulusへ暗号化した結果があります。中国剰余定理と整数立方根で平文を復元してください。
未知のLinuxカーネルバージョンのメモリプロファイルを作成せよ
社内で `CONFIG_RANDSTRUCT` を有効にしてビルドしたカーネルで動くサーバーの、物理メモリの一部 `/home/ctfuser/evidence/custom_kernel.dump` を解析します。構造体のメンバーの並びがビルドごとに変わるため、既製のプロファイルは使えません。`evidence/vmlinux`(System.map と pahole 形式の構造体定義)から `task_struct` と `mm_struct` の配置を読み取り、`init_task` からプロセスのリストをたどってください。アドレスの変換式は `/home/ctfuser/README.md` にあります。 端末から起動された攻撃者のツールが、カーネルスレッド(kworker)を装って常駐しています。ツールは自分の設定(コマンドライン引数)を、そのプロセスの `start_time`(8バイト、リトルエンディアン)の SHA-256(32バイト)を繰り返した鍵で XOR して持っています。引数の中の設定からフラグを復元してください。`evidence/profiles/` の既製プロファイルは、このカーネルのものではありません。
独自プロトコルのC&C通信を解読せよ
侵害された端末 10.20.4.88 の通信を、出口のプロキシが記録していました。`/challenge/beacon.log` は1行が1回の送受信で、`data=` は送受信したバイト列の Base64 です。大半は正規のテレメトリですが、1つのホストとの通信はマルウェア独自のバイナリプロトコルです。`/challenge/implant_decompiled.c` は、検体から復元したフレームの組み立てと暗号化の処理(逆コンパイル結果)です。 プロトコルを読み解き、攻撃者がコマンド `cat` で読み出して持ち出したトークンを復元してください。回線上で壊れて再送されたフレームがあります。これは攻撃の実行ではなく、記録済みの通信を解析する防御側の演習です。