チャレンジ一覧
Chromeブラウザからセッションクッキーを抽出せよ
Linux 版 Chrome のプロファイルから取り出した `/challenge/Cookies` と `/challenge/History`(どちらも SQLite)を渡します。 被害者は、社内メールのリンクから偽の SSO ページを経由して、ある社内管理画面にログインしました。その管理画面の `admin_session_id` クッキーの値(フラグ)を取り出してください。管理画面はいくつもあり、どの管理画面のクッキーも同じ形をしています。Cookies の値は暗号化されています。 使えるツール: sqlite3, openssl, python3, xxd
DNSトンネリングを検出せよ
DNS クエリの記録 `dns_queries.log` を解析し、DNS トンネリングによるデータ流出を検出してください。単一ドメインへ長いラベルの問い合わせを大量に出しているホストを見つけ、ラベルを seq 順に並べて hex デコードするとフラグになります。
Docker フォレンジック - コンテナ調査
Docker デーモンの無い環境で、イメージ `registry.internal/kinoco-billing-api:2.4.1` のメタデータを調べます。`/challenge/image_history.txt`(`docker history --no-trunc` 相当、新しいレイヤーが上)と `/challenge/image_config.json`(最終的な `Config.Env` と、古い順の `History[].created_by`)があります。この Dockerfile は `DB_ADMIN_PASSWORD` を `ENV` で何度も設定し直し、途中で一度だけ `python3 scripts/bootstrap_admin.py`(環境変数 `DB_ADMIN_PASSWORD` を読む)を実行し、最後に空で上書きしました。履歴にはフラグの形をした値がいくつもあります。フラグは、bootstrap_admin.py を実行した時点で有効だった `DB_ADMIN_PASSWORD` の値、つまりビルド順でそのRUNより前にある最後の `ENV DB_ADMIN_PASSWORD=...` の値です。それより前に上書きされた値、後に設定された値、別の変数の値、別のスクリプトにだけインラインで渡した値はおとりです。
Git履歴から削除されたAPIキーを探せ
/app/repo はGitリポジトリです。開発者がAPI_KEYを誤ってコミットし、後続コミットで削除しました。 通常のGit履歴から削除前の config.py を確認し、APIキーに含まれるフラグを見つけてください。
Linux-Capabilities. SUIDに頼らない権限昇格
このシステムでは特定のバイナリにLinux capabilitiesが付与されています。SUIDビットではなくcapabilitiesを使った権限昇格の手法を探してみましょう。
Linux-SUID悪用. findバイナリで権限昇格せよ
このシステムにはSUIDビットが付与された find コマンドのコピーがあります。GTFOBinsで知られる手法を使い、root権限のシェルを取得してください。
Linux-procメモリ. プロセスの環境変数を覗き見よ
バックグラウンドで動き続けるデーモンプロセスがあり、その環境変数の1つにフラグが設定されています。/procファイルシステムを使ってプロセスの情報を調べてください。
Linux-strace. システムコールを追ってファイルを暴け
標準出力にもファイルにも何も残さないバイナリが用意されています。このプログラムは隠しファイルから鍵を読み、メモリ上でフラグを復元して /dev/null へ書き込みます。straceでシステムコールを追跡し、どの引数にフラグが現れるかを突き止めてください。
Linux-競合状態. TOCTOUの隙を突いてroot権限のファイルを奪え
rootが定期的に実行するクリーンアップスクリプトには、チェックと処理の間に隙(TOCTOU)があります。シンボリックリンクをうまく使ってこの隙を悪用してみてください。
NTFS $MFTから削除ファイルの痕跡を探せ
Windows 端末 `KINOCO-WS07` の `$MFT` をレコード単位のテキストに書き出した `/challenge/mft_records.txt`(先頭にクラスタサイズとダンプの開始 LCN があります)と、ボリューム C: のクラスタの生データ `/challenge/cluster_dump.bin` を渡します。 ユーザー yuki が削除した `secret_note.txt.gz` は非常駐(non-resident)で、断片に分かれてディスクに残っています。MFT の `$DATA` に残るデータラン(RunList)の生バイトを読み解いて断片を集め、元のファイルを復元して、フラグを取り出してください。常駐データに見える文字列は、答えとは限りません。 使えるツール: python3, xxd, dd, gzip, grep, awk
Python自動化 - REST API データ収集
コンテナ内で `http://127.0.0.1:8000/api/records?page=N` というページ送りのローカルAPIが動いています。`next` が `null` になるまで全ページを巡回し、`tag == "flag"` のレコードだけを集めてください。各レコードは `{"seq": <int>, "part": "<断片>"}` の形式で、`seq` の昇順に `part` を連結するとフラグになります。1ページ目だけではフラグは揃わず、`login`/`metric`/`order` などのレコードはおとりです。
SQLクエリマスター - 複雑な結合
SQLite データベース `/challenge/company.db` には3つのテーブルがあります。 - employees (id, name, department_id, salary, email, note) - departments (id, name, manager_id) - projects (id, name, department_id, budget) 次の条件で従業員を1人選んでください。 1. budget が 100000 以上のプロジェクトを1つ以上持つ部署(小さいプロジェクトの合計が 100000 を超えても対象外) 2. それらの部署に所属する従業員の中で salary が最も高い人 その人の note 列がフラグです。各部署の最高給の従業員の note にはどれも KINOCO{...} の形の値が入っているので、条件を1つでも外すと別の人が選ばれます。
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で作られており、入力したメッセージをそのままテンプレートエンジンでレンダリングしています。テンプレート構文がどこまで実行されてしまうか調べてみましょう。
イベントログからブルートフォース攻撃を検出せよ
サーバー `kinoco-srv01` の sshd 認証ログ `/challenge/auth.log` を解析し、ブルートフォース攻撃を成功させた攻撃者のセッションを特定してください。 このサーバーはハニーポットで、セッションを開くたびに PAM モジュールがカナリアトークンを発行し、次の形でマスクして記録します。 sshd[PID]: pam_canary(sshd:session): token issued for USER: <hex> hex = トークン(ASCII 文字列)の各バイトを、SHA-256("<PID>:<送信元ポート>") のダイジェスト 32 バイトを繰り返したものと XOR し、16進にしたもの PID と送信元ポートは、そのセッションの `Accepted password` 行の値です。全セッションが同じ形のトークンを持つので、どれが攻撃者のものかは、ログイン失敗の様子から決める必要があります。フラグは、攻撃者のセッションのトークンです。 使えるツール: python3, grep, awk
システムコール追跡 - strace デバッグ
ソースコードのないプログラム `/app/mystery_program` を strace でトレースした記録 `/challenge/strace.log` を解析します。プログラムはトークンらしい中身(`KINOCO{...}` の形)のファイルをいくつも読み込みますが、(1) 隠しディレクトリ(名前が `.` で始まるディレクトリ)の中のファイルであり、かつ (2) `read` したその中身をあとで標準出力(fd 1)に `write` している、という2条件を両方満たすものはただ1つです。その中身がフラグです。普通のディレクトリにあるドットファイルは (1) を満たしません。fd 番号は `close` の後に使い回されます。
システムログ解析 - journalctl マスター
systemd ジャーナルを `journalctl -o short` 風に書き出したログ `/challenge/system.log` を解析します。各行は「日時 ホスト ユニット[PID]: 優先度: メッセージ」の形です。ユニットの欄が `authd` で、優先度の欄が `ERR` の行はただ1行で、その行のメッセージにフラグが含まれます。`KINOCO{...}` の形の文字列はほかの行にもありますが、ユニットが `authd-proxy` など別物だったり、本文に authd や ERR という文字が出てくるだけだったりします。コンテナに journalctl は無いので、`grep`/`awk` で欄の位置を見て絞り込んでください。
ネットワークマスター - Netcat リバースシェル
外部ホストへ接続せず、記録済みの artifacts/netcat/callback-transcript.log を解析してください。リスナーやシェルは起動されません。侵害されたホスト 10.0.5.23 から remote.target.com の 4444 番ポートへつながったコールバックを接続一覧から探し、その conn ID で「captured first bytes」の16進データを引き当て、文字列に戻すとフラグになります。送信元・宛先ホスト・宛先ポートのどれかが違う接続はおとりです。
パフォーマンス解析 - リソースホッグを見つけろ
サーバーのスナップショット `/challenge/metrics.log` を解析します。前半は top 風のプロセス一覧(%CPU は9列目、%MEM は10列目)、後半は ps -ef 風のフルコマンドライン一覧です。%CPU が 50.0 以上かつ %MEM が 20.0 以上のプロセスはただ1つで、その PID の ps -ef 行の `--token=` 引数がフラグです。`--token=KINOCO{...}` を持つプロセスはほかにもあり、%CPU 最大・%MEM 最大のプロセスはどちらも条件を両方は満たしません。
メモリから不審なネットワーク接続を見つけよ
侵害されたホスト `kinoco-app03` のメモリイメージから、ソケット一覧 `/challenge/netstat_dump.txt` と、ESTABLISHED のソケットを持つプロセスごとのヒープ領域 `/challenge/heap_carve/pid_<PID>.bin` を復元しました。 カーネルスレッドに偽装した不審なプロセス(インプラント)が外部の C2 サーバーと通信していて、ビーコン設定(フラグを含む)をヒープに、平文ではない形で隠し持っています。ソケット一覧からそのプロセスを特定し、ヒープから設定を取り出してください。ほかのヒープには、フラグに似たおとりの文字列が混ざっています。 使えるツール: python3, grep, strings, xxd, awk
メモリから実行コマンドを復元せよ
メモリ文字列の記録 `memdump.txt` を解析し、実行されたコマンド履歴を復元してください。Base64 文字列をデコードし、bash へ渡している不審なコマンドの引数からフラグを取得します。