Autonomous Professional Penetration Testing Agent
WatchTowerPT is an AI-powered autonomous pentester built on the Claude Code SDK. It conducts full professional penetration tests against authorized targets — from initial reconnaissance through post-exploitation, credential harvesting, lateral movement, and final report generation.
Two interfaces are available: a local web UI (recommended for multi-target work) and a terminal TUI (for single-target, keyboard-first workflows).
| Feature | Description |
|---|---|
| Web UI | Local browser dashboard at http://127.0.0.1:7777 — multi-target sidebar, live feed, findings panel, intel tab, reports viewer, session management |
| Terminal TUI | Two-panel terminal UI — activity feed + live stats (findings, hosts, intel, active tool, VPN status) |
| PTES Methodology | 6-phase professional pentest (Recon → Enum → Vuln Analysis → Exploit → Post-Exploit → Report) |
| CPTS Methodology | HTB-style non-linear per-host state machine (DISCOVERED→SCANNED→ENUMERATED→EXPLOITED→PILLAGED→OWNED) |
| Red Team Mode | RCE-focused with prioritized 12-vector attack queue and full data collection playbook |
| Professional Reports | Auto-generated Markdown + HTML reports with CVSS scores, PoC commands, and evidence |
| Auto Evidence Capture | Every tool execution saved as HTML evidence file in the report folder |
| Multi-Target / Parallel | Run agents against multiple targets simultaneously with configurable parallelism |
| Bulk Import | Paste or upload a target list (target | instruction | type) to launch multiple engagements at once |
| Session Resume | Resume any prior session from the web UI or --resume flag — agent picks up where it left off |
| Exploit Verification | Second-pass agent independently confirms findings and eliminates false positives |
| Active Directory Mode | Full AD attack chain — kerbrute, AS-REP roasting, Kerberoasting, BloodHound, DCSync, PTH/PTT |
| Evasion Mode | Non-evasive / hybrid / evasive timing and fragmentation profiles |
| NordVPN IP Rotation | Auto-rotates source IP when agent detects blocking (WAF, rate-limit, CAPTCHA). Kill Switch respected — never disabled |
| Per-Host Tracking | Live compromise state per host with phase icons in dashboard |
| Lateral Movement Map | Tracks and reports every lateral move across the network |
| Artifact & Cleanup Tracker | Logs every file dropped on targets and cleanup status |
| Startup Tool Check | Checks 35+ pentest tools at launch and prints a table of what's missing with install commands |
| Auto Tool Install | During engagement, if a needed tool is missing the agent installs it automatically (apt/pip/gem/go) |
| Web UI Authentication | Password-protect the web UI with --web-password or WEB_PASSWORD env var — session cookie auth, 24 h TTL |
| Zero Telemetry | No analytics, no external logging, no data leaves your machine |
One command installs everything: Python check, Node.js 20+, Claude Code CLI, and WatchTowerPT with web UI support.
git clone https://github.com/trulybad/WatchTowerPT.git
cd WatchTowerPT
bash install.shFor VPS / headless servers (shows hosted startup command in the summary):
bash install.sh --vpsThe script handles all prerequisites automatically on Kali, Ubuntu, and Debian (amd64/arm64). After it finishes, skip to Authenticate with Anthropic.
If you prefer to install each component yourself:
Step 1 — System prerequisites
# Python 3.12+
sudo apt update && sudo apt install -y python3.12 python3-pip
# Node.js 20+ (required for Claude Code CLI)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash -
sudo apt install -y nodejsStep 2 — Clone the repository
git clone https://github.com/trulybad/WatchTowerPT.git
cd WatchTowerPTStep 3 — Install WatchTowerPT with web UI support
pip install -e '.[web]'If you get an
externally-managed-environmenterror (Debian/Ubuntu), run:pip install -e '.[web]' --break-system-packages
Step 4 — Install Claude Code CLI
npm install -g @anthropic-ai/claude-codeStep 5 — Verify
watchtowerpt --helpIf the command is not found, add ~/.local/bin to your PATH:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc && source ~/.bashrcRun the Claude Code CLI once to log in (first time only):
claudeFollow the login prompt. You need either an Anthropic API key or an active Claude subscription (Pro/Max/Team).
sh <(curl -sSf https://downloads.nordcdn.com/apps/linux/install.sh)
nordvpn login
nordvpn set killswitch onWatchTowerPT auto-detects nordvpn at startup — no extra flags needed.
Launch the local web dashboard:
watchtowerpt --webOpen http://127.0.0.1:7777 in your browser. The UI is plain HTML/JS with no external dependencies — works fully offline and in air-gapped environments.
To run WatchTowerPT on a remote server and access it from your browser:
# Bind to all interfaces on port 7777 with password protection
watchtowerpt --web --web-host 0.0.0.0 --web-port 7777 --web-password MySecret42Then open http://<your-server-ip>:7777 in your browser.
--web-host 0.0.0.0makes the server listen on all network interfaces instead of localhost only- Browser auto-open is automatically skipped when binding to a non-local address
- Always set
--web-passwordwhen exposing the UI over a network — see Authentication below - For internet-facing deployments, put WatchTowerPT behind a reverse proxy (nginx, Caddy) that terminates TLS
By default the UI is accessible without a password (safe for localhost). For hosted deployments, set a password:
# Via flag
watchtowerpt --web --web-password MySecret42
# Via environment variable (preferred for scripts)
WEB_PASSWORD=MySecret42 watchtowerpt --webWhen a password is set:
- A full-screen login form is shown on first visit and after session expiry
- Sessions last 24 hours (cookie-based,
HttpOnly,SameSite=Lax) - A Logout button appears in the header
- All
/api/*routes and the WebSocket reject unauthenticated requests with401/ close code1008
Note: Without HTTPS the password travels in plaintext over the network. For internet-facing deployments, put WatchTowerPT behind a reverse proxy (nginx, Caddy) that terminates TLS.
watchtowerpt --web --target 10.10.11.50The engagement starts automatically when the server opens, and you land directly on its feed.
┌─ Sidebar ────────┬─── Feed / Findings / Intel / Reports / Notes ──────┬─ Right Panel ─┐
│ ◈ WATCHTOWERPT │ Feed Findings Intel Reports Notes [Filter] │ Findings │
│ │ ────────────────────────────────────────────────── │ Critical 0 │
│ Targets │ 13:41:02 ● Starting reconnaissance… │ High 2 │
│ ● 10.10.11.50 │ ━━━━━ RECONNAISSANCE ━━━━━ │ Medium 1 │
│ running │ ▍ nmap ⟳ 14s │ │
│ ○ 192.168.1.0 │ $ nmap -sV -sC 10.10.11.50 │ Intel │
│ completed 3F │ ▍ nmap ✓ 1m 12s │ Creds 1 │
│ │ [open 22,80,443,8080] │ Data 2 │
│ 📋 Prior Sessions│ HIGH: CVE-2021-27065 — Exchange RCE │ Laterals 0 │
│ + New Engagement │ ━━━━━ EXPLOITATION ━━━━━ │ │
└──────────────────┴────────────────────────────────────────────────────┴───────────────┘
- Real-time agent output streamed over WebSocket — one persistent connection per target, all open simultaneously
- Phase separators divide the feed into phases (RECONNAISSANCE, ENUMERATION, etc.)
- Tool blocks are collapsible
<details>elements — auto-expand when running, auto-collapse on completion, showing command, elapsed time, and output - Finding banners (colour-coded by severity) are clickable — opens the full detail modal
- ★ Tag any message or finding to append it to the Notes tab (hover the item, click ★)
- Filter bar — real-time search across the feed (Ctrl+F)
- ⬇ Feed — download the full feed as a Markdown file
- ↓ Jump button — appears when you scroll up; click to return to live tail
- Click any tool output to copy it to clipboard
- Feed is automatically trimmed at 1 500 items to prevent memory growth on long runs
- Table sorted by severity with CVSS score column
- Severity filter — [All] [CRITICAL] [HIGH] [MEDIUM] [LOW] [INFO]
- Click any finding to open the detail modal: CVSS score, CVE reference (links to NVD), PoC command, PoC output, remediation
- ⬇ CSV / ⬇ JSON — export all findings for the active target
Live structured view of red team intelligence collected during the engagement — updated in real-time as events arrive.
Harvested Credentials — every [CRED] marker the agent emits appears here as a row with description, source host, and timestamp. Click ⬇ CSV to export all credentials.
Data Collected — every [DATA:TYPE] marker appears with a colour-coded type badge (CREDENTIALS, DATABASE, FILE, HASH, KEY, PII, CLOUD) and description.
Lateral Movement — every [LATERAL:src→dst] marker appears as a source IP → destination IP row with technique.
All three sections are collapsible. The Intel tab badge shows the total count of items collected. The right panel shows a live Intel summary (Credentials / Data items / Lateral moves) whenever any intel has been collected.
- Lists all
.mdand.htmlreport files for the active target - HTML reports open in a sandboxed iframe that fills the pane
- Markdown reports render in a styled inline viewer
- Report list auto-refreshes when the engagement completes
- Per-target notes auto-saved to
~/.watchtowerpt/notes/<target>.md - Notes persist across browser sessions
- ⬇ Export — download notes as Markdown
- Items tagged with ★ in the feed are automatically appended here
Single Target tab:
| Field | Description |
|---|---|
| Target | IP, CIDR, or URL |
| Operator Instruction | Extra context for the agent (optional) |
| Engagement Type | External / Internal / Web App / API / Red Team |
| Methodology | Blackbox / Greybox / Whitebox (activates CPTS prompt) |
| Evasion | Non-evasive / Hybrid / Evasive |
| Network Mode | NAT (bind shells, tunnels) or WAN (reverse shells) |
| Backend | Claude / OpenAI / Ollama |
| Attacker IP | LHOST for reverse shells |
| AD Domain / DC IP | Active Directory targeting |
| In-Scope | CIDR/hosts to stay within (one per line) |
| Out-of-Scope | Items to avoid (one per line) |
| Prior Work Path | Path to a prior report — agent resumes from there |
| Compact Prompt | Shorter system prompt (~65% fewer tokens) |
| Mask Targets | Replaces IPs with aliases before sending to cloud API |
Bulk Import tab:
Paste one target per line, optionally pipe-separated:
10.10.11.50
10.10.11.51 | Focus on AD exploitation | internal
192.168.1.100 | Web app audit only | web_app
https://api.corp.local | Test REST endpoints | api
Or click 📂 Load from file to upload a .txt/.yaml file in the same format. Common settings (methodology, evasion, network mode, backend) apply to all targets. A live preview shows parsed targets as you type.
Lists all saved engagement sessions with status, target, date, finding count, cost, phases completed, and model. Two actions per session:
- ↩ Resume — pre-fills the engage form with the session's target and passes
resume_session_idto the agent so it continues from where it left off. A blue banner in the form confirms what is being resumed. - ✕ Delete — removes the session file (with confirmation)
| Key | Action |
|---|---|
Ctrl+N |
New Engagement modal |
Ctrl+H |
Prior Sessions modal |
Ctrl+P |
Pause / Resume active target |
Ctrl+I |
Focus instruction input bar |
Ctrl+F |
Focus feed filter |
Ctrl+L |
Toggle scroll lock |
1 |
Switch to Feed tab |
2 |
Switch to Findings tab |
3 |
Switch to Intel tab |
4 |
Switch to Reports tab |
5 |
Switch to Notes tab |
Escape |
Close any open modal |
The server exposes a documented REST API alongside the UI:
| Method | Path | Description |
|---|---|---|
POST |
/api/engage |
Start a new engagement |
GET |
/api/targets |
List all active targets |
GET |
/api/targets/{id} |
Single target status |
POST |
/api/targets/{id}/pause |
Pause agent |
POST |
/api/targets/{id}/resume |
Resume agent |
POST |
/api/targets/{id}/stop |
Stop agent |
POST |
/api/targets/{id}/instruction |
Send instruction to running agent |
GET |
/api/targets/{id}/reports |
List generated reports |
GET |
/api/targets/{id}/notes |
Get operator notes |
POST |
/api/targets/{id}/notes |
Save operator notes |
GET |
/api/reports/{target}/{file} |
Serve a report file |
GET |
/api/sessions |
List all saved sessions |
GET |
/api/sessions/{id} |
Full session detail with findings |
DELETE |
/api/sessions/{id} |
Delete a session |
WS |
/ws/{target_id} |
Live event stream for a target |
GET |
/api/auth/status |
Check if auth is enabled and session is valid |
POST |
/api/auth/login |
Obtain a session cookie (password in JSON body) |
POST |
/api/auth/logout |
Invalidate session and clear cookie |
# Standard professional pentest (PTES methodology) — launches TUI
watchtowerpt --target 10.10.11.50
# Web UI — open browser dashboard
watchtowerpt --web
# Web UI with a pre-loaded target
watchtowerpt --web --target 10.10.11.50
# Red team mode
watchtowerpt --target 10.10.11.50 --red-team
# CPTS methodology (HTB-style, non-linear)
watchtowerpt --target 10.10.11.50 --methodology blackbox
# Multi-target parallel scan
watchtowerpt --targets-file scope.txt --max-parallel 5
# Resume a previous session
watchtowerpt --target 10.10.11.50 --resume abc12345--target <IP/URL> Single target
--targets-file <file> Multi-target from file (one per line)
--max-parallel <n> Parallel agent limit (default: 3)
--web Launch local web UI at http://127.0.0.1:7777
--web-host <host> Bind address (default: 127.0.0.1; use 0.0.0.0 for VPS)
--web-port <port> Web UI port (default: 7777)
--web-password <pwd> Password to protect the web UI (also: WEB_PASSWORD env var)
--instruction <text> Custom context for the agent
--model <model-id> Override LLM model
--red-team Red team mode (RCE + data collection)
--methodology <mode> CPTS methodology (blackbox / greybox / whitebox)
--evasion <mode> Evasion profile (non-evasive / hybrid / evasive)
--network-mode <mode> NAT (bind shells) or WAN (reverse shells)
--backend <backend> LLM backend (claude / openai / ollama)
--api-base <url> Custom API base URL (OpenAI-compatible)
--api-key <key> API key override
--ad-domain <domain> Active Directory domain
--dc-ip <ip> Domain controller IP
--attacker-ip <ip> LHOST for reverse shells and callbacks
--prior-work <path> Load prior engagement context
--resume <session-id> Resume a previous session
--compact-prompt Shorter system prompt (~65% fewer tokens)
--mask-targets Replace IPs with aliases before sending to cloud API
--max-context-turns <n> Rolling context cap (default: 50)
--no-verify Skip exploit verification phase
--vpn-rotate Force-enable NordVPN IP rotation
--vpn-country <country> Preferred country for VPN rotation
--non-interactive CLI mode (no TUI)
--raw Raw streaming output
--debug Debug mode
# External blackbox with evasion
watchtowerpt --target 10.10.11.50 --evasion hybrid
# Internal AD engagement (greybox, known domain)
watchtowerpt --target 10.10.10.0/24 --methodology greybox \
--ad-domain inlanefreight.local --dc-ip 10.10.10.1
# Red team with evasion and NAT mode (no inbound connections)
watchtowerpt --target 10.10.11.50 --red-team --evasion evasive --network-mode nat
# Web UI on a custom port with a pre-loaded target
watchtowerpt --web --web-port 8080 --target 10.10.11.50
# Web UI with password protection (for hosted deployments)
watchtowerpt --web --web-password MySecret42
# Web UI on a VPS — bind all interfaces so you can reach it from your browser
watchtowerpt --web --web-host 0.0.0.0 --web-port 7777 --web-password MySecret42
# Compact prompt + masked targets for privacy-sensitive cloud API calls
watchtowerpt --target 10.10.11.50 --compact-prompt --mask-targets
# Resume a prior engagement and continue from where it left off
watchtowerpt --target 10.10.11.50 --resume ab669387
# Focus only on SQLi (non-interactive, no TUI)
watchtowerpt --target 10.10.11.50 --non-interactive \
--instruction "Only test for SQL injection vulnerabilities"
# Ollama local LLM
watchtowerpt --target 10.10.11.50 --backend ollama \
--api-base http://localhost:11434 --model qwen2.5-coder:32b
# Force VPN rotation to a specific country
watchtowerpt --target 10.10.11.50 --vpn-country NetherlandsWhen nordvpn is installed, WatchTowerPT automatically enables source-IP rotation. No configuration needed.
How it works:
- The agent monitors all tool output for signs of IP blocking
- When detected, it emits a
[VPN:ROTATE:Country]marker - The controller disconnects from the current server and reconnects to the requested country
- The agent verifies the new IP and continues the engagement
Kill Switch: The tool never disables the NordVPN Kill Switch. During the disconnect→reconnect gap, the Kill Switch blocks all traffic — your real IP is never exposed. If the Kill Switch is off, WatchTowerPT will warn you at startup.
Signs of blocking the agent detects:
- HTTP 403/429 with WAF or rate-limit messages
- Connection refused/timeout that wasn't present before
- CAPTCHA challenges appearing mid-engagement
- Tools (sqlmap, ffuf, hydra) suddenly returning zero results
All output is saved to ~/.watchtowerpt/:
~/.watchtowerpt/
├── reports/
│ └── 10.10.11.50/
│ ├── 10.10.11.50_20260330_143022.md ← final report (Markdown)
│ ├── 10.10.11.50_20260330_143022.html ← final report (HTML)
│ └── evidence/
│ ├── 143025_bash.html ← per-tool evidence capture
│ └── ...
├── notes/
│ └── 10.10.11.50.md ← operator notes (web UI)
├── workspace/ ← agent working directory
└── sessions/
└── ab669387.json ← session persistence files
- Executive Summary with overall risk rating
- Scope & Methodology
- Attack Narrative
- Attack Path Visualization (SVG flowchart in HTML report)
- Host Compromise Chain (CPTS mode)
- Lateral Movement Map
- Credential Harvest
- Pivot Tunnels
- Findings (CVSS scores, CVE references, PoC commands, remediation)
- Data Collected (red team mode)
- Verification & Proof Chain
- Artifacts & Cleanup Tracker
- Evidence Captures appendix
The agent emits structured markers parsed in real-time by the controller and displayed in the UI:
| Marker | Purpose |
|---|---|
[PHASE:RECONNAISSANCE] |
Phase transition |
[FINDING:CRITICAL] Title |
Security finding (Affected / Evidence / CVSS / CVE / PoC / Remediation) |
[ENGAGEMENT:COMPLETE] |
End of engagement |
[ATTACK_STEP] Step N: Desc -> Next |
Attack chain step |
[VERIFIED:CONFIRMED] title |
Verification result |
[DATA:CREDENTIALS] desc |
Red team data collection |
[HOST:ip] EXPLOITED |
Per-host phase update |
[LATERAL:src->dst] technique |
Lateral movement event |
[PIVOT:ip] description |
Pivot tunnel setup |
[CRED] user:value — source |
Harvested credential |
[ARTIFACT:ip] /path — type |
Dropped file on target |
[CLEANUP:ip] /path — REMOVED |
Cleanup event |
[VPN:ROTATE] |
Request IP rotation (best available server) |
[VPN:ROTATE:Germany] |
Request IP rotation to specific country |
| Key | Action |
|---|---|
F1 |
Help |
F2 |
Toggle scroll lock (freeze feed) |
Ctrl+P |
Pause / Resume agent |
Ctrl+N |
Open / close notes panel |
Ctrl+F |
Search / filter activity feed |
Ctrl+T |
Tag selected feed item |
Ctrl+E |
Export tagged items to Markdown |
Ctrl+W |
Workspace manager (browse / resume / delete sessions) |
Ctrl+S |
Target scoping wizard |
Ctrl+R |
Generate report on demand |
Ctrl+M |
Network map view |
Ctrl+Q |
Quit |
↑ / ↓ |
Scroll activity feed |
Enter |
Send instruction (when paused) |
watchtowerpt/
├── core/
│ ├── agent.py # PentestAgent entrypoint
│ ├── backend.py # ClaudeCodeBackend (Claude Code SDK)
│ ├── config.py # PentestGPTConfig (Pydantic BaseSettings)
│ ├── controller.py # AgentController — lifecycle, evidence capture, VPN rotation
│ ├── events.py # EventBus pub/sub (STATE_CHANGED, TOOL, FINDING_DISCOVERED, CREDENTIAL_HARVESTED, DATA_COLLECTED, LATERAL_MOVEMENT, …)
│ ├── langfuse.py # No-op stub (zero telemetry)
│ ├── orchestrator.py # MultiTargetOrchestrator (parallel agents)
│ ├── session.py # SessionStore (~/.watchtowerpt/sessions/)
│ ├── toolcheck.py # ToolChecker — startup check + auto-install for 35+ tools
│ └── vpn.py # NordVPNManager — detection-based IP rotation
├── findings/
│ └── models.py # All dataclasses + regex extractors
├── interface/
│ ├── main.py # CLI entrypoint — routes to web / TUI / CLI / multi-target
│ ├── tui.py # Textual TUI app
│ ├── styles.tcss # TUI CSS
│ ├── components/
│ │ ├── activity_feed.py # Scrolling agent output
│ │ ├── dashboard.py # Live stats panel
│ │ ├── network_map.py # ASCII host topology view
│ │ └── splash.py # Animated splash screen
│ └── screens/
│ ├── wizard.py # Target scoping wizard
│ └── workspace.py # Session workspace manager
├── prompts/
│ ├── pentesting.py # PTES professional prompt
│ ├── redteam.py # Red team RCE-focused prompt
│ ├── cpts.py # CPTS non-linear methodology prompt
│ └── verification.py # False-positive elimination prompt
├── reporting/
│ ├── collector.py # ReportCollector
│ └── generator.py # Markdown + HTML report generator
└── web/ # Local web UI (requires [web] extra)
├── server.py # FastAPI app factory + uvicorn launcher
├── api.py # REST endpoints (/api/engage, /api/targets/*, /api/sessions/*)
├── state.py # Thread-safe AppState + TargetSession
├── ws_bridge.py # EventBus → WebSocket bridge (thread-safe via asyncio.Queue)
└── static/
└── index.html # Single-file SPA — vanilla JS, no CDN, air-gap safe
# Edit source
vim watchtowerpt/core/controller.py
# Syntax check
python -m py_compile watchtowerpt/core/controller.py
# Commit and push
git add -A && git commit -m "..." && git push origin main
# Deploy to /opt (requires sudo)
sudo bash /home/kali/Desktop/patch_features.shThis tool is for authorized security testing only. Only use it against systems you own or have explicit written permission to test. The authors accept no liability for misuse.
MIT License — see LICENSE.md.