チャレンジ一覧
正規表現エキスパート - データバリデーション
/challenge/data.txt には受付記録が400行あり、各行にメールアドレス・電話番号・IPアドレス・日付が行ごとに違う順番・ラベルで並び、最後に memo="..." があります。書式が壊れた項目や、項目が無い行もあります。 次の条件をすべて正しい書式で1行に含む行はただ1行で、その行の memo がフラグです。 1. メールアドレス(xxx@yyy.zzz) 2. 電話番号(xxx-xxxx-xxxx または xxx.xxxx.xxxx。数字の桁数はこのとおり) 3. IPアドレス(xxx.xxx.xxx.xxx。数字1〜3桁を4つ) 4. 日付(YYYY-MM-DD) memo に KINOCO{...} の形の値を持つ行はほかにもありますが、どれも1つの条件が欠けています。正規表現を組み合わせて絞り込んでください。
音声ファイルに隠されたデータ
`hidden.wav` にはオンオフ変調(OOK)で符号化されたメッセージが隠されています。トーンのオン/オフをビット化してデコードし、フラグを取得してください。 参照用のデコーダは付いていません。標準ライブラリの `wave` モジュールなどで、自分で信号を読み解きます。 提供ファイル: hidden.wav
高度な自動化 - ディレクトリ監視スクリプト
`/challenge/logs/` に Web フロントエンド4台分のアクセスログ(combined log format、60ファイル・10万行超)があります。WAF は多数の送信元IPについて、それぞれ1行だけ `waf_rule=... note=...` を書き残しており、どの note もフラグの形をしています。フラグは、ステータスコード 404 のリクエスト数が最も多い送信元IPの行にある note です。404 が少し少ない別のスキャナー、総リクエスト数が最多のIP(ほとんど 200)、403 が最多のIP、通常の客のIPにも note があり、これらはおとりです。404 を IP ごとに集計して特定してください。
AWS CLI - S3バケット調査
S3 の設定をオフラインでエクスポートした監査記録が `/challenge/s3_audit/` にあります(`buckets.json` と、バケットごとの `*_publicaccessblock.json`・`*_policy.json`・`*_acl.json`・`*_objects.json`)。機密オブジェクト(`backups/prod.env` または `credentials/service-account.json`)を持つバケットは多数あり、どの `object_preview` にもフラグの形をした値があります。フラグは、本当に世界中に公開されているただ1つのバケットの機密オブジェクトにある値です。その条件は、(1) PublicAccessBlock の4設定がすべて false で、(2) ポリシーに `Effect: Allow`・`Principal: "*"`・`Action` に `s3:GetObject` を含み・`Resource` に `arn:aws:s3:::<バケット名>/*` を含み・`Condition` が無い statement があることです。ほかのバケットは、このどれか1つだけを外したおとりです。
Androidアプリから秘密鍵を抽出せよ
安全なZIP形式APK fixture(evidence/app.apk)を展開し、Androidリソースに記録された暗号化済みAPIシークレットを解析してください。開発者がビルドに同梱してしまった秘密鍵のうち、どれがそのシークレットに対応するかを見極めて復号します。実端末や実アプリは使用しません。
Ansible自動化 - サーバー構成管理
Ansibleや実サーバーを実行せず、生成済みの実行記録 artifacts/ansible/vault-export.yml を解析してください。記録には多数のタスク結果があり、そのうち多くに vault_payload_hex が付いています。本物は、host が web-03、task が deploy-index、status が changed の3つがすべて一致する1件だけです(名前の一部だけが一致する記録や、成功していない記録はおとりです)。値は Ansible vault の本体と同じく16進で書かれていて、16進を戻すと Base64 の文字列になります。それをさらに戻すとフラグです。
CI/CDセキュリティ - GitHub Actions 脆弱性
`/challenge/repo/.github/workflows/` にある20個の GitHub Actions ワークフローを監査します。多くのステップに `# audit-ticket: KINOCO{...}` というコメントが付いています。次の3条件をすべて満たす「pwn request」脆弱性を持つワークフローは1つだけで、そのステップの audit-ticket がフラグです。(1) トリガーが `pull_request_target`。(2) あるジョブが、チェックアウトの `ref:` に `github.event.pull_request.head.sha` や `head.ref` を指定して PR の head を明示的にチェックアウトしている。(3) その同じジョブが `secrets.*` を参照している。どれか1つでも欠けるワークフローはおとりです。
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` の値を答えてください。ほかの秘密ファイルや、削除前後の別の値はおとりです。
Infrastructure as Code - Terraform セキュリティ
Terraform providerを初期化せず、生成済みの terraform/terraform.tfstate を解析してください。outputs の recovery_secret_arn が、復旧用シークレットの ARN を指しています。resources の aws_secretsmanager_secret_version のうち、secret_id がその ARN と完全に一致し、version_stages に AWSCURRENT を含む版が現在の値です。その secret_string(JSON を文字列にしたもの)の recovery_token を Base64 デコードするとフラグになります。
Kubernetes入門 - クラスター調査
実Kubernetesクラスターへ接続せず、artifacts/kubernetes/ の2つのスナップショット(pod-snapshot.yaml と secret-snapshot.yaml)を調べてください。namespace security-lab の Pod suspicious-audit-pod は、環境変数 AUDIT_TOKEN を Secret から読んでいます。その secretKeyRef が指す Secret(同じ namespace で同じ名前)の、指定されたキーの値を Base64 デコードするとフラグになります。別の namespace の同名の Pod や Secret、似た名前の Secret、同じ Secret の別のキーはおとりです。
Linux-カーネルモジュール. 脆弱なドライバでroot権限を得よ
このチャレンジは、脆弱なキャラクタデバイスドライバを安全なユーザー空間シミュレーションとして解析します。実際のカーネルモジュールはロードされません。root デーモンがドライバを /run/vulnerable.sock として公開し、あなたは非特権ユーザー challenger(uid 1000)として接続します。提供されたドライバソース vulnerable.c を読み、read/write の境界不備を突いて自分の資格情報を uid 0 に書き換え、GETFLAG でフラグを取得してください。
Linux-バッファオーバーフロー. gets()の脆弱性を突け
SUIDが付与された脆弱なCバイナリが用意されています。保護機構が無効化されたこのプログラムのバッファオーバーフローを突いて、隠された関数へ制御を移してください。
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ペイロードで権限を昇格できないか調べてみましょう。
カスタムツール開発 - Webディレクトリスキャナー
ライブWebサイトを走査せず、ローカル生成された artifacts/scanner/directory-report.ndjson を解析してください。スキャナーは同じサイトを複数回(run)走査しています。最新の run で、path がちょうど /secret_admin/backup、status が 200 の記録だけが本物です。その body_b64 は gzip で圧縮した応答本文を Base64 にしたもので、戻すとフラグになります。
ネットワークトンネリング - SSH ポートフォワーディング
単一コンテナ内でSSHローカルポートフォワーディングを練習します。SSHは127.0.0.1:22、内部サービスは/run/tunnel/database.sockにあります。内部ソケットはローカルのプレイヤーから直接アクセスできません。転送専用ユーザーtunnel(パスワードpassword123)でSSH認証し、127.0.0.1:8888へ転送して応答を取得してください。外部ホストや実データベースは使用しません。
メモリからマルウェアのペイロードを抽出せよ
`/challenge/memstrings.txt` は、不審なプロセスのアドレス空間から取り出した文字列です。ローダーが展開した第2段ペイロード(Base64)が、おとりの文字列や Base64 に紛れています。`/challenge/malfind_region.txt` には、ファイルの裏付けが無い RWX 領域にある、ローダーのデコード処理の逆アセンブルと、同じ領域のデータ部の16進ダンプがあります。逆アセンブルからローダーが何をしているかを読み取り、第2段ペイロード(無害なドロッパーの記録で、何も実行しません)を復元して、campaign tag からフラグを取得してください。
メモリから隠されたカーネルモジュールを検出せよ
LKM ルートキットに感染した疑いのある Linux ホストのメモリから、モジュールの情報を3つ復元しました。`/challenge/modules_list.txt` はカーネルの modules 連結リスト(lsmod 相当)、`/challenge/sysfs_modules.txt` は `/sys/module/<name>/` の kobject とモジュールのアドレス情報、`/challenge/module_area.lime` は各モジュールのコア領域の先頭 8 KiB を LiME 形式(ヘッダー32バイト: magic, version, 開始アドレス, 終了アドレス, 予約)で並べたものです。連結リストから自身を外した隠しモジュールを特定し、その設定を取り出してフラグを取得してください。設定は、そのモジュールのコア領域の先頭から 0x200 バイト目に「長さ(2バイト、リトルエンディアン)+暗号化された本文」の形で置かれています。本文は、sysfs_modules.txt のそのモジュールの SrcVersion を材料に、SHA-256(`<SrcVersion>:<カウンタ>`)(カウンタは 0,1,2... の10進数)を連ねた鍵ストリームと XOR したものです。sysfs にしか無い名前には、組み込みコンポーネントやアンロード中のモジュールも混ざり、隠しモジュール以外にもおとりの設定を持つモジュールがあります。
多段階ステガノグラフィを解読せよ
`/challenge/cover.png` と `/challenge/notes.txt` に、3段階のステガノグラフィが仕掛けられています。各段階に、次の段階を読むための鍵(パスフレーズや符号の対応表)が入っていて、鍵は起動のたびに変わるため、途中を飛ばすことはできません。`cover.png` のピクセルの最下位ビット(先頭32ビットがバイト数)、PNG の `IEND` の後ろに付け足されたデータ、`notes.txt` に紛れたゼロ幅文字、の順にたどってフラグを取得してください。各段階におとりも混ざっています。