チャレンジ一覧
プログラミング - 独自プロトコルの解析
protocol.bin は起動のたびに作られるバイナリのキャプチャです(/challenge にあります)。KINO で始まる長さつきのフレームがいくつか並んでいます。フレームを先頭から順にたどり、type=3 のフレームの payload を 0x23 で XOR 復号するとフラグが現れます。フラグは平文では置かれていません。
プログラミング - 画像ステガノグラフィ
image.pgm は起動のたびに作られるテキスト形式(P2)の PGM 画像です(/challenge にあります)。画素値の最下位ビット(LSB)を先頭から集め、8ビットずつ1バイトにまとめて読むと、NUL(0 のバイト)の手前までがフラグです。フラグは平文では置かれていません。
メモリから不審なネットワーク接続を見つけよ
侵害されたホスト `kinoco-app03` のメモリイメージから、ソケット一覧 `/challenge/netstat_dump.txt` と、ESTABLISHED のソケットを持つプロセスごとのヒープ領域 `/challenge/heap_carve/pid_<PID>.bin` を復元しました。 カーネルスレッドに偽装した不審なプロセス(インプラント)が外部の C2 サーバーと通信していて、ビーコン設定(フラグを含む)をヒープに、平文ではない形で隠し持っています。ソケット一覧からそのプロセスを特定し、ヒープから設定を取り出してください。ほかのヒープには、フラグに似たおとりの文字列が混ざっています。 使えるツール: python3, grep, strings, xxd, awk
メモリから実行コマンドを復元せよ
メモリ文字列の記録 `memdump.txt` を解析し、実行されたコマンド履歴を復元してください。Base64 文字列をデコードし、bash へ渡している不審なコマンドの引数からフラグを取得します。
削除されたSQLiteレコードを復元せよ
社内チャット「kinoco-msg」の SQLite データベース `/challenge/app.db` を渡します。「機密メッセージ」として送られた本文は、次の形で保存されます。 body = "enc:v1:" + hex(本文 XOR 鍵ストリーム) 鍵ストリーム = SHA-256("<salt>|<sender>|<sent_at>|0") || SHA-256("<salt>|<sender>|<sent_at>|1") || ... salt = settings テーブルの secure_msg_salt(sender と sent_at は、そのメッセージの列の値) 管理者がワンタイムのアカウントリカバリートークンを機密メッセージで送り、すぐに削除しました。SELECT では見えない削除済みのレコードを復元し、本文を復号してトークン(フラグ)を取り出してください。 使えるツール: sqlite3, python3, xxd, strings, grep
多重に圧縮されたファイルを解凍せよ
`/challenge/artifact.xz` は、攻撃者が持ち出そうとしていたファイルで、gzip・bzip2・xz・zip・tar が何重にも重ねてあります。形式を1層ずつ見極めながら剥がし、最も深いところにある `flag.txt` からフラグを取り出してください。 途中のアーカイブには、README・ノイズ・偽の `flag.txt` などのおとりが一緒に入っている階層があります。ファイルの拡張子はあてになりません。 使えるツール: file, gzip, bzip2, xz, zip/unzip, tar, python3
暗号化されたディスクを復号せよ
`/challenge/secret_disk.img` は本物の LUKS2 コンテナで、データ領域にはバックアップ(tar アーカイブ)が入っています。パスフレーズは弱いもので、`/challenge/wordlist.txt` のどれかです。 このターミナルでは device-mapper が使えず、`cryptsetup open` でボリュームを開けません。キースロットから取り出したボリュームキーで、データ領域を自分で復号し、中のファイルからフラグを見つけてください。 使えるツール: cryptsetup, openssl, python3, dd, tar
暗号解析 - RSA共通モジュラス攻撃
2つのシステムが同じRSAの法nを使い回し、公開指数だけを変えていました。同じメッセージを e1 と e2 で暗号化した暗号文 c1, c2 が漏れています(public_keys.txt、ciphertexts.txt)。nは素因数分解できませんが、秘密鍵なしでメッセージを取り戻し、フラグを提出してください。
暗号解析 - 小さい素数のDiffie-Hellman
古いIoT機器が36ビットしかない素数pでDiffie-Hellman鍵共有をしていました。handshake.txtには p, g, A = g^a mod p, B = g^b mod p と、共有鍵から作った鍵ストリームで暗号化された設定データがあります。離散対数を解いて共有鍵を求め、設定データに含まれるフラグを取り出してください。鍵ストリームの作り方はREADME.mdにあります。
音声ファイルに隠されたデータ
`hidden.wav` にはオンオフ変調(OOK)で符号化されたメッセージが隠されています。トーンのオン/オフをビット化してデコードし、フラグを取得してください。 参照用のデコーダは付いていません。標準ライブラリの `wave` モジュールなどで、自分で信号を読み解きます。 提供ファイル: hidden.wav
Androidアプリから秘密鍵を抽出せよ
安全なZIP形式APK fixture(evidence/app.apk)を展開し、Androidリソースに記録された暗号化済みAPIシークレットを解析してください。開発者がビルドに同梱してしまった秘密鍵のうち、どれがそのシークレットに対応するかを見極めて復号します。実端末や実アプリは使用しません。
CloudTrailログから不正アクセスを検出せよ
AWS CloudTrail の書き出し `/challenge/cloudtrail.json` を解析し、盗まれたアクセスキーによる不正アクセスと、シークレットの持ち出しを追ってください。 攻撃者は偵察・権限昇格・新しいアクセスキーの作成のあと、読み出したシークレットを、その新しいキーで外部バケットへ S3 PutObject として分割して送りました(CloudTrail は GetSecretValue の値を記録しません)。オブジェクトキーは `<prefix>/<連番4桁>-<16進>.part` で、16進は6バイトずつの暗号文です。連番順に連結したバイト列は、SHA-256("<新しいアクセスキーID>:<カウンタ>")(カウンタは0から始まる10進の文字列)を順に連結した鍵ストリームと XOR されています。 許可済みのレッドチーム演習(送信元 192.0.2.50)も同じ手口で記録されています。演習ではなく、実際のインシデントで持ち出されたデータを復元してください。 提供ファイル: cloudtrail.json
Dockerイメージレイヤーから秘密を抽出せよ
`/challenge/image/` は `docker save`(OCI レイアウト)の書き出しを展開したものです。レイヤーは `blobs/sha256/` にダイジェスト名の gzip 圧縮した tar として置かれ、順番は `manifest.json` から読みます。 `/root/.aws/credentials` は複数のレイヤーで書き換えられ、クリーンアップのレイヤーで whiteout(削除マーカー)され、その後に別の値で作り直されています。最終ビューからは消えている、whiteout で削除された時点の credentials を回収し、その `aws_secret_access_key` の値を答えてください。ほかの秘密ファイルや、削除前後の別の値はおとりです。
Linux-カーネルモジュール. 脆弱なドライバでroot権限を得よ
このチャレンジは、脆弱なキャラクタデバイスドライバを安全なユーザー空間シミュレーションとして解析します。実際のカーネルモジュールはロードされません。root デーモンがドライバを /run/vulnerable.sock として公開し、あなたは非特権ユーザー challenger(uid 1000)として接続します。提供されたドライバソース vulnerable.c を読み、read/write の境界不備を突いて自分の資格情報を uid 0 に書き換え、GETFLAG でフラグを取得してください。
Linux-バッファオーバーフロー. gets()の脆弱性を突け
SUIDが付与された脆弱なCバイナリが用意されています。保護機構が無効化されたこのプログラムのバッファオーバーフローを突いて、隠された関数へ制御を移してください。
Python上級 - カスタムVMバイトコードの実行
program.kvmは独自の4レジスタVM用バイトコードです。READMEの命令仕様を基にPythonでインタプリタを実装し、VMの出力を復元してください。
TLS暗号化されたHTTPS通信を復号せよ
`~/evidence/` に、あるクライアント PC の HTTPS 通信を記録したキャプチャ `traffic.pcap`(libpcap 形式)と、ブラウザが書き出した TLS の鍵ログ `sslkeylog.txt`(NSS 形式)があります。鍵ログには、このキャプチャに含まれない通信の行も混ざっています。キャプチャ内の TLS 1.2 の通信を復号し、外部へ持ち出された情報(HTTP の POST の内容)からフラグを取得してください。通信は実際に傍受したものではなく、演習のために作った記録です。python3(cryptography)と openssl が使えます。
Web-26. User Profile Managerのプロトタイプ汚染
このNode.js/Express製アプリではログイン中のユーザーが自分のプロフィールを更新できます。更新処理に使われている再帰的なマージ関数が特殊なキーをきちんと除外しているか確認してみましょう。
Web-27. GraphQL APIのイントロスペクション漏洩
このGraphQL APIはUserオブジェクトのスキーマを公開しており、イントロスペクションが有効になっています。公式には案内されていないクエリやフィールドが存在しないか調べてみましょう。
Web-28. OAuth認可コードの横取り
このOAuth 2.0認可プロバイダーはログインフローを提供していますが、redirect_uriの検証が甘い可能性があります。認可コードを横取りして管理者権限のアクセストークンを得られないか確認してみましょう。
Web-29. MongoDBログインフォームのNoSQLインジェクション
このログインポータルはMongoDBを使っており、ユーザー名・パスワードをJSONとしてそのままクエリに組み込んでいます。パスワードを知らなくても管理者としてログインできないか確認してみましょう。
Web-30. KinoVaultの安全でないデシリアライズ
レガシーなバックアップシステム「KinoVault」は、ユーザーセッションをPythonのpickleでシリアライズしてCookieに保存していると噂されています。Cookieの形式を解析し、悪意あるpickleペイロードで権限を昇格できないか調べてみましょう。
バイナリ修復 - ファームウェアヘッダーとCRC32
firmware.bin の先頭4バイトを KINO に修復し、byte 12以降の CRC32 をリトルエンディアンで byte 8-11 に書き戻してください。修正ファイルを challenge.py に渡すと起動時注入 FLAG が表示されます。
プログラミング - C2通信の解析
起動のたびに乱数で作られた合成ログ beacon.log を解析します(ネットワーク接続は不要です)。複数の端末(セッション)の通信が時刻順に混ざっています。各セッションは最初の hello で nonce を送り、そのセッションの鍵は SHA-256(b"beacon-v1" + bytes.fromhex(nonce)) の先頭8バイトです。pulse の payload を seq の順につなぐと Base64 になり、それを復号して鍵で繰り返し XOR すると `task=... code=...` のような `キー=値` の平文になります(通信が途切れると同じ seq が再送されます)。task がちょうど `exfil` のセッションの code の値(16文字)が答えです。似た名前のタスクと取り違えないでください。答えを `python3 challenge.py '<答え>'` に渡すと、正解のときだけフラグが表示されます。