
元々はCVE-2026-20131用のハニーポット
低対話型ハニーポット。Cisco Secure Firewall Management Center(FMC)のWeb面を模倣し、認証を要しないJavaシリアライゼーション形式の攻撃トラフィック(CVE型の安全でないデシリアライゼーションプローブ)を捕捉します。
\xac\xed\x00\x05(およびBase64のrO0AB…)を検出し、正規表現とヒューリスティックを使用してシェルやURL文字列を抽出します。requests のみを使用して、実行不可のダウンロードボリュームに取得されます。1行JSONのログ(SplunkおよびELK互換)、オプションのTelegramアラート、ハッシュ化されたセカンドステージのアーティファクト、非rootコンテナユーザー。このプロジェクトは、追加の統合コードなしに特化したFMC型トラップを必要とする研究者を対象としています。
| 項目 | 備考 |
|---|---|
| Docker と Docker Compose v2 | Dockerのインストール |
| VPSまたはホスト | 専用または分離されたネットワークセグメントを推奨 |
| ドメイン(オプション) | HTTPS利用時: DNSを設定し、ホストへのインバウンド TCP 80 と TCP 443 を許可する |
git clone https://github.com/Hassan-Pouladi/Cisco-FMC-honeypot
cd FMC-Trap
cp .env.example .env
必要に応じて .env を編集してください(環境変数を参照)。同梱のCaddyの背後にデプロイする場合は、ログ内のクライアントIPアドレスが元のクライアントを反映するように、TRUST_X_FORWARDED_FOR=1 を設定してください。
Caddyfile を編集し、プレースホルダーのホスト名をご自身のドメイン(該当する場合は www も)に置き換えます:
example.com, www.example.com {
reverse_proxy fmc-trap:5000
}
オプションで、Let's Encryptの有効期限通知を受け取るために、Caddyfile 内のグローバルな email [email protected] ブロックのコメントを解除します。
yourdomain.com をサーバーのパブリックIPに、使用する場合は**www** も同様に設定します。ufw allow 80,443/tcp)。アプリケーションはコンテナ内でUID 10001 として実行されます。バインドマウントされた ./data ディレクトリは書き込み可能である必要があります:
mkdir -p data/logs data/downloads
sudo chown -R 10001:10001 data/logs data/downloads
正しい所有権がない場合、エクスプロイトのPOSTリクエストは500を返す可能性があります(ログや生のblobの書き込み時にPermission denied)。
docker compose up -d --build
docker compose ps
curl -sI https://yourdomain.com/
HTTP/2 200(または301や302)と**Via: Caddy** が返ることを確認します。ブラウザでは、https://yourdomain.com/ にシミュレートされたFMCログインページが表示されるはずです。
イベント、ペイロード、Docker出力の確認場所については、ログ、ダウンロード、サービス出力の確認と一般的な操作を参照してください。
以下はすべて、プロジェクトディレクトリ(docker-compose.yml を含むフォルダ。クローン後は通常 FMC-Trap)を基準としています。パスはホスト上のもので、Dockerがコンテナにバインドマウントします。
ログファイルに何かが表示されるタイミング: リクエストがデシリアライゼーションプローブの挙動(POST内のマジックバイト)に一致すると、fmc-trap.json は1行に1つのJSONオブジェクトを受け取ります。偽のログインページへの通常のGETリクエストは、デフォルトではこのファイルに書き込まれません。
ダウンロードフォルダにファイルがあるタイミング: パイプラインがプローブからURLを抽出し、ハーベスタがMAX_DOWNLOAD_MB以内で許可されたリモートコンテンツの取得に成功した場合のみ、エントリが表示されます。ディレクトリが空のままの場合は、該当するURLがまだないか、アプリケーションのポリシーによって取得がブロックされている可能性があります。
JSONの整形表示(オプション): 1行の場合は、python -m json.tool にパイプするか、インストール済みであれば jq を使用します。
Internet :443/:80 → Caddy (TLS, Let’s Encrypt) → fmc-trap:5000 (Gunicorn/Flask)
↓
./data/logs, ./data/downloads (bind mounts)
expose: "5000" を参照)。Composeはこれらの変数を**fmc-trap** サービスに渡します。詳細は docker-compose.yml を参照してください。
data/logs/fmc-trap.json の各行は1つのJSONオブジェクトです。一般的なキーには、timestamp、event_type、src_ip、headers、raw_payload_hash、extracted_commands があり、ファイルが保存された場合は downloaded_file_hash も含まれます。data/downloads/ に保存されたblobはモード0400(所有者のみ読み取り可能)です。
CaddyなしでGunicornに直接アクセスするには、docker-compose.yml の fmc-trap の下に次を追加します:
ports:
- "127.0.0.1:5000:5000"
CaddyがTLSを終端する本番環境では、アプリケーションを 0.0.0.0 にバインドしないでください。
.env にのみ保存してください(.env をコミットしないでください)。所有しているシステム、または計測機器のデプロイを明示的に許可されているシステムにのみデプロイしてください。ハニーポットは攻撃トラフィックやマルウェアを収集する可能性があります。適用される法律と組織のポリシーに従ってください。このソフトウェアはセキュリティ研究を目的としています。
| 内容 | ホスト上のパス | 開き方・追跡方法 |
|---|
| イベントログ(JSON Lines) | data/logs/fmc-trap.json | tail -f data/logs/fmc-trap.json(ライブストリーム)、またはエディタで開く、またはSplunkやELKに取り込む |
| ダウンロードされたセカンドステージペイロード | data/downloads/ | ハーベスタがリモートレスポンスを保存した場合のみファイルが表示されます。各ファイルはSHA256ハッシュ(64桁の16進数)で命名され、拡張子はありません。ls -la data/downloads(LinuxまたはmacOS)または Get-ChildItem data\downloads(Windows PowerShell)で一覧表示 |
| アプリケーションのプロセス出力 | ファイルではありません。Docker | docker compose logs -f fmc-trap |
| Caddy(TLS、プロキシ、ACME) | ファイルではありません。Docker | docker compose logs -f caddy |
| Telegramアラート(オプション) | data/ には保存されません | .env で TELEGRAM_BOT_TOKEN と TELEGRAM_CHAT_ID を設定。イベントがログに記録されるとアラートが発火します |
| 目的 | コマンドまたは操作 |
|---|
| コンテナが稼働しているか確認 | docker compose ps |
.env または Caddyfile 編集後に再起動 | docker compose up -d --build(envのみ変更の場合は docker compose up -d --force-recreate) |
| スタックを停止 | docker compose down |
| 新しいJSONイベントを継続的に追跡 | tail -f data/logs/fmc-trap.json |
| 直近のイベントを確認 | tail -n 50 data/logs/fmc-trap.json |
| ダウンロードされたアーティファクトの数を数える | ファイルマネージャで data/downloads を開くか、そのディレクトリでシェルのファイル数カウントを使用(ファイルはSHA256で命名) |
| ハニーポットページが読み込まれることを確認 | ブラウザで https://yourdomain.com/ を開くか、確認手順と同様に curl -sI を使用 |
| 変数 | 目的 | デフォルト / 備考 |
|---|
TRUST_X_FORWARDED_FOR | 最初の X-Forwarded-For ホップを src_ip として使用 | Caddy使用時は 1 を推奨 |
DECEPTION_STATUS | 200 はHTMLボディを返し、302 はリダイレクトを返す | 200 |
DECEPTION_REDIRECT_URL | ステータスが 302 のときのリダイレクト先パス | / |
MAX_DOWNLOAD_MB | URLごとのハーベスタの上限 | 16 |
TELEGRAM_BOT_TOKEN / TELEGRAM_CHAT_ID | オプションのアラート | 空の場合はアラート無効 |
FMC_SERVER_HEADER | Server レスポンスヘッダー | nginx |
VT_API_KEY | 予約済み | オプション |
| 症状 | 解決方法 |
|---|
data/ 配下への書き込み時に Permission denied | sudo chown -R 10001:10001 data/logs data/downloads を実行 |
Bind for 0.0.0.0:80 failed: port is already allocated | 別のサービスまたはコンテナが80にバインドされています。そのサービスを停止するか80を解放してください。ホストごとに80で待ち受けできるプロセスは1つのみです。 |
| CaddyログでLet's EncryptまたはACMEエラー | DNSがこのサーバーを解決し、80と443がインターネットから到達可能であることを確認してください。ホストのリゾルバがDocker内で失敗する場合、ComposeはCaddy にDNS 1.1.1.1と8.8.8.8を設定します。 |
HTTPSへの**curl** が空の出力を返す、または最初の試行で失敗する | docker compose logs caddy に certificate obtained successfully が表示されるまで待ちます。 |
ログ内のクライアントIPが 172.x.x.x | Caddy使用時は TRUST_X_FORWARDED_FOR=1 を設定し、コンテナを再作成: docker compose up -d --force-recreate |