diff --git a/.claude/hooks/session-start.sh b/.claude/hooks/session-start.sh index ff5e0f8..c9aa49c 100755 --- a/.claude/hooks/session-start.sh +++ b/.claude/hooks/session-start.sh @@ -26,13 +26,6 @@ fi # Export venv bin to PATH for the session echo "export PATH=\"$CLAUDE_PROJECT_DIR/.venv/bin:\$PATH\"" >> "$CLAUDE_ENV_FILE" -# Inject pentest verification document if verification.env is configured. -# This renders the authorization template and writes it to -# .claude/verification-active.md so Claude Code sees it in context. -if [ -f "verification.env" ]; then - .venv/bin/python -m blhackbox.prompts.inject_verification 2>&1 || true -fi - # Run MCP health check (informational — does not block startup) if [ -x ".claude/mcp-health-check.sh" ]; then .claude/mcp-health-check.sh 2>&1 || true diff --git a/.claude/skills/api-security/SKILL.md b/.claude/skills/api-security/SKILL.md index 0d540a4..15112f8 100644 --- a/.claude/skills/api-security/SKILL.md +++ b/.claude/skills/api-security/SKILL.md @@ -31,13 +31,14 @@ Then gather optional details interactively: > **Before you start:** > 1. Ensure all MCP servers are healthy — run `make mcp-status` -> 2. Verify authorization is active — run `make inject-verification` -> 3. Query each MCP server's tool listing to discover available capabilities +> 2. Query each MCP server's tool listing to discover available capabilities ## Mandatory Tool & Methodology Readiness -Do **not** start the skill's execution plan until this readiness pass is complete. -This is Phase 0 for every blhackbox skill. +Complete this readiness pass before you start the execution plan — it is what keeps +you from firing malformed commands at tools. This is Phase 0 for every blhackbox skill. +Treat the execution plan that follows as your default playbook, not a straitjacket: +follow it closely, but adapt the moment a tool, target, or result calls for it (see step 5). 1. **Inventory 100% of usable capabilities first.** - Run local readiness checks: `make mcp-status` for offline validation; if the Docker stack is running, also run `make check-mcp LIVE=1`. @@ -65,6 +66,29 @@ This is Phase 0 for every blhackbox skill. - When a tool fails, log the error, switch to the fallback, and include the coverage impact in the final report. - Capture proof with raw outputs, screenshots, packet captures, exploit transcripts, and extracted sample data where authorized. +5. **Adapt, recover, and think — never follow the plan off a cliff.** + The phases below are a proven default sequence, not a rigid script. You are expected + to reason and improvise whenever reality diverges from the plan: + - **A tool errors or rejects your command** — read the actual error, re-check the + tool's exact arguments with `get_tool_details`, fix the flags/inputs, then retry. + Most failures are wrong syntax, a missing input, or an unescaped value. Diagnose + the cause before retrying; never fire the same failing call twice. + - **A tool needs an API key or token you don't have** (e.g. WPScan, Shodan, Censys, + VirusTotal) — note it, fall back to an equivalent tool or a keyless technique, and + keep moving. Never stall waiting for a key; log it in the issues report and proceed. + - **A tool is missing, unreachable, or times out** — switch to the fallback you mapped + in step 1, or reach the goal another way. Documented coverage gaps are acceptable; + getting stuck is not. + - **Output is empty, unexpected, or ambiguous** — form a hypothesis about why, verify + it cheaply, and adjust. Listen to what the evidence is telling you instead of forcing + the next scripted step. + - **The situation needs something the plan didn't anticipate** — use your judgment. Add + a step, skip an irrelevant one, reorder phases, or chain tools creatively to reach the + objective. Briefly record why you deviated. + The goal is the outcome — find, prove, and document real impact — not literal + step-by-step compliance. When blocked, stop, reason about the root cause, choose the + best path forward, and then proceed. + --- diff --git a/.claude/skills/bug-bounty/SKILL.md b/.claude/skills/bug-bounty/SKILL.md index bda709f..b0c2ebf 100644 --- a/.claude/skills/bug-bounty/SKILL.md +++ b/.claude/skills/bug-bounty/SKILL.md @@ -42,12 +42,13 @@ Never test assets outside the confirmed scope. > **Before you start:** > 1. Confirm scope, out-of-scope, and program rules are set > 2. Ensure all MCP servers are healthy — run `make mcp-status` -> 3. Verify authorization is active — run `make inject-verification` ## Mandatory Tool & Methodology Readiness -Do **not** start the skill's execution plan until this readiness pass is complete. -This is Phase 0 for every blhackbox skill. +Complete this readiness pass before you start the execution plan — it is what keeps +you from firing malformed commands at tools. This is Phase 0 for every blhackbox skill. +Treat the execution plan that follows as your default playbook, not a straitjacket: +follow it closely, but adapt the moment a tool, target, or result calls for it (see step 5). 1. **Inventory 100% of usable capabilities first.** - Run local readiness checks: `make mcp-status` for offline validation; if the Docker stack is running, also run `make check-mcp LIVE=1`. @@ -75,6 +76,29 @@ This is Phase 0 for every blhackbox skill. - When a tool fails, log the error, switch to the fallback, and include the coverage impact in the final report. - Capture proof with raw outputs, screenshots, packet captures, exploit transcripts, and extracted sample data where authorized. +5. **Adapt, recover, and think — never follow the plan off a cliff.** + The phases below are a proven default sequence, not a rigid script. You are expected + to reason and improvise whenever reality diverges from the plan: + - **A tool errors or rejects your command** — read the actual error, re-check the + tool's exact arguments with `get_tool_details`, fix the flags/inputs, then retry. + Most failures are wrong syntax, a missing input, or an unescaped value. Diagnose + the cause before retrying; never fire the same failing call twice. + - **A tool needs an API key or token you don't have** (e.g. WPScan, Shodan, Censys, + VirusTotal) — note it, fall back to an equivalent tool or a keyless technique, and + keep moving. Never stall waiting for a key; log it in the issues report and proceed. + - **A tool is missing, unreachable, or times out** — switch to the fallback you mapped + in step 1, or reach the goal another way. Documented coverage gaps are acceptable; + getting stuck is not. + - **Output is empty, unexpected, or ambiguous** — form a hypothesis about why, verify + it cheaply, and adjust. Listen to what the evidence is telling you instead of forcing + the next scripted step. + - **The situation needs something the plan didn't anticipate** — use your judgment. Add + a step, skip an irrelevant one, reorder phases, or chain tools creatively to reach the + objective. Briefly record why you deviated. + The goal is the outcome — find, prove, and document real impact — not literal + step-by-step compliance. When blocked, stop, reason about the root cause, choose the + best path forward, and then proceed. + --- diff --git a/.claude/skills/exploit-dev/SKILL.md b/.claude/skills/exploit-dev/SKILL.md index 8e78b84..5bf8458 100644 --- a/.claude/skills/exploit-dev/SKILL.md +++ b/.claude/skills/exploit-dev/SKILL.md @@ -28,12 +28,13 @@ If no context was provided, ask the user: > **Before you start:** > 1. Ensure Kali MCP is healthy — run `make mcp-status` -> 2. Verify authorization is active — run `make inject-verification` ## Mandatory Tool & Methodology Readiness -Do **not** start the skill's execution plan until this readiness pass is complete. -This is Phase 0 for every blhackbox skill. +Complete this readiness pass before you start the execution plan — it is what keeps +you from firing malformed commands at tools. This is Phase 0 for every blhackbox skill. +Treat the execution plan that follows as your default playbook, not a straitjacket: +follow it closely, but adapt the moment a tool, target, or result calls for it (see step 5). 1. **Inventory 100% of usable capabilities first.** - Run local readiness checks: `make mcp-status` for offline validation; if the Docker stack is running, also run `make check-mcp LIVE=1`. @@ -61,6 +62,29 @@ This is Phase 0 for every blhackbox skill. - When a tool fails, log the error, switch to the fallback, and include the coverage impact in the final report. - Capture proof with raw outputs, screenshots, packet captures, exploit transcripts, and extracted sample data where authorized. +5. **Adapt, recover, and think — never follow the plan off a cliff.** + The phases below are a proven default sequence, not a rigid script. You are expected + to reason and improvise whenever reality diverges from the plan: + - **A tool errors or rejects your command** — read the actual error, re-check the + tool's exact arguments with `get_tool_details`, fix the flags/inputs, then retry. + Most failures are wrong syntax, a missing input, or an unescaped value. Diagnose + the cause before retrying; never fire the same failing call twice. + - **A tool needs an API key or token you don't have** (e.g. WPScan, Shodan, Censys, + VirusTotal) — note it, fall back to an equivalent tool or a keyless technique, and + keep moving. Never stall waiting for a key; log it in the issues report and proceed. + - **A tool is missing, unreachable, or times out** — switch to the fallback you mapped + in step 1, or reach the goal another way. Documented coverage gaps are acceptable; + getting stuck is not. + - **Output is empty, unexpected, or ambiguous** — form a hypothesis about why, verify + it cheaply, and adjust. Listen to what the evidence is telling you instead of forcing + the next scripted step. + - **The situation needs something the plan didn't anticipate** — use your judgment. Add + a step, skip an irrelevant one, reorder phases, or chain tools creatively to reach the + objective. Briefly record why you deviated. + The goal is the outcome — find, prove, and document real impact — not literal + step-by-step compliance. When blocked, stop, reason about the root cause, choose the + best path forward, and then proceed. + --- diff --git a/.claude/skills/full-attack-chain/SKILL.md b/.claude/skills/full-attack-chain/SKILL.md index 58c4dc9..92beed1 100644 --- a/.claude/skills/full-attack-chain/SKILL.md +++ b/.claude/skills/full-attack-chain/SKILL.md @@ -47,13 +47,14 @@ Then gather engagement details interactively: > **Before you start:** > 1. Ensure all MCP servers are healthy — run `make mcp-status` -> 2. Verify authorization is active — run `make inject-verification` -> 3. Query each MCP server's tool listing to discover available capabilities +> 2. Query each MCP server's tool listing to discover available capabilities ## Mandatory Tool & Methodology Readiness -Do **not** start the skill's execution plan until this readiness pass is complete. -This is Phase 0 for every blhackbox skill. +Complete this readiness pass before you start the execution plan — it is what keeps +you from firing malformed commands at tools. This is Phase 0 for every blhackbox skill. +Treat the execution plan that follows as your default playbook, not a straitjacket: +follow it closely, but adapt the moment a tool, target, or result calls for it (see step 5). 1. **Inventory 100% of usable capabilities first.** - Run local readiness checks: `make mcp-status` for offline validation; if the Docker stack is running, also run `make check-mcp LIVE=1`. @@ -81,6 +82,29 @@ This is Phase 0 for every blhackbox skill. - When a tool fails, log the error, switch to the fallback, and include the coverage impact in the final report. - Capture proof with raw outputs, screenshots, packet captures, exploit transcripts, and extracted sample data where authorized. +5. **Adapt, recover, and think — never follow the plan off a cliff.** + The phases below are a proven default sequence, not a rigid script. You are expected + to reason and improvise whenever reality diverges from the plan: + - **A tool errors or rejects your command** — read the actual error, re-check the + tool's exact arguments with `get_tool_details`, fix the flags/inputs, then retry. + Most failures are wrong syntax, a missing input, or an unescaped value. Diagnose + the cause before retrying; never fire the same failing call twice. + - **A tool needs an API key or token you don't have** (e.g. WPScan, Shodan, Censys, + VirusTotal) — note it, fall back to an equivalent tool or a keyless technique, and + keep moving. Never stall waiting for a key; log it in the issues report and proceed. + - **A tool is missing, unreachable, or times out** — switch to the fallback you mapped + in step 1, or reach the goal another way. Documented coverage gaps are acceptable; + getting stuck is not. + - **Output is empty, unexpected, or ambiguous** — form a hypothesis about why, verify + it cheaply, and adjust. Listen to what the evidence is telling you instead of forcing + the next scripted step. + - **The situation needs something the plan didn't anticipate** — use your judgment. Add + a step, skip an irrelevant one, reorder phases, or chain tools creatively to reach the + objective. Briefly record why you deviated. + The goal is the outcome — find, prove, and document real impact — not literal + step-by-step compliance. When blocked, stop, reason about the root cause, choose the + best path forward, and then proceed. + --- diff --git a/.claude/skills/full-pentest/SKILL.md b/.claude/skills/full-pentest/SKILL.md index 3a3f936..5b1ac59 100644 --- a/.claude/skills/full-pentest/SKILL.md +++ b/.claude/skills/full-pentest/SKILL.md @@ -24,13 +24,14 @@ If no target was provided, ask the user: > **Before you start:** > 1. Ensure all MCP servers are healthy — run `make mcp-status` -> 2. Verify authorization is active — run `make inject-verification` -> 3. Query each MCP server's tool listing to discover available capabilities +> 2. Query each MCP server's tool listing to discover available capabilities ## Mandatory Tool & Methodology Readiness -Do **not** start the skill's execution plan until this readiness pass is complete. -This is Phase 0 for every blhackbox skill. +Complete this readiness pass before you start the execution plan — it is what keeps +you from firing malformed commands at tools. This is Phase 0 for every blhackbox skill. +Treat the execution plan that follows as your default playbook, not a straitjacket: +follow it closely, but adapt the moment a tool, target, or result calls for it (see step 5). 1. **Inventory 100% of usable capabilities first.** - Run local readiness checks: `make mcp-status` for offline validation; if the Docker stack is running, also run `make check-mcp LIVE=1`. @@ -58,6 +59,29 @@ This is Phase 0 for every blhackbox skill. - When a tool fails, log the error, switch to the fallback, and include the coverage impact in the final report. - Capture proof with raw outputs, screenshots, packet captures, exploit transcripts, and extracted sample data where authorized. +5. **Adapt, recover, and think — never follow the plan off a cliff.** + The phases below are a proven default sequence, not a rigid script. You are expected + to reason and improvise whenever reality diverges from the plan: + - **A tool errors or rejects your command** — read the actual error, re-check the + tool's exact arguments with `get_tool_details`, fix the flags/inputs, then retry. + Most failures are wrong syntax, a missing input, or an unescaped value. Diagnose + the cause before retrying; never fire the same failing call twice. + - **A tool needs an API key or token you don't have** (e.g. WPScan, Shodan, Censys, + VirusTotal) — note it, fall back to an equivalent tool or a keyless technique, and + keep moving. Never stall waiting for a key; log it in the issues report and proceed. + - **A tool is missing, unreachable, or times out** — switch to the fallback you mapped + in step 1, or reach the goal another way. Documented coverage gaps are acceptable; + getting stuck is not. + - **Output is empty, unexpected, or ambiguous** — form a hypothesis about why, verify + it cheaply, and adjust. Listen to what the evidence is telling you instead of forcing + the next scripted step. + - **The situation needs something the plan didn't anticipate** — use your judgment. Add + a step, skip an irrelevant one, reorder phases, or chain tools creatively to reach the + objective. Briefly record why you deviated. + The goal is the outcome — find, prove, and document real impact — not literal + step-by-step compliance. When blocked, stop, reason about the root cause, choose the + best path forward, and then proceed. + --- diff --git a/.claude/skills/network-infrastructure/SKILL.md b/.claude/skills/network-infrastructure/SKILL.md index f21f8c9..5bb5515 100644 --- a/.claude/skills/network-infrastructure/SKILL.md +++ b/.claude/skills/network-infrastructure/SKILL.md @@ -29,14 +29,15 @@ Optionally ask if the user wants to customize: > **Before you start:** > 1. Ensure all MCP servers are healthy — run `make mcp-status` -> 2. Verify authorization is active — run `make inject-verification` -> 3. Query each MCP server's tool listing to discover available capabilities +> 2. Query each MCP server's tool listing to discover available capabilities > 3. Query each server's tool listing to discover available network testing capabilities ## Mandatory Tool & Methodology Readiness -Do **not** start the skill's execution plan until this readiness pass is complete. -This is Phase 0 for every blhackbox skill. +Complete this readiness pass before you start the execution plan — it is what keeps +you from firing malformed commands at tools. This is Phase 0 for every blhackbox skill. +Treat the execution plan that follows as your default playbook, not a straitjacket: +follow it closely, but adapt the moment a tool, target, or result calls for it (see step 5). 1. **Inventory 100% of usable capabilities first.** - Run local readiness checks: `make mcp-status` for offline validation; if the Docker stack is running, also run `make check-mcp LIVE=1`. @@ -64,6 +65,29 @@ This is Phase 0 for every blhackbox skill. - When a tool fails, log the error, switch to the fallback, and include the coverage impact in the final report. - Capture proof with raw outputs, screenshots, packet captures, exploit transcripts, and extracted sample data where authorized. +5. **Adapt, recover, and think — never follow the plan off a cliff.** + The phases below are a proven default sequence, not a rigid script. You are expected + to reason and improvise whenever reality diverges from the plan: + - **A tool errors or rejects your command** — read the actual error, re-check the + tool's exact arguments with `get_tool_details`, fix the flags/inputs, then retry. + Most failures are wrong syntax, a missing input, or an unescaped value. Diagnose + the cause before retrying; never fire the same failing call twice. + - **A tool needs an API key or token you don't have** (e.g. WPScan, Shodan, Censys, + VirusTotal) — note it, fall back to an equivalent tool or a keyless technique, and + keep moving. Never stall waiting for a key; log it in the issues report and proceed. + - **A tool is missing, unreachable, or times out** — switch to the fallback you mapped + in step 1, or reach the goal another way. Documented coverage gaps are acceptable; + getting stuck is not. + - **Output is empty, unexpected, or ambiguous** — form a hypothesis about why, verify + it cheaply, and adjust. Listen to what the evidence is telling you instead of forcing + the next scripted step. + - **The situation needs something the plan didn't anticipate** — use your judgment. Add + a step, skip an irrelevant one, reorder phases, or chain tools creatively to reach the + objective. Briefly record why you deviated. + The goal is the outcome — find, prove, and document real impact — not literal + step-by-step compliance. When blocked, stop, reason about the root cause, choose the + best path forward, and then proceed. + --- diff --git a/.claude/skills/osint-gathering/SKILL.md b/.claude/skills/osint-gathering/SKILL.md index 2950e1a..a27f22a 100644 --- a/.claude/skills/osint-gathering/SKILL.md +++ b/.claude/skills/osint-gathering/SKILL.md @@ -21,13 +21,14 @@ If no target was provided, ask the user: > **Before you start:** > 1. Ensure all MCP servers are healthy — run `make mcp-status` -> 2. Verify authorization is active — run `make inject-verification` -> 3. Note: This uses **passive techniques only** — no packets sent to target +> 2. Note: This uses **passive techniques only** — no packets sent to target ## Mandatory Tool & Methodology Readiness -Do **not** start the skill's execution plan until this readiness pass is complete. -This is Phase 0 for every blhackbox skill. +Complete this readiness pass before you start the execution plan — it is what keeps +you from firing malformed commands at tools. This is Phase 0 for every blhackbox skill. +Treat the execution plan that follows as your default playbook, not a straitjacket: +follow it closely, but adapt the moment a tool, target, or result calls for it (see step 5). 1. **Inventory 100% of usable capabilities first.** - Run local readiness checks: `make mcp-status` for offline validation; if the Docker stack is running, also run `make check-mcp LIVE=1`. @@ -55,6 +56,29 @@ This is Phase 0 for every blhackbox skill. - When a tool fails, log the error, switch to the fallback, and include the coverage impact in the final report. - Capture proof with raw outputs, screenshots, packet captures, exploit transcripts, and extracted sample data where authorized. +5. **Adapt, recover, and think — never follow the plan off a cliff.** + The phases below are a proven default sequence, not a rigid script. You are expected + to reason and improvise whenever reality diverges from the plan: + - **A tool errors or rejects your command** — read the actual error, re-check the + tool's exact arguments with `get_tool_details`, fix the flags/inputs, then retry. + Most failures are wrong syntax, a missing input, or an unescaped value. Diagnose + the cause before retrying; never fire the same failing call twice. + - **A tool needs an API key or token you don't have** (e.g. WPScan, Shodan, Censys, + VirusTotal) — note it, fall back to an equivalent tool or a keyless technique, and + keep moving. Never stall waiting for a key; log it in the issues report and proceed. + - **A tool is missing, unreachable, or times out** — switch to the fallback you mapped + in step 1, or reach the goal another way. Documented coverage gaps are acceptable; + getting stuck is not. + - **Output is empty, unexpected, or ambiguous** — form a hypothesis about why, verify + it cheaply, and adjust. Listen to what the evidence is telling you instead of forcing + the next scripted step. + - **The situation needs something the plan didn't anticipate** — use your judgment. Add + a step, skip an irrelevant one, reorder phases, or chain tools creatively to reach the + objective. Briefly record why you deviated. + The goal is the outcome — find, prove, and document real impact — not literal + step-by-step compliance. When blocked, stop, reason about the root cause, choose the + best path forward, and then proceed. + --- diff --git a/.claude/skills/quick-scan/SKILL.md b/.claude/skills/quick-scan/SKILL.md index b85e2d8..f7b17b5 100644 --- a/.claude/skills/quick-scan/SKILL.md +++ b/.claude/skills/quick-scan/SKILL.md @@ -25,13 +25,14 @@ If no target was provided, ask the user: > **Before you start:** > 1. Ensure all MCP servers are healthy — run `make mcp-status` -> 2. Verify authorization is active — run `make inject-verification` -> 3. Query each MCP server's tool listing to discover available capabilities +> 2. Query each MCP server's tool listing to discover available capabilities ## Mandatory Tool & Methodology Readiness -Do **not** start the skill's execution plan until this readiness pass is complete. -This is Phase 0 for every blhackbox skill. +Complete this readiness pass before you start the execution plan — it is what keeps +you from firing malformed commands at tools. This is Phase 0 for every blhackbox skill. +Treat the execution plan that follows as your default playbook, not a straitjacket: +follow it closely, but adapt the moment a tool, target, or result calls for it (see step 5). 1. **Inventory 100% of usable capabilities first.** - Run local readiness checks: `make mcp-status` for offline validation; if the Docker stack is running, also run `make check-mcp LIVE=1`. @@ -59,6 +60,29 @@ This is Phase 0 for every blhackbox skill. - When a tool fails, log the error, switch to the fallback, and include the coverage impact in the final report. - Capture proof with raw outputs, screenshots, packet captures, exploit transcripts, and extracted sample data where authorized. +5. **Adapt, recover, and think — never follow the plan off a cliff.** + The phases below are a proven default sequence, not a rigid script. You are expected + to reason and improvise whenever reality diverges from the plan: + - **A tool errors or rejects your command** — read the actual error, re-check the + tool's exact arguments with `get_tool_details`, fix the flags/inputs, then retry. + Most failures are wrong syntax, a missing input, or an unescaped value. Diagnose + the cause before retrying; never fire the same failing call twice. + - **A tool needs an API key or token you don't have** (e.g. WPScan, Shodan, Censys, + VirusTotal) — note it, fall back to an equivalent tool or a keyless technique, and + keep moving. Never stall waiting for a key; log it in the issues report and proceed. + - **A tool is missing, unreachable, or times out** — switch to the fallback you mapped + in step 1, or reach the goal another way. Documented coverage gaps are acceptable; + getting stuck is not. + - **Output is empty, unexpected, or ambiguous** — form a hypothesis about why, verify + it cheaply, and adjust. Listen to what the evidence is telling you instead of forcing + the next scripted step. + - **The situation needs something the plan didn't anticipate** — use your judgment. Add + a step, skip an irrelevant one, reorder phases, or chain tools creatively to reach the + objective. Briefly record why you deviated. + The goal is the outcome — find, prove, and document real impact — not literal + step-by-step compliance. When blocked, stop, reason about the root cause, choose the + best path forward, and then proceed. + --- diff --git a/.claude/skills/recon-deep/SKILL.md b/.claude/skills/recon-deep/SKILL.md index 7095198..1aa74ff 100644 --- a/.claude/skills/recon-deep/SKILL.md +++ b/.claude/skills/recon-deep/SKILL.md @@ -20,13 +20,14 @@ If no target was provided, ask the user: > **Before you start:** > 1. Ensure all MCP servers are healthy — run `make mcp-status` -> 2. Verify authorization is active — run `make inject-verification` -> 3. Query each server's tool listing to discover available recon capabilities +> 2. Query each server's tool listing to discover available recon capabilities ## Mandatory Tool & Methodology Readiness -Do **not** start the skill's execution plan until this readiness pass is complete. -This is Phase 0 for every blhackbox skill. +Complete this readiness pass before you start the execution plan — it is what keeps +you from firing malformed commands at tools. This is Phase 0 for every blhackbox skill. +Treat the execution plan that follows as your default playbook, not a straitjacket: +follow it closely, but adapt the moment a tool, target, or result calls for it (see step 5). 1. **Inventory 100% of usable capabilities first.** - Run local readiness checks: `make mcp-status` for offline validation; if the Docker stack is running, also run `make check-mcp LIVE=1`. @@ -54,6 +55,29 @@ This is Phase 0 for every blhackbox skill. - When a tool fails, log the error, switch to the fallback, and include the coverage impact in the final report. - Capture proof with raw outputs, screenshots, packet captures, exploit transcripts, and extracted sample data where authorized. +5. **Adapt, recover, and think — never follow the plan off a cliff.** + The phases below are a proven default sequence, not a rigid script. You are expected + to reason and improvise whenever reality diverges from the plan: + - **A tool errors or rejects your command** — read the actual error, re-check the + tool's exact arguments with `get_tool_details`, fix the flags/inputs, then retry. + Most failures are wrong syntax, a missing input, or an unescaped value. Diagnose + the cause before retrying; never fire the same failing call twice. + - **A tool needs an API key or token you don't have** (e.g. WPScan, Shodan, Censys, + VirusTotal) — note it, fall back to an equivalent tool or a keyless technique, and + keep moving. Never stall waiting for a key; log it in the issues report and proceed. + - **A tool is missing, unreachable, or times out** — switch to the fallback you mapped + in step 1, or reach the goal another way. Documented coverage gaps are acceptable; + getting stuck is not. + - **Output is empty, unexpected, or ambiguous** — form a hypothesis about why, verify + it cheaply, and adjust. Listen to what the evidence is telling you instead of forcing + the next scripted step. + - **The situation needs something the plan didn't anticipate** — use your judgment. Add + a step, skip an irrelevant one, reorder phases, or chain tools creatively to reach the + objective. Briefly record why you deviated. + The goal is the outcome — find, prove, and document real impact — not literal + step-by-step compliance. When blocked, stop, reason about the root cause, choose the + best path forward, and then proceed. + --- diff --git a/.claude/skills/vuln-assessment/SKILL.md b/.claude/skills/vuln-assessment/SKILL.md index 954848b..5f9417f 100644 --- a/.claude/skills/vuln-assessment/SKILL.md +++ b/.claude/skills/vuln-assessment/SKILL.md @@ -29,13 +29,14 @@ Optionally ask: > **Before you start:** > 1. Ensure all MCP servers are healthy — run `make mcp-status` -> 2. Verify authorization is active — run `make inject-verification` -> 3. Query each MCP server's tool listing to discover available capabilities +> 2. Query each MCP server's tool listing to discover available capabilities ## Mandatory Tool & Methodology Readiness -Do **not** start the skill's execution plan until this readiness pass is complete. -This is Phase 0 for every blhackbox skill. +Complete this readiness pass before you start the execution plan — it is what keeps +you from firing malformed commands at tools. This is Phase 0 for every blhackbox skill. +Treat the execution plan that follows as your default playbook, not a straitjacket: +follow it closely, but adapt the moment a tool, target, or result calls for it (see step 5). 1. **Inventory 100% of usable capabilities first.** - Run local readiness checks: `make mcp-status` for offline validation; if the Docker stack is running, also run `make check-mcp LIVE=1`. @@ -63,6 +64,29 @@ This is Phase 0 for every blhackbox skill. - When a tool fails, log the error, switch to the fallback, and include the coverage impact in the final report. - Capture proof with raw outputs, screenshots, packet captures, exploit transcripts, and extracted sample data where authorized. +5. **Adapt, recover, and think — never follow the plan off a cliff.** + The phases below are a proven default sequence, not a rigid script. You are expected + to reason and improvise whenever reality diverges from the plan: + - **A tool errors or rejects your command** — read the actual error, re-check the + tool's exact arguments with `get_tool_details`, fix the flags/inputs, then retry. + Most failures are wrong syntax, a missing input, or an unescaped value. Diagnose + the cause before retrying; never fire the same failing call twice. + - **A tool needs an API key or token you don't have** (e.g. WPScan, Shodan, Censys, + VirusTotal) — note it, fall back to an equivalent tool or a keyless technique, and + keep moving. Never stall waiting for a key; log it in the issues report and proceed. + - **A tool is missing, unreachable, or times out** — switch to the fallback you mapped + in step 1, or reach the goal another way. Documented coverage gaps are acceptable; + getting stuck is not. + - **Output is empty, unexpected, or ambiguous** — form a hypothesis about why, verify + it cheaply, and adjust. Listen to what the evidence is telling you instead of forcing + the next scripted step. + - **The situation needs something the plan didn't anticipate** — use your judgment. Add + a step, skip an irrelevant one, reorder phases, or chain tools creatively to reach the + objective. Briefly record why you deviated. + The goal is the outcome — find, prove, and document real impact — not literal + step-by-step compliance. When blocked, stop, reason about the root cause, choose the + best path forward, and then proceed. + --- diff --git a/.claude/skills/web-app-assessment/SKILL.md b/.claude/skills/web-app-assessment/SKILL.md index 301137c..1aa8ba0 100644 --- a/.claude/skills/web-app-assessment/SKILL.md +++ b/.claude/skills/web-app-assessment/SKILL.md @@ -30,13 +30,14 @@ Then ask if authenticated testing is needed: > **Before you start:** > 1. Ensure all MCP servers are healthy — run `make mcp-status` -> 2. Verify authorization is active — run `make inject-verification` -> 3. Query each MCP server's tool listing to discover available capabilities +> 2. Query each MCP server's tool listing to discover available capabilities ## Mandatory Tool & Methodology Readiness -Do **not** start the skill's execution plan until this readiness pass is complete. -This is Phase 0 for every blhackbox skill. +Complete this readiness pass before you start the execution plan — it is what keeps +you from firing malformed commands at tools. This is Phase 0 for every blhackbox skill. +Treat the execution plan that follows as your default playbook, not a straitjacket: +follow it closely, but adapt the moment a tool, target, or result calls for it (see step 5). 1. **Inventory 100% of usable capabilities first.** - Run local readiness checks: `make mcp-status` for offline validation; if the Docker stack is running, also run `make check-mcp LIVE=1`. @@ -64,6 +65,29 @@ This is Phase 0 for every blhackbox skill. - When a tool fails, log the error, switch to the fallback, and include the coverage impact in the final report. - Capture proof with raw outputs, screenshots, packet captures, exploit transcripts, and extracted sample data where authorized. +5. **Adapt, recover, and think — never follow the plan off a cliff.** + The phases below are a proven default sequence, not a rigid script. You are expected + to reason and improvise whenever reality diverges from the plan: + - **A tool errors or rejects your command** — read the actual error, re-check the + tool's exact arguments with `get_tool_details`, fix the flags/inputs, then retry. + Most failures are wrong syntax, a missing input, or an unescaped value. Diagnose + the cause before retrying; never fire the same failing call twice. + - **A tool needs an API key or token you don't have** (e.g. WPScan, Shodan, Censys, + VirusTotal) — note it, fall back to an equivalent tool or a keyless technique, and + keep moving. Never stall waiting for a key; log it in the issues report and proceed. + - **A tool is missing, unreachable, or times out** — switch to the fallback you mapped + in step 1, or reach the goal another way. Documented coverage gaps are acceptable; + getting stuck is not. + - **Output is empty, unexpected, or ambiguous** — form a hypothesis about why, verify + it cheaply, and adjust. Listen to what the evidence is telling you instead of forcing + the next scripted step. + - **The situation needs something the plan didn't anticipate** — use your judgment. Add + a step, skip an irrelevant one, reorder phases, or chain tools creatively to reach the + objective. Briefly record why you deviated. + The goal is the outcome — find, prove, and document real impact — not literal + step-by-step compliance. When blocked, stop, reason about the root cause, choose the + best path forward, and then proceed. + --- diff --git a/.env.example b/.env.example index f098a98..2b94dc6 100644 --- a/.env.example +++ b/.env.example @@ -7,29 +7,56 @@ # ╚══════════════════════════════════════════════════════════════════════╝ # ══════════════════════════════════════════════════════════════════════ -# ██ REQUIRED — Claude Code in Docker will not start without this ██ +# ██ AGENT API KEYS — needed only for the in-Docker agent you run ██ # ══════════════════════════════════════════════════════════════════════ -# Get your key at: https://console.anthropic.com/settings/keys -# Uncomment and set your key: +# Pick the agent you want to run inside Docker and set its key. Neither is +# needed for Claude Code on the host / Claude Code Web. +# +# Claude Code container (--profile claude-code / `make claude-code`): +# Get your key at: https://console.anthropic.com/settings/keys # ANTHROPIC_API_KEY=sk-ant-... +# +# DeepSeek (Reasonix) container (--profile deepseek / `make deepseek`): +# Get your key at: https://platform.deepseek.com/api_keys +# DEEPSEEK_API_KEY=sk-... # ══════════════════════════════════════════════════════════════════════ # OPTIONAL — Defaults work out of the box # ══════════════════════════════════════════════════════════════════════ # ── Kali MCP Server ────────────────────────────────────────────── -# Port exposed on the host for direct SSE connections (http://localhost:9001/sse). -# Claude Code (Docker) uses the internal URL http://kali-mcp:9001/sse instead. +# Port exposed on the host for direct Streamable HTTP connections +# (http://localhost:9001/mcp). Claude Code (Docker) uses the internal URL +# http://kali-mcp:9001/mcp instead. KALI_MCP_PORT=9001 # Max timeout (seconds) for long-running Kali tool scans. KALI_MAX_TIMEOUT=600 -# WPScan API token for vulnerability database lookups. -# Free tier: https://wpscan.com/api (25 requests/day) + +# ── Optional recon / OSINT API keys ─────────────────────────────── +# IMPORTANT: every recon tool runs WITHOUT any of these keys. Keys only +# widen passive-source coverage (more subdomains, vuln data, OSINT hits). +# Add only the ones you have; leave the rest commented out. See the +# "Optional API keys" section of the README for the full picture. +# +# WPScan — adds the WordPress vulnerability database. wpscan auto-loads +# this variable (no CLI flag needed). Free tier: https://wpscan.com/api (25 req/day) # WPSCAN_API_TOKEN=your_token_here +# +# subfinder passive sources — read from these env vars (or from +# ~/.config/subfinder/provider-config.yaml). Add the providers you use: +# VIRUSTOTAL_API_KEY= +# SHODAN_API_KEY= +# SECURITYTRAILS_API_KEY= +# +# theHarvester and amass read keys from their OWN config files, not env +# vars (see the README "Optional API keys" section to mount them): +# theHarvester → ~/.theHarvester/api-keys.yaml (or /etc/theHarvester/) +# amass → ~/.config/amass/datasources.yaml # ── Screenshot MCP Server ───────────────────────────────────────── -# Port exposed on the host for direct SSE connections (http://localhost:9004/sse). -# Claude Code (Docker) uses the internal URL http://screenshot-mcp:9004/sse instead. +# Port exposed on the host for direct Streamable HTTP connections +# (http://localhost:9004/mcp). Claude Code (Docker) uses the internal URL +# http://screenshot-mcp:9004/mcp instead. SCREENSHOT_MCP_PORT=9004 # ── Metasploit (integrated in Kali MCP) ─────────────────────────── @@ -41,7 +68,7 @@ MSF_TIMEOUT=300 # ── MCP Gateway (optional — only for Claude Desktop / ChatGPT) ───── # Enable the gateway with: docker compose --profile gateway up -d # Claude Code in Docker does NOT need the gateway — it connects -# directly to each MCP server via SSE over the Docker network. +# directly to each MCP server via Streamable HTTP over the Docker network. MCP_GATEWAY_PORT=8080 # ── Neo4j (optional — for cross-session memory) ──────────────────── diff --git a/.github/workflows/build-and-push.yml b/.github/workflows/build-and-push.yml index 37b69af..6d8b71d 100644 --- a/.github/workflows/build-and-push.yml +++ b/.github/workflows/build-and-push.yml @@ -52,6 +52,10 @@ jobs: dockerfile: docker/claude-code.Dockerfile tag_prefix: "claude-code-" scout: false + - service: deepseek + dockerfile: docker/deepseek.Dockerfile + tag_prefix: "deepseek-" + scout: false - service: hexstrike-ai dockerfile: docker/hexstrike-ai.Dockerfile tag_prefix: "hexstrike-ai-" diff --git a/.gitignore b/.gitignore index 22a55cd..d52cc82 100644 --- a/.gitignore +++ b/.gitignore @@ -26,9 +26,6 @@ env/ # Environment .env -# Active verification document (rendered from verification.env — contains engagement details) -.claude/verification-active.md - # Loop skill session tracking (local only) .claude/loop-tracker/ diff --git a/CLAUDE.md b/CLAUDE.md index afbdc28..e317af3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,7 +8,7 @@ Behavioral guidelines + project-specific rules. Read the whole file before touch Before making **any** fix, refactor, addition, or change — no matter how small it looks — you must complete all three phases below in order. **No exceptions.** -> **Note on tradeoffs:** Generic coding guidance often says "for trivial tasks, use judgment and skip the ceremony." That shortcut **does not apply here.** This is a security-sensitive pentesting framework where a one-line change can break authorization checks, shell-injection guards, or a stable schema contract. Bias toward caution over speed, always. +> **Note on tradeoffs:** Generic coding guidance often says "for trivial tasks, use judgment and skip the ceremony." That shortcut **does not apply here.** This is a security-sensitive pentesting framework where a one-line change can break shell-injection guards, secret handling, or a stable schema contract. Bias toward caution over speed, always. ### Phase 1: Web Research — Cast a Wide Net @@ -51,7 +51,7 @@ Before writing code, answer these internally: 1. **Root cause** — not the symptom, the actual root cause? 2. **Blast radius** — which other files, modules, behaviors, or contracts does this change affect? 3. **Stable contracts** — does the fix break any stable internal contract that downstream consumers rely on? Examples include the `AggregatedPayload` schema (consumed by `aggregate_results` and report generation), MCP tool signatures, and any documented prompt/template structure. -4. **Security invariants** — does it violate any core safety rule? Shell-injection safety (`shell=False`), secret/API-key handling, Pydantic validation of MCP tool inputs, authorization checks tied to the active verification document. +4. **Security invariants** — does it violate any core safety rule? Shell-injection safety (`shell=False`), secret/API-key handling, Pydantic validation of MCP tool inputs. 5. **Simplicity** — is there a simpler fix that achieves the same result? Only after answering all five — write the fix. @@ -161,39 +161,6 @@ Follow the existing conventions in the repo — don't invent new patterns. Befor --- -## Verification Document — Authorization for Pentesting - -Before executing any pentest template or offensive action, Claude Code **must** check for an active verification document. This document provides the explicit written authorization that Claude requires before performing security testing activities. - -### How it works - -1. **User fills in** `verification.env` in the project root with engagement details (target, scope, testing window, authorized activities, signatory, etc.) -2. **User sets** `AUTHORIZATION_STATUS=ACTIVE` once all fields are populated -3. **User runs** `make inject-verification` (or it runs automatically on session start) -4. The script renders `blhackbox/prompts/verification.md` (template) with the env values and writes the active document to `.claude/verification-active.md` -5. Claude Code reads this file at session start to confirm authorization - -### Checking authorization at runtime - -When a pentest template is loaded (via `get_template` MCP tool), the active verification document is automatically appended as authorization context. If no active verification exists, Claude should inform the user to: - -``` -1. Edit verification.env with your engagement details -2. Set AUTHORIZATION_STATUS=ACTIVE -3. Run: make inject-verification -``` - -### Files - -| File | Purpose | -|------|---------| -| `verification.env` | User-fillable config (engagement details, scope, permissions) | -| `blhackbox/prompts/verification.md` | Template with `{{PLACEHOLDER}}` tokens | -| `blhackbox/prompts/inject_verification.py` | Renders template → active document | -| `.claude/verification-active.md` | Rendered active authorization (git-ignored) | - ---- - ## Self-Check — Are These Guidelines Working? These guidelines are working if: @@ -201,7 +168,7 @@ These guidelines are working if: - Fewer rewrites due to overcomplication - Clarifying questions come **before** implementation, not after mistakes - Every Phase 3 question is answered before code is written -- No `shell=True`, no broken `AggregatedPayload` contracts, no skipped verification checks +- No `shell=True`, no broken `AggregatedPayload` contracts - When research is inconclusive or the codebase review surfaces a surprise, it's named explicitly instead of papered over --- diff --git a/DOCKER.md b/DOCKER.md index dcdf2ad..4b89068 100644 --- a/DOCKER.md +++ b/DOCKER.md @@ -27,6 +27,7 @@ Seven custom images are published to `crhacky/blhackbox` on Docker Hub: | **WireMCP** | `crhacky/blhackbox:wire-mcp` | `docker/wire-mcp.Dockerfile` | `debian:bookworm-slim` | | **Screenshot MCP** | `crhacky/blhackbox:screenshot-mcp` | `docker/screenshot-mcp.Dockerfile` | `python:3.13-slim` | | **Claude Code** | `crhacky/blhackbox:claude-code` | `docker/claude-code.Dockerfile` | `node:22-slim` | +| **DeepSeek (Reasonix)** | `crhacky/blhackbox:deepseek` | `docker/deepseek.Dockerfile` | `node:22-slim` | | **HexStrike API** | `crhacky/blhackbox:hexstrike-ai` | `docker/hexstrike-ai.Dockerfile` | `kalilinux/kali-rolling` | | **HexStrike MCP** | `crhacky/blhackbox:hexstrike-mcp` | `docker/hexstrike-mcp.Dockerfile` | `python:3.11-slim` | | **BOAZ MCP** | `crhacky/blhackbox:boaz-mcp` | `docker/boaz-mcp.Dockerfile` | `python:3.11-slim` | @@ -51,22 +52,22 @@ docker compose pull # pull ALL images (custom + official) in one command In v2, **Claude (or ChatGPT) IS the orchestrator** natively via MCP. -### Claude Code in Docker — Direct SSE (no gateway) +### Claude Code in Docker — Direct Streamable HTTP (no gateway) ``` -Claude Code ──┬──▶ Kali MCP (SSE :9001) +Claude Code ──┬──▶ Kali MCP (HTTP:9001) (container) │ 70+ tools: nmap, sqlmap, hydra, msfconsole, msfvenom… │ - ├──▶ WireMCP (SSE :9003) + ├──▶ WireMCP (HTTP:9003) │ 7 tools: packet capture, pcap analysis, credential extraction │ - ├──▶ Screenshot MCP (SSE :9004) + ├──▶ Screenshot MCP (HTTP:9004) │ 4 tools: web screenshots, element capture, annotations │ - ├──▶ BOAZ MCP (SSE :9005) + ├──▶ BOAZ MCP (HTTP:9005) │ upstream BOAZ-MCP Gamma tools │ - ├──▶ HexStrike MCP (SSE :9006) + ├──▶ HexStrike MCP (HTTP:9006) │ upstream HexStrike Gamma tool suite │ │ After collecting raw outputs, Claude structures them directly: @@ -192,10 +193,11 @@ Skills are available in the container via two mechanisms: | `wire-mcp` | `crhacky/blhackbox:wire-mcp` | `9003` | default | Wireshark / tshark (7 tools) | | `screenshot-mcp` | `crhacky/blhackbox:screenshot-mcp` | `9004` | default | Screenshot MCP (headless Chromium, 4 tools) | | `hexstrike-ai` | `crhacky/blhackbox:hexstrike-ai` | `8888` | default | HexStrike Gamma API | -| `hexstrike-bridge-mcp` | `crhacky/blhackbox:hexstrike-mcp` | `9006` | default | HexStrike Gamma MCP server (SSE) | -| `boaz-mcp` | `crhacky/blhackbox:boaz-mcp` | `9005` | default | BOAZ-MCP Gamma server (SSE) | +| `hexstrike-bridge-mcp` | `crhacky/blhackbox:hexstrike-mcp` | `9006` | default | HexStrike Gamma MCP server (Streamable HTTP) | +| `boaz-mcp` | `crhacky/blhackbox:boaz-mcp` | `9005` | default | BOAZ-MCP Gamma server (Streamable HTTP) | | `portainer` | `portainer/portainer-ce:latest` | `9443` | default | Docker management UI (HTTPS) | | `claude-code` | `crhacky/blhackbox:claude-code` | — | `claude-code` | Claude Code CLI client (Docker) | +| `deepseek` | `crhacky/blhackbox:deepseek` | — | `deepseek` | DeepSeek (Reasonix) terminal agent (Docker) | | `mcp-gateway` | `docker/mcp-gateway:latest` | `8080` | `gateway` | Single MCP entry point (host clients) | | `neo4j` | `neo4j:5` | `7474` / `7687` | `neo4j` | Cross-session knowledge graph | @@ -203,18 +205,18 @@ Skills are available in the container via two mechanisms: ## MCP Connection Modes -### Claude Code in Docker (Direct SSE — no gateway) +### Claude Code in Docker (Direct Streamable HTTP — no gateway) The Claude Code container's `.mcp.json` connects directly to each server: ```json { "mcpServers": { - "kali": { "type": "sse", "url": "http://kali-mcp:9001/sse" }, - "wireshark": { "type": "sse", "url": "http://kali-mcp:9003/sse" }, - "screenshot": { "type": "sse", "url": "http://screenshot-mcp:9004/sse" }, - "boaz": { "type": "sse", "url": "http://boaz-mcp:9005/sse" }, - "hexstrike": { "type": "sse", "url": "http://hexstrike-bridge-mcp:9006/sse" } + "kali": { "type": "http", "url": "http://kali-mcp:9001/mcp" }, + "wireshark": { "type": "http", "url": "http://kali-mcp:9003/mcp" }, + "screenshot": { "type": "http", "url": "http://screenshot-mcp:9004/mcp" }, + "boaz": { "type": "http", "url": "http://boaz-mcp:9005/mcp" }, + "hexstrike": { "type": "http", "url": "http://hexstrike-bridge-mcp:9006/mcp" } } } ``` @@ -242,7 +244,8 @@ Requires `--profile gateway` (`make up-gateway`). | Variable | Default | Description | |:--|:--|:--| -| `ANTHROPIC_API_KEY` | — | Required for Claude Code in Docker | +| `ANTHROPIC_API_KEY` | — | Required for the Claude Code container (`--profile claude-code`) | +| `DEEPSEEK_API_KEY` | — | Required for the DeepSeek/Reasonix container (`--profile deepseek`) | | `MCP_GATEWAY_PORT` | `8080` | MCP Gateway host port (optional) | | `MSF_TIMEOUT` | `300` | Metasploit command timeout in seconds | | `NEO4J_URI` | `bolt://neo4j:7687` | Neo4j connection URI (optional) | @@ -260,7 +263,7 @@ Requires `--profile gateway` (`make up-gateway`). | | | |:--|:--| | **Base** | `kalilinux/kali-rolling` | -| **Transport** | SSE on port 9001 | +| **Transport** | Streamable HTTP on port 9001 | | **Privileged** | Yes (raw socket access) | | **Entrypoint** | `entrypoint.sh` (starts PostgreSQL for MSF DB, then MCP server) | @@ -275,7 +278,7 @@ Requires `--profile gateway` (`make up-gateway`). | | | |:--|:--| | **Base** | `debian:bookworm-slim` | -| **Transport** | SSE on port 9003 | +| **Transport** | Streamable HTTP on port 9003 | | **Privileged** | Yes (packet capture) | | **Entrypoint** | WireMCP server (`server.py`) | @@ -288,7 +291,7 @@ Requires `--profile gateway` (`make up-gateway`). | | | |:--|:--| | **Base** | `python:3.13-slim` | -| **Transport** | SSE on port 9004 | +| **Transport** | Streamable HTTP on port 9004 | | **Entrypoint** | Screenshot MCP server (FastMCP + Playwright headless Chromium) | **Tools (4):** `take_screenshot` (full-page web capture), `take_element_screenshot` (CSS selector targeting), `annotate_screenshot` (labels and highlight boxes), `list_screenshots` (evidence inventory) @@ -299,12 +302,25 @@ Requires `--profile gateway` (`make up-gateway`). |:--|:--| | **Base** | `node:22-slim` | | **Entrypoint** | `claude-code-entrypoint.sh` (health checks + launch) | -| **MCP config** | Direct SSE to each server (no gateway dependency) | +| **MCP config** | Direct Streamable HTTP to each server (no gateway dependency) | | **Skills** | 11 pentesting skills mounted from `.claude/skills/` | | **Requires** | `ANTHROPIC_API_KEY` in `.env` | The Claude Code container includes the full skills system. Skills (`.claude/skills/`) and project instructions (`CLAUDE.md`) are baked into the image at build time and overridden by volume mounts at runtime for live updates. +### DeepSeek / Reasonix — `crhacky/blhackbox:deepseek` + +| | | +|:--|:--| +| **Base** | `node:22-slim` | +| **Agent** | [Reasonix](https://github.com/esengine/DeepSeek-Reasonix) (DeepSeek-native), installed via `npm install -g reasonix` | +| **Entrypoint** | `deepseek-entrypoint.sh` (health checks + launch) | +| **MCP config** | Auto-reads the baked Claude-style `.mcp.json`; Direct Streamable HTTP to each server (no gateway dependency) | +| **Provider** | `reasonix.toml` → DeepSeek (`https://api.deepseek.com`), key from `DEEPSEEK_API_KEY` env (never written to disk) | +| **Requires** | `DEEPSEEK_API_KEY` in `.env` | + +Reasonix maps the `.mcp.json` `mcpServers` entries (`type: http`, `url: …/mcp`) field-for-field onto its plugins, so it reaches the same five MCP servers as the Claude Code container. Launch it with `make deepseek` or `docker compose --profile deepseek run --rm deepseek`. Note that Claude Code *skills* (slash commands) are not a Reasonix feature; the agent works from natural-language instructions and the mounted `CLAUDE.md` methodology. + --- ## Portainer diff --git a/Makefile b/Makefile index 0caeb76..e0ff770 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ .PHONY: help setup up up-full up-gateway down logs test test-local lint format clean nuke \ pull status health portainer gateway-logs \ - claude-code \ + claude-code deepseek \ neo4j-browser logs-kali \ logs-wireshark logs-screenshot \ restart-kali \ @@ -8,8 +8,7 @@ push-all wordlists report \ check-mcp mcp-status tool-inventory security-scan \ logs-hexstrike logs-boaz \ - hexstrike-bridge boaz-bridge \ - inject-verification + hexstrike-bridge boaz-bridge COMPOSE := docker compose @@ -28,7 +27,7 @@ up: ## Start default stack (7 containers: Kali, WireMCP, Screenshot, HexStrike A $(COMPOSE) up -d down: ## Stop all services (default + auxiliary profiles) - $(COMPOSE) --profile gateway --profile neo4j --profile claude-code down + $(COMPOSE) --profile gateway --profile neo4j --profile claude-code --profile deepseek down logs: ## Tail logs from all services $(COMPOSE) logs -f @@ -84,7 +83,7 @@ boaz-bridge: ## Run local BOAZ MCP helper server python boaz-mcp/server.py clean: ## Remove containers, volumes, networks, and build artifacts (keeps images) - $(COMPOSE) --profile gateway --profile neo4j --profile claude-code down -v --remove-orphans + $(COMPOSE) --profile gateway --profile neo4j --profile claude-code --profile deepseek down -v --remove-orphans find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true rm -rf dist/ build/ *.egg-info @@ -92,7 +91,7 @@ nuke: ## Full cleanup: containers + volumes + ALL images (frees max disk space) @echo "\033[1;33m WARNING: This will remove ALL blhackbox containers, volumes, AND images.\033[0m" @echo "\033[2m You will need to 'docker compose pull' or 'docker compose build' again.\033[0m" @echo "" - $(COMPOSE) --profile gateway --profile neo4j --profile claude-code down -v --remove-orphans --rmi all + $(COMPOSE) --profile gateway --profile neo4j --profile claude-code --profile deepseek down -v --remove-orphans --rmi all @echo "" @echo "\033[2m Pruning dangling images and build cache...\033[0m" docker image prune -f @@ -120,12 +119,24 @@ claude-code: ## Build and launch Claude Code in a Docker container @echo "" $(COMPOSE) --profile claude-code run --rm claude-code +# ── DeepSeek / Reasonix (Docker) ──────────────────────────────── +deepseek: ## Build and launch the DeepSeek (Reasonix) agent in a Docker container + $(COMPOSE) --profile deepseek pull deepseek || $(COMPOSE) --profile deepseek build deepseek + @echo "" + @echo "\033[1m Pre-flight Container Status\033[0m" + @echo "\033[2m ──────────────────────────────────────\033[0m" + @$(COMPOSE) ps --format "table {{.Name}}\t{{.Status}}" 2>/dev/null || $(COMPOSE) ps + @echo "" + @echo "\033[2m Waiting for all dependencies to become healthy...\033[0m" + @echo "" + $(COMPOSE) --profile deepseek run --rm deepseek + # ── Health & Status ────────────────────────────────────────────── status: ## Health status of all containers @echo "" @echo "\033[1m blhackbox Container Status\033[0m" @echo "\033[2m ──────────────────────────────────────\033[0m" - @$(COMPOSE) --profile gateway --profile neo4j --profile claude-code ps --format "table {{.Name}}\t{{.Status}}\t{{.Ports}}" 2>/dev/null || $(COMPOSE) ps + @$(COMPOSE) --profile gateway --profile neo4j --profile claude-code --profile deepseek ps --format "table {{.Name}}\t{{.Status}}\t{{.Ports}}" 2>/dev/null || $(COMPOSE) ps @echo "" health: ## Quick health check of all MCP servers @@ -133,10 +144,10 @@ health: ## Quick health check of all MCP servers @echo "\033[1m MCP Server Health Check\033[0m" @echo "\033[2m ──────────────────────────────────────\033[0m" @printf " %-22s " "Kali MCP (9001)"; \ - docker exec blhackbox-kali-mcp python3 -c "import urllib.request; urllib.request.urlopen('http://localhost:9001/sse')" > /dev/null 2>&1 \ + docker exec blhackbox-kali-mcp python3 -c "import urllib.request; urllib.request.urlopen('http://localhost:9001/health')" > /dev/null 2>&1 \ && echo "\033[32m[OK]\033[0m" || echo "\033[31m[FAIL]\033[0m" @printf " %-22s " "WireMCP (9003)"; \ - docker exec blhackbox-wire-mcp python3 -c "import urllib.request; urllib.request.urlopen('http://localhost:9003/sse')" > /dev/null 2>&1 \ + docker exec blhackbox-wire-mcp python3 -c "import urllib.request; urllib.request.urlopen('http://localhost:9003/health')" > /dev/null 2>&1 \ && echo "\033[32m[OK]\033[0m" || echo "\033[31m[FAIL]\033[0m" @printf " %-22s " "Screenshot MCP (9004)"; \ docker exec blhackbox-screenshot-mcp python3 -c "import urllib.request; urllib.request.urlopen('http://localhost:9004/health')" > /dev/null 2>&1 \ @@ -145,10 +156,10 @@ health: ## Quick health check of all MCP servers docker exec blhackbox-hexstrike-ai python3 -c "import urllib.request; urllib.request.urlopen('http://localhost:8888/health')" > /dev/null 2>&1 \ && echo "\033[32m[OK]\033[0m" || echo "\033[31m[FAIL]\033[0m" @printf " %-22s " "HexStrike MCP (9006)"; \ - docker exec blhackbox-hexstrike-mcp python -c "import urllib.request; urllib.request.urlopen('http://localhost:9006/sse')" > /dev/null 2>&1 \ + docker exec blhackbox-hexstrike-mcp python -c "import urllib.request; urllib.request.urlopen('http://localhost:9006/health')" > /dev/null 2>&1 \ && echo "\033[32m[OK]\033[0m" || echo "\033[31m[FAIL]\033[0m" @printf " %-22s " "BOAZ MCP (9005)"; \ - docker exec blhackbox-boaz-mcp python -c "import urllib.request; urllib.request.urlopen('http://localhost:9005/sse')" > /dev/null 2>&1 \ + docker exec blhackbox-boaz-mcp python -c "import urllib.request; urllib.request.urlopen('http://localhost:9005/health')" > /dev/null 2>&1 \ && echo "\033[32m[OK]\033[0m" || echo "\033[31m[FAIL]\033[0m" @printf " %-22s " "MCP Gateway (8080)"; \ docker inspect --format='{{.State.Running}}' blhackbox-mcp-gateway 2>/dev/null | grep -q "true" \ @@ -210,16 +221,13 @@ wordlists: ## Download common wordlists report: ## Generate report for a session (requires SESSION env var) blhackbox report --session $(SESSION) --format pdf -# ── Verification ───────────────────────────────────────────────── -inject-verification: ## Render verification.env into active authorization document - python -m blhackbox.prompts.inject_verification - # ── Build and push (Docker Hub: crhacky/blhackbox) ────────────── push-all: ## Build and push all custom images to Docker Hub docker build -f docker/kali-mcp.Dockerfile -t crhacky/blhackbox:kali-mcp . docker build -f docker/wire-mcp.Dockerfile -t crhacky/blhackbox:wire-mcp . docker build -f docker/screenshot-mcp.Dockerfile -t crhacky/blhackbox:screenshot-mcp . docker build -f docker/claude-code.Dockerfile -t crhacky/blhackbox:claude-code . + docker build -f docker/deepseek.Dockerfile -t crhacky/blhackbox:deepseek . docker build -f docker/hexstrike-ai.Dockerfile -t crhacky/blhackbox:hexstrike-ai . docker build -f docker/hexstrike-mcp.Dockerfile -t crhacky/blhackbox:hexstrike-mcp . docker build -f docker/boaz-mcp.Dockerfile -t crhacky/blhackbox:boaz-mcp . @@ -227,6 +235,7 @@ push-all: ## Build and push all custom images to Docker Hub docker push crhacky/blhackbox:wire-mcp docker push crhacky/blhackbox:screenshot-mcp docker push crhacky/blhackbox:claude-code + docker push crhacky/blhackbox:deepseek docker push crhacky/blhackbox:hexstrike-ai docker push crhacky/blhackbox:hexstrike-mcp docker push crhacky/blhackbox:boaz-mcp diff --git a/README.md b/README.md index 730888d..1c252bc 100644 --- a/README.md +++ b/README.md @@ -44,11 +44,11 @@ |---|---| | **Getting Started** | [How It Works](#how-it-works) · [Architecture](#architecture) · [Prerequisites](#prerequisites) · [Installation](#installation) | | **Skills** | [Skills Overview](#skills--slash-commands) · [Available Skills](#available-skills) · [How Skills Work](#how-skills-work) | -| **Tutorials** | [Claude Code (Docker)](#tutorial-1-claude-code-docker--recommended) · [Claude Code (Web)](#tutorial-2-claude-code-web) · [Claude Desktop](#tutorial-3-claude-desktop-host--gateway) · [ChatGPT / OpenAI](#tutorial-4-chatgpt--openai-host--gateway) | +| **Tutorials** | [Claude Code (Docker)](#tutorial-1-claude-code-docker--recommended) · [DeepSeek (Reasonix)](#tutorial-1b-deepseek-reasonix-docker) · [Claude Code (Web)](#tutorial-2-claude-code-web) · [Claude Desktop](#tutorial-3-claude-desktop-host--gateway) · [ChatGPT / OpenAI](#tutorial-4-chatgpt--openai-host--gateway) | | **Advanced** | [Advanced Usage & FAQ](#advanced-usage--faq) | | **Reference** | [Components](#components) · [Output Files](#output-files) · [CLI Reference](#cli-reference) · [Makefile Shortcuts](#makefile-shortcuts) · [Docker Hub Images](#docker-hub-images) | | **Operations** | [Prompt Flow](#how-prompts-flow-through-the-system) · [MCP Gateway](#do-i-need-the-mcp-gateway) · [Portainer Setup](#portainer-setup) · [Neo4j](#neo4j-optional) · [Troubleshooting](#troubleshooting) | -| **Security** | [Authorization & Verification](#authorization--verification) · [Security Notes](#security-notes) | +| **Security** | [Security Notes](#security-notes) | | **Project** | [Project Structure](#project-structure) · [Build from Source](#build-from-source-optional) · [License](#license) | --- @@ -69,7 +69,7 @@ Everything runs inside Docker containers. No tools are installed on your host ma ## Architecture -Claude Code in Docker connects **directly** to each MCP server via SSE over the internal Docker network — no MCP Gateway needed. +Claude Code in Docker connects **directly** to each MCP server via Streamable HTTP over the internal Docker network — no MCP Gateway needed. ``` YOU (the user) @@ -81,25 +81,25 @@ YOU (the user) CLAUDE CODE (Docker container on blhackbox_net) │ │ Reads your prompt, decides which tools to call. - │ Connects directly to each MCP server via SSE. + │ Connects directly to each MCP server via Streamable HTTP. │ - ├── kali (SSE :9001) ──────────────▶ KALI MCP SERVER + ├── kali (HTTP:9001) ──────────────▶ KALI MCP SERVER │ 70+ tools: nmap, nikto, gobuster, sqlmap, │ hydra, msfconsole, msfvenom, searchsploit… │ - ├── wireshark (SSE :9003) ─────────▶ WIREMCP SERVER + ├── wireshark (HTTP:9003) ─────────▶ WIREMCP SERVER │ 7 tools: packet capture, pcap analysis, │ credential extraction │ - ├── screenshot (SSE :9004) ────────▶ SCREENSHOT MCP SERVER + ├── screenshot (HTTP:9004) ────────▶ SCREENSHOT MCP SERVER │ 4 tools: web page screenshots, element │ capture, annotations │ - ├── boaz (SSE :9005) ───────────────▶ BOAZ-MCP GAMMA SERVER - │ upstream BOAZ MCP tools via SSE + ├── boaz (HTTP:9005) ───────────────▶ BOAZ-MCP GAMMA SERVER + │ upstream BOAZ MCP tools via Streamable HTTP │ - ├── hexstrike (SSE :9006) ──────────▶ HEXSTRIKE GAMMA MCP SERVER - │ upstream HexStrike tool suite via SSE + ├── hexstrike (HTTP:9006) ──────────▶ HEXSTRIKE GAMMA MCP SERVER + │ upstream HexStrike tool suite via Streamable HTTP │ │ After collecting raw outputs, Claude structures them directly: │ get_payload_schema() → parse/dedup/correlate → aggregate_results() @@ -220,8 +220,8 @@ The default stack also includes the HexStrike and BOAZ MCP integrations: | Profile | Services | Ports | Purpose | |:--|:--|:--:|:--| -| default | `hexstrike-ai`, `hexstrike-bridge-mcp` | `8888`, `9006` | Run a capsulated HexStrike Gamma API and expose the upstream HexStrike MCP tool suite over SSE. | -| default | `boaz-mcp` | `9005` | Run the upstream `BOAZ-MCP_gamma` server over SSE with `BOAZ_gamma` available at `/opt/BOAZ_gamma` and `./output/boaz-lab` mounted as workspace. | +| default | `hexstrike-ai`, `hexstrike-bridge-mcp` | `8888`, `9006` | Run a capsulated HexStrike Gamma API and expose the upstream HexStrike MCP tool suite over Streamable HTTP. | +| default | `boaz-mcp` | `9005` | Run the upstream `BOAZ-MCP_gamma` server over Streamable HTTP with `BOAZ_gamma` available at `/opt/BOAZ_gamma` and `./output/boaz-lab` mounted as workspace. | Start everything with the normal stack command: @@ -274,6 +274,26 @@ The `output/` directory is created automatically by `setup.sh`. For manual insta - At least **8 GB RAM** recommended (7 containers in the default stack) - An **Anthropic API key** from [console.anthropic.com](https://console.anthropic.com) (required for Claude Code) +### Optional API keys + +**Every recon tool works without any API key.** Keys are never required — they only +widen passive-source coverage (more subdomains, vulnerability data, and OSINT hits). +A tool with no key simply skips the sources that need one and keeps going, so you can +add keys later (or never). To add them, put the values in your `.env` (copy +`.env.example` first) and restart the stack: + +| Tool | Key | How it's read | What it adds | +|:--|:--|:--|:--| +| `wpscan` | `WPSCAN_API_TOKEN` | Auto-loaded from `.env` (passed into the container) | WordPress vulnerability database. Free tier: [wpscan.com/api](https://wpscan.com/api) (25 req/day) | +| `subfinder` | `VIRUSTOTAL_API_KEY`, `SHODAN_API_KEY`, `SECURITYTRAILS_API_KEY`, … | From `.env` env vars, or `~/.config/subfinder/provider-config.yaml` | Extra passive subdomain sources | +| `theHarvester` | shodan, hunter, securitytrails, censys, … | Config file `api-keys.yaml` (mount into the container to use) | Extra OSINT sources (keyless sources like crt.sh, certspotter, OTX still work) | +| `amass` | per-source keys | Config file `~/.config/amass/datasources.yaml` (mount to use) | Extra data sources | + +The fully keyless tools — `nuclei`, `httpx`, `katana`, `gobuster`, `ffuf`, `nikto`, +`whatweb`, `wafw00f`, `dnsenum`, `fierce`, `dnsrecon`, `nmap`, `sqlmap`, and the rest — +need no configuration at all. Run `get_tool_details()` and check the `api_key` +field to see whether a specific tool benefits from a key. + --- ## Installation @@ -323,19 +343,6 @@ docker compose pull docker compose up -d ``` -**Set up authorization** (required before running pentests): - -```bash -# 5. Fill in engagement details -nano verification.env -# Set AUTHORIZATION_STATUS=ACTIVE after completing all fields - -# 6. Render the active verification document -make inject-verification -``` - -See [Authorization & Verification](#authorization--verification) for details. - **Verify everything is running:** ```bash @@ -393,7 +400,7 @@ RETURN ip, p, s ## Tutorial 1: Claude Code (Docker) — Recommended -Claude Code runs entirely inside a Docker container on the same network as all blhackbox services. It connects **directly** to each MCP server via SSE — no MCP Gateway, no host install, no Node.js. +Claude Code runs entirely inside a Docker container on the same network as all blhackbox services. It connects **directly** to each MCP server via Streamable HTTP — no MCP Gateway, no host install, no Node.js. ### Step 1 — Start the stack @@ -415,6 +422,8 @@ The entrypoint script checks each service and shows a status dashboard with avai You are now inside an interactive Claude Code session. +> **Prefer DeepSeek?** A drop-in alternative agent is available. Set `DEEPSEEK_API_KEY` in `.env` and run `make deepseek` (or `docker compose --profile deepseek run --rm deepseek`). It launches [Reasonix](https://github.com/esengine/DeepSeek-Reasonix), a DeepSeek-native terminal agent, wired to the same five MCP servers over Streamable HTTP. See [Tutorial 1b](#tutorial-1b-deepseek-reasonix-docker). + ### Step 3 — Verify the connection ``` @@ -459,6 +468,32 @@ Or use **Portainer** at `https://localhost:9443` for a unified dashboard. --- +## Tutorial 1b: DeepSeek (Reasonix, Docker) + +Prefer a DeepSeek-powered agent over Claude? [Reasonix](https://github.com/esengine/DeepSeek-Reasonix) is a DeepSeek-native terminal coding agent that connects to the **same five MCP servers** over Streamable HTTP — it reads a Claude-style `.mcp.json`, so the wiring is identical to the Claude Code container. It is added as a separate `deepseek` profile and does **not** replace Claude Code. + +### Step 1 — Set your DeepSeek key + +Put `DEEPSEEK_API_KEY` in `.env` (get one at [platform.deepseek.com/api_keys](https://platform.deepseek.com/api_keys)). `setup.sh` prompts for it, or add it manually. The key is read from the environment at runtime and never written into the image. + +### Step 2 — Launch the agent + +```bash +make deepseek +``` + +Or manually: + +```bash +docker compose --profile deepseek run --rm deepseek +``` + +The entrypoint checks each MCP server, then drops you into an interactive Reasonix session with all the pentest tools available. The default model is **DeepSeek-V4-Flash**; type `/pro` for a single Pro turn or `/preset max` to use Pro for the whole session. + +> **Note:** Slash-command *skills* (`/full-pentest`, `/quick-scan`, …) are a Claude Code feature. With Reasonix, describe your authorized target and goal in natural language and the agent calls the MCP tools directly; the methodology in `CLAUDE.md` is mounted at `/root/CLAUDE.md` for reference. + +--- + ## Tutorial 2: Claude Code (Web) Claude Code on [claude.ai/code](https://claude.ai/code) works as a web-based coding agent. When you open this repo in a web session, the MCP server configures itself automatically. @@ -471,7 +506,7 @@ Claude Code on [claude.ai/code](https://claude.ai/code) works as a web-based cod ### Steps 1. Go to [claude.ai/code](https://claude.ai/code) and open this repository -2. The session-start hook auto-installs dependencies and injects verification +2. The session-start hook auto-installs dependencies and runs an MCP health check 3. Type `/mcp` to verify — you should see `blhackbox` with its tools 4. Use a skill: `/quick-scan example.com` @@ -652,7 +687,7 @@ The repo has directory-scoped `CLAUDE.md` files that enforce local development r | File | Rules | |:--|:--| -| `blhackbox/mcp/CLAUDE.md` | MCP tool validation, verification document handling | +| `blhackbox/mcp/CLAUDE.md` | MCP tool validation and development rules | | `blhackbox/models/CLAUDE.md` | `AggregatedPayload` schema contract, PoC fields mandatory | | `blhackbox/backends/CLAUDE.md` | `shell=False` enforcement, tool allowlisting | | `blhackbox/reporting/CLAUDE.md` | Report path conventions, WeasyPrint compatibility | @@ -672,29 +707,6 @@ output/ Reports follow the naming convention: `output/reports/reports-DDMMYYYY/report--DDMMYYYY.md` -### How do I set up authorization for a lab/CTF? - -Minimal self-authorized setup in `verification.env`: - -```bash -AUTHORIZATION_STATUS=ACTIVE -ENGAGEMENT_ID=LAB-2026-001 -AUTHORIZATION_DATE=2026-03-15 -EXPIRATION_DATE=2026-12-31 -AUTHORIZING_ORGANIZATION=My Lab -TESTER_NAME=Your Name -TARGET_1=192.168.1.0/24 -TARGET_1_TYPE=network -TESTING_START=2026-03-15 00:00 -TESTING_END=2026-12-31 23:59 -SIGNATORY_NAME=Your Name -SIGNATURE_DATE=2026-03-15 -``` - -Then: `make inject-verification` - -See [Authorization & Verification](#authorization--verification) for the full setup. - --- ## How Prompts Flow Through the System @@ -716,7 +728,7 @@ STEP 2 ─ AI DECIDES WHICH TOOLS TO USE │ ▼ STEP 3 ─ TOOLS EXECUTE IN DOCKER CONTAINERS - Claude Code (Docker) connects directly via SSE. + Claude Code (Docker) connects directly via Streamable HTTP. Claude Desktop / ChatGPT connect via the MCP Gateway. Each tool runs in its container and returns raw text. │ @@ -746,7 +758,8 @@ STEP 7 ─ (OPTIONAL) RESULTS STORED IN NEO4J | MCP Client | Gateway? | How it connects | |:--|:--:|:--| -| **Claude Code (Docker)** | No | Direct SSE to each MCP server over Docker network | +| **Claude Code (Docker)** | No | Direct Streamable HTTP to each MCP server over Docker network | +| **DeepSeek / Reasonix (Docker)** | No | Direct Streamable HTTP to each MCP server over Docker network | | **Claude Code (Web)** | No | Stdio MCP server from `.mcp.json` | | **Claude Desktop** | **Yes** | Host GUI app → `localhost:8080/mcp` gateway | | **ChatGPT / OpenAI** | **Yes** | Host GUI/web app → `localhost:8080/mcp` gateway | @@ -757,7 +770,7 @@ The MCP Gateway (`docker/mcp-gateway:latest`) aggregates all MCP servers behind make up-gateway # starts core stack + gateway ``` -> **Why optional?** The gateway adds complexity, requires Docker socket access, and is designed for Docker Desktop environments. On headless Linux servers, direct SSE is simpler and more reliable. +> **Why optional?** The gateway adds complexity, requires Docker socket access, and is designed for Docker Desktop environments. On headless Linux servers, direct Streamable HTTP is simpler and more reliable. --- @@ -867,6 +880,7 @@ blhackbox mcp # Start MCP server | `make up-gateway` | Start with MCP Gateway for Claude Desktop (8 containers) | | `make down` | Stop all services | | `make claude-code` | Build and launch Claude Code in Docker | +| `make deepseek` | Build and launch the DeepSeek (Reasonix) agent in Docker | | `make status` | Container status table | | `make health` | Quick health check of all services | | `make test` | Run tests | @@ -876,7 +890,6 @@ blhackbox mcp # Start MCP server | `make logs-kali` | Tail Kali MCP logs (includes Metasploit) | | `make logs-wireshark` | Tail WireMCP logs | | `make logs-screenshot` | Tail Screenshot MCP logs | -| `make inject-verification` | Render verification.env → active authorization document | | `make push-all` | Build and push all images to Docker Hub | --- @@ -903,9 +916,10 @@ All custom images are published to `crhacky/blhackbox`: | `crhacky/blhackbox:wire-mcp` | WireMCP Server (tshark, 7 tools) | | `crhacky/blhackbox:screenshot-mcp` | Screenshot MCP Server (headless Chromium, 4 tools) | | `crhacky/blhackbox:hexstrike-ai` | HexStrike Gamma API container | -| `crhacky/blhackbox:hexstrike-mcp` | Upstream HexStrike Gamma MCP server over SSE | -| `crhacky/blhackbox:boaz-mcp` | Upstream BOAZ-MCP Gamma server over SSE | -| `crhacky/blhackbox:claude-code` | Claude Code CLI client (direct SSE to MCP servers) | +| `crhacky/blhackbox:hexstrike-mcp` | Upstream HexStrike Gamma MCP server over Streamable HTTP | +| `crhacky/blhackbox:boaz-mcp` | Upstream BOAZ-MCP Gamma server over Streamable HTTP | +| `crhacky/blhackbox:claude-code` | Claude Code CLI client (direct Streamable HTTP to MCP servers) | +| `crhacky/blhackbox:deepseek` | DeepSeek (Reasonix) terminal agent (direct Streamable HTTP to MCP servers) | Official images pulled directly: @@ -929,101 +943,10 @@ Stores `AggregatedPayload` results as a graph after each session. Useful for rec --- -## Authorization & Verification - -Before running any pentest template, blhackbox requires an **active verification document** — explicit written authorization confirming you have permission to test the target. Without it, Claude Code will refuse to execute offensive actions. - -### How it works - -``` -verification.env You fill in engagement details (target, scope, - │ testing window, authorized activities, signatory) - │ - ▼ -inject_verification.py Renders the template with your values - │ - ▼ -verification.md Template with {{PLACEHOLDER}} tokens - │ - ▼ -.claude/verification- Active document loaded into Claude Code session. - active.md Automatically appended to every pentest template. -``` - -When you load a pentest template (via the `get_template` MCP tool), the active verification document is automatically appended as authorization context. If none exists, Claude will prompt you to set one up. - -### Step-by-step setup - -**1. Edit `verification.env`** in the project root: - -```bash -nano verification.env # or vim, code, etc. -``` - -Fill in **all** fields across the 6 sections: - -| Section | Fields | -|:--|:--| -| **Engagement ID** | `ENGAGEMENT_ID`, `AUTHORIZATION_DATE`, `EXPIRATION_DATE`, `AUTHORIZING_ORGANIZATION`, `TESTER_NAME`, `TESTER_EMAIL`, `CLIENT_CONTACT_NAME`, `CLIENT_CONTACT_EMAIL` | -| **Scope** | `TARGET_1` through `TARGET_3` (with `_TYPE` and `_NOTES`), `OUT_OF_SCOPE`, `ENGAGEMENT_TYPE`, `CREDENTIALS` | -| **Activities** | Toggle each `PERMIT_*` field (`x` = allowed, blank = denied): recon, scanning, enumeration, exploitation, data extraction, credential testing, post-exploitation, traffic capture, screenshots | -| **Testing Window** | `TESTING_START`, `TESTING_END`, `TIMEZONE`, `EMERGENCY_CONTACT`, `EMERGENCY_PHONE` | -| **Legal** | `APPLICABLE_STANDARDS`, `REPORT_CLASSIFICATION`, `REPORT_DELIVERY` | -| **Signature** | `SIGNATORY_NAME`, `SIGNATORY_TITLE`, `SIGNATORY_ORGANIZATION`, `SIGNATURE_DATE`, `DIGITAL_SIGNATURE` | - -**2. Activate** — set the status field: - -```bash -AUTHORIZATION_STATUS=ACTIVE -``` - -**3. Inject** — render the active document: - -```bash -make inject-verification -``` - -Or directly: `python -m blhackbox.prompts.inject_verification` - -On success: - -``` -Verification document activated → .claude/verification-active.md -Engagement: PENTEST-2026-001 -Targets: example.com, 10.0.0.0/24 -Window: 2026-03-01 09:00 — 2026-03-31 17:00 UTC -Authorized by: Jane Smith -``` - -**4. Start your session** — Claude Code will automatically pick up the verification document. On Claude Code Web, the session-start hook runs `inject-verification` automatically if `verification.env` exists. - -### Validation rules - -The injection script validates before rendering: - -- `AUTHORIZATION_STATUS` must be `ACTIVE` -- All required fields must be filled (`ENGAGEMENT_ID`, `AUTHORIZATION_DATE`, `EXPIRATION_DATE`, `AUTHORIZING_ORGANIZATION`, `TESTER_NAME`, `TARGET_1`, `TESTING_START`, `TESTING_END`, `SIGNATORY_NAME`, `SIGNATURE_DATE`) -- `EXPIRATION_DATE` must not be in the past - -If any check fails, the script exits with an error explaining what to fix. - -### Files involved - -| File | Purpose | -|:--|:--| -| `verification.env` | User-fillable config with engagement details, scope, and permissions | -| `blhackbox/prompts/verification.md` | Template with `{{PLACEHOLDER}}` tokens | -| `blhackbox/prompts/inject_verification.py` | Renders the template into the active document | -| `.claude/verification-active.md` | Rendered active authorization (git-ignored) | - -For a minimal self-authorized lab setup, see [How do I set up authorization for a lab/CTF?](#how-do-i-set-up-authorization-for-a-labctf) in the Advanced FAQ. - ---- - ## Security Notes - **Docker socket** — MCP Gateway (optional) and Portainer mount `/var/run/docker.sock`. This grants effective root on the host. Never expose ports 8080 or 9443 to the public internet. -- **Authorization** — Set up a [verification document](#authorization--verification) before running any pentest. Claude Code will not execute offensive actions without active authorization. The rendered document (`.claude/verification-active.md`) is git-ignored. +- **Authorization** — Only test systems you have explicit written permission to assess. Unauthorized scanning or exploitation is illegal. - **Neo4j** — Set a strong password in `.env`. Never use defaults in production. - **Portainer** — Uses HTTPS with a self-signed certificate. Create a strong admin password on first run. @@ -1037,7 +960,6 @@ blhackbox/ ├── CLAUDE.md Project-wide development rules ├── .claude/ │ ├── settings.json Claude Code hooks config -│ ├── verification-active.md Rendered authorization (git-ignored) │ ├── hooks/ │ │ ├── session-start.sh Auto-setup for web sessions │ │ └── loop-detector.sh MCP tool loop detection (Reflector pattern) @@ -1057,14 +979,15 @@ blhackbox/ │ ├── reports/ Generated pentest reports │ ├── screenshots/ PoC evidence captures │ └── sessions/ Aggregated session JSONs -├── verification.env Pentest authorization config ├── .mcp.json MCP server config (Claude Code Web) ├── docker/ │ ├── kali-mcp.Dockerfile Kali Linux + Metasploit Framework │ ├── wire-mcp.Dockerfile │ ├── screenshot-mcp.Dockerfile │ ├── claude-code.Dockerfile MCP client container -│ └── claude-code-entrypoint.sh Startup script with health checks +│ ├── claude-code-entrypoint.sh Startup script with health checks +│ ├── deepseek.Dockerfile DeepSeek (Reasonix) MCP client container +│ └── deepseek-entrypoint.sh DeepSeek startup script with health checks ├── kali-mcp/ Kali MCP server (70+ tools + Metasploit) ├── wire-mcp/ WireMCP server (tshark, 7 tools) ├── screenshot-mcp/ Screenshot MCP server (Playwright, 4 tools) @@ -1081,9 +1004,7 @@ blhackbox/ │ │ └── CLAUDE.md Backend safety rules (shell=False) │ ├── prompts/ │ │ ├── templates/ 11 pentest template .md files -│ │ ├── claude_playbook.md Pentest playbook for MCP host -│ │ ├── verification.md Authorization template -│ │ └── inject_verification.py Renders template → active document +│ │ └── claude_playbook.md Pentest playbook for MCP host │ ├── reporting/ │ │ ├── html_generator.py, pdf_generator.py, md_generator.py │ │ └── CLAUDE.md Reporting path conventions diff --git a/blhackbox-mcp-catalog.yaml b/blhackbox-mcp-catalog.yaml index 25f094b..601b7ff 100644 --- a/blhackbox-mcp-catalog.yaml +++ b/blhackbox-mcp-catalog.yaml @@ -19,8 +19,8 @@ registry: title: "Kali MCP Server" type: "server" remote: - url: "http://kali-mcp:9001/sse" - transport_type: sse + url: "http://kali-mcp:9001/mcp" + transport_type: streamable wire-mcp: description: "Wireshark/tshark — 7 tools: packet capture, pcap analysis, credential extraction, stream following" @@ -28,29 +28,29 @@ registry: type: "server" remote: # wire-mcp shares kali-mcp's network namespace for traffic visibility - url: "http://kali-mcp:9003/sse" - transport_type: sse + url: "http://kali-mcp:9003/mcp" + transport_type: streamable screenshot-mcp: description: "Headless Chromium screenshots — 4 tools: take_screenshot, take_element_screenshot, list_screenshots, annotate_screenshot" title: "Screenshot MCP Server" type: "server" remote: - url: "http://screenshot-mcp:9004/sse" - transport_type: sse + url: "http://screenshot-mcp:9004/mcp" + transport_type: streamable hexstrike-bridge-mcp: description: "HexStrike Gamma MCP — upstream tool surface connected to the local HexStrike API container" title: "HexStrike MCP Server" type: "server" remote: - url: "http://hexstrike-bridge-mcp:9006/sse" - transport_type: sse + url: "http://hexstrike-bridge-mcp:9006/mcp" + transport_type: streamable boaz-mcp: - description: "BOAZ MCP — upstream BOAZ-MCP Gamma server exposed over SSE" + description: "BOAZ MCP — upstream BOAZ-MCP Gamma server exposed over Streamable HTTP" title: "BOAZ MCP Server" type: "server" remote: - url: "http://boaz-mcp:9005/sse" - transport_type: sse + url: "http://boaz-mcp:9005/mcp" + transport_type: streamable diff --git a/blhackbox-mcp.json b/blhackbox-mcp.json index 4e7e289..33bc972 100644 --- a/blhackbox-mcp.json +++ b/blhackbox-mcp.json @@ -1,9 +1,9 @@ { "mcpServers": { "kali": { - "type": "sse", - "url": "http://localhost:9001/sse", - "description": "Kali Linux security tools + Metasploit Framework \u2014 70+ tools including msfconsole, msfvenom, nmap, sqlmap, hydra, etc. Connects via SSE to docker compose service on port 9001." + "type": "http", + "url": "http://localhost:9001/mcp", + "description": "Kali Linux security tools + Metasploit Framework — 70+ tools including msfconsole, msfvenom, nmap, sqlmap, hydra, etc. Connects via Streamable HTTP to docker compose service on port 9001." }, "wireshark": { "command": "docker", @@ -16,12 +16,12 @@ "--privileged", "crhacky/blhackbox:wire-mcp" ], - "description": "WireMCP Server \u2014 Wireshark/tshark for packet capture and network analysis (7 tools)" + "description": "WireMCP Server — Wireshark/tshark for packet capture and network analysis (7 tools)" }, "screenshot": { - "type": "sse", - "url": "http://localhost:9004/sse", - "description": "Screenshot MCP Server \u2014 headless Chromium screenshots for bug bounty PoC evidence capture (4 tools)" + "type": "http", + "url": "http://localhost:9004/mcp", + "description": "Screenshot MCP Server — headless Chromium screenshots for bug bounty PoC evidence capture (4 tools)" }, "blhackbox": { "command": "blhackbox", @@ -29,17 +29,17 @@ "mcp" ], "env": {}, - "description": "blhackbox core MCP server \u2014 recon, tool execution, graph queries, report generation" + "description": "blhackbox core MCP server — recon, tool execution, graph queries, report generation" }, "hexstrike": { - "type": "sse", - "url": "http://localhost:9006/sse", - "description": "HexStrike MCP Server \u2014 full upstream HexStrike Gamma MCP service connected to the HexStrike API container." + "type": "http", + "url": "http://localhost:9006/mcp", + "description": "HexStrike MCP Server — full upstream HexStrike Gamma MCP service connected to the HexStrike API container." }, "boaz": { - "type": "sse", - "url": "http://localhost:9005/sse", - "description": "BOAZ MCP Server \u2014 upstream BOAZ-MCP Gamma server exposed over SSE." + "type": "http", + "url": "http://localhost:9005/mcp", + "description": "BOAZ MCP Server — upstream BOAZ-MCP Gamma server exposed over Streamable HTTP." } } } diff --git a/blhackbox/data/tools_catalog.json b/blhackbox/data/tools_catalog.json index b4a4b5c..60fa90e 100644 --- a/blhackbox/data/tools_catalog.json +++ b/blhackbox/data/tools_catalog.json @@ -13,7 +13,8 @@ ], "example_params": { "target": "example.com" - } + }, + "api_key": "Optional — runs without keys. Extra passive sources (VirusTotal, Shodan, SecurityTrails, etc.) activate via env vars in .env or ~/.config/subfinder/provider-config.yaml. Sources with no key are skipped, not fatal." }, { "category": "dns", @@ -29,7 +30,8 @@ ], "example_params": { "target": "example.com" - } + }, + "api_key": "Optional — runs without keys. Data-source keys (read from ~/.config/amass/datasources.yaml) only widen coverage; amass works standalone." }, { "category": "dns", @@ -90,7 +92,8 @@ ], "example_params": { "target": "example.com" - } + }, + "api_key": "Optional — runs without keys (keyless sources: crtsh, certspotter, duckduckgo, otx, rapiddns, etc.). Key-required sources (shodan, hunter, securitytrails, censys) read from api-keys.yaml; missing keys produce warnings, not failure." }, { "category": "intelligence", @@ -601,7 +604,8 @@ ], "example_params": { "target": "https://example.com" - } + }, + "api_key": "Optional — scans without one. wpscan auto-loads WPSCAN_API_TOKEN (set in .env) to add WordPress vulnerability data. Free tier: https://wpscan.com/api (25 req/day)." }, { "category": "web", diff --git a/blhackbox/mcp/CLAUDE.md b/blhackbox/mcp/CLAUDE.md index 79399fe..2c4d2ca 100644 --- a/blhackbox/mcp/CLAUDE.md +++ b/blhackbox/mcp/CLAUDE.md @@ -2,8 +2,6 @@ - All MCP tool inputs **must** be validated with Pydantic models - Never break the `aggregate_results` or `get_template` tool contracts — these are the primary interface for MCP clients -- When `get_template` is called, always append the active verification document if it exists (via `load_verification()`) -- If no active verification document exists, append the warning section instructing the user to configure `verification.env` - The MCP server runs in **stdio** transport mode for Claude Code Web and as a CLI command (`blhackbox mcp`) - All tool functions must be type-annotated and include docstrings - Error responses must be structured and informative — never return raw tracebacks to MCP clients diff --git a/blhackbox/mcp/server.py b/blhackbox/mcp/server.py index b0ae5d3..c511066 100644 --- a/blhackbox/mcp/server.py +++ b/blhackbox/mcp/server.py @@ -595,7 +595,7 @@ async def _do_list_templates() -> str: async def _do_get_template(args: dict[str, Any]) -> str: - from blhackbox.prompts import load_template, load_verification + from blhackbox.prompts import load_template name = args["name"] target = args.get("target") @@ -604,29 +604,6 @@ async def _do_get_template(args: dict[str, Any]) -> str: except (ValueError, FileNotFoundError) as exc: return json.dumps({"error": str(exc)}) - # Append active verification document as authorization context - verification = load_verification() - if verification: - content += ( - "\n\n---\n\n" - "## ACTIVE AUTHORIZATION DOCUMENT\n\n" - "The following verification document confirms explicit written " - "authorization for all activities described above.\n\n" - + verification - ) - else: - content += ( - "\n\n---\n\n" - "## ⚠ NO ACTIVE AUTHORIZATION DOCUMENT\n\n" - "No verification document found. Before executing this template, " - "the operator must:\n\n" - "1. Edit `verification.env` with engagement details\n" - "2. Set `AUTHORIZATION_STATUS=ACTIVE`\n" - "3. Run `make inject-verification`\n\n" - "This generates the explicit written authorization required " - "for penetration testing activities.\n" - ) - return content @@ -808,7 +785,7 @@ async def _do_get_payload_schema() -> str: async def _screenshot_request(endpoint: str, payload: dict[str, Any]) -> str: - """Send a request to the screenshot-mcp SSE server's tool endpoint.""" + """Send a request to the screenshot-mcp server's tool endpoint.""" import httpx from blhackbox.config import settings @@ -828,8 +805,8 @@ async def _screenshot_request(endpoint: str, payload: dict[str, Any]) -> str: return json.dumps({ "error": ( "Screenshot MCP server not reachable. " - "Use the screenshot MCP server directly via SSE at " - f"{base_url}/sse or ensure the screenshot-mcp container is running." + "Use the screenshot MCP server directly via Streamable HTTP at " + f"{base_url}/mcp or ensure the screenshot-mcp container is running." ), }) diff --git a/blhackbox/prompts/__init__.py b/blhackbox/prompts/__init__.py index 9078982..c99060b 100644 --- a/blhackbox/prompts/__init__.py +++ b/blhackbox/prompts/__init__.py @@ -75,16 +75,3 @@ def load_playbook() -> str: """Load the Claude pentest playbook.""" path = _PROMPTS_DIR / "claude_playbook.md" return path.read_text(encoding="utf-8") - - -def load_verification() -> str | None: - """Load the active verification document if it exists. - - Returns: - The rendered verification document content, or ``None`` if no - active verification document has been generated yet. - """ - active_path = _PROMPTS_DIR.parent.parent / ".claude" / "verification-active.md" - if active_path.exists(): - return active_path.read_text(encoding="utf-8") - return None diff --git a/blhackbox/prompts/inject_verification.py b/blhackbox/prompts/inject_verification.py deleted file mode 100644 index 5a8c225..0000000 --- a/blhackbox/prompts/inject_verification.py +++ /dev/null @@ -1,202 +0,0 @@ -"""Inject verification document into the Claude Code session context. - -Reads ``verification.env`` from the project root, renders the -``verification.md`` template with the configured values, and writes -the active document to ``.claude/verification-active.md``. - -The session-start hook (or ``make inject-verification``) calls this -script so that the rendered authorization document is present in -the Claude Code context before any pentest prompt templates run. - -Usage:: - - python -m blhackbox.prompts.inject_verification [--env PATH] [--out PATH] -""" - -from __future__ import annotations - -import argparse -import re -import sys -from datetime import UTC, datetime -from pathlib import Path -from typing import Any - - -def _parse_env_file(env_path: Path) -> dict[str, str]: - """Parse a simple KEY=VALUE env file, ignoring comments and blanks.""" - values: dict[str, str] = {} - for line in env_path.read_text(encoding="utf-8").splitlines(): - line = line.strip() - if not line or line.startswith("#"): - continue - if "=" not in line: - continue - key, _, value = line.partition("=") - values[key.strip()] = value.strip() - return values - - -def _validate_required_fields(env: dict[str, str]) -> list[str]: - """Return a list of missing required fields.""" - required = [ - "AUTHORIZATION_STATUS", - "ENGAGEMENT_ID", - "AUTHORIZATION_DATE", - "EXPIRATION_DATE", - "AUTHORIZING_ORGANIZATION", - "TESTER_NAME", - "TARGET_1", - "TESTING_START", - "TESTING_END", - "SIGNATORY_NAME", - "SIGNATURE_DATE", - ] - return [f for f in required if not env.get(f)] - - -def _check_expiration(env: dict[str, str]) -> str | None: - """Return an error message if the authorization has expired.""" - exp = env.get("EXPIRATION_DATE", "") - if not exp: - return None - try: - exp_date = datetime.strptime(exp, "%Y-%m-%d").date() - today = datetime.now(UTC).date() - if exp_date < today: - return f"Authorization expired on {exp}." - except ValueError: - return f"Invalid EXPIRATION_DATE format: {exp!r} (expected YYYY-MM-DD)." - return None - - -def render_verification(env: dict[str, str], template_text: str) -> str: - """Replace ``{{PLACEHOLDER}}`` tokens in the template with env values.""" - def _replace(match: re.Match[str]) -> str: - key = match.group(1) - return env.get(key, match.group(0)) - - return re.sub(r"\{\{(\w+)\}\}", _replace, template_text) - - -def inject( - env_path: Path | None = None, - out_path: Path | None = None, -) -> dict[str, Any]: - """Run the full injection pipeline. - - Returns: - Dict with ``status``, ``output_path``, and optional ``warnings``. - """ - project_root = Path(__file__).resolve().parents[2] - - if env_path is None: - env_path = project_root / "verification.env" - if out_path is None: - out_path = project_root / ".claude" / "verification-active.md" - - result: dict[str, Any] = {"warnings": []} - - # --- Read env --- - if not env_path.exists(): - return { - "status": "error", - "message": ( - f"verification.env not found at {env_path}. " - "Copy verification.env and fill in your engagement details." - ), - } - - env = _parse_env_file(env_path) - - # --- Check status --- - status = env.get("AUTHORIZATION_STATUS", "PENDING").upper() - if status != "ACTIVE": - return { - "status": "inactive", - "message": ( - "AUTHORIZATION_STATUS is not ACTIVE. " - "Set AUTHORIZATION_STATUS=ACTIVE in verification.env " - "after filling in all fields." - ), - } - - # --- Validate required fields --- - missing = _validate_required_fields(env) - if missing: - return { - "status": "error", - "message": ( - f"Missing required fields in verification.env: {', '.join(missing)}. " - "Fill in all required fields before activating." - ), - } - - # --- Check expiration --- - exp_err = _check_expiration(env) - if exp_err: - return {"status": "expired", "message": exp_err} - - # --- Read template --- - template_path = Path(__file__).parent / "verification.md" - if not template_path.exists(): - return { - "status": "error", - "message": f"Verification template not found: {template_path}", - } - - template_text = template_path.read_text(encoding="utf-8") - - # --- Render --- - rendered = render_verification(env, template_text) - - # --- Write active document --- - out_path.parent.mkdir(parents=True, exist_ok=True) - out_path.write_text(rendered, encoding="utf-8") - - result["status"] = "active" - result["output_path"] = str(out_path) - targets = ", ".join( - env.get(f"TARGET_{i}", "") - for i in range(1, 4) - if env.get(f"TARGET_{i}") - ) - result["message"] = ( - f"Verification document activated → {out_path}\n" - f"Engagement: {env.get('ENGAGEMENT_ID', 'N/A')}\n" - f"Targets: {targets}\n" - f"Window: {env.get('TESTING_START', '?')} — " - f"{env.get('TESTING_END', '?')} {env.get('TIMEZONE', 'UTC')}\n" - f"Authorized by: {env.get('SIGNATORY_NAME', 'N/A')}" - ) - return result - - -def main() -> None: - """CLI entry point.""" - parser = argparse.ArgumentParser( - description="Inject pentest verification into Claude Code session." - ) - parser.add_argument( - "--env", - type=Path, - default=None, - help="Path to verification.env (default: /verification.env)", - ) - parser.add_argument( - "--out", - type=Path, - default=None, - help="Output path (default: /.claude/verification-active.md)", - ) - args = parser.parse_args() - - result = inject(env_path=args.env, out_path=args.out) - print(result["message"]) - - if result["status"] not in ("active",): - sys.exit(1) - - -if __name__ == "__main__": - main() diff --git a/blhackbox/prompts/templates/api-security.md b/blhackbox/prompts/templates/api-security.md index a9ff49f..b36317b 100644 --- a/blhackbox/prompts/templates/api-security.md +++ b/blhackbox/prompts/templates/api-security.md @@ -36,13 +36,14 @@ TARGET = "[TARGET_API_BASE_URL]" > 2. If you have API documentation (Swagger/OpenAPI), set `API_DOCS_URL` > 3. If testing authenticated endpoints, fill in the optional auth fields above > 4. Ensure all MCP servers are healthy — run `make mcp-status` -> 5. Verify authorization is active — run `make inject-verification` -> 6. Query each server's tool listing to discover available API testing capabilities +> 5. Query each server's tool listing to discover available API testing capabilities ## Mandatory Tool & Methodology Readiness -Do **not** start the skill's execution plan until this readiness pass is complete. -This is Phase 0 for every blhackbox skill. +Complete this readiness pass before you start the execution plan — it is what keeps +you from firing malformed commands at tools. This is Phase 0 for every blhackbox skill. +Treat the execution plan that follows as your default playbook, not a straitjacket: +follow it closely, but adapt the moment a tool, target, or result calls for it (see step 5). 1. **Inventory 100% of usable capabilities first.** - Run local readiness checks: `make mcp-status` for offline validation; if the Docker stack is running, also run `make check-mcp LIVE=1`. @@ -70,6 +71,29 @@ This is Phase 0 for every blhackbox skill. - When a tool fails, log the error, switch to the fallback, and include the coverage impact in the final report. - Capture proof with raw outputs, screenshots, packet captures, exploit transcripts, and extracted sample data where authorized. +5. **Adapt, recover, and think — never follow the plan off a cliff.** + The phases below are a proven default sequence, not a rigid script. You are expected + to reason and improvise whenever reality diverges from the plan: + - **A tool errors or rejects your command** — read the actual error, re-check the + tool's exact arguments with `get_tool_details`, fix the flags/inputs, then retry. + Most failures are wrong syntax, a missing input, or an unescaped value. Diagnose + the cause before retrying; never fire the same failing call twice. + - **A tool needs an API key or token you don't have** (e.g. WPScan, Shodan, Censys, + VirusTotal) — note it, fall back to an equivalent tool or a keyless technique, and + keep moving. Never stall waiting for a key; log it in the issues report and proceed. + - **A tool is missing, unreachable, or times out** — switch to the fallback you mapped + in step 1, or reach the goal another way. Documented coverage gaps are acceptable; + getting stuck is not. + - **Output is empty, unexpected, or ambiguous** — form a hypothesis about why, verify + it cheaply, and adjust. Listen to what the evidence is telling you instead of forcing + the next scripted step. + - **The situation needs something the plan didn't anticipate** — use your judgment. Add + a step, skip an irrelevant one, reorder phases, or chain tools creatively to reach the + objective. Briefly record why you deviated. + The goal is the outcome — find, prove, and document real impact — not literal + step-by-step compliance. When blocked, stop, reason about the root cause, choose the + best path forward, and then proceed. + --- diff --git a/blhackbox/prompts/templates/bug-bounty.md b/blhackbox/prompts/templates/bug-bounty.md index 0b70ae4..b3d7c98 100644 --- a/blhackbox/prompts/templates/bug-bounty.md +++ b/blhackbox/prompts/templates/bug-bounty.md @@ -38,15 +38,16 @@ PROGRAM_RULES = "[PROGRAM_RULES]" > **Before you start:** > 1. Confirm all placeholders above (`TARGET`, `SCOPE`, `OUT_OF_SCOPE`, > `PROGRAM_RULES`) are set with actual program details -> 2. Double-check the scope — never test out-of-scope assets -> 3. Ensure all MCP servers are healthy — run `make mcp-status` -> 4. Verify authorization is active — run `make inject-verification` -> 5. Query each server's tool listing to discover available hunting capabilities +> 1. Double-check the scope — never test out-of-scope assets +> 2. Ensure all MCP servers are healthy — run `make mcp-status` +> 3. Query each server's tool listing to discover available hunting capabilities ## Mandatory Tool & Methodology Readiness -Do **not** start the skill's execution plan until this readiness pass is complete. -This is Phase 0 for every blhackbox skill. +Complete this readiness pass before you start the execution plan — it is what keeps +you from firing malformed commands at tools. This is Phase 0 for every blhackbox skill. +Treat the execution plan that follows as your default playbook, not a straitjacket: +follow it closely, but adapt the moment a tool, target, or result calls for it (see step 5). 1. **Inventory 100% of usable capabilities first.** - Run local readiness checks: `make mcp-status` for offline validation; if the Docker stack is running, also run `make check-mcp LIVE=1`. @@ -74,6 +75,29 @@ This is Phase 0 for every blhackbox skill. - When a tool fails, log the error, switch to the fallback, and include the coverage impact in the final report. - Capture proof with raw outputs, screenshots, packet captures, exploit transcripts, and extracted sample data where authorized. +5. **Adapt, recover, and think — never follow the plan off a cliff.** + The phases below are a proven default sequence, not a rigid script. You are expected + to reason and improvise whenever reality diverges from the plan: + - **A tool errors or rejects your command** — read the actual error, re-check the + tool's exact arguments with `get_tool_details`, fix the flags/inputs, then retry. + Most failures are wrong syntax, a missing input, or an unescaped value. Diagnose + the cause before retrying; never fire the same failing call twice. + - **A tool needs an API key or token you don't have** (e.g. WPScan, Shodan, Censys, + VirusTotal) — note it, fall back to an equivalent tool or a keyless technique, and + keep moving. Never stall waiting for a key; log it in the issues report and proceed. + - **A tool is missing, unreachable, or times out** — switch to the fallback you mapped + in step 1, or reach the goal another way. Documented coverage gaps are acceptable; + getting stuck is not. + - **Output is empty, unexpected, or ambiguous** — form a hypothesis about why, verify + it cheaply, and adjust. Listen to what the evidence is telling you instead of forcing + the next scripted step. + - **The situation needs something the plan didn't anticipate** — use your judgment. Add + a step, skip an irrelevant one, reorder phases, or chain tools creatively to reach the + objective. Briefly record why you deviated. + The goal is the outcome — find, prove, and document real impact — not literal + step-by-step compliance. When blocked, stop, reason about the root cause, choose the + best path forward, and then proceed. + --- diff --git a/blhackbox/prompts/templates/exploit-dev.md b/blhackbox/prompts/templates/exploit-dev.md index bb6d984..b74fff1 100644 --- a/blhackbox/prompts/templates/exploit-dev.md +++ b/blhackbox/prompts/templates/exploit-dev.md @@ -25,12 +25,13 @@ TARGET = "[TARGET]" > **Before you start:** > 1. Confirm the `TARGET` placeholder above is set to your actual target/vulnerability > 2. Ensure all MCP servers are healthy — run `make mcp-status` -> 3. Verify authorization is active — run `make inject-verification` ## Mandatory Tool & Methodology Readiness -Do **not** start the skill's execution plan until this readiness pass is complete. -This is Phase 0 for every blhackbox skill. +Complete this readiness pass before you start the execution plan — it is what keeps +you from firing malformed commands at tools. This is Phase 0 for every blhackbox skill. +Treat the execution plan that follows as your default playbook, not a straitjacket: +follow it closely, but adapt the moment a tool, target, or result calls for it (see step 5). 1. **Inventory 100% of usable capabilities first.** - Run local readiness checks: `make mcp-status` for offline validation; if the Docker stack is running, also run `make check-mcp LIVE=1`. @@ -58,6 +59,29 @@ This is Phase 0 for every blhackbox skill. - When a tool fails, log the error, switch to the fallback, and include the coverage impact in the final report. - Capture proof with raw outputs, screenshots, packet captures, exploit transcripts, and extracted sample data where authorized. +5. **Adapt, recover, and think — never follow the plan off a cliff.** + The phases below are a proven default sequence, not a rigid script. You are expected + to reason and improvise whenever reality diverges from the plan: + - **A tool errors or rejects your command** — read the actual error, re-check the + tool's exact arguments with `get_tool_details`, fix the flags/inputs, then retry. + Most failures are wrong syntax, a missing input, or an unescaped value. Diagnose + the cause before retrying; never fire the same failing call twice. + - **A tool needs an API key or token you don't have** (e.g. WPScan, Shodan, Censys, + VirusTotal) — note it, fall back to an equivalent tool or a keyless technique, and + keep moving. Never stall waiting for a key; log it in the issues report and proceed. + - **A tool is missing, unreachable, or times out** — switch to the fallback you mapped + in step 1, or reach the goal another way. Documented coverage gaps are acceptable; + getting stuck is not. + - **Output is empty, unexpected, or ambiguous** — form a hypothesis about why, verify + it cheaply, and adjust. Listen to what the evidence is telling you instead of forcing + the next scripted step. + - **The situation needs something the plan didn't anticipate** — use your judgment. Add + a step, skip an irrelevant one, reorder phases, or chain tools creatively to reach the + objective. Briefly record why you deviated. + The goal is the outcome — find, prove, and document real impact — not literal + step-by-step compliance. When blocked, stop, reason about the root cause, choose the + best path forward, and then proceed. + --- diff --git a/blhackbox/prompts/templates/full-attack-chain.md b/blhackbox/prompts/templates/full-attack-chain.md index f3bb78d..7b1f294 100644 --- a/blhackbox/prompts/templates/full-attack-chain.md +++ b/blhackbox/prompts/templates/full-attack-chain.md @@ -12,8 +12,10 @@ data extraction, and post-exploitation — with comprehensive reporting. ## Mandatory Tool & Methodology Readiness -Do **not** start the skill's execution plan until this readiness pass is complete. -This is Phase 0 for every blhackbox skill. +Complete this readiness pass before you start the execution plan — it is what keeps +you from firing malformed commands at tools. This is Phase 0 for every blhackbox skill. +Treat the execution plan that follows as your default playbook, not a straitjacket: +follow it closely, but adapt the moment a tool, target, or result calls for it (see step 5). 1. **Inventory 100% of usable capabilities first.** - Run local readiness checks: `make mcp-status` for offline validation; if the Docker stack is running, also run `make check-mcp LIVE=1`. @@ -41,6 +43,29 @@ This is Phase 0 for every blhackbox skill. - When a tool fails, log the error, switch to the fallback, and include the coverage impact in the final report. - Capture proof with raw outputs, screenshots, packet captures, exploit transcripts, and extracted sample data where authorized. +5. **Adapt, recover, and think — never follow the plan off a cliff.** + The phases below are a proven default sequence, not a rigid script. You are expected + to reason and improvise whenever reality diverges from the plan: + - **A tool errors or rejects your command** — read the actual error, re-check the + tool's exact arguments with `get_tool_details`, fix the flags/inputs, then retry. + Most failures are wrong syntax, a missing input, or an unescaped value. Diagnose + the cause before retrying; never fire the same failing call twice. + - **A tool needs an API key or token you don't have** (e.g. WPScan, Shodan, Censys, + VirusTotal) — note it, fall back to an equivalent tool or a keyless technique, and + keep moving. Never stall waiting for a key; log it in the issues report and proceed. + - **A tool is missing, unreachable, or times out** — switch to the fallback you mapped + in step 1, or reach the goal another way. Documented coverage gaps are acceptable; + getting stuck is not. + - **Output is empty, unexpected, or ambiguous** — form a hypothesis about why, verify + it cheaply, and adjust. Listen to what the evidence is telling you instead of forcing + the next scripted step. + - **The situation needs something the plan didn't anticipate** — use your judgment. Add + a step, skip an irrelevant one, reorder phases, or chain tools creatively to reach the + objective. Briefly record why you deviated. + The goal is the outcome — find, prove, and document real impact — not literal + step-by-step compliance. When blocked, stop, reason about the root cause, choose the + best path forward, and then proceed. + --- @@ -74,9 +99,8 @@ REPORT_FORMAT = "[REPORT_FORMAT]" > **Before you start:** > 1. Confirm all placeholders above (`TARGET`, `SCOPE`, `OUT_OF_SCOPE`, > `ENGAGEMENT_TYPE`, `CREDENTIALS`, `REPORT_FORMAT`) are set -> 2. Ensure all MCP servers are healthy — run `make mcp-status` -> 3. Verify authorization is active — run `make inject-verification` -> 4. Query each server's tool listing to discover available capabilities +> 1. Ensure all MCP servers are healthy — run `make mcp-status` +> 2. Query each server's tool listing to discover available capabilities --- diff --git a/blhackbox/prompts/templates/full-pentest.md b/blhackbox/prompts/templates/full-pentest.md index 726f96c..fe80ed0 100644 --- a/blhackbox/prompts/templates/full-pentest.md +++ b/blhackbox/prompts/templates/full-pentest.md @@ -24,13 +24,14 @@ TARGET = "[TARGET]" > **Before you start:** > 1. Confirm the `TARGET` placeholder above is set to your actual target > 2. Ensure all MCP servers are healthy — run `make mcp-status` -> 3. Verify authorization is active — run `make inject-verification` -> 4. Query each server's tool listing at the start to discover available capabilities +> 3. Query each server's tool listing at the start to discover available capabilities ## Mandatory Tool & Methodology Readiness -Do **not** start the skill's execution plan until this readiness pass is complete. -This is Phase 0 for every blhackbox skill. +Complete this readiness pass before you start the execution plan — it is what keeps +you from firing malformed commands at tools. This is Phase 0 for every blhackbox skill. +Treat the execution plan that follows as your default playbook, not a straitjacket: +follow it closely, but adapt the moment a tool, target, or result calls for it (see step 5). 1. **Inventory 100% of usable capabilities first.** - Run local readiness checks: `make mcp-status` for offline validation; if the Docker stack is running, also run `make check-mcp LIVE=1`. @@ -58,6 +59,29 @@ This is Phase 0 for every blhackbox skill. - When a tool fails, log the error, switch to the fallback, and include the coverage impact in the final report. - Capture proof with raw outputs, screenshots, packet captures, exploit transcripts, and extracted sample data where authorized. +5. **Adapt, recover, and think — never follow the plan off a cliff.** + The phases below are a proven default sequence, not a rigid script. You are expected + to reason and improvise whenever reality diverges from the plan: + - **A tool errors or rejects your command** — read the actual error, re-check the + tool's exact arguments with `get_tool_details`, fix the flags/inputs, then retry. + Most failures are wrong syntax, a missing input, or an unescaped value. Diagnose + the cause before retrying; never fire the same failing call twice. + - **A tool needs an API key or token you don't have** (e.g. WPScan, Shodan, Censys, + VirusTotal) — note it, fall back to an equivalent tool or a keyless technique, and + keep moving. Never stall waiting for a key; log it in the issues report and proceed. + - **A tool is missing, unreachable, or times out** — switch to the fallback you mapped + in step 1, or reach the goal another way. Documented coverage gaps are acceptable; + getting stuck is not. + - **Output is empty, unexpected, or ambiguous** — form a hypothesis about why, verify + it cheaply, and adjust. Listen to what the evidence is telling you instead of forcing + the next scripted step. + - **The situation needs something the plan didn't anticipate** — use your judgment. Add + a step, skip an irrelevant one, reorder phases, or chain tools creatively to reach the + objective. Briefly record why you deviated. + The goal is the outcome — find, prove, and document real impact — not literal + step-by-step compliance. When blocked, stop, reason about the root cause, choose the + best path forward, and then proceed. + --- diff --git a/blhackbox/prompts/templates/network-infrastructure.md b/blhackbox/prompts/templates/network-infrastructure.md index 371525e..7a0a069 100644 --- a/blhackbox/prompts/templates/network-infrastructure.md +++ b/blhackbox/prompts/templates/network-infrastructure.md @@ -31,13 +31,14 @@ TARGET = "[TARGET]" > 1. Confirm the `TARGET` placeholder above is set to your target IP, range, or domain > 2. Set optional `PORTS`, `SCAN_RATE`, and `EXCLUDES` if needed > 3. Ensure all MCP servers are healthy — run `make mcp-status` -> 4. Verify authorization is active — run `make inject-verification` -> 5. Query each server's tool listing to discover available network testing capabilities +> 4. Query each server's tool listing to discover available network testing capabilities ## Mandatory Tool & Methodology Readiness -Do **not** start the skill's execution plan until this readiness pass is complete. -This is Phase 0 for every blhackbox skill. +Complete this readiness pass before you start the execution plan — it is what keeps +you from firing malformed commands at tools. This is Phase 0 for every blhackbox skill. +Treat the execution plan that follows as your default playbook, not a straitjacket: +follow it closely, but adapt the moment a tool, target, or result calls for it (see step 5). 1. **Inventory 100% of usable capabilities first.** - Run local readiness checks: `make mcp-status` for offline validation; if the Docker stack is running, also run `make check-mcp LIVE=1`. @@ -65,6 +66,29 @@ This is Phase 0 for every blhackbox skill. - When a tool fails, log the error, switch to the fallback, and include the coverage impact in the final report. - Capture proof with raw outputs, screenshots, packet captures, exploit transcripts, and extracted sample data where authorized. +5. **Adapt, recover, and think — never follow the plan off a cliff.** + The phases below are a proven default sequence, not a rigid script. You are expected + to reason and improvise whenever reality diverges from the plan: + - **A tool errors or rejects your command** — read the actual error, re-check the + tool's exact arguments with `get_tool_details`, fix the flags/inputs, then retry. + Most failures are wrong syntax, a missing input, or an unescaped value. Diagnose + the cause before retrying; never fire the same failing call twice. + - **A tool needs an API key or token you don't have** (e.g. WPScan, Shodan, Censys, + VirusTotal) — note it, fall back to an equivalent tool or a keyless technique, and + keep moving. Never stall waiting for a key; log it in the issues report and proceed. + - **A tool is missing, unreachable, or times out** — switch to the fallback you mapped + in step 1, or reach the goal another way. Documented coverage gaps are acceptable; + getting stuck is not. + - **Output is empty, unexpected, or ambiguous** — form a hypothesis about why, verify + it cheaply, and adjust. Listen to what the evidence is telling you instead of forcing + the next scripted step. + - **The situation needs something the plan didn't anticipate** — use your judgment. Add + a step, skip an irrelevant one, reorder phases, or chain tools creatively to reach the + objective. Briefly record why you deviated. + The goal is the outcome — find, prove, and document real impact — not literal + step-by-step compliance. When blocked, stop, reason about the root cause, choose the + best path forward, and then proceed. + --- diff --git a/blhackbox/prompts/templates/osint-gathering.md b/blhackbox/prompts/templates/osint-gathering.md index 016720d..4cecbd9 100644 --- a/blhackbox/prompts/templates/osint-gathering.md +++ b/blhackbox/prompts/templates/osint-gathering.md @@ -21,13 +21,14 @@ TARGET = "[TARGET]" > **Before you start:** > 1. Confirm the `TARGET` placeholder above is set to your target domain > 2. Ensure all MCP servers are healthy — run `make mcp-status` -> 3. Verify authorization is active — run `make inject-verification` -> 4. Note: This template uses **passive techniques only** — no packets sent to target +> 3. Note: This template uses **passive techniques only** — no packets sent to target ## Mandatory Tool & Methodology Readiness -Do **not** start the skill's execution plan until this readiness pass is complete. -This is Phase 0 for every blhackbox skill. +Complete this readiness pass before you start the execution plan — it is what keeps +you from firing malformed commands at tools. This is Phase 0 for every blhackbox skill. +Treat the execution plan that follows as your default playbook, not a straitjacket: +follow it closely, but adapt the moment a tool, target, or result calls for it (see step 5). 1. **Inventory 100% of usable capabilities first.** - Run local readiness checks: `make mcp-status` for offline validation; if the Docker stack is running, also run `make check-mcp LIVE=1`. @@ -55,6 +56,29 @@ This is Phase 0 for every blhackbox skill. - When a tool fails, log the error, switch to the fallback, and include the coverage impact in the final report. - Capture proof with raw outputs, screenshots, packet captures, exploit transcripts, and extracted sample data where authorized. +5. **Adapt, recover, and think — never follow the plan off a cliff.** + The phases below are a proven default sequence, not a rigid script. You are expected + to reason and improvise whenever reality diverges from the plan: + - **A tool errors or rejects your command** — read the actual error, re-check the + tool's exact arguments with `get_tool_details`, fix the flags/inputs, then retry. + Most failures are wrong syntax, a missing input, or an unescaped value. Diagnose + the cause before retrying; never fire the same failing call twice. + - **A tool needs an API key or token you don't have** (e.g. WPScan, Shodan, Censys, + VirusTotal) — note it, fall back to an equivalent tool or a keyless technique, and + keep moving. Never stall waiting for a key; log it in the issues report and proceed. + - **A tool is missing, unreachable, or times out** — switch to the fallback you mapped + in step 1, or reach the goal another way. Documented coverage gaps are acceptable; + getting stuck is not. + - **Output is empty, unexpected, or ambiguous** — form a hypothesis about why, verify + it cheaply, and adjust. Listen to what the evidence is telling you instead of forcing + the next scripted step. + - **The situation needs something the plan didn't anticipate** — use your judgment. Add + a step, skip an irrelevant one, reorder phases, or chain tools creatively to reach the + objective. Briefly record why you deviated. + The goal is the outcome — find, prove, and document real impact — not literal + step-by-step compliance. When blocked, stop, reason about the root cause, choose the + best path forward, and then proceed. + --- diff --git a/blhackbox/prompts/templates/quick-scan.md b/blhackbox/prompts/templates/quick-scan.md index 727996d..c557da3 100644 --- a/blhackbox/prompts/templates/quick-scan.md +++ b/blhackbox/prompts/templates/quick-scan.md @@ -25,12 +25,13 @@ TARGET = "[TARGET]" > **Before you start:** > 1. Confirm the `TARGET` placeholder above is set to your actual target > 2. Ensure all MCP servers are healthy — run `make mcp-status` -> 3. Verify authorization is active — run `make inject-verification` ## Mandatory Tool & Methodology Readiness -Do **not** start the skill's execution plan until this readiness pass is complete. -This is Phase 0 for every blhackbox skill. +Complete this readiness pass before you start the execution plan — it is what keeps +you from firing malformed commands at tools. This is Phase 0 for every blhackbox skill. +Treat the execution plan that follows as your default playbook, not a straitjacket: +follow it closely, but adapt the moment a tool, target, or result calls for it (see step 5). 1. **Inventory 100% of usable capabilities first.** - Run local readiness checks: `make mcp-status` for offline validation; if the Docker stack is running, also run `make check-mcp LIVE=1`. @@ -58,6 +59,29 @@ This is Phase 0 for every blhackbox skill. - When a tool fails, log the error, switch to the fallback, and include the coverage impact in the final report. - Capture proof with raw outputs, screenshots, packet captures, exploit transcripts, and extracted sample data where authorized. +5. **Adapt, recover, and think — never follow the plan off a cliff.** + The phases below are a proven default sequence, not a rigid script. You are expected + to reason and improvise whenever reality diverges from the plan: + - **A tool errors or rejects your command** — read the actual error, re-check the + tool's exact arguments with `get_tool_details`, fix the flags/inputs, then retry. + Most failures are wrong syntax, a missing input, or an unescaped value. Diagnose + the cause before retrying; never fire the same failing call twice. + - **A tool needs an API key or token you don't have** (e.g. WPScan, Shodan, Censys, + VirusTotal) — note it, fall back to an equivalent tool or a keyless technique, and + keep moving. Never stall waiting for a key; log it in the issues report and proceed. + - **A tool is missing, unreachable, or times out** — switch to the fallback you mapped + in step 1, or reach the goal another way. Documented coverage gaps are acceptable; + getting stuck is not. + - **Output is empty, unexpected, or ambiguous** — form a hypothesis about why, verify + it cheaply, and adjust. Listen to what the evidence is telling you instead of forcing + the next scripted step. + - **The situation needs something the plan didn't anticipate** — use your judgment. Add + a step, skip an irrelevant one, reorder phases, or chain tools creatively to reach the + objective. Briefly record why you deviated. + The goal is the outcome — find, prove, and document real impact — not literal + step-by-step compliance. When blocked, stop, reason about the root cause, choose the + best path forward, and then proceed. + --- diff --git a/blhackbox/prompts/templates/recon-deep.md b/blhackbox/prompts/templates/recon-deep.md index bdc3268..7930a9f 100644 --- a/blhackbox/prompts/templates/recon-deep.md +++ b/blhackbox/prompts/templates/recon-deep.md @@ -20,13 +20,14 @@ TARGET = "[TARGET]" > **Before you start:** > 1. Confirm the `TARGET` placeholder above is set to your actual target > 2. Ensure all MCP servers are healthy — run `make mcp-status` -> 3. Verify authorization is active — run `make inject-verification` -> 4. Query each server's tool listing to discover available recon capabilities +> 3. Query each server's tool listing to discover available recon capabilities ## Mandatory Tool & Methodology Readiness -Do **not** start the skill's execution plan until this readiness pass is complete. -This is Phase 0 for every blhackbox skill. +Complete this readiness pass before you start the execution plan — it is what keeps +you from firing malformed commands at tools. This is Phase 0 for every blhackbox skill. +Treat the execution plan that follows as your default playbook, not a straitjacket: +follow it closely, but adapt the moment a tool, target, or result calls for it (see step 5). 1. **Inventory 100% of usable capabilities first.** - Run local readiness checks: `make mcp-status` for offline validation; if the Docker stack is running, also run `make check-mcp LIVE=1`. @@ -54,6 +55,29 @@ This is Phase 0 for every blhackbox skill. - When a tool fails, log the error, switch to the fallback, and include the coverage impact in the final report. - Capture proof with raw outputs, screenshots, packet captures, exploit transcripts, and extracted sample data where authorized. +5. **Adapt, recover, and think — never follow the plan off a cliff.** + The phases below are a proven default sequence, not a rigid script. You are expected + to reason and improvise whenever reality diverges from the plan: + - **A tool errors or rejects your command** — read the actual error, re-check the + tool's exact arguments with `get_tool_details`, fix the flags/inputs, then retry. + Most failures are wrong syntax, a missing input, or an unescaped value. Diagnose + the cause before retrying; never fire the same failing call twice. + - **A tool needs an API key or token you don't have** (e.g. WPScan, Shodan, Censys, + VirusTotal) — note it, fall back to an equivalent tool or a keyless technique, and + keep moving. Never stall waiting for a key; log it in the issues report and proceed. + - **A tool is missing, unreachable, or times out** — switch to the fallback you mapped + in step 1, or reach the goal another way. Documented coverage gaps are acceptable; + getting stuck is not. + - **Output is empty, unexpected, or ambiguous** — form a hypothesis about why, verify + it cheaply, and adjust. Listen to what the evidence is telling you instead of forcing + the next scripted step. + - **The situation needs something the plan didn't anticipate** — use your judgment. Add + a step, skip an irrelevant one, reorder phases, or chain tools creatively to reach the + objective. Briefly record why you deviated. + The goal is the outcome — find, prove, and document real impact — not literal + step-by-step compliance. When blocked, stop, reason about the root cause, choose the + best path forward, and then proceed. + --- diff --git a/blhackbox/prompts/templates/vuln-assessment.md b/blhackbox/prompts/templates/vuln-assessment.md index 63e5e27..082a6da 100644 --- a/blhackbox/prompts/templates/vuln-assessment.md +++ b/blhackbox/prompts/templates/vuln-assessment.md @@ -30,13 +30,14 @@ TARGET = "[TARGET]" > 1. Confirm the `TARGET` placeholder above is set to your actual target > 2. Set `FOCUS_AREA` if you want to narrow the assessment scope > 3. Ensure all MCP servers are healthy — run `make mcp-status` -> 4. Verify authorization is active — run `make inject-verification` -> 5. Query each server's tool listing to discover available scanning capabilities +> 4. Query each server's tool listing to discover available scanning capabilities ## Mandatory Tool & Methodology Readiness -Do **not** start the skill's execution plan until this readiness pass is complete. -This is Phase 0 for every blhackbox skill. +Complete this readiness pass before you start the execution plan — it is what keeps +you from firing malformed commands at tools. This is Phase 0 for every blhackbox skill. +Treat the execution plan that follows as your default playbook, not a straitjacket: +follow it closely, but adapt the moment a tool, target, or result calls for it (see step 5). 1. **Inventory 100% of usable capabilities first.** - Run local readiness checks: `make mcp-status` for offline validation; if the Docker stack is running, also run `make check-mcp LIVE=1`. @@ -64,6 +65,29 @@ This is Phase 0 for every blhackbox skill. - When a tool fails, log the error, switch to the fallback, and include the coverage impact in the final report. - Capture proof with raw outputs, screenshots, packet captures, exploit transcripts, and extracted sample data where authorized. +5. **Adapt, recover, and think — never follow the plan off a cliff.** + The phases below are a proven default sequence, not a rigid script. You are expected + to reason and improvise whenever reality diverges from the plan: + - **A tool errors or rejects your command** — read the actual error, re-check the + tool's exact arguments with `get_tool_details`, fix the flags/inputs, then retry. + Most failures are wrong syntax, a missing input, or an unescaped value. Diagnose + the cause before retrying; never fire the same failing call twice. + - **A tool needs an API key or token you don't have** (e.g. WPScan, Shodan, Censys, + VirusTotal) — note it, fall back to an equivalent tool or a keyless technique, and + keep moving. Never stall waiting for a key; log it in the issues report and proceed. + - **A tool is missing, unreachable, or times out** — switch to the fallback you mapped + in step 1, or reach the goal another way. Documented coverage gaps are acceptable; + getting stuck is not. + - **Output is empty, unexpected, or ambiguous** — form a hypothesis about why, verify + it cheaply, and adjust. Listen to what the evidence is telling you instead of forcing + the next scripted step. + - **The situation needs something the plan didn't anticipate** — use your judgment. Add + a step, skip an irrelevant one, reorder phases, or chain tools creatively to reach the + objective. Briefly record why you deviated. + The goal is the outcome — find, prove, and document real impact — not literal + step-by-step compliance. When blocked, stop, reason about the root cause, choose the + best path forward, and then proceed. + --- diff --git a/blhackbox/prompts/templates/web-app-assessment.md b/blhackbox/prompts/templates/web-app-assessment.md index 2db4442..dc2b1d1 100644 --- a/blhackbox/prompts/templates/web-app-assessment.md +++ b/blhackbox/prompts/templates/web-app-assessment.md @@ -32,13 +32,14 @@ TARGET = "[TARGET]" > 1. Confirm the `TARGET` placeholder above is set to your web application URL > 2. If testing authenticated areas, fill in the optional auth fields above > 3. Ensure all MCP servers are healthy — run `make mcp-status` -> 4. Verify authorization is active — run `make inject-verification` -> 5. Query each server's tool listing to discover available web testing capabilities +> 4. Query each server's tool listing to discover available web testing capabilities ## Mandatory Tool & Methodology Readiness -Do **not** start the skill's execution plan until this readiness pass is complete. -This is Phase 0 for every blhackbox skill. +Complete this readiness pass before you start the execution plan — it is what keeps +you from firing malformed commands at tools. This is Phase 0 for every blhackbox skill. +Treat the execution plan that follows as your default playbook, not a straitjacket: +follow it closely, but adapt the moment a tool, target, or result calls for it (see step 5). 1. **Inventory 100% of usable capabilities first.** - Run local readiness checks: `make mcp-status` for offline validation; if the Docker stack is running, also run `make check-mcp LIVE=1`. @@ -66,6 +67,29 @@ This is Phase 0 for every blhackbox skill. - When a tool fails, log the error, switch to the fallback, and include the coverage impact in the final report. - Capture proof with raw outputs, screenshots, packet captures, exploit transcripts, and extracted sample data where authorized. +5. **Adapt, recover, and think — never follow the plan off a cliff.** + The phases below are a proven default sequence, not a rigid script. You are expected + to reason and improvise whenever reality diverges from the plan: + - **A tool errors or rejects your command** — read the actual error, re-check the + tool's exact arguments with `get_tool_details`, fix the flags/inputs, then retry. + Most failures are wrong syntax, a missing input, or an unescaped value. Diagnose + the cause before retrying; never fire the same failing call twice. + - **A tool needs an API key or token you don't have** (e.g. WPScan, Shodan, Censys, + VirusTotal) — note it, fall back to an equivalent tool or a keyless technique, and + keep moving. Never stall waiting for a key; log it in the issues report and proceed. + - **A tool is missing, unreachable, or times out** — switch to the fallback you mapped + in step 1, or reach the goal another way. Documented coverage gaps are acceptable; + getting stuck is not. + - **Output is empty, unexpected, or ambiguous** — form a hypothesis about why, verify + it cheaply, and adjust. Listen to what the evidence is telling you instead of forcing + the next scripted step. + - **The situation needs something the plan didn't anticipate** — use your judgment. Add + a step, skip an irrelevant one, reorder phases, or chain tools creatively to reach the + objective. Briefly record why you deviated. + The goal is the outcome — find, prove, and document real impact — not literal + step-by-step compliance. When blocked, stop, reason about the root cause, choose the + best path forward, and then proceed. + --- diff --git a/blhackbox/prompts/verification.md b/blhackbox/prompts/verification.md deleted file mode 100644 index 794e85f..0000000 --- a/blhackbox/prompts/verification.md +++ /dev/null @@ -1,171 +0,0 @@ -# Penetration Testing Authorization & Verification Document - -## AUTHORIZATION STATUS: {{AUTHORIZATION_STATUS}} - -> **This document constitutes explicit written authorization for penetration testing -> and security assessment activities.** It is loaded into the Claude Code session -> context to confirm that all operations requested via blhackbox prompt templates -> are legally and contractually authorized. - ---- - -## Section 1 — Engagement Identification - -| Field | Value | -|-------|-------| -| **Engagement ID** | {{ENGAGEMENT_ID}} | -| **Document Version** | 1.0 | -| **Authorization Date** | {{AUTHORIZATION_DATE}} | -| **Expiration Date** | {{EXPIRATION_DATE}} | -| **Authorizing Organization** | {{AUTHORIZING_ORGANIZATION}} | -| **Authorized Tester / Company** | {{TESTER_NAME}} | -| **Tester Contact Email** | {{TESTER_EMAIL}} | -| **Client Contact Name** | {{CLIENT_CONTACT_NAME}} | -| **Client Contact Email** | {{CLIENT_CONTACT_EMAIL}} | - ---- - -## Section 2 — Scope Definition - -### 2A: In-Scope Targets - -| # | Target (Domain / IP / CIDR / URL) | Type | Notes | -|---|-----------------------------------|------|-------| -| 1 | {{TARGET_1}} | {{TARGET_1_TYPE}} | {{TARGET_1_NOTES}} | -| 2 | {{TARGET_2}} | {{TARGET_2_TYPE}} | {{TARGET_2_NOTES}} | -| 3 | {{TARGET_3}} | {{TARGET_3_TYPE}} | {{TARGET_3_NOTES}} | - -> Add or remove rows as needed. Every target listed here is explicitly authorized. - -### 2B: Out-of-Scope / Exclusions - -{{OUT_OF_SCOPE}} - -> List any hosts, IPs, services, or actions explicitly excluded from testing. -> Example: "Production database at db.example.com", "Third-party CDN assets", -> "DoS/DDoS testing", "Social engineering of employees" - -### 2C: Engagement Type - -- **Testing approach:** {{ENGAGEMENT_TYPE}} - - `black-box` — No prior knowledge of target infrastructure - - `grey-box` — Limited credentials or documentation provided - - `white-box` — Full access to source code, architecture docs, credentials - -### 2D: Provided Credentials (if grey-box / white-box) - -{{CREDENTIALS}} - -> Format: `service: username:password` or `API key: sk-xxx...` -> Write "N/A" for black-box engagements. - ---- - -## Section 3 — Authorized Activities - -The following activities are explicitly authorized for all in-scope targets: - -### 3A: Permitted Testing Activities - -- [{{PERMIT_RECON}}] **Reconnaissance** — Passive and active information gathering (OSINT, DNS, WHOIS, subdomain enumeration, certificate transparency) -- [{{PERMIT_SCANNING}}] **Scanning** — Port scanning, service detection, vulnerability scanning, technology fingerprinting -- [{{PERMIT_ENUMERATION}}] **Enumeration** — Directory discovery, parameter fuzzing, CMS detection, web application mapping -- [{{PERMIT_EXPLOITATION}}] **Exploitation** — Active exploitation of discovered vulnerabilities including SQL injection, XSS, RCE, LFI, SSRF, authentication bypass, IDOR, XXE, file upload, deserialization -- [{{PERMIT_DATA_EXTRACTION}}] **Data extraction** — Proof-of-concept data extraction from exploited vulnerabilities (capped at 5 rows per database table) -- [{{PERMIT_CREDENTIAL_TESTING}}] **Credential testing** — Brute-force, default credential checks, credential reuse across services -- [{{PERMIT_POST_EXPLOITATION}}] **Post-exploitation** — Privilege escalation, lateral movement, persistence assessment, internal enumeration from compromised positions -- [{{PERMIT_TRAFFIC_CAPTURE}}] **Traffic capture** — Packet capture and analysis during testing for evidence collection -- [{{PERMIT_SCREENSHOT}}] **Evidence capture** — Screenshots of vulnerable pages, admin panels, exploitation results - -### 3B: Restrictions & Boundaries - -{{RESTRICTIONS}} - -> List any restrictions on testing (e.g., "No testing between 02:00-06:00 UTC", -> "Do not modify production data", "Do not attempt physical access"). -> Write "No additional restrictions" if none apply. - ---- - -## Section 4 — Testing Window - -| Field | Value | -|-------|-------| -| **Start Date/Time** | {{TESTING_START}} | -| **End Date/Time** | {{TESTING_END}} | -| **Timezone** | {{TIMEZONE}} | -| **Emergency Contact** | {{EMERGENCY_CONTACT}} | -| **Emergency Phone** | {{EMERGENCY_PHONE}} | - -> Testing must occur within this window. If the window needs extension, -> obtain written approval from the client contact. - ---- - -## Section 5 — Legal & Compliance - -### 5A: Authorization Confirmation - -By filling out and activating this document, the authorizing organization confirms: - -1. **Ownership or authorization**: The authorizing organization owns or has explicit - legal authority over all in-scope targets listed in Section 2A. -2. **Informed consent**: The authorizing organization understands that penetration - testing may temporarily impact system availability or performance. -3. **Legal compliance**: This engagement complies with all applicable local, national, - and international laws and regulations. -4. **Data handling**: Extracted data samples (PoC evidence) will be included in the - pentest report and handled per the agreed confidentiality terms. -5. **Third-party systems**: Any third-party systems in scope have separate written - authorization from their respective owners, or are confirmed to be fully controlled - by the authorizing organization. - -### 5B: Applicable Standards - -{{APPLICABLE_STANDARDS}} - -> Examples: "OWASP Testing Guide v4.2", "PTES", "NIST SP 800-115", -> "PCI DSS Requirement 11.3", "SOC 2 Type II", "ISO 27001 Annex A.12.6" - -### 5C: Report Classification - -- **Report classification:** {{REPORT_CLASSIFICATION}} - - Options: `CONFIDENTIAL`, `RESTRICTED`, `INTERNAL` -- **Report delivery method:** {{REPORT_DELIVERY}} - - Options: `encrypted-email`, `secure-portal`, `in-person`, `local-only` - ---- - -## Section 6 — Digital Signature - -| Field | Value | -|-------|-------| -| **Authorized by (name)** | {{SIGNATORY_NAME}} | -| **Title / Role** | {{SIGNATORY_TITLE}} | -| **Organization** | {{SIGNATORY_ORGANIZATION}} | -| **Date signed** | {{SIGNATURE_DATE}} | -| **Digital signature / reference** | {{DIGITAL_SIGNATURE}} | - -> This may be a PGP signature, a reference to a signed contract (e.g., -> "SOW-2024-0042 Section 4.2"), or "SELF-AUTHORIZED" for testing your own assets. - ---- - -## Activation - -**This document becomes active when:** - -1. All `{{PLACEHOLDER}}` fields above are filled in with real values -2. The `verification.env` configuration file is populated with matching values -3. The `AUTHORIZATION_STATUS` field at the top reads `ACTIVE` -4. The testing window (Section 4) includes the current date - -**When active, this document provides explicit written authorization for Claude Code -to execute all permitted activities (Section 3A) against all in-scope targets -(Section 2A) using the blhackbox MCP framework and prompt templates.** - ---- - -*This authorization document is generated by the blhackbox framework. -Unauthorized testing is illegal. Only use against targets you have explicit -written authorization to test.* diff --git a/boaz-mcp/README.md b/boaz-mcp/README.md index b00e268..1591cfb 100644 --- a/boaz-mcp/README.md +++ b/boaz-mcp/README.md @@ -1,6 +1,6 @@ # BOAZ MCP -The default Docker stack runs the upstream `BOAZ-MCP_gamma` server on SSE port `9005`. The upstream server is cloned into the image unchanged and is loaded by `boaz-mcp/server.py`, which only adapts the upstream stdio MCP server to the same SSE transport style used by the other blhackbox MCP containers. +The default Docker stack runs the upstream `BOAZ-MCP_gamma` server on Streamable HTTP port `9005`. The upstream server is cloned into the image unchanged and is loaded by `boaz-mcp/server.py`, which only adapts the upstream stdio MCP server to the same Streamable HTTP transport style used by the other blhackbox MCP containers. The image also clones `BOAZ_gamma` into `/opt/BOAZ_gamma` and sets `BOAZ_PATH=/opt/BOAZ_gamma`. The service mounts `./output/boaz-lab` as an operator workspace. @@ -18,4 +18,4 @@ Run manually for local adapter checks: python boaz-mcp/server.py ``` -Default SSE port: `9005`. +Default Streamable HTTP endpoint: `http://localhost:9005/mcp` (health probe at `/health`). diff --git a/boaz-mcp/server.py b/boaz-mcp/server.py index c19ed3f..4db7df3 100644 --- a/boaz-mcp/server.py +++ b/boaz-mcp/server.py @@ -1,29 +1,49 @@ -"""SSE entrypoint for the upstream BOAZ-MCP Gamma server. +"""Streamable HTTP entrypoint for the upstream BOAZ-MCP Gamma server. This file does not reimplement BOAZ tools. It loads the unmodified upstream `boaz_mcp.server.BoazMCPServer` from BOAZ-MCP_gamma and exposes that low-level -MCP server over SSE so it behaves like the other blhackbox Docker MCP services. +MCP server over Streamable HTTP so it behaves like the other blhackbox Docker +MCP services. """ from __future__ import annotations +import contextlib import os import sys +from collections.abc import AsyncIterator from pathlib import Path from typing import Any import uvicorn -from mcp.server.sse import SseServerTransport +from mcp.server.streamable_http_manager import StreamableHTTPSessionManager from starlette.applications import Starlette from starlette.requests import Request -from starlette.responses import JSONResponse, Response -from starlette.routing import Mount, Route +from starlette.responses import JSONResponse +from starlette.routing import Route +from starlette.types import Receive, Scope, Send DEFAULT_BOAZ_MCP_PATH = Path(os.environ.get("BOAZ_MCP_PATH", "/opt/BOAZ-MCP_gamma")) DEFAULT_HOST = os.environ.get("BOAZ_MCP_HOST", "0.0.0.0") DEFAULT_PORT = int(os.environ.get("BOAZ_MCP_PORT", "9005")) +class _StreamableHTTPASGIApp: + """ASGI wrapper around the session manager's request handler. + + Mounting the handler with a Starlette ``Route`` whose endpoint is a class + instance (rather than ``Mount``) serves the Streamable HTTP transport at the + exact ``/mcp`` path, matching the FastMCP-based servers. ``Mount`` would + redirect ``/mcp`` to ``/mcp/`` and break clients that POST to ``/mcp``. + """ + + def __init__(self, session_manager: StreamableHTTPSessionManager) -> None: + self.session_manager = session_manager + + async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: + await self.session_manager.handle_request(scope, receive, send) + + def _add_upstream_to_path(upstream_path: Path = DEFAULT_BOAZ_MCP_PATH) -> None: """Make the cloned upstream BOAZ-MCP_gamma package importable.""" resolved = upstream_path.expanduser().resolve() @@ -40,21 +60,13 @@ def _load_upstream_mcp_server(upstream_path: Path = DEFAULT_BOAZ_MCP_PATH) -> An def create_app(upstream_path: Path = DEFAULT_BOAZ_MCP_PATH) -> Starlette: - """Create a Starlette SSE app around the upstream BOAZ MCP server.""" + """Create a Starlette Streamable HTTP app around the upstream BOAZ MCP server.""" upstream_server = _load_upstream_mcp_server(upstream_path) - sse = SseServerTransport("/messages/") - - async def handle_sse(scope: Any, receive: Any, send: Any) -> Response: - async with sse.connect_sse(scope, receive, send) as streams: - await upstream_server.run( - streams[0], - streams[1], - upstream_server.create_initialization_options(), - ) - return Response() - - async def sse_endpoint(request: Request) -> Response: - return await handle_sse(request.scope, request.receive, request._send) # type: ignore[attr-defined] + session_manager = StreamableHTTPSessionManager( + app=upstream_server, + json_response=False, + stateless=False, + ) async def health(_: Request) -> JSONResponse: return JSONResponse( @@ -62,21 +74,28 @@ async def health(_: Request) -> JSONResponse: "status": "ok", "service": "boaz-mcp", "upstream": "BOAZ-MCP_gamma", - "transport": "sse", + "transport": "streamable-http", } ) + @contextlib.asynccontextmanager + async def lifespan(_: Starlette) -> AsyncIterator[None]: + # The session manager's task group must be running for the duration of + # the app; handle_request fails otherwise. + async with session_manager.run(): + yield + return Starlette( routes=[ Route("/health", endpoint=health, methods=["GET"]), - Route("/sse", endpoint=sse_endpoint, methods=["GET"]), - Mount("/messages/", app=sse.handle_post_message), - ] + Route("/mcp", endpoint=_StreamableHTTPASGIApp(session_manager)), + ], + lifespan=lifespan, ) def main() -> None: - """Run BOAZ-MCP Gamma over SSE.""" + """Run BOAZ-MCP Gamma over Streamable HTTP.""" uvicorn.run(create_app(), host=DEFAULT_HOST, port=DEFAULT_PORT) diff --git a/docker-compose.yml b/docker-compose.yml index b0dc95a..4d4bd28 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,13 +5,14 @@ # docker compose up -d Start default stack (Kali, WireMCP, Screenshot, HexStrike, BOAZ, Portainer) # docker compose --profile gateway up -d Start with MCP Gateway # docker compose --profile claude-code up -d Start with Claude Code container +# docker compose --profile deepseek run --rm deepseek Run the DeepSeek (Reasonix) agent # docker compose --profile neo4j up -d Start with Neo4j # docker compose build Build all custom images locally # # MCP servers (core — always started): -# kali-mcp (FastMCP SSE, port 9001) — Kali Linux security tools (70+) + Metasploit Framework -# wire-mcp (FastMCP SSE, port 9003) — Wireshark/tshark (7 tools) -# screenshot-mcp (FastMCP SSE, port 9004) — Headless Chromium screenshots (4 tools) +# kali-mcp (FastMCP Streamable HTTP, port 9001) — Kali Linux security tools (70+) + Metasploit Framework +# wire-mcp (FastMCP Streamable HTTP, port 9003) — Wireshark/tshark (7 tools) +# screenshot-mcp (FastMCP Streamable HTTP, port 9004) — Headless Chromium screenshots (4 tools) # # Integrated MCP services in the default stack: # hexstrike-ai (port 8888) — HexStrike Gamma API @@ -23,7 +24,7 @@ # structures them into an AggregatedPayload, then validates via the # aggregate_results tool. # -# Claude Code (Docker) connects directly to MCP servers via SSE. +# Claude Code (Docker) connects directly to MCP servers via Streamable HTTP. # Claude Desktop / ChatGPT connect via the MCP Gateway (--profile gateway). # # Claude Desktop config (requires --profile gateway): @@ -89,9 +90,9 @@ services: condition: service_healthy # -- KALI MCP SERVER ------------------------------------------------------- - # Host-based clients can connect directly via SSE at http://localhost:9001/sse - # without the MCP Gateway. Claude Code (Docker) uses the internal URL - # http://kali-mcp:9001/sse instead. + # Host-based clients can connect directly via Streamable HTTP at + # http://localhost:9001/mcp without the MCP Gateway. Claude Code (Docker) + # uses the internal URL http://kali-mcp:9001/mcp instead. # # Includes Metasploit Framework (msfconsole, msfvenom) — Metasploit tools # are integrated directly into kali-mcp via CLI execution (`msfconsole -qx`). @@ -106,8 +107,12 @@ services: privileged: true init: true environment: - # WPScan API token for vulnerability database lookups (Issue #15) + # WPScan API token — wpscan auto-loads this; adds the WP vuln database. WPSCAN_API_TOKEN: "${WPSCAN_API_TOKEN:-}" + # Optional subfinder passive-source keys (all optional; recon runs without them). + VIRUSTOTAL_API_KEY: "${VIRUSTOTAL_API_KEY:-}" + SHODAN_API_KEY: "${SHODAN_API_KEY:-}" + SECURITYTRAILS_API_KEY: "${SECURITYTRAILS_API_KEY:-}" # Max timeout for long-running scans (Issue #8) KALI_MAX_TIMEOUT: "${KALI_MAX_TIMEOUT:-600}" # Metasploit timeout for msfconsole commands @@ -117,7 +122,7 @@ services: ports: - "${KALI_MCP_PORT:-9001}:9001" healthcheck: - test: ["CMD-SHELL", "python3 -c \"import urllib.request; urllib.request.urlopen('http://localhost:9001/sse')\""] + test: ["CMD-SHELL", "python3 -c \"import urllib.request; urllib.request.urlopen('http://localhost:9001/health')\""] interval: 15s timeout: 10s retries: 10 @@ -156,7 +161,7 @@ services: kali-mcp: condition: service_healthy healthcheck: - test: ["CMD-SHELL", "python3 -c \"import urllib.request; urllib.request.urlopen('http://localhost:9003/sse')\""] + test: ["CMD-SHELL", "python3 -c \"import urllib.request; urllib.request.urlopen('http://localhost:9003/health')\""] interval: 15s timeout: 10s retries: 5 @@ -199,7 +204,7 @@ services: # -- HEXSTRIKE GAMMA API + FULL MCP SERVER --------------------------------- # Runs with the default stack like the other MCP services. The API service # capsules HexStrike Gamma; the MCP service exposes the upstream tool suite - # over SSE on port 9006. + # over Streamable HTTP on port 9006. hexstrike-ai: image: crhacky/blhackbox:hexstrike-ai build: @@ -213,6 +218,11 @@ services: init: true environment: HEXSTRIKE_PORT: "8888" + # Optional recon keys — all tools run without them (see README). + WPSCAN_API_TOKEN: "${WPSCAN_API_TOKEN:-}" + VIRUSTOTAL_API_KEY: "${VIRUSTOTAL_API_KEY:-}" + SHODAN_API_KEY: "${SHODAN_API_KEY:-}" + SECURITYTRAILS_API_KEY: "${SECURITYTRAILS_API_KEY:-}" ports: - "${HEXSTRIKE_API_PORT:-8888}:8888" volumes: @@ -253,7 +263,7 @@ services: # -- BOAZ MCP SERVER -------------------------------------------------------- # Runs with the default stack like the other MCP services. The image carries # the unmodified upstream BOAZ-MCP Gamma server plus a BOAZ_gamma checkout. - # blhackbox only adds the SSE entrypoint used by the container. + # blhackbox only adds the Streamable HTTP entrypoint used by the container. boaz-mcp: image: crhacky/blhackbox:boaz-mcp build: @@ -317,7 +327,7 @@ services: # Enable with: docker compose --profile claude-code up -d # Then run: docker compose run --rm claude-code # - # Connects DIRECTLY to each MCP server via SSE over the Docker network. + # Connects DIRECTLY to each MCP server via Streamable HTTP over the Docker network. # Does NOT require the MCP Gateway. claude-code: image: crhacky/blhackbox:claude-code @@ -359,6 +369,54 @@ services: networks: - blhackbox_net + # -- DEEPSEEK / REASONIX (OPTIONAL) ---------------------------------------- + # DeepSeek-native MCP client running inside Docker -- no host install needed. + # Enable with: docker compose --profile deepseek run --rm deepseek + # (or `make deepseek`) + # + # Reasonix (https://github.com/esengine/DeepSeek-Reasonix) connects DIRECTLY + # to each MCP server via Streamable HTTP over the Docker network by reading + # its baked .mcp.json (Claude Code's mcpServers schema). Does NOT require the + # MCP Gateway. Requires DEEPSEEK_API_KEY (read from env, never written to disk). + deepseek: + image: crhacky/blhackbox:deepseek + build: + context: . + dockerfile: docker/deepseek.Dockerfile + container_name: blhackbox-deepseek + profiles: ["deepseek"] + stdin_open: true + tty: true + environment: + DEEPSEEK_API_KEY: "${DEEPSEEK_API_KEY:-}" + # Bypass egress proxies (e.g. GitHub Codespaces) for internal Docker traffic + no_proxy: "mcp-gateway,kali-mcp,wire-mcp,screenshot-mcp,hexstrike-ai,hexstrike-bridge-mcp,boaz-mcp,localhost,127.0.0.1" + NO_PROXY: "mcp-gateway,kali-mcp,wire-mcp,screenshot-mcp,hexstrike-ai,hexstrike-bridge-mcp,boaz-mcp,localhost,127.0.0.1" + dns: + - 8.8.8.8 + - 1.1.1.1 + volumes: + - ./output/screenshots:/tmp/screenshots:ro + - ./output/reports:/root/reports + - ./output/sessions:/root/results + # Shared working data from Kali MCP (recon files, tool artifacts) + - shared-output:/root/kali-data:ro + # Mount project instructions so the agent has the latest methodology + - ./CLAUDE.md:/root/CLAUDE.md:ro + depends_on: + kali-mcp: + condition: service_healthy + wire-mcp: + condition: service_healthy + screenshot-mcp: + condition: service_healthy + hexstrike-bridge-mcp: + condition: service_healthy + boaz-mcp: + condition: service_healthy + networks: + - blhackbox_net + # -- PORTAINER CE ---------------------------------------------------------- # Web UI for container management -- https://localhost:9443 # Source: https://github.com/portainer/portainer diff --git a/docker/claude-code-entrypoint.sh b/docker/claude-code-entrypoint.sh index f48afb0..cd6e30d 100755 --- a/docker/claude-code-entrypoint.sh +++ b/docker/claude-code-entrypoint.sh @@ -43,10 +43,10 @@ check_service() { local timeout="${3:-3}" curl -s --max-time "$timeout" -o /dev/null "$url" 2>/dev/null local rc=$? - # Exit code 28 = curl connected but the transfer timed out. This is - # expected for SSE/streaming endpoints (like /sse) that keep the - # connection open indefinitely. Treat it the same as 0 (success): - # the server is up and responding. + # A bare GET to the Streamable HTTP endpoint (/mcp) returns an HTTP 4xx + # (no MCP session/headers) — curl still exits 0 because it received a + # response, which confirms the server is up. Exit code 28 (transfer + # timed out) is also treated as success for any endpoint that streams. [ "$rc" -eq 0 ] || [ "$rc" -eq 28 ] } @@ -93,34 +93,34 @@ MCP_FAIL=0 REST_OK=0 REST_FAIL=0 -# -- MCP Servers (Claude Code connects via SSE) -- +# -- MCP Servers (Claude Code connects via Streamable HTTP) -- echo -e " ${BOLD}MCP Servers${NC}" -if wait_for_service "Kali MCP" "http://kali-mcp:9001/sse"; then +if wait_for_service "Kali MCP" "http://kali-mcp:9001/mcp"; then MCP_OK=$((MCP_OK + 1)) else MCP_FAIL=$((MCP_FAIL + 1)) fi # WireMCP shares kali-mcp's network namespace, so use kali-mcp hostname -if wait_for_service "WireMCP" "http://kali-mcp:9003/sse"; then +if wait_for_service "WireMCP" "http://kali-mcp:9003/mcp"; then MCP_OK=$((MCP_OK + 1)) else MCP_FAIL=$((MCP_FAIL + 1)) fi -if wait_for_service "Screenshot MCP" "http://screenshot-mcp:9004/sse"; then +if wait_for_service "Screenshot MCP" "http://screenshot-mcp:9004/mcp"; then MCP_OK=$((MCP_OK + 1)) else MCP_FAIL=$((MCP_FAIL + 1)) fi -if wait_for_service "BOAZ MCP" "http://boaz-mcp:9005/sse"; then +if wait_for_service "BOAZ MCP" "http://boaz-mcp:9005/mcp"; then MCP_OK=$((MCP_OK + 1)) else MCP_FAIL=$((MCP_FAIL + 1)) fi -if wait_for_service "HexStrike MCP" "http://hexstrike-bridge-mcp:9006/sse"; then +if wait_for_service "HexStrike MCP" "http://hexstrike-bridge-mcp:9006/mcp"; then MCP_OK=$((MCP_OK + 1)) else MCP_FAIL=$((MCP_FAIL + 1)) @@ -143,7 +143,7 @@ fi echo "" echo -e "${DIM}──────────────────────────────────────────────────${NC}" -echo -e " ${BOLD}MCP servers (connected via SSE):${NC}" +echo -e " ${BOLD}MCP servers (connected via Streamable HTTP):${NC}" echo -e " kali ${DIM}Kali Linux security tools + Metasploit (70+ tools)${NC}" echo -e " wireshark ${DIM}WireMCP — tshark packet capture & analysis${NC}" echo -e " screenshot ${DIM}Screenshot MCP — headless Chromium evidence capture${NC}" diff --git a/docker/claude-code.Dockerfile b/docker/claude-code.Dockerfile index 21fe975..28b338b 100644 --- a/docker/claude-code.Dockerfile +++ b/docker/claude-code.Dockerfile @@ -2,7 +2,7 @@ # Usage: # docker compose --profile claude-code run --rm claude-code # -# Connects DIRECTLY to each MCP server via SSE on the internal +# Connects DIRECTLY to each MCP server via Streamable HTTP on the internal # blhackbox_net network. No MCP Gateway required. No host-side install. FROM node:22-slim @@ -20,30 +20,30 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ WORKDIR /root -# Pre-configure MCP to connect directly to each FastMCP server via SSE. -# Wire-MCP shares kali-mcp's network namespace, so it's accessed via -# kali-mcp hostname on port 9003. +# Pre-configure MCP to connect directly to each FastMCP server via +# Streamable HTTP. Wire-MCP shares kali-mcp's network namespace, so it's +# accessed via the kali-mcp hostname on port 9003. RUN echo '{ \ "mcpServers": { \ "kali": { \ - "type": "sse", \ - "url": "http://kali-mcp:9001/sse" \ + "type": "http", \ + "url": "http://kali-mcp:9001/mcp" \ }, \ "wireshark": { \ - "type": "sse", \ - "url": "http://kali-mcp:9003/sse" \ + "type": "http", \ + "url": "http://kali-mcp:9003/mcp" \ }, \ "screenshot": { \ - "type": "sse", \ - "url": "http://screenshot-mcp:9004/sse" \ + "type": "http", \ + "url": "http://screenshot-mcp:9004/mcp" \ }, \ "boaz": { \ - "type": "sse", \ - "url": "http://boaz-mcp:9005/sse" \ + "type": "http", \ + "url": "http://boaz-mcp:9005/mcp" \ }, \ "hexstrike": { \ - "type": "sse", \ - "url": "http://hexstrike-bridge-mcp:9006/sse" \ + "type": "http", \ + "url": "http://hexstrike-bridge-mcp:9006/mcp" \ } \ } \ }' > .mcp.json diff --git a/docker/deepseek-entrypoint.sh b/docker/deepseek-entrypoint.sh new file mode 100755 index 0000000..f3d0cc7 --- /dev/null +++ b/docker/deepseek-entrypoint.sh @@ -0,0 +1,172 @@ +#!/bin/bash +set -euo pipefail + +# ── Colors ────────────────────────────────────────────────────────── +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +CYAN='\033[0;36m' +BOLD='\033[1m' +DIM='\033[2m' +NC='\033[0m' # No Color + +# ── Symbols ───────────────────────────────────────────────────────── +CHECK="${GREEN}OK${NC}" +CROSS="${RED}FAIL${NC}" +WARN="${YELLOW}WARN${NC}" +WAIT="${DIM}....${NC}" + +# ── Configuration ─────────────────────────────────────────────────── +MAX_RETRIES=20 +RETRY_INTERVAL=3 + +# Ensure internal Docker hostnames bypass any egress proxy. +export no_proxy="${no_proxy:+${no_proxy},}mcp-gateway,kali-mcp,wire-mcp,screenshot-mcp,hexstrike-ai,hexstrike-bridge-mcp,boaz-mcp,localhost,127.0.0.1" +export NO_PROXY="$no_proxy" + +# ── Functions ─────────────────────────────────────────────────────── + +print_banner() { + echo "" + echo -e "${CYAN}${BOLD} ╔══════════════════════════════════════════════╗${NC}" + echo -e "${CYAN}${BOLD} ║ blhackbox v2.0 — DeepSeek (Reasonix) ║${NC}" + echo -e "${CYAN}${BOLD} ║ MCP-based Pentesting Framework ║${NC}" + echo -e "${CYAN}${BOLD} ╚══════════════════════════════════════════════╝${NC}" + echo "" +} + +# Check a single service. Returns 0 on success, 1 on failure. +check_service() { + local name="$1" + local url="$2" + local timeout="${3:-3}" + curl -s --max-time "$timeout" -o /dev/null "$url" 2>/dev/null + local rc=$? + # A bare GET to the Streamable HTTP endpoint (/mcp) returns an HTTP 4xx + # (no MCP session/headers) — curl still exits 0 because it received a + # response, which confirms the server is up. Exit code 28 (transfer + # timed out) is also treated as success for any endpoint that streams. + [ "$rc" -eq 0 ] || [ "$rc" -eq 28 ] +} + +# Wait for a service with retries. Prints status. +wait_for_service() { + local name="$1" + local url="$2" + local retries="${3:-$MAX_RETRIES}" + + printf " %-22s " "$name" + + for i in $(seq 1 "$retries"); do + if check_service "$name" "$url"; then + echo -e "[ ${CHECK} ]" + return 0 + fi + sleep "$RETRY_INTERVAL" + done + + echo -e "[ ${CROSS} ] (unreachable at $url)" + return 1 +} + +# ── Output directory symlinks ────────────────────────────────────── +# Report/session paths resolve to /root/output/* (WORKDIR is /root). +# Bind mounts are at /root/reports, /root/results, /tmp/screenshots. +# Create symlinks so both path conventions reach the bind mounts. +mkdir -p /root/output +ln -sfn /root/reports /root/output/reports +ln -sfn /root/results /root/output/sessions +ln -sfn /tmp/screenshots /root/output/screenshots + +# ── Main ──────────────────────────────────────────────────────────── + +print_banner + +# DeepSeek API key is required for Reasonix to authenticate against the +# DeepSeek API. It is read from the environment (reasonix.toml api_key_env). +if [ -z "${DEEPSEEK_API_KEY:-}" ]; then + echo -e " ${WARN} DEEPSEEK_API_KEY is not set — Reasonix cannot authenticate." + echo -e " ${DIM}Add it to .env and re-run, or pass -e DEEPSEEK_API_KEY=sk-...${NC}" + echo -e " ${DIM}Get a key at https://platform.deepseek.com/api_keys${NC}" + echo "" +fi + +echo -e "${BOLD}Checking service connectivity...${NC}" +echo -e "${DIM}Waiting for services to become healthy.${NC}" +echo "" + +MCP_OK=0 +MCP_FAIL=0 + +# -- MCP Servers (Reasonix connects via Streamable HTTP) -- +echo -e " ${BOLD}MCP Servers${NC}" +if wait_for_service "Kali MCP" "http://kali-mcp:9001/mcp"; then + MCP_OK=$((MCP_OK + 1)) +else + MCP_FAIL=$((MCP_FAIL + 1)) +fi + +# WireMCP shares kali-mcp's network namespace, so use kali-mcp hostname +if wait_for_service "WireMCP" "http://kali-mcp:9003/mcp"; then + MCP_OK=$((MCP_OK + 1)) +else + MCP_FAIL=$((MCP_FAIL + 1)) +fi + +if wait_for_service "Screenshot MCP" "http://screenshot-mcp:9004/mcp"; then + MCP_OK=$((MCP_OK + 1)) +else + MCP_FAIL=$((MCP_FAIL + 1)) +fi + +if wait_for_service "BOAZ MCP" "http://boaz-mcp:9005/mcp"; then + MCP_OK=$((MCP_OK + 1)) +else + MCP_FAIL=$((MCP_FAIL + 1)) +fi + +if wait_for_service "HexStrike MCP" "http://hexstrike-bridge-mcp:9006/mcp"; then + MCP_OK=$((MCP_OK + 1)) +else + MCP_FAIL=$((MCP_FAIL + 1)) +fi + +# Summary +echo "" +echo -e "${DIM}──────────────────────────────────────────────────${NC}" + +if [ "$MCP_FAIL" -eq 0 ]; then + echo -e "${GREEN}${BOLD} All $MCP_OK MCP servers connected.${NC}" +else + echo -e "${YELLOW}${BOLD} $MCP_OK/$((MCP_OK + MCP_FAIL)) MCP servers connected. $MCP_FAIL unreachable.${NC}" + echo -e "${DIM} Reasonix will start — unreachable servers simply won't expose tools.${NC}" + echo -e "${DIM} Use 'docker compose ps' in another terminal to check container health.${NC}" +fi + +echo "" +echo -e "${DIM}──────────────────────────────────────────────────${NC}" +echo -e " ${BOLD}MCP servers (connected via Streamable HTTP):${NC}" +echo -e " kali ${DIM}Kali Linux security tools + Metasploit (70+ tools)${NC}" +echo -e " wireshark ${DIM}WireMCP — tshark packet capture & analysis${NC}" +echo -e " screenshot ${DIM}Screenshot MCP — headless Chromium evidence capture${NC}" +echo -e " boaz ${DIM}BOAZ-MCP Gamma — agentic offensive security tools${NC}" +echo -e " hexstrike ${DIM}HexStrike Gamma — AI security automation tools${NC}" +echo "" +echo -e " ${BOLD}Model:${NC} ${DIM}DeepSeek-V4-Flash (default). Type ${NC}${CYAN}/pro${NC}${DIM} for one Pro turn,${NC}" +echo -e " ${DIM}or ${NC}${CYAN}/preset max${NC}${DIM} to use Pro for the whole session.${NC}" +echo "" +echo -e " ${BOLD}Methodology:${NC} ${DIM}Pentest workflow and rules are in ${NC}${CYAN}/root/CLAUDE.md${NC}${DIM}.${NC}" +echo -e " ${DIM}Describe your authorized target and goal; Reasonix will call the MCP tools.${NC}" +echo "" +echo -e " ${BOLD}Output files${NC} ${DIM}(mounted to host ./output/)${NC}${BOLD}:${NC}" +echo -e " ${DIM}output/reports/ → ./output/reports/ pentest reports${NC}" +echo -e " ${DIM}output/screenshots/ → ./output/screenshots/ PoC evidence (read-only)${NC}" +echo -e " ${DIM}output/sessions/ → ./output/sessions/ session data${NC}" +echo -e " ${DIM}/root/kali-data/ ← shared Kali MCP recon artifacts (read-only)${NC}" +echo -e "${DIM}──────────────────────────────────────────────────${NC}" +echo "" + +# Launch the Reasonix coding agent. `reasonix code` opens the interactive TUI; +# any args passed to the container are forwarded. +exec reasonix code "$@" diff --git a/docker/deepseek.Dockerfile b/docker/deepseek.Dockerfile new file mode 100644 index 0000000..be74b7e --- /dev/null +++ b/docker/deepseek.Dockerfile @@ -0,0 +1,64 @@ +# DeepSeek (Reasonix) MCP Client — runs inside the blhackbox Docker network. +# Usage: +# docker compose --profile deepseek run --rm deepseek +# +# Reasonix is a DeepSeek-native terminal coding agent (https://github.com/ +# esengine/DeepSeek-Reasonix). It connects DIRECTLY to each MCP server via +# Streamable HTTP on the internal blhackbox_net network by reading the baked +# .mcp.json (Claude Code's exact mcpServers schema). No MCP Gateway required, +# no host-side install. + +FROM node:22-slim + +# Reasonix ships a single Go binary delivered through npm. +RUN npm install -g reasonix + +# curl for health checks, python3/jq for data processing, +# and dnsutils for DNS resolution debugging +RUN apt-get update && apt-get install -y --no-install-recommends \ + curl \ + jq \ + python3 \ + dnsutils \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /root + +# DeepSeek provider config. The API key is read from the DEEPSEEK_API_KEY +# environment variable at runtime (api_key_env) and is never written to disk. +# Default model is the cost-efficient DeepSeek-V4-Flash; switch to Pro at +# runtime with /pro (next turn) or /preset max (whole session). +RUN printf '%s\n' \ + 'default_model = "deepseek-flash"' \ + '' \ + '[[providers]]' \ + 'name = "deepseek-flash"' \ + 'kind = "openai"' \ + 'base_url = "https://api.deepseek.com"' \ + 'model = "deepseek-v4-flash"' \ + 'api_key_env = "DEEPSEEK_API_KEY"' \ + > reasonix.toml + +# Reasonix auto-reads a Claude-Code .mcp.json from the project root and maps it +# field-for-field onto its plugins (type/url/headers, ${VAR} expansion). This is +# the same wiring the claude-code container uses. Wire-MCP shares kali-mcp's +# network namespace, so it's accessed via the kali-mcp hostname on port 9003. +RUN echo '{ \ + "mcpServers": { \ + "kali": { "type": "http", "url": "http://kali-mcp:9001/mcp" }, \ + "wireshark": { "type": "http", "url": "http://kali-mcp:9003/mcp" }, \ + "screenshot": { "type": "http", "url": "http://screenshot-mcp:9004/mcp" }, \ + "boaz": { "type": "http", "url": "http://boaz-mcp:9005/mcp" }, \ + "hexstrike": { "type": "http", "url": "http://hexstrike-bridge-mcp:9006/mcp" } \ + } \ +}' > .mcp.json + +# Project methodology, available on the filesystem for reference. A volume mount +# in docker-compose.yml overrides this at runtime with the latest version. +COPY CLAUDE.md /root/CLAUDE.md + +# Startup script: checks each MCP server, shows status, launches Reasonix. +COPY docker/deepseek-entrypoint.sh /usr/local/bin/deepseek-entrypoint.sh +RUN chmod +x /usr/local/bin/deepseek-entrypoint.sh + +ENTRYPOINT ["/usr/local/bin/deepseek-entrypoint.sh"] diff --git a/docs/mcp-server-review.md b/docs/mcp-server-review.md index 900a340..cd945ff 100644 --- a/docs/mcp-server-review.md +++ b/docs/mcp-server-review.md @@ -4,13 +4,13 @@ | Server | Transport | Port | Primary role | Tools / capability surface | |---|---:|---:|---|---| -| `kali-mcp` | SSE | `9001` | Kali security-tool execution and Metasploit CLI workflows | 70+ allow-listed command tools including recon, web, exploitation, wireless, forensics, and utility commands | -| `wire-mcp` | SSE | `9003` | Wireshark/tshark packet capture and pcap analysis | Capture, pcap read, conversations, statistics, credential extraction, stream following, interface listing | -| `screenshot-mcp` | SSE | `9004` | Headless Chromium evidence capture | Page screenshots, element screenshots, screenshot listing, annotation | +| `kali-mcp` | Streamable HTTP | `9001` | Kali security-tool execution and Metasploit CLI workflows | 70+ allow-listed command tools including recon, web, exploitation, wireless, forensics, and utility commands | +| `wire-mcp` | Streamable HTTP | `9003` | Wireshark/tshark packet capture and pcap analysis | Capture, pcap read, conversations, statistics, credential extraction, stream following, interface listing | +| `screenshot-mcp` | Streamable HTTP | `9004` | Headless Chromium evidence capture | Page screenshots, element screenshots, screenshot listing, annotation | | `blhackbox` | stdio | n/a | Core orchestration, graph/reporting, templates, catalogue discovery | Tool execution, graph queries, reports, template retrieval, result aggregation, payload schema, catalogue search | | Docker MCP Gateway | streaming HTTP | `8080` | Optional host-client aggregation proxy | Proxies Kali, WireMCP, Screenshot MCP, BOAZ MCP, and HexStrike MCP through the Docker catalog | -| `boaz-mcp` | SSE | `9005` | Default BOAZ MCP service | Upstream BOAZ-MCP Gamma server exposed over SSE | -| `hexstrike-bridge-mcp` | SSE | `9006` | Default HexStrike Gamma MCP service | Upstream HexStrike Gamma MCP server loaded unchanged and exposed over SSE, connected to `hexstrike-ai` | +| `boaz-mcp` | Streamable HTTP | `9005` | Default BOAZ MCP service | Upstream BOAZ-MCP Gamma server exposed over Streamable HTTP | +| `hexstrike-bridge-mcp` | Streamable HTTP | `9006` | Default HexStrike Gamma MCP service | Upstream HexStrike Gamma MCP server loaded unchanged and exposed over Streamable HTTP, connected to `hexstrike-ai` | ## Changes made in this review @@ -32,7 +32,7 @@ ### Kali MCP -- The Docker Compose service exposes `http://localhost:9001/sse` and has an HTTP healthcheck against `/sse`. +- The Docker Compose service exposes the Streamable HTTP endpoint `http://localhost:9001/mcp` and has an HTTP healthcheck against the dedicated `/health` route. - The server has an explicit allowlist instead of unrestricted arbitrary execution. - Tool output is consistently structured with `stdout`, `stderr`, `exit_code`, `tool_name`, `timestamp`, and `target`. - Recommendation: keep the allowlist, but prefer high-level wrappers for dangerous/high-impact workflows where possible. @@ -40,7 +40,7 @@ ### WireMCP - `wire-mcp` shares `kali-mcp`'s network namespace to observe Kali-generated traffic. -- Gateway catalog points WireMCP to `http://kali-mcp:9003/sse`, matching the shared namespace design. +- Gateway catalog points WireMCP to `http://kali-mcp:9003/mcp`, matching the shared namespace design. - Recommendation: preserve this network-mode design; add pcap fixture tests in a future PR if sample pcaps can be committed safely. ### Screenshot MCP diff --git a/docs/pentagi-comparison.md b/docs/pentagi-comparison.md index aec2a8e..f9bb98f 100644 --- a/docs/pentagi-comparison.md +++ b/docs/pentagi-comparison.md @@ -239,7 +239,6 @@ PentAGI's Adviser uses a stronger model for strategic analysis before execution. | **Workflow templates** | 10 production-ready slash command skills | No equivalent | | **PoC rigor** | Mandatory `evidence`, `poc_steps`, `poc_payload` fields | No enforced PoC structure | | **Protocol standard** | MCP-native (works with any MCP client) | Custom API | -| **Authorization framework** | verification.env with legal workflow | No equivalent | | **Metasploit integration** | Full msfconsole + msfvenom via CLI | Basic Metasploit | | **Report formats** | MD + PDF + HTML with AggregatedPayload contract | Less structured | diff --git a/hexstrike-mcp/README.md b/hexstrike-mcp/README.md index 705ea6b..11bf131 100644 --- a/hexstrike-mcp/README.md +++ b/hexstrike-mcp/README.md @@ -1,7 +1,7 @@ # HexStrike MCP -The default Docker stack runs the upstream `hexstrike-ai_gamma` MCP server on SSE port `9006`. The upstream server is cloned into the image unchanged and is loaded by `hexstrike-mcp/server.py`, which only adapts the upstream FastMCP server to the same container entrypoint style used by the other blhackbox MCP containers. +The default Docker stack runs the upstream `hexstrike-ai_gamma` MCP server on Streamable HTTP port `9006`. The upstream server is cloned into the image unchanged and is loaded by `hexstrike-mcp/server.py`, which only adapts the upstream FastMCP server to the same container entrypoint style used by the other blhackbox MCP containers. The adapter points the upstream MCP server at `HEXSTRIKE_URL=http://hexstrike-ai:8888`, where the default stack runs the HexStrike Gamma API. -Default SSE port: `9006`. +Default Streamable HTTP endpoint: `http://localhost:9006/mcp` (health probe at `/health`). diff --git a/hexstrike-mcp/server.py b/hexstrike-mcp/server.py index 185754f..f6a669f 100644 --- a/hexstrike-mcp/server.py +++ b/hexstrike-mcp/server.py @@ -1,9 +1,9 @@ -"""SSE entrypoint for the upstream HexStrike AI Gamma MCP server. +"""Streamable HTTP entrypoint for the upstream HexStrike AI Gamma MCP server. This file does not reimplement HexStrike tools. It loads the unmodified upstream `hexstrike_mcp.py` module from a cloned `hexstrike-ai_gamma` checkout and runs -its FastMCP server over SSE so it behaves like the other blhackbox Docker MCP -services. +its FastMCP server over Streamable HTTP so it behaves like the other blhackbox +Docker MCP services. """ from __future__ import annotations @@ -82,7 +82,7 @@ def create_app( allowed_hosts, allowed_origins, ) - app = fastmcp.sse_app() + app = fastmcp.streamable_http_app() async def health(_: Request) -> JSONResponse: return JSONResponse( @@ -91,7 +91,7 @@ async def health(_: Request) -> JSONResponse: "service": "hexstrike-bridge-mcp", "upstream": "hexstrike-ai_gamma", "hexstrike_url": server_url, - "transport": "sse", + "transport": "streamable-http", } ) @@ -100,7 +100,7 @@ async def health(_: Request) -> JSONResponse: def main() -> None: - """Run HexStrike AI Gamma MCP over SSE.""" + """Run HexStrike AI Gamma MCP over Streamable HTTP.""" uvicorn.run(create_app(), host=DEFAULT_HOST, port=DEFAULT_PORT) diff --git a/kali-mcp/server.py b/kali-mcp/server.py index d09722b..686c165 100644 --- a/kali-mcp/server.py +++ b/kali-mcp/server.py @@ -92,6 +92,18 @@ mcp = FastMCP("kali-mcp", host="0.0.0.0", port=MCP_PORT) +@mcp.custom_route("/health", methods=["GET"]) +async def health_check(request): # type: ignore[no-untyped-def] + """Lightweight health probe for Docker and Makefile checks. + + The Streamable HTTP endpoint (/mcp) only answers MCP protocol requests, + so container health checks target this dedicated route instead. + """ + from starlette.responses import JSONResponse + + return JSONResponse({"status": "healthy", "service": "kali-mcp", "port": MCP_PORT}) + + # --------------------------------------------------------------------------- # Helper: run a subprocess and return structured result # --------------------------------------------------------------------------- @@ -986,7 +998,7 @@ async def get_exploit_code( # --------------------------------------------------------------------------- if __name__ == "__main__": - transport = os.environ.get("MCP_TRANSPORT", "sse") + transport = os.environ.get("MCP_TRANSPORT", "streamable-http") logger.info( "Starting Kali Linux MCP Server (%s on port %d, allowed tools: %d, msf: %s)", transport, MCP_PORT, len(ALLOWED_TOOLS), diff --git a/screenshot-mcp/server.py b/screenshot-mcp/server.py index f156578..1be7601 100644 --- a/screenshot-mcp/server.py +++ b/screenshot-mcp/server.py @@ -9,7 +9,7 @@ - list_screenshots → List captured screenshots with metadata - annotate_screenshot → Add text/box annotations to a screenshot for PoC docs -Transport: FastMCP SSE on port 9004. +Transport: FastMCP Streamable HTTP on port 9004. """ from __future__ import annotations @@ -139,6 +139,7 @@ async def take_screenshot( full_page: bool = False, wait_for_selector: str = "", wait_timeout: int = 0, + wait_until: str = "load", output_path: str = "", ) -> str: """Capture a screenshot of a web page via headless Chromium. @@ -150,6 +151,10 @@ async def take_screenshot( full_page: Capture the full scrollable page (default false) wait_for_selector: CSS selector to wait for before capture wait_timeout: Extra milliseconds to wait after page load (0-30000) + wait_until: Navigation wait condition — 'load' (default), 'domcontentloaded', + 'networkidle', or 'commit'. 'networkidle' often times out on live sites + with analytics/websockets; prefer 'load' and use wait_for_selector or + wait_timeout when you need specific content to render. output_path: Custom output file path (optional) Returns: @@ -158,6 +163,9 @@ async def take_screenshot( if not url.startswith(("http://", "https://")): return json.dumps({"error": "URL must start with http:// or https://"}) + if wait_until not in ("load", "domcontentloaded", "networkidle", "commit"): + wait_until = "load" + width = _clamp(width, 1, MAX_WIDTH) height = _clamp(height, 1, MAX_HEIGHT) wait_timeout = _clamp(wait_timeout, 0, 30000) @@ -171,7 +179,7 @@ async def take_screenshot( ) page = await context.new_page() - await page.goto(url, timeout=NAVIGATION_TIMEOUT, wait_until="networkidle") + await page.goto(url, timeout=NAVIGATION_TIMEOUT, wait_until=wait_until) if wait_for_selector: await page.wait_for_selector(wait_for_selector, timeout=NAVIGATION_TIMEOUT) @@ -480,6 +488,6 @@ async def annotate_screenshot( # --------------------------------------------------------------------------- if __name__ == "__main__": - transport = os.environ.get("MCP_TRANSPORT", "sse") + transport = os.environ.get("MCP_TRANSPORT", "streamable-http") logger.info("Starting Screenshot MCP server (%s on port %d)", transport, MCP_PORT) mcp.run(transport=transport) diff --git a/scripts/check_mcp_servers.py b/scripts/check_mcp_servers.py index feb55f2..0d1ef39 100644 --- a/scripts/check_mcp_servers.py +++ b/scripts/check_mcp_servers.py @@ -42,13 +42,16 @@ class Endpoint: LIVE_ENDPOINTS = [ - Endpoint("kali-mcp", "http://localhost:9001/sse"), - Endpoint("wire-mcp", "http://localhost:9003/sse"), + # Health probes use each server's dedicated /health route. A bare GET to + # the Streamable HTTP endpoint (/mcp) returns HTTP 4xx, which urlopen + # raises on — so health checks target /health (200) instead. + Endpoint("kali-mcp", "http://localhost:9001/health"), + Endpoint("wire-mcp", "http://localhost:9003/health"), Endpoint("screenshot-mcp", "http://localhost:9004/health"), Endpoint("mcp-gateway", "http://localhost:8080/mcp", required=False), Endpoint("hexstrike-api", "http://localhost:8888/health"), - Endpoint("hexstrike-bridge", "http://localhost:9006/sse"), - Endpoint("boaz-mcp", "http://localhost:9005/sse"), + Endpoint("hexstrike-bridge", "http://localhost:9006/health"), + Endpoint("boaz-mcp", "http://localhost:9005/health"), ] @@ -107,7 +110,7 @@ def run_checks(live: bool) -> list[CheckResult]: def main() -> int: parser = argparse.ArgumentParser(description="Validate blhackbox MCP servers") - parser.add_argument("--live", action="store_true", help="Check live HTTP/SSE endpoints") + parser.add_argument("--live", action="store_true", help="Check live HTTP endpoints") parser.add_argument("--json", action="store_true", help="Emit JSON") args = parser.parse_args() diff --git a/setup.sh b/setup.sh index 54ba906..38f3739 100755 --- a/setup.sh +++ b/setup.sh @@ -27,6 +27,7 @@ ARROW="${CYAN}→${NC}" # ── Globals ────────────────────────────────────────────────────────── SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" API_KEY="" +DEEPSEEK_KEY="" MINIMAL=false SKIP_PULL=false NEO4J_PASS="" @@ -47,7 +48,8 @@ usage() { echo "Usage: $0 [OPTIONS]" echo "" echo "Options:" - echo " --api-key KEY Set ANTHROPIC_API_KEY (skips interactive prompt)" + echo " --api-key KEY Set ANTHROPIC_API_KEY for the Claude Code container" + echo " --deepseek-key KEY Set DEEPSEEK_API_KEY for the DeepSeek (Reasonix) container" echo " --minimal Core stack only (no Neo4j)" echo " --with-neo4j Enable Neo4j knowledge graph" echo " --with-gateway Enable MCP Gateway for Claude Desktop/ChatGPT" @@ -163,6 +165,23 @@ configure_env() { echo -e " ${WARN} ANTHROPIC_API_KEY skipped — Claude Code Docker won't start without it" fi + # --- DEEPSEEK_API_KEY (for the DeepSeek / Reasonix container) --- + if [ -z "$DEEPSEEK_KEY" ]; then + echo "" + echo -e " ${BOLD}DEEPSEEK_API_KEY${NC} ${DIM}(for the DeepSeek/Reasonix agent in Docker)${NC}" + echo -e " ${DIM}Get yours at: https://platform.deepseek.com/api_keys${NC}" + echo -e " ${DIM}Press Enter to skip if you won't use the DeepSeek agent.${NC}" + read -rsp " API Key: " DEEPSEEK_KEY + echo "" + fi + + if [ -n "$DEEPSEEK_KEY" ]; then + sed -i "s|^# DEEPSEEK_API_KEY=sk-.*|DEEPSEEK_API_KEY=${DEEPSEEK_KEY}|" "$SCRIPT_DIR/.env" + echo -e " ${CHECK} DEEPSEEK_API_KEY configured" + else + echo -e " ${WARN} DEEPSEEK_API_KEY skipped — the DeepSeek agent won't start without it" + fi + # --- NEO4J_PASSWORD --- if [[ "$PROFILES" == *"neo4j"* ]]; then if [ -z "$NEO4J_PASS" ]; then @@ -175,6 +194,36 @@ configure_env() { echo -e " ${CHECK} NEO4J_PASSWORD configured" fi + # --- Keys & tokens reference --- + # Print the full list of keys/tokens the framework can use so the user + # knows exactly what to provide. Only ANTHROPIC_API_KEY (Docker client) is + # ever required; every pentest tool runs without the rest — they only widen + # passive recon coverage and extra data sources. + echo "" + echo -e " ${BOLD}Keys & tokens${NC} ${DIM}(edit .env to add them, then restart the stack):${NC}" + echo "" + echo -e " ${BOLD}Agent keys (set the one for the in-Docker agent you run)${NC}" + echo -e " ${CYAN}ANTHROPIC_API_KEY${NC} ${DIM}Claude Code container (--profile claude-code).${NC}" + echo -e " ${DIM}Not needed for Claude Code Web/host.${NC}" + echo -e " ${DIM}→ https://console.anthropic.com/settings/keys${NC}" + echo -e " ${CYAN}DEEPSEEK_API_KEY${NC} ${DIM}DeepSeek (Reasonix) container (--profile deepseek).${NC}" + echo -e " ${DIM}→ https://platform.deepseek.com/api_keys${NC}" + echo "" + echo -e " ${BOLD}Optional — widen recon (all tools work without them)${NC}" + echo -e " ${CYAN}WPSCAN_API_TOKEN${NC} ${DIM}WordPress vuln database; wpscan auto-reads it.${NC}" + echo -e " ${DIM}→ https://wpscan.com/api (free: 25 req/day)${NC}" + echo -e " ${CYAN}SHODAN_API_KEY${NC} ${DIM}subfinder passive source + Shodan host data.${NC}" + echo -e " ${DIM}→ https://account.shodan.io${NC}" + echo -e " ${CYAN}VIRUSTOTAL_API_KEY${NC} ${DIM}subfinder passive source.${NC}" + echo -e " ${DIM}→ https://www.virustotal.com/gui/my-apikey${NC}" + echo -e " ${CYAN}SECURITYTRAILS_API_KEY${NC} ${DIM}subfinder passive source (subdomains/history).${NC}" + echo -e " ${DIM}→ https://securitytrails.com/app/account/credentials${NC}" + echo -e " ${CYAN}OPENAI_API_KEY${NC} ${DIM}Only for ChatGPT/OpenAI MCP clients (host-based).${NC}" + echo -e " ${DIM}→ https://platform.openai.com/api-keys${NC}" + echo "" + echo -e " ${DIM}theHarvester and amass read keys from their OWN config files, not${NC}" + echo -e " ${DIM}env vars: ~/.theHarvester/api-keys.yaml and ~/.config/amass/datasources.yaml${NC}" + echo "" } @@ -294,6 +343,7 @@ print_summary() { echo "" echo -e " ${BOLD}Quick start:${NC}" echo -e " ${CYAN}make claude-code${NC} ${DIM}Launch Claude Code in Docker${NC}" + echo -e " ${CYAN}make deepseek${NC} ${DIM}Launch the DeepSeek (Reasonix) agent in Docker${NC}" echo -e " ${CYAN}make status${NC} ${DIM}Check service status${NC}" echo -e " ${CYAN}make health${NC} ${DIM}Run health checks${NC}" echo -e " ${CYAN}make logs${NC} ${DIM}View service logs${NC}" @@ -314,9 +364,12 @@ print_summary() { echo -e " ${BOLD}MCP Gateway:${NC} ${CYAN}http://localhost:8080${NC}" fi echo -e " ${BOLD}For pentesting:${NC}" - echo -e " 1. Edit ${CYAN}verification.env${NC} with your engagement details" - echo -e " 2. Run ${CYAN}make inject-verification${NC}" - echo -e " 3. Use a pentest template: ${DIM}full-pentest, quick-scan, etc.${NC}" + echo -e " Use a pentest template or skill: ${DIM}full-pentest, quick-scan, etc.${NC}" + echo "" + echo -e " ${BOLD}Optional API keys${NC} ${DIM}(none required — all tools run without them):${NC}" + echo -e " Add keys to ${CYAN}.env${NC} to widen recon coverage, then restart the stack." + echo -e " ${DIM}WPSCAN_API_TOKEN (WordPress vulns), VIRUSTOTAL_API_KEY / SHODAN_API_KEY /${NC}" + echo -e " ${DIM}SECURITYTRAILS_API_KEY (subfinder sources). See README → Optional API keys.${NC}" echo "" } @@ -328,6 +381,10 @@ while [[ $# -gt 0 ]]; do API_KEY="$2" shift 2 ;; + --deepseek-key) + DEEPSEEK_KEY="$2" + shift 2 + ;; --minimal) MINIMAL=true shift diff --git a/tests/test_boaz_mcp.py b/tests/test_boaz_mcp.py index 7f83345..6258184 100644 --- a/tests/test_boaz_mcp.py +++ b/tests/test_boaz_mcp.py @@ -1,4 +1,4 @@ -"""Tests for the BOAZ-MCP Gamma SSE adapter.""" +"""Tests for the BOAZ-MCP Gamma Streamable HTTP adapter.""" from __future__ import annotations @@ -40,8 +40,7 @@ def test_boaz_adapter_uses_upstream_package(tmp_path: Path, monkeypatch) -> None app = module.create_app(upstream) route_paths = {getattr(route, "path", "") for route in app.routes} assert "/health" in route_paths - assert "/sse" in route_paths - assert "/messages" in route_paths or "/messages/" in route_paths + assert "/mcp" in route_paths def test_boaz_dockerfile_clones_upstream_repos() -> None: diff --git a/tests/test_compose_integrations.py b/tests/test_compose_integrations.py index 40c0f94..ce0aea0 100644 --- a/tests/test_compose_integrations.py +++ b/tests/test_compose_integrations.py @@ -37,8 +37,8 @@ def test_integration_ports_are_documented_in_configs() -> None: assert 'HEXSTRIKE_REF: "${HEXSTRIKE_REF:-master}"' in compose assert "hexstrike-bridge-mcp" in catalog assert "boaz-mcp" in catalog - assert mcp_json["mcpServers"]["hexstrike"]["url"] == "http://localhost:9006/sse" - assert mcp_json["mcpServers"]["boaz"]["url"] == "http://localhost:9005/sse" + assert mcp_json["mcpServers"]["hexstrike"]["url"] == "http://localhost:9006/mcp" + assert mcp_json["mcpServers"]["boaz"]["url"] == "http://localhost:9005/mcp" def test_integration_dockerfiles_exist() -> None: @@ -70,11 +70,11 @@ def test_claude_code_container_wires_all_default_mcp_servers() -> None: ) for expected in [ - "http://kali-mcp:9001/sse", - "http://kali-mcp:9003/sse", - "http://screenshot-mcp:9004/sse", - "http://boaz-mcp:9005/sse", - "http://hexstrike-bridge-mcp:9006/sse", + "http://kali-mcp:9001/mcp", + "http://kali-mcp:9003/mcp", + "http://screenshot-mcp:9004/mcp", + "http://boaz-mcp:9005/mcp", + "http://hexstrike-bridge-mcp:9006/mcp", ]: assert expected in dockerfile assert expected in entrypoint @@ -83,3 +83,34 @@ def test_claude_code_container_wires_all_default_mcp_servers() -> None: assert "hexstrike" in dockerfile assert "boaz-mcp" in entrypoint assert "hexstrike-bridge-mcp" in entrypoint + + +def test_deepseek_container_wires_all_default_mcp_servers() -> None: + dockerfile = (ROOT / "docker" / "deepseek.Dockerfile").read_text(encoding="utf-8") + entrypoint = (ROOT / "docker" / "deepseek-entrypoint.sh").read_text(encoding="utf-8") + + for expected in [ + "http://kali-mcp:9001/mcp", + "http://kali-mcp:9003/mcp", + "http://screenshot-mcp:9004/mcp", + "http://boaz-mcp:9005/mcp", + "http://hexstrike-bridge-mcp:9006/mcp", + ]: + assert expected in dockerfile + assert expected in entrypoint + + # Reasonix install + DeepSeek provider that reads the key from the env. + assert "npm install -g reasonix" in dockerfile + assert "reasonix.toml" in dockerfile + assert 'api_key_env = "DEEPSEEK_API_KEY"' in dockerfile + # Launches the Reasonix coding agent. + assert "reasonix code" in entrypoint + + +def test_deepseek_service_is_in_compose_under_profile() -> None: + compose = COMPOSE.read_text(encoding="utf-8") + assert "deepseek:" in compose + assert "image: crhacky/blhackbox:deepseek" in compose + assert 'profiles: ["deepseek"]' in compose + assert "docker/deepseek.Dockerfile" in compose + assert "DEEPSEEK_API_KEY" in compose diff --git a/tests/test_hexstrike_mcp.py b/tests/test_hexstrike_mcp.py index c71964d..74261c9 100644 --- a/tests/test_hexstrike_mcp.py +++ b/tests/test_hexstrike_mcp.py @@ -1,4 +1,4 @@ -"""Tests for the HexStrike AI Gamma SSE adapter.""" +"""Tests for the HexStrike AI Gamma Streamable HTTP adapter.""" from __future__ import annotations @@ -44,8 +44,7 @@ def test_hexstrike_adapter_uses_upstream_package(tmp_path: Path, monkeypatch) -> app = module.create_app(upstream, "http://hexstrike-ai:8888", 1) route_paths = {getattr(route, "path", "") for route in app.routes} assert "/health" in route_paths - assert "/sse" in route_paths - assert "/messages" in route_paths or "/messages/" in route_paths + assert "/mcp" in route_paths def test_hexstrike_adapter_allows_internal_docker_hostname(tmp_path: Path, monkeypatch) -> None: # type: ignore[no-untyped-def] diff --git a/tests/test_skill_readiness.py b/tests/test_skill_readiness.py index 44e672b..7265df6 100644 --- a/tests/test_skill_readiness.py +++ b/tests/test_skill_readiness.py @@ -18,7 +18,10 @@ def test_skill_and_template_files_discovered() -> None: def test_all_skills_require_tool_and_methodology_readiness() -> None: required_phrases = [ "## Mandatory Tool & Methodology Readiness", - "Do **not** start the skill's execution plan until this readiness pass is complete.", + "Complete this readiness pass before you start the execution plan", + # The readiness methodology stays, but skills must also empower adaptive, + # judgment-driven recovery instead of following the plan off a cliff. + "Adapt, recover, and think", "Inventory 100% of usable capabilities first.", "Build a working tool matrix before execution", "closest supported profile", diff --git a/verification.env b/verification.env deleted file mode 100644 index 7ce5aca..0000000 --- a/verification.env +++ /dev/null @@ -1,112 +0,0 @@ -# ┌──────────────────────────────────────────────────────────────────────┐ -# │ BLHACKBOX — Penetration Testing Authorization Configuration │ -# │ │ -# │ Fill in ALL fields below, then run: │ -# │ make inject-verification │ -# │ or: │ -# │ python -m blhackbox.prompts.inject_verification │ -# │ │ -# │ This generates the active verification document that gets loaded │ -# │ into your Claude Code session as explicit written authorization. │ -# └──────────────────────────────────────────────────────────────────────┘ - -# ── Section 1: Engagement Identification ───────────────────────────── -# Set to ACTIVE when all fields are filled and testing is authorized. -AUTHORIZATION_STATUS=PENDING - -# Unique engagement identifier (e.g., "PENTEST-2026-001", "SOW-2026-042") -ENGAGEMENT_ID= - -# Date this authorization was granted (YYYY-MM-DD) -AUTHORIZATION_DATE= - -# Date this authorization expires (YYYY-MM-DD) -EXPIRATION_DATE= - -# Organization that owns or controls the target assets -AUTHORIZING_ORGANIZATION= - -# Person or company performing the test -TESTER_NAME= -TESTER_EMAIL= - -# Client-side point of contact -CLIENT_CONTACT_NAME= -CLIENT_CONTACT_EMAIL= - -# ── Section 2: Scope Definition ────────────────────────────────────── -# In-scope targets. Add up to 10. Leave unused slots empty. -# Format: domain.com, 10.0.0.0/24, https://app.example.com -TARGET_1= -TARGET_1_TYPE= -TARGET_1_NOTES= - -TARGET_2= -TARGET_2_TYPE= -TARGET_2_NOTES= - -TARGET_3= -TARGET_3_TYPE= -TARGET_3_NOTES= - -# Explicitly excluded from testing (comma-separated or "None") -OUT_OF_SCOPE=None - -# Engagement type: black-box, grey-box, white-box -ENGAGEMENT_TYPE=black-box - -# Credentials for grey-box/white-box (or "N/A") -CREDENTIALS=N/A - -# ── Section 3: Authorized Activities ───────────────────────────────── -# Mark each with "x" to permit or leave blank to deny. -# Example: PERMIT_RECON=x (permitted) -# PERMIT_RECON= (not permitted) -PERMIT_RECON=x -PERMIT_SCANNING=x -PERMIT_ENUMERATION=x -PERMIT_EXPLOITATION=x -PERMIT_DATA_EXTRACTION=x -PERMIT_CREDENTIAL_TESTING=x -PERMIT_POST_EXPLOITATION=x -PERMIT_TRAFFIC_CAPTURE=x -PERMIT_SCREENSHOT=x - -# Additional restrictions (free text, or "No additional restrictions") -RESTRICTIONS=No additional restrictions - -# ── Section 4: Testing Window ──────────────────────────────────────── -# Format: YYYY-MM-DD HH:MM -TESTING_START= -TESTING_END= -TIMEZONE=UTC - -# Who to call if something goes wrong during testing -EMERGENCY_CONTACT= -EMERGENCY_PHONE= - -# ── Section 5: Legal & Compliance ──────────────────────────────────── -# Applicable standards (comma-separated) -APPLICABLE_STANDARDS=OWASP Testing Guide v4.2, PTES - -# Report classification: CONFIDENTIAL, RESTRICTED, INTERNAL -REPORT_CLASSIFICATION=CONFIDENTIAL - -# How the report will be delivered: encrypted-email, secure-portal, in-person, local-only -REPORT_DELIVERY=local-only - -# ── Section 6: Digital Signature ───────────────────────────────────── -# Name of the person authorizing this engagement -SIGNATORY_NAME= - -# Title or role (e.g., "CISO", "CTO", "Asset Owner") -SIGNATORY_TITLE= - -# Organization of the signatory -SIGNATORY_ORGANIZATION= - -# Date signed (YYYY-MM-DD) -SIGNATURE_DATE= - -# Digital signature reference (PGP sig, contract ref, or "SELF-AUTHORIZED") -DIGITAL_SIGNATURE= diff --git a/wire-mcp/server.py b/wire-mcp/server.py index 308edc1..e213626 100644 --- a/wire-mcp/server.py +++ b/wire-mcp/server.py @@ -13,7 +13,7 @@ - follow_stream — reconstruct a TCP/UDP stream - list_interfaces — list available capture interfaces -Transport: FastMCP SSE on port 9003. +Transport: FastMCP Streamable HTTP on port 9003. """ from __future__ import annotations @@ -38,6 +38,18 @@ mcp = FastMCP("wire-mcp", host="0.0.0.0", port=MCP_PORT) +@mcp.custom_route("/health", methods=["GET"]) +async def health_check(request): # type: ignore[no-untyped-def] + """Lightweight health probe for Docker and Makefile checks. + + The Streamable HTTP endpoint (/mcp) only answers MCP protocol requests, + so container health checks target this dedicated route instead. + """ + from starlette.responses import JSONResponse + + return JSONResponse({"status": "healthy", "service": "wire-mcp", "port": MCP_PORT}) + + async def _run_tshark(args: list[str], timeout: int = 60) -> dict: """Run a tshark command and return structured output.""" tshark = shutil.which("tshark") @@ -350,7 +362,7 @@ async def list_interfaces() -> str: # --------------------------------------------------------------------------- if __name__ == "__main__": - transport = os.environ.get("MCP_TRANSPORT", "sse") + transport = os.environ.get("MCP_TRANSPORT", "streamable-http") logger.info( "Starting WireMCP Server (%s on port %d)", transport, MCP_PORT,