AI-driven PTES workflow: open this repo with an agent that loads AGENTS.md, run the phase chain, and land a validated engagement under target/${ID}/ plus a client Report.
| Deliverable | Where |
|---|---|
| Engagement workspace | target/${ID}/ |
| Phase handoff | phases/XX-name/manifest.md + chain-status.md |
| Verified issues | vulns/vuln-NNN/ + Evidence |
| Client report | report.md (user-language body) |
Chain: 0 → 1 → 1b? → 2 → 3 → 4 → 5 → 6 (run 1b only when web ports exist).
Needs: Node.js, Docker (optional Kali), an agent that loads AGENTS.md.
cd pentester
npm run test:all
cd .agents/skills/pentester-playwright && npm run setup && cd -
# Wordlists (PentesterSpecialDict git submodule)
npm run setup:dicts
# node .agents/wordlists/ensure.js
docker pull kalilinux/kali-rolling # optionalSkills live in .agents/skills/ (do not commit host skill mirrors; see docs/agents/host-skills.md).
Open the repo root in your agent and state the target:
Pentest 192.168.1.100
Test https://app.example.com — scope is that host only
The agent should:
- Read
AGENTS.md/ROLE.md/ the current phase procedure - Phase 0: materialize workspace, clarify Scope and Authorization
- Wait until you confirm auth →
phases/00-pre-engagement/authorization.mdhas- status: confirmed - Run 1→…→6, writing Manifests and validating each handoff
No offensive work at phase ≥1 until Authorization is confirmed.
Chat, progress notes, and report.md body follow your language. Paths, CVE, VULN-NNN, schema keys stay English.
One engagement = one skill pipeline; schema.json gates keep it from skipping steps, dropping evidence, or going out of scope.
Force skill load at each phase entry (do not rely on description auto-match alone):
node .agents/skills/resolve-skills.js --id ${ID} --phase <0|1|1b|2|3|4|5|6> --write --strict
# Prints MUST Read / ON DEMAND — Read each MUST path before phase Steps
# Map: .agents/skills/skill-map.json · depth packs: .agents/skills/third-party/Phase order is serial (0→1→1b?→2→3→4→5→6); inside a phase, parallelize: independent / long / large-dict work must run as subagents. Main agent only orchestrates, keeps a live Task List, merges into Schema paths, and validates.
Long scans & big wordlists (full nmap, ffuf/gobuster, hydra, sqlmap, deep Playwright, …): no short timeout (0 or ≥3600s; Task List note 无 timeout). Spec: AGENTS.md / ROLE.md.
setup-tools → init-target → enum-services + recon (+toolkit)
→ playwright / src-hunter → threat-model
→ scan-ingest + src-hunter / playwright → exploit (+waf-bypass)
→ post-exploit → gen-report
| Phase | Main skill | What you / the agent do | Output |
|---|---|---|---|
| — prep | pentester-setup-tools |
Framework deps + wordlist submodule + DotSlash tools | ready |
| 0 kickoff | pentester-init-target |
Materialize workspace, Scope / Authorization | scope.md · authorization.md |
| 1 recon | pentester-enum-services · pentester-recon · toolkit |
Ports / services / fingerprint / OSINT | ports/ · services/ · recon-summary.md |
| 1b web | pentester-playwright · pentester-src-hunter |
Browser recon + web playbooks | function-map.md · screenshots |
| 2 threat model | pentester-threat-model |
STRIDE + Signals for Phase 3 | threat-model.md |
| 3 vuln analysis | scan-ingest · src-hunter · playwright + signal packs |
Scan → triage → verify + evidence | triage.md · vulns/vuln-NNN/ |
| 4 exploitation | pentester-exploit · playwright · waf-bypass? |
guard.js → PoC → access |
access.md · exploit-log.md |
| 5 post-exploit | pentester-post-exploit · toolkit |
Situational / privesc / lateral (scope-gated) | post-exploitation/* |
| 6 reporting | pentester-gen-report |
SKELETON → quality-gate → deliver | report.md |
Skill layers: pentester-* = phase adapters / Schema paths; third-party/* = technique depth (selected by resolve-skills from handoffs / Signals).
Wordlists: PentesterSpecialDict is a git submodule (evilc0deooo/PentesterSpecialDict). Run npm run setup:dicts or node .agents/wordlists/ensure.js before fuzz. Docker: /wordlists/PentesterSpecialDict/….
Throughout: pentester-knowledge-base (LOOKUP) · offensive commands through guard.js.
Two hard rules: ① no phase ≥1 until authorization: confirmed; ② deny_hosts / window / banned enforced by scope-check.js + guard.js.
Example: ID=lab1, scan_host=192.168.1.100, scan-env=docker.
node .agents/schema/materialize.js \
--id lab1 \
--host 192.168.1.100 \
--form IP \
--scan-env docker--form |
Use when |
|---|---|
IP / DOMAIN / URL |
How you identify the Target |
--scan-env |
Use when |
|---|---|
docker |
Tools in Kali container (target/lab1 → /target) |
host-kali |
Tools already on the host |
Then:
- Edit
target/lab1/phases/00-pre-engagement/scope.md(structured:allow_hosts/deny_hosts/window/banned) - Set
target/lab1/phases/00-pre-engagement/authorization.md→- status: confirmed - Complete phase-0 handoff summary fields in
target/lab1/phases/00-pre-engagement/manifest.md
Scope is now machine-checkable — gate before scanning:
node .agents/schema/scope-check.js lab1 --host 192.168.1.100(adeny_hostsmatch refuses and exits non-zero).
node .agents/schema/validate-target-schema.js lab1 --strict-summary --stamp-chainOptional container (also printed by materialize):
docker run -d --name kali-target-lab1 \
-v "$(pwd)/target/lab1:/target" \
-v "$(pwd)/.agents/wordlists:/wordlists:ro" \
kalilinux/kali-rolling sleep infinitynode .agents/schema/validate-target-schema.js --print-phase-map
node .agents/schema/validate-target-schema.js --print-session-packet 1
node .agents/schema/validate-target-schema.js --print-plan 1 \
--id lab1 --host 192.168.1.100 --scan-env docker
node .agents/schema/env-render.js --scan-env docker --id lab1 --host 192.168.1.100
eval "$(node .agents/schema/env-render.js --scan-env docker --id lab1 --host 192.168.1.100 --export)"
# One-screen engagement status (human view: phase / severities / coverage / next)
node .agents/schema/status.js lab1Execution steps live only in .agents/phases/ for the current phase. Do not copy legacy examples/DC-* layouts.
Follow phases/01-intelligence.md → ports/, services/, recon-summary.md, phases/01-intelligence/manifest.md.
node .agents/schema/validate-target-schema.js lab1 --strict-summary --stamp-chainIf handoff web_ports is non-empty → run 1b. If none and no 1b manifest → skip 1b.
Browser on the host; Evidence paths only from env-render:
eval "$(node .agents/schema/env-render.js --scan-env docker --id lab1 --host 192.168.1.100 --export)"
mkdir -p "$EVIDENCE_DIR" "$SCREENSHOT_DIR"
# pentester-playwright: scripts/poc.js runs /tmp scripts, screenshots under EVIDENCE_DIR
node .agents/skills/pentester-src-hunter/playbook.js --signal "unauth,info,idor"
# Read returned playbook paths — no invented payloadsThen phases/01b-web-pretest/manifest.md + validate/stamp.
| Phase | Procedure | Outcome to care about |
|---|---|---|
| 2 | 02-threat-modeling.md |
threat-model.md (priorities, not a vuln list) |
| 3 | 03-vulnerability-analysis.md |
Confirmed VULN-NNN + Evidence; triage ledger vulns/triage.md; threat coverage threat-coverage.md |
| 4 | 04-exploitation.md |
exploit-log.md, access.md |
| 5 | 05-post-exploitation.md |
post-exploitation/* inside Scope |
Phase 3 adds two auditable ledgers (validator-gated): every Raw scan result gets a disposition in
vulns/triage.md(handofftriaged_count); everypriority_threata disposition inthreat-coverage.md(handoffthreat_coverage). Raw scans / prioritized threats present but ledger missing →--strict-summaryfails.
node .agents/bin/lookup.js --phase 3 --keywords "sqli,ssrf"
node .agents/skills/pentester-src-hunter/playbook.js --signal "sqli,idor"
eval "$(node .agents/schema/env-render.js --scan-env docker --id lab1 --host 192.168.1.100 --export)"
# For a given VULN, point EVIDENCE_DIR at vulns/vuln-NNN/evidenceEnd every phase with:
node .agents/schema/validate-target-schema.js lab1 --strict-summary --stamp-chain- Fill
target/lab1/report.mdfrom.agents/REPORT-SKELETON.mdin the user language - Cite real relative Evidence paths in backticks
- Optional wording only:
knowledge/reporting/report-wording-depth.md
# Assemble data sections (findings table / risk / Evidence index / coverage) — you write narrative
node .agents/schema/assemble-report.js lab1 # paste under SKELETON 1.3 / 5 / 8
node .agents/schema/check-report.js lab1 # also fails if the report omits any Verified Vulnerability
node .agents/schema/validate-target-schema.js lab1 --strict-summary --check-report --stamp-chain
# Expect next_phase: done
# Client delivery bundle (attestation + index → Report / Evidence)
node .agents/schema/deliver.js lab1 # writes target/lab1/delivery/
# Remediation retest (when this run re-tests a prior engagement): fixed / still-open / new
node .agents/schema/retest.js --baseline OLD_ID --current lab1 --write□ Products under Schema paths (no forbidden paths)
□ Manifest: backtick paths + handoff summary keys
□ Authorization confirmed for phase ≥1
□ validate --strict-summary [--stamp-chain] green
□ Reusable methods → knowledge-base / PTES-INDEX
□ Temps cleaned; progress in user language
| Goal | Command |
|---|---|
| Materialize | node .agents/schema/materialize.js --id ID --host HOST --form IP --scan-env docker |
| Validate + stamp | node .agents/schema/validate-target-schema.js ID --strict-summary --stamp-chain |
| Phase map | … --print-phase-map |
| Session packet | … --print-session-packet [N] |
| Phase plan | … --print-plan 1 --id ID --host HOST |
| Env / Evidence | … env-render.js … [--export] |
| Scope gate | … scope-check.js ID --host HOST |
| Engagement status | … status.js ID |
| Assemble report data | … assemble-report.js ID |
| Report quality | … check-report.js ID |
| Delivery bundle | … deliver.js ID |
| Retest diff | … retest.js --baseline OLD --current ID --write |
| LOOKUP | node .agents/bin/lookup.js --phase N --keywords "…" |
| Playbook | node .agents/skills/pentester-src-hunter/playbook.js --signal "sqli" |
| Tool resolver | node .agents/tools/resolve.js --id ID --phase N --scan-env ENV |
| Tool install | node .agents/tools/ensure.js --scan-env ENV --id ID --install TOOL |
| Full tests | npm run test:all |
AGENTS.md # orchestration entry
.agents/phases/ # how to run each phase
.agents/schema/ # paths + validation
.agents/skills/ # tool adapters
.agents/tools/ # tool catalog + resolver + DotSlash provisioning
.agents/knowledge/ # LOOKUP corpus
.agents/REPORT-SKELETON.md
examples/schema-mini/ # minimal golden fixture (fast contract check)
examples/DC-1-engagement/ # realistic golden fixture (real grammar + toolchain smoke)
target/${ID}/ # this engagement
| Skill | When |
|---|---|
pentester-init-target |
Phase 0 |
pentester-enum-services |
Phase 1 plan |
pentester-toolkit |
DotSlash tool provisioning (.agents/tools/) |
pentester-scan-ingest |
scanner output → Triage ledger |
pentester-threat-model |
Phase 2 STRIDE + Signal (checkable) |
pentester-src-hunter / pentester-playwright |
Web / Evidence |
pentester-post-exploit |
Phase 5 post-exploitation (scope-gated) |
pentester-gen-report |
Phase 6 |
pentester-knowledge-base |
LOOKUP / tier-1 write |
pentester-setup-tools |
deps |
pentester-knowledge-import |
maintainer offline only |
- Validate fails — missing files, summary keys,
pendingAuthorization, empty Evidence dirs, broken citations. Fix under--strict-summarybefore--stamp-chain. - 1b? — required when phase-1
web_portsnon-empty. - Report language — same as the user; keep technical IDs English.
- Huge knowledge trees — use LOOKUP only; externalize bulk via
KNOWLEDGE_ARCHIVE_ROOT(docs/agents/archive-locality.md). - DC- examples* —
DC-1/DC-2are legacy pre-schema captures (report reference only), don't copy their layout. For a realistic conforming workspace, readexamples/DC-1-engagement/(examples/README.md).
Only inside Scope + confirmed Authorization. Reconfirm before destructive ops. Redact secrets from reports and knowledge.
AGENTS.md · .agents/ROLE.md · .agents/phases/ · CONTEXT.md · docs/adr/ · docs/agents/host-skills.md · docs/agents/archive-locality.md
License: LICENSE.