| name | pentest-kit |
| description | Tool-orchestrated penetration testing. Coordinates free external tools (nmap, nuclei, sqlmap, ffuf, Caido, mitmproxy, ZAP, dalfox, jwt_tool, semgrep, trivy) via specialized agents. Executors never attack directly — they run tools, parse output, and chain results. Use for engagement planning, automated scanning, and manual-assisted security testing. |
Tool-orchestrated penetration testing. Deploy tool-based executors, aggregate results, generate reports.
Use when user requests pentesting, security assessment, vulnerability testing, or bug bounty hunting.
Tool Stack (38 Tools, Free)
| Category | Tools |
|---|
| Recon | subfinder, dnsx, httpx, nmap |
| Crawling | katana, gau, waybackurls |
| Discovery | ffuf, feroxbuster, gobuster, arjun, paramspider |
| Scanning | nuclei, OWASP ZAP, nikto, wapiti |
| Injection | sqlmap, dalfox, commix, tplmap |
| Auth/Creds | jwt_tool, hydra |
| SAST | semgrep (multi-lang), bandit (Python) |
| SCA | trivy (deps, containers, IaC), grype |
| Secrets | gitleaks, trufflehog |
| SSL/TLS | testssl.sh |
| Proxy | Caido (host), mitmproxy (container), proxychains4, tor |
| Browser | Playwright MCP (copilot mode) |
| Reporting | pandoc (DOCX/PDF) |
CLI Commands
All tools run inside a hardened Docker container. Use the pentest-kit CLI:
pentest-kit init <engagement> --target <url> [--source <path>]
pentest-kit up / down / shell / status
pentest-kit proxy off
pentest-kit proxy socks5 <host:port>
pentest-kit proxy http <host:port>
pentest-kit proxy preset <name>
pentest-kit proxy tor
pentest-kit proxy chain <p1,p2,p3>
pentest-kit proxy status
pentest-kit exec <command>
pentest-kit exec proxychains4 -q <cmd>
pentest-kit scan <pipeline> --target <url> --engagement <name>
pentest-kit report generate <engagement>
pentest-kit report status <engagement>
pentest-kit engage list / status <engagement>
pentest-kit preflight [--deep] [--save]
pentest-kit logs [engagement]
If CLI not installed: curl -sSL https://get.nunenuh.me/pentest-kit | bash
Path Mapping
The workspace is wherever docker-compose.yml lives — either a clone directory or ~/.pentest-kit/ (remote install). The CLI auto-detects this via pentest-kit status.
| Host (relative to workspace) | Container | Access |
|---|
./targets/ (or TARGETS_PATH) | /pentest-kit/targets/ | Read-only |
./results/{engagement}/ (or RESULTS_PATH) | /pentest-kit/results/{engagement}/ | Read-write (777) |
./rules/ | /pentest-kit/rules/ | Read-only |
./rules.local/ | /pentest-kit/rules.local/ | Read-only |
All pentest-kit exec commands run inside the container at /pentest-kit/.
Output paths in commands use container paths: /pentest-kit/results/{engagement}/scans/...
Target Sources
--target <url> is required for every engagement. --source <path> is optional.
1. URL only (DAST — black-box)
pentest-kit init my-audit --target https://app.example.com
Runs network scanners (nmap, nuclei, sqlmap, etc.) against the live URL. No source code access — SAST/SCA pipelines are skipped.
2. URL + local source code (DAST + SAST + SCA — full coverage)
pentest-kit init my-audit --target https://app.example.com --source /path/to/local/code
Mounts --source as read-only at /pentest-kit/targets/ inside the container. Enables SAST (semgrep, bandit) and SCA (trivy, grype) pipelines alongside DAST.
3. Git repo URL (clone first, then scan)
git clone https://github.com/org/repo.git /tmp/repo
pentest-kit init my-audit --target https://app.example.com --source /tmp/repo
The CLI does not auto-clone — clone manually first, then pass the local path via --source.
Custom Rules
Shared rules (rules/)
Checked into git. Available to all users. Mounted at /pentest-kit/rules/ (read-only).
rules/
├── semgrep/ # sqli-patterns.yml, insecure-crypto.yml, jwt-misuse.yml, auth-bypass.yml
├── nuclei/ # custom-headers.yaml, sensitive-files.yaml
└── bandit/ # .bandit.yml
Project rules ({cwd}/rules/ → rules.local/)
The CLI auto-detects a rules/ directory in your current working directory and mounts it as /pentest-kit/rules.local/ (read-only) in the container. This is for org/project-specific rules that shouldn't be in the shared repo.
cd /my/project
mkdir -p rules/semgrep rules/nuclei rules/bandit
pentest-kit init my-audit --target https://app.com
Use both in tool commands:
pentest-kit exec semgrep --config /pentest-kit/rules/semgrep/ --config /pentest-kit/rules.local/semgrep/ /pentest-kit/targets/
pentest-kit exec nuclei -u https://target.com -t /pentest-kit/rules/nuclei/ -t /pentest-kit/rules.local/nuclei/
Examples:
pentest-kit exec nmap -sV target.com -oX /pentest-kit/results/my-eng/scans/reconnaissance/raw/nmap.xml
pentest-kit exec proxychains4 -q nuclei -u https://target.com -jsonl -o /pentest-kit/results/my-eng/scans/vulnerability/nuclei/nuclei-full.json
pentest-kit exec bash -c "subfinder -d target.com -silent | httpx -silent -json -o /pentest-kit/results/my-eng/scans/reconnaissance/raw/httpx.json"
pentest-kit exec bash -c "curl -s http://target/api/users 2>&1 | head -50"
pentest-kit exec bash -c "nmap -sV target.com && echo done"
CRITICAL: Always use bash -c "..." for piped or chained commands. Without it,
shell operators are parsed by the HOST shell and never reach the container.
Core Principles
- Executors NEVER attack directly. They run tools from
tools/REGISTRY.md following tools/PIPELINES.md.
- All tools run inside the Docker container. Use
pentest-kit exec <command>. Never run tools on the host.
- Choose a proxy mode explicitly per engagement. Use the decision tree in
specs/PROXY.md. Default for authorized pentest with IP whitelist is direct (pentest-kit proxy off). Tor is NOT the default — it fails against Cloudflare/Akamai/most production WAFs. Exception: ssl, sast, and sca pipelines skip proxy automatically.
- Run tools from orchestrator directly using
pentest-kit exec. This is the primary pattern. Deploying parallel executor subagents is optional for independent pipelines.
Startup Sequence (ALL MODES)
1. pentest-kit init <engagement> --target <url> ← creates dirs, starts container, runs preflight
2. Choose proxy mode for THIS engagement ← see decision tree in specs/PROXY.md
• Authorized, IP whitelisted → pentest-kit proxy off
• Authorized, no whitelist → pentest-kit proxy socks5 <vps> (or preset)
• Bug bounty + residential → pentest-kit proxy preset <name> (auth via env)
• Anonymous research → pentest-kit proxy tor
3. pentest-kit proxy status ← verify chosen mode actually works
4. Proceed to scanning (Phase 2)
Workflow
Auto Mode (/pentest-kit)
1. pentest-kit init <eng> --target <url> ← bootstrap
2. pentest-kit proxy tor && pentest-kit proxy status ← mandatory
3. pentest-kit scan recon --target <domain> ← asset discovery
4. Analyze recon output, present plan, GET USER APPROVAL
5. pentest-kit scan webapp-scan --target <url> ← vuln scanning
pentest-kit scan injection --target <url> ← injection testing
pentest-kit scan ssl --target <url> ← SSL (auto-skips proxy)
6. Create scripts/ with PoC scripts for confirmed vulns
7. Write findings.json from confirmed results
8. Write reports/raw/ sections using reference/templates/
9. pentest-kit report generate <eng> ← combines raw → final + pandoc
If a scan pipeline fails, fall back to running tools directly:
pentest-kit exec subfinder -d example.com -silent -json -o /pentest-kit/results/{eng}/scans/reconnaissance/raw/subfinder.json
pentest-kit exec nmap -sV example.com -oX /pentest-kit/results/{eng}/scans/reconnaissance/raw/nmap.xml
pentest-kit engage reset <eng>
Assist Mode (/pentest-kit assist)
Init → Proxy → User browses in Caido → User exports HAR →
Agent processes export (pentest-kit exec nuclei/sqlmap/dalfox) →
Results → User verifies → Report
Copilot Mode (/pentest-kit copilot)
Browser-driven, LLM-reasoned pentesting. Use for:
- CTF/gamified targets (OWASP Juice Shop, DVWA, HackTheBox Web)
- SPAs where scanners can't see post-auth routes
- Business logic flaws (IDOR, race conditions, workflow bypass)
- Targets requiring authenticated testing
1. pentest-kit init <eng> --target <url>
2. Choose proxy mode (see specs/PROXY.md)
3. pentest-kit copilot start <eng> ← launches loop
4. Agent drives turns via the 4 primitives:
pentest-kit copilot turn <eng> --primitive browser --action navigate --args '{"url":"..."}'
pentest-kit copilot turn <eng> --primitive shell --args '{"argv":["nmap","-sV","target"]}'
pentest-kit copilot turn <eng> --primitive http --args '{"method":"POST","url":"...","body":"..."}'
pentest-kit copilot turn <eng> --primitive note --args '{"type":"vulnerability","title":"SQLi","severity":"high"}'
5. pentest-kit copilot status <eng> ← turns, findings, loop health
6. pentest-kit copilot stop <eng> ← shutdown
7. Write reports/raw/ sections from copilot findings
8. pentest-kit report generate <eng>
Primitives (4 total — no convenience wrappers):
| Primitive | What it does | Key args |
|---|
browser | Playwright navigation, click, fill, eval, screenshot, extract, reload | action + selector/url/value |
http | Raw HTTP with browser's current session cookies | method, url, headers, body |
shell | Run any container tool (curl, jq, jwt_tool, sqlmap, ffuf, …) | argv (list) or cmd (string) |
note | Record a finding, hypothesis, or dead end | type, title, severity, evidence |
Authentication (if auth.yaml exists):
Place auth.yaml in results/{eng}/auth.yaml before starting copilot:
version: 1
type: form
login_url: /#/login
username_field: email
password_field: password
success_indicator: token
credentials:
- role: admin
email: admin@example.com
password: admin123
- role: user
email: user@example.com
password: user123
- role: anonymous
Switch roles mid-session: browser switch_role --args '{"role":"admin"}'
Resume (for long sessions):
pentest-kit copilot resume <eng> ← restarts loop from state + summary
pentest-kit copilot turn <eng> --primitive resume ← get full resume context
Reasoning strategy (CRITICAL — think like an expert, not a checklist):
See specs/PENTEST-REASONING.md for the full reasoning model. Key points:
HYPOTHESIS-DRIVEN LOOP (every turn):
EXPLORE → OBSERVE → HYPOTHESIZE → TEST → INTERPRET → CHAIN → REPEAT
EXPLORE (turns 1-15):
Browse as a normal user first. Sign up, log in, use features.
Build a mental model: what does this app do? What are the roles?
Map: pages, forms, APIs, file uploads, auth mechanism, tech stack.
OBSERVE:
What's interesting in the turn response?
- events.dialogs: XSS confirmed if alert() fired
- events.console_errors: CSP violations, stack traces, debug output
- events.response_errors: 500s, 403→200 between roles, leaked headers
- events.page_errors: broken middleware, auth bypass signals
- recent_findings: what have I already found? can I chain?
- dom_digest: same as last turn? my action had no effect
- interceptor auto-findings: IDOR candidates, JWTs, sensitive data
HYPOTHESIZE:
Form a specific, testable hypothesis:
"This /rest/products/search?q= endpoint echoes my input.
Hypothesis: it might be SQL-injectable."
NOT: "Let me run my SQLi checklist on everything."
TEST:
Execute ONE primitive to test the hypothesis.
Use the most appropriate:
- browser: UI interaction, XSS verification (watch for dialogs!)
- http: raw API requests, header manipulation, IDOR role comparison
- shell: tools (sqlmap, jwt_tool, ffuf, nuclei)
- note: record hypothesis BEFORE testing, result AFTER
INTERPRET:
Did the response confirm or deny?
- Status code changed? (200→500 = error-based injection signal)
- Response body different? (more data = IDOR, error = SQLi)
- Response TIME different? (slow = time-based blind injection)
- Dialog fired? (XSS confirmed)
- Console error? (CSP blocked it — try bypass)
If DENIED: don't give up. Try 3 variations before dead_end:
1. Different encoding (URL encode, double encode, unicode)
2. Different injection point (body, cookie, header instead of URL)
3. Different technique (time-based instead of error-based)
CHAIN:
After each finding, ask: "Can I combine this with anything?"
- IDOR + mass assignment = privilege escalation
- SQLi + hash cracking = account takeover
- Open redirect + OAuth = token theft
- SSRF + cloud metadata = credential extraction
- XSS + CSRF = authenticated action as victim
- Info disclosure + default creds = admin access
REPEAT:
Follow the evidence, not the checklist.
What's the next most interesting thing based on what I just learned?
OSINT & WEB SEARCH (use for challenges requiring external knowledge):
When you need information NOT available in the target app:
- Password hash cracking: use Exa MCP (`mcp__exa__web_search_exa`) to look up
known hashes (e.g., MD5 `030f05e45e30710c3ad3c32f00de0473` → search online)
- Security question answers: search for public info about fictional/real
characters (e.g., "Bender first company Futurama", "Bjoern Kimminich ZIP code")
- CVE/advisory lookup: search for specific CVEs referenced in app responses
- Default credentials: search for default creds of identified software
- Leaked credentials: search for known leaked databases/pastes
Hash lookup strategy (password cracking without wordlists):
1. Extract hash from SQLi dump or API response
2. Identify hash type: MD5 (32 hex), SHA-1 (40 hex), bcrypt ($2b$)
3. Try local: `pentest-kit exec hashcat -m 0 <hash> /usr/share/wordlists/rockyou.txt`
4. If not found locally → web search: `mcp__exa__web_search_exa("MD5 <hash>")`
5. Try online databases: hashes.org, crackstation.net, cmd5.org
6. For bcrypt/scrypt: web search is unlikely to help, focus on common passwords
Social media OSINT strategy (security question answers):
1. Identify the target user's name/persona from the app
2. For fictional characters: search "<character> <question topic>" (e.g.,
"Bender Futurama first job", "Morty Smith pet name")
3. For real people (e.g., app maintainers): search "<name> hometown",
"<name> high school", "<name> pet name" — public info from GitHub,
Twitter, LinkedIn, conference talks
4. For app-specific questions: check the app's About page, README, or
CSAF advisory for author details
5. Try ROT13/base64 decoding on obfuscated security answers
When to use web search vs local tools:
- Hash NOT in rockyou-75.txt → web search for known hash
- Security question about fictional character → web search for lore
- Security question about real person → web search for OSINT
- CVE number referenced in app → web search for exploit details
TECH STACK → ATTACK PRIORITIZATION:
After fingerprinting, adjust your approach:
Node.js/Express → prototype pollution, NoSQL injection, path traversal via %2f
JWT detected → immediately: alg:none, key confusion, expiry bypass
File upload → extension bypass, content-type, magic bytes, polyglot
GraphQL → introspection, batch queries, nested DoS, IDOR via query
Angular SPA → template injection, hash routing bypass
(See specs/PENTEST-REASONING.md for full stack→attack mapping)
SCOPE CHECK:
Before every shell primitive, check engagement mode:
- blackbox: do NOT access target container internals (no docker cp/exec on target)
- graybox: source code access allowed, but no config changes
- whitebox: full access
If tempted to break scope, STOP and ask the user to expand scope.
WSTG reference checklist (use as a coverage check, not as the driver):
After 30+ turns of hypothesis-driven testing, use this checklist to verify
you haven't missed entire categories. Don't follow it linearly — use it as
a "did I forget to check this area?" reference.
□ RECON: tech fingerprint, robots.txt, JS analysis, content discovery, endpoint map
□ CONFIG: security headers, cookie flags, CORS, HTTP methods, default creds, TLS, error handling
□ AUTH: account enumeration, password reset, MFA bypass, lockout, session management, JWT
□ AUTHZ: IDOR across roles, privilege escalation, path traversal, horizontal access
□ INPUT: SQLi, XSS (check dialogs!), SSTI, command injection, SSRF, XXE, HPP, open redirect, file upload
□ API: mass assignment, rate limiting, GraphQL, BOLA, API versioning
□ LOGIC: price manipulation, workflow bypass, race conditions, coupon abuse
□ CLIENT: clickjacking, postMessage, browser storage, prototype pollution, WebSocket
Pattern recipes (read before attacking a specific vuln type):
When you identify a vulnerability type, read the corresponding pattern recipe
from patterns/ for step-by-step exploitation:
patterns/union-sqli-extraction.md — column count → schema → dump → crack
patterns/jwt-attack-triage.md — decode → algo check → forge variants
patterns/idor-enumeration.md — baseline → iterate IDs → diff responses
patterns/auth-session-loop.md — login → store token → use in requests
patterns/file-upload-chains.md — extension → content-type → magic bytes
patterns/xxe-exploitation.md — basic → parameter entities → OOB
patterns/csrf-origin-crafting.md — headers → method confusion → SameSite bypass
patterns/nosql-operator-catalog.md — $ne, $where, $gt with contexts
patterns/graphql-introspection.md — detect → schema dump → query abuse
patterns/cloud-metadata-ssrf.md — 169.254.169.254 → credentials → escalation
patterns/jwt-rsa-confusion.md — RS256→HS256 algorithm confusion with public key
patterns/sanitize-html-bypass.md — single-pass sanitizer bypass (nested tags, mutation XSS)
patterns/csp-injection.md — CSP bypass via trusted domains, JSONP, legacy pages
patterns/node-deserialize-rce.md — node-serialize $$ND_FUNC$$ to RCE
patterns/nosql-operator-advanced.md — $regex exfiltration, $where ReDoS, operator auth bypass
patterns/local-file-read.md — path traversal, null byte, Swagger file access
patterns/ssti-pug-jade.md — Pug/Jade SSTI detection → code execution → RCE
patterns/ssrf-internal-access.md — SSRF to cloud metadata, internal services, URL bypass
patterns/z85-coupon-forge.md — z85 coupon reverse engineering and forging
patterns/race-condition-testing.md — TOCTOU race conditions via concurrent requests
ANTI-PATTERNS (avoid these):
- Don't follow the WSTG checklist linearly — follow the evidence
- Don't try once and record dead_end — try 3 variations first
- Don't test without a hypothesis — "let me try SQLi everywhere" wastes turns
- Don't ignore events.dialogs — if alert() fires, XSS is confirmed
- Don't ignore recent_findings — chain your discoveries
- Don't forget to switch roles — test the same endpoint as admin AND user
- Don't run heavy tools (sqlmap, ffuf) before mapping the target
- Don't report theoretical findings — every vulnerability needs a working PoC
- Don't break engagement scope — check blackbox/graybox/whitebox before shell commands
Traffic is auto-intercepted by mitmproxy + tools/copilot/interceptor.py.
The interceptor auto-detects IDOR candidates, JWTs, UUIDs, sensitive data,
and missing security headers — these appear in copilot/interceptor/findings.ndjson.
All scraped page content passes through prompt-injection guardrails before
reaching the agent.
See specs/COPILOT.md for the full architecture.
Results Structure
{workspace}/results/{engagement}/ ← host path (workspace = where docker-compose.yml is)
/pentest-kit/results/{engagement}/ ← container path (same content, mounted)
├── reports/raw/ ← numbered markdown sections
├── reports/final/ ← combined .md + .docx + .pdf
├── scripts/ ← numbered PoC bash scripts
├── scans/ ← raw tool output by category
│ ├── reconnaissance/raw/
│ ├── vulnerability/nuclei/, zap/, nikto/
│ ├── injection/sqlmap/, dalfox/
│ ├── sast/semgrep/, bandit/
│ ├── sca/trivy/, grype/
│ ├── secrets/gitleaks/, trufflehog/
│ └── ssl/testssl/
├── evidence/ ← per-finding (FIND-001/)
├── copilot/ ← traffic.ndjson, findings.ndjson
├── activity/ ← NDJSON execution logs
├── findings.json ← machine-readable findings
└── state.json ← engagement tracking (auto-updated)
Attack Categories (9 categories, 50+ types)
| Category | Primary Tools |
|---|
| Injection (SQLi, CMDi, SSTI, XXE) | sqlmap, commix, tplmap, nuclei |
| Client-Side (XSS, CSRF, CORS) | dalfox, nuclei, Playwright |
| Server-Side (SSRF, File Upload, Path Traversal) | nuclei, ffuf, feroxbuster |
| Authentication (JWT, OAuth, Brute Force) | jwt_tool, hydra, Playwright |
| API (GraphQL, REST, WebSockets) | nuclei, arjun, ffuf |
| Web App (Business Logic, Race Conditions, IDOR) | Caido (manual), Playwright |
| Cloud (AWS, Azure, GCP, Docker, K8s) | nuclei, trivy, gitleaks |
| System (AD, PrivEsc) | nmap, hydra |
| Infrastructure (Ports, DNS, SSL) | nmap, dnsx, testssl.sh |
See reference/ATTACK_INDEX.md for complete list.
Reference (read on demand, not at startup)
tools/REGISTRY.md — tool commands and flags
tools/PIPELINES.md — pipeline definitions
reference/templates/ — 16 report section templates
reference/FINAL_REPORT.md — rendering spec + quality checklist
reference/OUTPUT_STRUCTURE.md — directory layout
reference/ATTACK_INDEX.md — attack type index
reference/CAIDO_INTEGRATION.md — manual proxy workflow
Findings Format
Two types of findings in findings.json:
- Vulnerability (
type: "vulnerability") — exploitable, tool-confirmed, has working PoC, gets CVSS + difficulty rating
- Observation (
type: "observation") — hardening advice, not exploitable, no PoC needed, severity = "info"
Every vulnerability MUST have:
- Confirmed by tool output (not theoretical)
- Copy-paste reproducible PoC
- Evidence in
evidence/FIND-{NNN}/
Report Generation
The report follows a strict order. Each step depends on the previous one.
Step 1 — Scans produce tool output:
pentest-kit scan recon/webapp-scan/injection/etc → scans/{category}/{tool}/
Step 2 — Agent creates PoC scripts from confirmed exploits:
Write scripts/01-sqli-login.sh, scripts/02-idor-user.sh, etc.
Write scripts/README.md (dependency tree, prerequisites)
Write scripts/NN-cleanup.sh (second-to-last)
Write scripts/NN-verify-remediation.sh (last)
Step 3 — Agent creates findings.json from confirmed results:
Write findings.json at engagement root with all findings + observations.
Each finding must reference its PoC script and evidence directory.
Step 4 — Agent writes report sections using templates:
Read reference/templates/COVER-AND-SCOPE.md → fill → write reports/raw/01-COVER-AND-SCOPE.md
Read reference/templates/EXECUTIVE-SUMMARY.md → fill → write reports/raw/02-EXECUTIVE-SUMMARY.md
Read reference/templates/FINDINGS.md → fill → write reports/raw/03-FINDINGS.md
Read reference/templates/REMEDIATION.md → fill → write reports/raw/04-REMEDIATION.md
Read reference/templates/EVIDENCE-LOG.md → fill → write reports/raw/05-EVIDENCE-LOG.md
... (additional sections as needed — see reference/FINAL_REPORT.md)
Step 5 — CLI combines raw → final + pandoc:
pentest-kit report generate <engagement>
The CLI does NOT auto-generate content. It only combines and exports what the agent wrote.
Error Handling & Troubleshooting
| Symptom | Cause | Fix |
|---|
flag provided but not defined | Tool version mismatch | Check pentest-kit exec <tool> -h for available flags |
| Empty output file (0 results) | Proxy blocking tool | Retry with pentest-kit exec --no-proxy <cmd> |
DNS lookup failed / -cdn crash | httpx flag incompatible | Remove -cdn flag, use stdin instead of -u |
connection refused / timeout | Target down or unreachable | Verify: pentest-kit exec curl -sv <url> |
| testssl always fails | SSL can't go through SOCKS5 | Use pentest-kit exec --no-proxy testssl <url> (ssl pipeline auto-skips proxy) |
| katana/gau return 0 URLs | Tor exit node blocked | Retry without proxy or use direct connection |
| state.json stuck on "failed" | Pipeline crashed | pentest-kit engage reset <eng> |
report generate can't find engagement | Path mismatch (cwd vs workspace) | Run from same directory where you ran init, or check pentest-kit engage list |
| Pipeline succeeds but 0 findings | Tool ran but found nothing | Check raw output in scans/ directory, not an error |
Critical Rules
- Choose proxy explicitly: pick one mode per engagement via the decision tree in
specs/PROXY.md. Direct (proxy off) is valid and often correct. Tor is rarely correct against production WAFs.
- Preflight MANDATORY:
pentest-kit preflight before every engagement
- User approval MANDATORY: Present test plan and get approval before exploitation
- Tool-based only: All commands from REGISTRY.md, all chains from PIPELINES.md
- Container paths: All exec commands use
/pentest-kit/results/{engagement}/...
- Evidence from tools: Save raw tool output as evidence
- Working PoCs required: Every vulnerability needs a reproducible PoC
- No theoretical findings: Tool output must confirm vulnerability
- Report via CLI:
pentest-kit report generate <eng> combines reports/raw/ → final .md + .docx + .pdf (agent writes raw sections first)