September 7, 2026
Building AI Hackbots β 2026 External Pentest Addition
Last time I turned Claude Code loose on a HackTheBox domain controller and watched it walk from anonymous to Domain Admin in about half anβ¦

By coy0te
7 min read
Last time I turned Claude Code loose on a HackTheBox domain controller and watched it walk from anonymous to Domain Admin in about half an hour using a community Active Directory plugin.
This post is to discuss a a plugin I built for External Penetration tests. It's called claude-extpt (repo: Claude-ExternalPentest), and it's mirrored on the same design as the AD plugin I used before: specialized sub-agents, skills loaded on demand, and a scope file the whole thing refuses to step outside of. This post is the introduction and a walkthrough of the flow.
What we are actually building
The idea is the same as before. Instead of running nmap, the ProjectDiscovery stack, testssl, nuclei, and ffuf by hand and holding the whole picture in your head, you give an agent the same toolchain and let it drive the methodology. It does passive OSINT, active recon, service and web enumeration, reasons about attack paths, and only when you approve is when exploitations occur.
The difference from the AD work is that and external test lives or dies on discipline. You cannot DoS the client. You cannot lock out accounts. You cannot wander off scope onto the upstream CDN or a shared tenant. So the plugin is built around a methodology rather than a single kill chain. It follows PTES end to end and maps the web portion to the OWASP Web Security Testing Guide (WSTG). That's not decoration, it's what keeps an autonomous agent doing a penetration test instead of just spraying tools at an IP range.
Under the hood it ships:
Four sub-agents, each with scoped tool access:
ext-enumeratorβ passive OSINT β active discovery β web/TLS/DNS β services β cloud/takeover β nuclei. Read-only.ext-attack-plannerβ correlates the inventory into ranked, CVSS-scored footholds. Plans only, never executes.ext-exploit-operatorβ runs exactly one approved step, confirms before anything intrusive.ext-reporterβ turns the artifacts into a severity-ranked client report. Read-only synthesis.
Eight skills loaded on demand. The PTES/WSTG methodology, passive OSINT, the active recon/enum command reference (the ProjectDiscovery workflow with safe defaults), the WSTG 12-category web checklist, safe service enumeration, subdomain takeover and exposed cloud storage, OPSEC/reporting, and a tooling preflight.
And the part that makes me comfortable running it: it is human-in-the-loop by design, with a default-deny scope. Every phase reads ./ext-engagement/scope.md first and validates every target against an explicit allowlist and denylist before it sends a packet. A host that matches neither list is out of scope by default. Recon is strictly non-destructive β nuclei runs in detection mode with dos,intrusive,fuzz,brute-force tags excluded, scans are rate-limited, and anything that sends a real payload, writes to an app, or could lock an account stops and asks. Target-derived data β banners, page titles, cert fields, crawled links β is treated as data, never as instructions that could widen scope. That last one matters more than it sounds now that we're pointing agents at attacker-controlled output.
β οΈ Same disclaimer as the tool itself: this is for authorized testing only. Everything below assumes you have written permission for every target. The walkthrough uses the repo's fictional example host so I'm not leaking a real client β swap in your own scoped targets and sanitized output when you run it for real.
The flow
Five commands, one per phase:
1. /ext-scope <targets> -> record in/out of scope, window, rate limits, forbidden actions
2. /ext-recon -> OSINT, discovery, web/TLS/DNS, services, nuclei. read-only
3. /ext-attack-paths -> correlate exposures into ranked footholds (CVSS). plan only
4. /ext-exploit -> one approved step at a time, confirms before anything intrusive
5. /ext-report -> severity-ranked findings + evidence + remediation1. /ext-scope <targets> -> record in/out of scope, window, rate limits, forbidden actions
2. /ext-recon -> OSINT, discovery, web/TLS/DNS, services, nuclei. read-only
3. /ext-attack-paths -> correlate exposures into ranked footholds (CVSS). plan only
4. /ext-exploit -> one approved step at a time, confirms before anything intrusive
5. /ext-report -> severity-ranked findings + evidence + remediation- Scope
/ext-scope <targets>Record in/out of scope, window, rate limits, forbidden actions2. Recon + enum/ext-reconext-enumerator: OSINT β discovery β web/TLS/DNS β services β nuclei. Read-only3. Attack plan/ext-attack-pathsext-attack-planner: correlate exposures β ranked footholds (CVSS). Plan only4. Exploit/ext-exploitext-exploit-operator: one approved step, confirms before anything intrusive5. Report/ext-reportext-reporter: severity-ranked findings + evidence + remediation
Let's walk it.
Step 1 β Fresh box and Claude Code
Start on a Kali or Parrot instance that already has the offensive toolchain. Install Claude Code if you haven't:
npm install -g @anthropic-ai/claude-codenpm install -g @anthropic-ai/claude-codeMake an engagement directory and launch:
mkdir ~/extpt && cd ~/extpt
claudemkdir ~/extpt && cd ~/extpt
claudeFirst launch walks you through auth, and then you have an interactive agent in your terminal.
Step 2 β Install the plugin
/plugin marketplace add https://github.com/xcoy0te/Claude-ExternalPentest
/plugin install claude-extpt/plugin marketplace add https://github.com/xcoy0te/Claude-ExternalPentest
/plugin install claude-extptNo build step β it's all Markdown plus a small JSON manifest, so you can read every agent and skill before you trust it, and edit anything you want. After install you'll have the five /ext-* commands.
Step 3 β Preflight the toolchain
The agents drive external tools, so it's worth letting the ext-tooling-setup skill check what's present. The stack it expects: nmap, the ProjectDiscovery suite (subfinder, dnsx, httpx, naabu, nuclei, katana), ffuf/feroxbuster, testssl, sslscan, whatweb, wafw00f, smbclient, enum4linux-ng, gowitness, subzy, amass, sqlmap, nikto, and SecLists. A current Kali has most of it; the plugin notes and substitutes what's missing instead of silently skipping.
Step 4 β Define the scope
This is the most important step and the one that keeps the whole thing authorized. Before the agent touches anything, you tell it exactly what it's allowed to hit.
/ext-scope 203.0.113.10 app.example.com/ext-scope 203.0.113.10 app.example.comIt will ask for the things a real ROE needs: exact in-scope targets (and whether subdomains count or only the exact host), out-of-scope hosts and third-party/shared infrastructure, the testing window, permitted rate limits, forbidden actions (no DoS, no lockouts, no data exfil beyond proof), the objective, a stop/rollback contact, and the source IP the client should allowlist so your traffic is attributable. It does a light reachability ping only β no scanning here β and writes ./ext-engagement/scope.md with an explicit In scope (allowlist) and Out of scope (denylist). Every later agent enforces that file. This is the difference between an agent and a liability.
Step 5 β Recon and enumeration (read-only)
/ext-recon/ext-reconThe ext-enumerator runs the whole map-before-you-exploit sweep, quietest first: passive OSINT (ASN/IP ranges, cert transparency, passive subdomains, DNS and email posture, leaked secrets), then active discovery (host discovery β ports β service/version β TLS), then the web surface (httpx/whatweb, security headers, throttled content discovery and crawl, screenshots with gowitness), then safe per-service enumeration, subdomain-takeover and exposed-bucket checks, and finally a rate-limited nuclei detection pass mapped to the tech it found.
Everything is throttled and non-destructive β nmap -T3, capped rates, nuclei with the dangerous tags excluded. It writes raw output under ./ext-engagement/recon/, captured data under loot/, and a structured inventory.md, then hands back a summary: live hosts, ports/services with versions, web apps and tech, TLS/DNS/email issues, takeover and cloud findings, and candidate CVEs with a confidence rating. The kinds of things it surfaces on a typical external: an exposed /actuator/health, a forgotten staging vhost, TLS 1.0 still enabled, a dangling CNAME pointing at a de-provisioned bucket.
![placeholder β recon summary output: host/service counts and flagged exposures]
Step 6 β Let it reason about attack paths
/ext-attack-paths/ext-attack-pathsThis is the part that feels like magic, same as it did on the AD side. The ext-attack-planner reads the inventory and correlates services, versions, web findings and cloud exposure against known vulns, default creds, misconfigurations and takeovers. For each candidate foothold it gives you the concrete vector (service+version β CVE, exposed panel, WSTG-mapped web vuln, subdomain takeover, open bucket, leaked secret), the exact check or exploit command, the prerequisites and what would break it (WAF, patched build, MFA), the blast radius, and a provisional CVSS. Then it ranks them β most reliable, quietest, highest impact β and recommends a single first move.
And crucially, it plans only. Nothing runs. On our example host that might rank a subdomain takeover on a dangling asset (High), default creds on an exposed admin panel (High, but needs an auth attempt β flagged for confirmation), and a known CVE on a VPN portal version (detection-only until approved). Each is marked for whether it needs operator sign-off before the exploit operator will touch it. It'll also rule out techniques that don't fit the environment rather than trying them blindly.
![placeholder β attack plan output: ranked footholds with CVSS and the recommended first move]
Step 7 β Exploit one approved step at a time
/ext-exploit/ext-exploitYou pick a step from the plan and approve it. The ext-exploit-operator re-validates the target against the scope, states exactly what it's about to run and the expected effect, and β for anything intrusive or state-changing β waits for your explicit go-ahead. It prefers the least-intrusive proof of a finding: a benign PoC or a version confirmation over a weaponized exploit, unless the client authorized going deeper. It records the exact command, timestamp, target and result to loot/, then hands back. It does not chain into the next step on its own β you return to planning for the next move. You are never surprised by a write.
![placeholder β exploit operator confirming an action before running it]
Step 8 β Report
/ext-report/ext-reportThe ext-reporter synthesizes everything already collected β it does not re-scan or exploit. You get ./ext-engagement/report.md (and a self-contained, print-to-PDF-ready report.html on request) with an executive summary, scope and authorization, methodology, severity-ranked findings (each with CVSS, affected asset, evidence, reproduction, business impact and remediation), detection notes for the blue team, a remediation roadmap, an attack narrative, and a full command appendix. Every finding traces to a real artifact β it under-claims rather than inventing impact.
Secrets are handled the way they should be: recovered credentials go in a clearly marked SENSITIVE appendix by reference, report files with secrets get chmod 600, and nothing containing secrets is ever published to an external service. It hands over as a local file through the client's secure channel. It'll also produce variants β full, client-safe with secrets stripped, or an executive one-pager.
![placeholder β rendered HTML report with severity-color-coded finding cards]
Where the efficiency actually comes from
The honest pitch isn't "the AI finds bugs you can't." It's that the agent collapses the tedious 70% of an external test β the enumeration sprawl, the "did I check TLS on every host," the copy-pasting nuclei output into notes, the writing-up β into something you supervise instead of type. On the AD box, the bulk of my time was reading output and clicking approve, not running commands. External is the same shape: the agent keeps the methodology consistent across every host so nothing gets skipped because you were tired on host number nineteen, and the reporter turns your loot folder into a defensible deliverable while you're still thinking about the next foothold.
The guardrails are what make that trade acceptable on a paid engagement. Read-only recon, default-deny scope, no DoS, no lockouts, human confirmation before every intrusive action, attributable rate-limited traffic, and secrets that stay local. Those aren't bolted on β every agent enforces them, and I can read the Markdown to prove it.
Wrapping up
We took the same design that walked a domain controller and pointed it at the messier, higher-stakes problem of an authorized external test: scope it in writing, let it enumerate read-only, let it reason about paths, approve exploitation one step at a time, and let it write the report. It's on GitHub β xcoy0te/Claude-ExternalPentest β MIT licensed, no build step, contributions welcome.
Scope it tight, keep the human in the loop, and let the agent do the typing.