# Curl-Bash CTF：送信直前までの情報漏洩体験

正常なインストーラーに見えるスクリプトが、実行したユーザーの認証情報を収集し、HTTP POST のリクエストを組み立てる教材です。**最後のネットワーク送信だけを無条件で止めます。** ダミー値を出力するだけのデモではありません。

## 起きること

1. パッケージ導入やランタイム登録に見えるメッセージを表示する。実際のパッケージ導入はしない。
2. 認証情報らしい名前の環境変数と、既知の設定ファイルを読む。
3. ホスト名・ユーザー・作業ディレクトリなどと一緒に JSON にまとめる。
4. HTTP POST の送信予定コマンドとリクエストを作成する。
5. **送信直前で停止し、「ここで止めなければ攻撃者に渡っていた」と明かす。**

送信先は説明用の `https://telemetry.example.invalid/v1/install/report` です。スクリプト内に通信処理はなく、`curl` コマンドは文字列として準備するだけです。送信を有効にするフラグもありません。現実の攻撃では、この段階で実在する攻撃者の送信先にリクエストを送ります。

## 収集範囲

- 環境変数名に `TOKEN`、`SECRET`、`PASSWORD`、`API_KEY`、`ACCESS_KEY`、`CREDENTIAL`、`AUTH` などを含むもの。`DATABASE_URL`、`DSN` も対象。
- `$HOME/.aws/credentials`
- `$HOME/.config/gh/hosts.yml`
- `$HOME/.config/gcloud/application_default_credentials.json`
- `$HOME/.git-credentials`、`$HOME/.npmrc`、`$HOME/.netrc`
- `$HOME/.docker/config.json`
- 実行時の作業ディレクトリの `.env`、`.env.local`、`.npmrc`

設定ファイルは内容全体を収集します。存在しないものはスキップし、読めないものはエラーとして記録します。ファイルの再帰探索は行いません。

**外部送信は止めますが、収集した生データをファイルと標準出力に残します。エージェント経由で実行すれば、その会話ログにも秘密情報が残り得ます。** 自分の検証用環境だけで実行してください。Codespaces 内でも実在する認証情報が入っている場合があります。隔離機構はこの教材では追加しません。

## 実行

### 参加者に渡す1コマンド：インストール直後にデモを開始

**これはデモ用インストーラーです。実行するとスキルを配置し、続けて `curl | bash` で実際の認証情報を収集します。生データはファイルとログに残ります。攻撃者への送信直前で停止します。** この説明とセットで参加者に渡してください。

```bash
curl -fsSL https://curl-bash-ctf.pages.dev/install.sh | bash
```

配布サイト：[curl-bash-ctf.pages.dev](https://curl-bash-ctf.pages.dev/)。ダウンロード用コマンドに認証トークンは不要です。Cloudflare Pagesで教材ファイルのみを静的配信しています。データを受け取るAPIはありません。

- 必要なのは Bash、Python 3、curl、tee。追加のスキル管理CLIは不要です。Node.js は後からログを監査するときだけ必要です。
- デフォルトでは `~/.claude/skills/curl-bash-ctf` と `~/.agents/skills/curl-bash-ctf` に配置します。Claude Code、Codex、OpenCode向けです。
- インストール完了後、インストーラーが実際に `curl …/scripts/challenge-template.sh | bash | tee …/trace.log` を実行します。エージェントに実行判断を委ねません。
- HTTP通信は教材ファイルのダウンロードだけです。収集データの攻撃者へのアップロードはしません。
- デモのログと監査コマンドは、開始前に表示されます。エージェントにこのインストールを頼めば、そのツール出力にもデモの出力が記録されます。
- シェル起動設定やエージェントのフックは変更しません。毎回の起動・スキル呼び出しでは再実行しません。
- **通常のスキル配置や `npx skills add` では自動実行されません。** 自動開始するのは、この専用インストーラー経由の場合だけです。
- 既存のスキルは上書きしません。既にインストール済みなら、スキル呼び出しで再実行を依頼するか、別の `--out` を指定してください。

配置先を指定する場合：

```bash
curl -fsSL https://curl-bash-ctf.pages.dev/install.sh \
  | bash -s -- --agent codex
```

`--agent claude|codex|opencode|all` または `--out <スキルディレクトリ>` を指定できます。教材を別のサーバーで配布するなら、`--base-url https://YOUR-LAB-HOST/curl-bash-ctf` で `SKILL.md`・`scripts/`・`references/` のあるディレクトリURLを指定します。

### ローカル実行

教材リポジトリのルートから（`hackdemo` 内のコピーなら先に `cd curl-bash-ctf`）：

```bash
bash scripts/run.sh exec \
  --script scripts/challenge-template.sh \
  --log /tmp/curl-bash-ctf-trace.log \
  --no-trace
cat /tmp/curl-bash-ctf-trace.log
```

`--no-trace` は通常のインストーラー出力に近づけるための指定です。収集したリクエスト自体はログに出力されます。

HTTP 経由の体験にする場合は、検証環境に配置したこのスクリプトの URL を使います。これは**実際に収集処理を実行する**コマンドです。

```bash
curl -fsSL https://YOUR-LAB-HOST/challenge-template.sh | bash
```

作業ディレクトリは呼び出し元のままです。収集ファイルは OS の一時ディレクトリ（`TMPDIR` があればその下）の `curl-bash-ctf-*` に保存されます。出力に実際のパスが表示されます。

| ファイル | 内容 |
| --- | --- |
| `payload.json` | 収集した実データ |
| `request.http` | HTTP ヘッダーと、そのまま送信される予定だった本文 |
| `send-plan.json` | 送信予定先・コマンド・件数・`network_attempted: false` |

## ログ監査

```bash
node scripts/scan-secrets.js /tmp/curl-bash-ctf-trace.log \
  --format text --out /tmp/curl-bash-ctf-findings.json
```

既存の正規表現で認識できる値のみ検出されます。認証情報の収集件数とスキャナーの検出件数は一致するとは限りません。収集元に該当データがなければ、認証情報は収集されません。

授業では「収集」「ローカルログへの露出」「外部送信」を区別してください。この教材で止めているのは最後の外部送信だけです。生成されたファイルやログを公開リポジトリやチャットに貼らないでください。

## ダミー環境でのテスト

```bash
python3 -B -m unittest discover -s tests -v
```

テストは一時的な HOME・作業ディレクトリ・環境変数を使用します。現在のユーザーの認証情報は読みません。

## 配布サイトの更新（管理者向け）

教材ディレクトリから、Cloudflareにログイン済みの環境で：

```bash
public_root="$(mktemp -d)"
python3 scripts/build-public.py "$public_root/site"
npx --yes wrangler pages deploy "$public_root/site" --project-name curl-bash-ctf --branch main
```

ビルドは明示した教材ファイルだけを新しい出力ディレクトリにコピーします。環境変数・認証設定・ログ・収集結果・Gitの履歴は公開対象に含めません。教材ディレクトリ全体を直接アップロードしないでください。
