Skip to content
Back to skills

Pt Workflow

BSecurity

Autonomous pentest campaign driver. Runs a scoped engagement end to end with no operator approvals - the deterministic driver (scripts/campaign.py) owns pass state, generates the killchain board from recon, and prints the exact next action (Skill + tool) every turn. Use when starting or resuming a pentest, "run the pt workflow", "work this CIDR/domain", or when handed a client SoW/scope to reach a stated objective or domain admin. Single agent, refuter-verified, wiki-first, tool-first. Delive...

  • 323 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 19, 2026
ai-agentspythonrustgoshellbashapi

Works with

  • cli
  • api
  • mcp

Security analysis

B75/100
  • criticalAccesses sensitive system or user directories

Pro shows the line behind each finding and how to fix it

Scanned September 19, 2026

npx -y skills add Encod3d-Sec/TORCH --skill pt-workflow --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Pt Workflow?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Pt Workflow
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/encod3d-sec-pt-workflow/badge)](https://www.skillsdirectory.com/skills/encod3d-sec-pt-workflow)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: pt-workflow
description: Autonomous pentest campaign driver. Runs a scoped engagement end to end with no operator approvals - the deterministic driver (scripts/campaign.py) owns pass state, generates the killchain board from recon, and prints the exact next action (Skill + tool) every turn. Use when starting or resuming a pentest, "run the pt workflow", "work this CIDR/domain", or when handed a client SoW/scope to reach a stated objective or domain admin. Single agent, refuter-verified, wiki-first, tool-first. Deliverable is a client report.
---

# pt-workflow

The driver is the plan. Run one command, do exactly what it prints, record the result, repeat. The
gates are enforced by `scripts/campaign.py`; follow its output literally.

## The loop

```
python3 scripts/campaign.py next
python3 scripts/campaign.py note <row> --arsenal <slug>
python3 scripts/campaign.py done <row> --poc <img> --kind req   # | --dead R | --park Q | --find F
```

## Start / resume

1. `python3 scripts/campaign.py init --type pt` - validates `scope.md` + envelope, repairs
   type/schema. An empty `scope.md` must be filled from the client SoW first (CIDRs, domains, RoE,
   lockout policy). The lockout policy and any destructive-op limits live in `scope.md`, not here.
2. Passes 1-3 feed `state.md` - rustscan/nmap/nxc/LDAP/kerbrute/BloodHound per the recon defaults,
   which yield to `scope.md`'s allowed tooling. Read service output end to end.
3. `python3 scripts/campaign.py board` - writes the 4a rows (plus 4b lateral/privesc/DCSync for the
   pentest approach). Refuses on empty state.
4. Enter the loop, depth-first, one open row at a time.
5. **When a shell/session lands on a host** (reverse shell via `vm-scan.sh --win shell`, or
   meterpreter via `--win msf`), record it: `python3 scripts/campaign.py foothold <host> --win shell`
   (or ride it on the closing find with `done ... --win`). The driver flips that host's `state.md`
   row to `access=foothold`, routes its 4b lateral/privesc rows through `vm-rsh --win <win>`
   (persistent session + operator visibility), and prints `tmux attach -t <eng>` for takeover.

## Gates

Same as the shared driver: G1 arsenal-first, G2 skill-first, G3 typed evidence, G8 tool-first. AD
attacks route through `Skill(hunt-ad)`; local privesc through `Skill(hunt-windows)` /
`Skill(hunt-macos)`; the driver names which per row.

## Autonomy

No approvals. Out-of-envelope work parks to `decisions.md`; the loop never blocks. A spray is gated by
the lockout policy in `scope.md` (the envelope), never attempted blind. Destructive AD operations
(Zerologon and similar) park unless the envelope authorises them.

## Model routing

Explicit per-role model assignment (the driver enforces the verifier gate; the rest is operating policy):

- **Main brain - Opus 5 1M:** the `campaign.py` loop, board/state, strategy, Burp/chrome-devtools, finding write-ups. This session.
- **Verifier - Opus (fresh context), MANDATORY:** before any CONFIRMED, `campaign.py verify <F>` prints an Opus refuter prompt; dispatch ONE fresh Opus agent that reads the raw PoC, tries to REFUTE, and writes `verdicts/<F>.json`. `done --find` refuses unless that verdict exists, is `refuted:false`, and cites the finding's PoC (anti-rubber-stamp). Fails CLOSED.
- **RTL - Opus (fresh context):** `Skill(redteamlead)` for direction at a fork or when a vector stalls.
- **Short tasks - Haiku:** `Skill(wiki-arsenal)` deep, `Skill(delegate)` (mechanical exploit-run), `Skill(ingest)` recon-parse. Bounded, fully-specified, single-shot ONLY.

The line that keeps quota safety: Haiku is allowed for a **bounded single job**, never for open-ended parallel hunting.

**Manual login / MFA the agent cannot do headlessly** (Smart-ID, an SSO/MFA prompt, a CAPTCHA) -> `Skill(chrome-devtools-browser)`: a VISIBLE chromium on the VM desktop (`scripts/browser-visible.sh`) the operator logs into, driven + observed live via the chrome-devtools MCP to capture the authenticated session + real API calls.

## Discipline

- Do NOT invoke `superpowers:brainstorming`/`writing-plans` mid-run; keep no parallel task list.
- Model routing (see `## Model routing`): Opus-1M drives; Haiku for bounded short tasks; the mandatory
  Opus **verifier** gates every finding via `verdicts/<F>.json`. No open-ended hunter fan-out.
- Load-bearing requests through Burp when reachable; degrade to `capture.sh req` otherwise.
- Scope, lockout policy and destructive-op limits come from `scope.md`.
- **RCE-first:** when >1 vector is open, take the one that yields code-exec first - it is the attack
  vector that carries impact; chase lower-impact classes only after code-exec is ruled out or the
  objective needs them (the driver ranks code-exec rows first).
- **Read whole, not grep:** when a sudoer has no findable password and cron/writable/SUID/group
  vectors dead-end, READ `/etc/pam.d/{sudo,su}` + `/etc/sudoers.d/*` whole - a `pam_ssh_agent_auth`
  (hijack a forwarded agent socket -> passwordless sudo), `pam_exec`, or bare `NOPASSWD` line IS the
  vector; read linpeas output WHOLE, a keyword grep skips the tell. See [[linux-privesc]].
- **Long tools:** run pspy/linpeas/tcpdump via `bash scripts/vm-bg.sh <eng> <win> '<tool>'`
  (stages to `/dev/shm`, runs in the stabilized shell, `--read`/`--wait 120` the logfile); never
  hand-roll a backgrounded watcher, and never retry a broken tool pattern >2x - switch method or
  call `Skill(redteamlead)`.

## Close-out

Run the printed chain: `Skill(triage)` -> `Skill(evidence)` -> `Skill(report)` -> `Skill(learn)`.
**The pentest deliverable is a client report**, not a CTF walkthrough. The report generator must run
with `PATH=/opt/prep_report/.venv/bin:$PATH` or every finding loses its severity callout box.

## If the driver is unavailable

Manual fallback: read `Approach.md`, take the top open row for the current host, run its wiki lookup
then its hunt skill, capture `req` evidence, mark `[x]`; on exhaustion one `Deadends.md` line + `[!]`.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.