pentest · git:20260423.f0067ce · 2026-04-23 · sha256 af25f25b68ad78ac
pentest git:20260423.f0067ceB
Immutable. This exact content is served forever at /api/v1/blob/af25f25b68ad78ac.
---
name: pentest
description: Security testing and OSINT toolkit wrapping 183+ tools from Z4nzu/hackingtool (nmap, sherlock, amass, subfinder, nuclei, httpx, holehe, maigret, trufflehog, sqlmap, impacket, netexec, and more). Use whenever the user asks to recon a target, scan a network, enumerate subdomains, investigate a username or email, test a web app, check for leaked secrets, or any other pentest / OSINT task. Runs locally on any OS via native Bash, WSL, or purpose-built Docker images — the skill picks the right backend automatically.
---
# Pentest / OSINT Skill
Claude Code runs on the user's machine. You have real Bash, real filesystem, real process execution. **Run tools immediately; the runtime wrapper handles environment details for you.**
## The execution model
Every tool runs through `ht_run.py`, which:
1. Reads `ht_env.py` to pick a backend — **native** on Linux/macOS, **WSL** on Windows with a real distro, **Docker** anywhere with Docker Desktop.
2. Looks up a purpose-built Docker image for the tool if one exists (`instrumentisto/nmap`, `projectdiscovery/nuclei`, `caffix/amass`, 20+ more). Falls back to `kalilinux/kali-rolling` for anything not mapped.
3. Executes the command. If permission-denied on native/WSL, auto-retries with `sudo -n`. If an error is classifiable as recoverable, handles it.
4. Returns structured JSON with `status`, `stdout`, `stderr`, `returncode`, and the command that ran.
Only one pre-block exists: tools flagged `interactive` (they read stdin mid-run). Bypass with `--force` + `--command` if you have non-interactive args.
## Bundled scripts
All scripts live at `${CLAUDE_PLUGIN_ROOT}/scripts/`. Call them with `python ${CLAUDE_PLUGIN_ROOT}/scripts/<script>.py ...`. They emit JSON on stdout.
| Script | Purpose |
|---|---|
| `ht_search.py` | Query the tool index. Filter by `--q`, `--category`, `--tag`, `--capability runnable_by_claude`, `--os linux`. |
| `ht_env.py` | Report host OS, WSL distros, Docker availability, and `preferred_backend`. |
| `ht_run.py` | Execute a tool. `--command "..."` for a full-command override. `--args "..."` for append-args. `--network-host` for LAN scans via docker. `--privileged` for raw sockets / hardware. `--force` to bypass the interactive pre-block. |
## Golden path
1. **Read the ask.** Map to a workflow if possible — see `reference/workflows.md`.
2. **Check the environment once.** `python ${CLAUDE_PLUGIN_ROOT}/scripts/ht_env.py` tells you which backend will run. If Windows + no WSL + Docker stopped, ask the user to start Docker before Linux-only work.
3. **Find candidate tools.** `ht_search.py --q "<keyword>"` to discover tool ids. Don't assume ids.
4. **Execute them.**
- If RUN_COMMANDS is populated → `ht_run.py <tool_id> --args "..."`
- If RUN_COMMANDS is empty (many upstream tools have `runnable=False`) → use `--command "<full command>"`. The wrapper still picks the backend and image for you.
- For LAN / gateway scans via Docker → add `--network-host` so the container sees your LAN.
- For raw sockets / hardware → add `--privileged`.
5. **Parse the JSON result:**
- `status: ok` → summarize the interesting parts of stdout; don't paste the whole output if it's long.
- `status: error` with `returncode != 0` → tool ran but failed. Report stderr and decide whether to retry with different args.
- `status: fallback` → see `reference/runtime-fallbacks.md`. Pick the template matching the `reason` field.
- `status: timeout` → raise `--timeout <N>` or break the scan into smaller chunks.
6. **Compose, don't just call once.** OSINT chains: `subfinder → httpx → nuclei`. `holehe → sherlock → maigret`. Feed outputs into the next step.
## Docker image overrides
`ht_run.py` maps common tools to purpose-built images. These pull faster than Kali and have proper ENTRYPOINTs, so you just pass args:
| Tool | Image |
|---|---|
| NMAP | `instrumentisto/nmap` |
| Nuclei | `projectdiscovery/nuclei` |
| Subfinder / Httpx / Katana | `projectdiscovery/*` |
| Amass | `caffix/amass` |
| TheHarvester | `secsi/theharvester` |
| Holehe / Maigret / SpiderFoot | official images |
| TruffleHog / Gitleaks | official images |
| Sqlmap | `paoloo/sqlmap` |
| Impacket / NetExec | `rflathers/impacket`, `byt3bl33d3r/netexec` |
Override with `--docker-image my/image` for one-off swaps.
## Ad-hoc commands (no wrapper)
For one-off invocations that don't map to a hackingtool tool id — e.g. `curl -I https://target`, `arp -a`, `dig @8.8.8.8 example.com` — just use Bash directly. Use `ht_run.py` when:
- The tool is in the index and you want automatic image/backend selection
- You want permission-error auto-retry
- You're chaining multiple tools and want uniform JSON output
## References
- `${CLAUDE_PLUGIN_ROOT}/skills/pentest/reference/workflows.md` — named playbooks
- `${CLAUDE_PLUGIN_ROOT}/skills/pentest/reference/runtime-fallbacks.md` — templates for each fallback reason