# Pentest

> 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.

- Skill: `akcodez/pentest` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add akcodez/pentest`
- Raw SKILL.md: https://api.skillmd.com/api/skills/akcodez/pentest/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: akcodez (https://skillmd.com/u/akcodez)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/akcodez/pentest

---


# Pentest / OSINT Skill

You have real Bash, real filesystem, real process execution, and a fleet of pentest tools one wrapper call away. **Use the wrappers — manual `curl` loops are a fallback, not a default.**

## Step 0 — Preflight (run first, every session)

```bash
python ${CLAUDE_PLUGIN_ROOT}/scripts/ht_preflight.py
```

Read the `verdict` and act:

- **`ready`** → state the backend in one sentence (e.g. "Running native on macOS" / "Running via Docker on Windows" / "Running native in WSL Ubuntu") and start work.
- **`partial`** → tell the user what's missing (use `recommendations`); offer to proceed with reduced coverage.
- **`blocked`** → stop. Surface the recommendations and wait. **Do not** substitute manual `curl` / `Invoke-WebRequest` probes for a missing tool — that misleads the user about coverage.

Re-run preflight if the user installs something, starts Docker, or switches into WSL.

## Tool-first defaults

When the ask is "audit / scan / find vulns", reach for:

| Ask | Default chain |
|-----|---------------|
| Subdomain enumeration | `subfinder -all` → `httpx -title -tech-detect` |
| Web vuln scan | `nuclei -severity medium,high,critical` |
| Port scan | `nmap -sV -sC` (or `naabu` for fast SYN sweep) |
| Directory / API discovery | `ffuf -w wordlist -u https://target/FUZZ` |
| Secret hunting | `trufflehog filesystem .` or `gitleaks detect` |
| Username / email investigation | `holehe` → `sherlock` → `maigret` |
| TLS audit | `nuclei -tags ssl,tls` |
| Domain OSINT | `amass intel` → `theharvester` |

Anti-patterns: `for`-looping curl across many paths instead of `ffuf` / `nuclei`; hand-parsing TLS output instead of `nuclei -tags ssl`; saying "I don't have nuclei" when preflight returned `ready` (you have it via Docker).

## 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`.
3. Executes the command. Auto-retries with `sudo -n` on permission-denied (native/WSL).
4. Returns JSON: `status`, `stdout`, `stderr`, `returncode`, `command`.

Only one pre-block: tools flagged `interactive`. Bypass with `--force` + `--command` if you have non-interactive args.

## Bundled scripts

All at `${CLAUDE_PLUGIN_ROOT}/scripts/`. Emit JSON.

| Script | Purpose |
|---|---|
| `ht_preflight.py` | **Run first.** Capability check + setup recommendations. |
| `ht_search.py` | Query the tool index (`--q`, `--category`, `--tag`, `--capability`, `--os`). |
| `ht_env.py` | Low-level env detect. (Preflight wraps this.) |
| `ht_run.py` | Execute. `--command "..."` to override, `--args "..."` to append, `--network-host` for LAN, `--privileged` for raw sockets, `--force` to bypass the interactive block. |

## Golden path

1. **Preflight** — handle verdict per Step 0.
2. **Read the ask** — map to a workflow (`reference/workflows.md`) and apply the defaults table.
3. **Find tool ids** — `ht_search.py --q "<keyword>"`. Don't guess; ids are namespaced (e.g. `web_attack.Nuclei`).
4. **Execute** — `ht_run.py <tool_id> --args "..."`, or `--command "<full>"` for tools where `runnable=False`. Add `--network-host` for LAN, `--privileged` for raw sockets.
5. **Parse status:** `ok` → summarize highlights; `error` → report stderr, decide whether to retry; `fallback` → see `reference/runtime-fallbacks.md`; `timeout` → raise `--timeout` or chunk the scan.
6. **Compose** — `subfinder → httpx → nuclei`, `holehe → sherlock → maigret`. Feed outputs forward.

## Docker image overrides

`ht_run.py` maps common tools to purpose-built images (faster pulls, proper ENTRYPOINTs):

| 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-offs.

## Ad-hoc commands

Bash directly is fine for spot-checks: a single `curl -I`, `arp -a`, `dig @8.8.8.8 example.com`. Reach for `ht_run.py` whenever:

- The tool is in the index and you want auto image/backend selection.
- You're chaining multiple tools and want uniform JSON output.
- The task is enumeration / scanning / fuzzing at any scale (**≥5 requests against a target**).

If you're about to write a `for` loop hitting many paths with `curl`, **stop — use `ffuf` / `nuclei` / `gobuster` instead.**

## References

- `${CLAUDE_PLUGIN_ROOT}/skills/pentest/reference/workflows.md` — named playbooks
- `${CLAUDE_PLUGIN_ROOT}/skills/pentest/reference/runtime-fallbacks.md` — templates per fallback reason

