| Operation | Action |
|---|---|
| Query | qmd_query "..." via wiki-search MCP -> read results -> synthesise |
| Ingest skip check | Read frontmatter only; skip page if ingest slug already in sources: |
| Re-index / wiki status | wiki skill |
| Git clone | Always WSL: wsl -d kali-linux -u kali -- git clone <url> /home/kali/<name> |
| Run tooling against a target | Kali VM over SSH: bash /root/vm.sh '<cmd>' (VPN route + tools + chromium live there) -> docs/virtual-machine.md |
| Task | Use |
|---|---|
| Multi-step planning | superpowers:brainstorming then superpowers:writing-plans |
| Execute a plan | superpowers:subagent-driven-development |
| Debug unexpected behavior | superpowers:systematic-debugging |
| About to claim done | superpowers:verification-before-completion |
Write/edit vault .md |
obsidian:obsidian-markdown |
| Fetch URL for ingest | WebFetch tool |
| Read vault file | Read tool with machine path (see below) |
| Search vault | qmd_query (semantic) or qmd_search (keyword) via wiki-search MCP |
| Maintain wiki index (re-index, status) | wiki skill |
| Load engagement playbook / FIND schema | Read targets/TARGETS.md |
| Audit CLAUDE.md (full review) | claude-md-management:claude-md-improver |
| Update CLAUDE.md (targeted session learnings) | claude-md-management:revise-claude-md |
| Session end / pause work | gsd:pause-work (optional plugin) or the manual pause-work steps |
| Parallel independent tasks | superpowers:dispatching-parallel-agents |
| Run a full bb/pt/ctf engagement autonomously | bb-workflow / pt-workflow / ctf-workflow skill (driver: scripts/campaign.py; the single source of truth for the execution loop) |
| Check the workflow driver is set up on this machine | campaign-health skill (scripts/campaign-doctor.py) |
| About to attack a web endpoint | hunt-<type> skill (see auto-triggers below) |
| Driving a web target through Burp (proxy-history triage, Repeater/Intruder/Collaborator) | hunt-burp skill (Burp MCP; setup [[burp-mcp]]) |
| Starting recon on any target | wiki-recon skill |
| Manual login / MFA the agent can't do headlessly (Smart-ID, Mobile-ID, captcha) + drive & observe via CDP | chrome-devtools-browser skill (visible chromium on the VM via scripts/browser-visible.sh + chrome-devtools MCP) |
| Manual login / MFA the agent can't do headlessly (Smart-ID, Mobile-ID, captcha) + drive & observe via CDP | chrome-devtools-browser skill (visible chromium on the VM via scripts/browser-visible.sh + chrome-devtools MCP) |
| Validating / moving finding to Completed | triage then evidence skills |
| Vuln/CVE research on a target (binary/repo/app/firmware) | research skill (scaffolds raw/research/<project>/) |
| Hand a fiddly, fully-specified exploit-compile/escalation run to a sub-agent | delegate skill (autonomous sub-agent exploit-run; false-root/hostname guardrail mandatory) |
| Drive msfconsole (recon, exploit search/run, reverse shells, post-ex) | metasploit skill (msfconsole framework-driver; cheatsheet [[metasploit]]) |
Vault-local skills live under skills/: skills/hunt/ (the hunt-* vuln-class skills + the shared hunt-core spine every hunt assumes), skills/workflow/ (engagement PROCESS skills: arsenal/wiki-arsenal, triage, evidence, coverage, ingest, next-move, wiki-recon, nday, research-ingest, delegate, metasploit, ctf-box, ctf-category, screenshot, chrome-devtools-browser, learn, walkthrough), skills/burp/ (hunt-burp + screenshot-burp, the Burp MCP driver + Repeater-PoC capture; driver scripts in scripts/burp/, host setup in setup/burp/), and the standalone wiki/, research/, disclosure/, code-review/. They load on demand via the Skill tool (descriptions in the /skills picker), discovered by basename so directory placement is organizational only. arsenal delegates to wiki-arsenal; the hunt-* skills inline their own qmd_query and assume hunt-core. claude-md-improver/ is an offline fallback for the claude-md-management plugin. MCP/hook/plugin troubleshooting: skills/skills-setup.md.
Search rule: never read wiki/index.md to find pages - always search first. MCP tool names: mcp__wiki-search__qmd_query (semantic), mcp__wiki-search__qmd_search (keyword).
session/memory.md holds long-term editorial patterns. Load it when making editorial or tagging decisions.
The hunt-trigger.py UserPromptSubmit hook matches your prompt against skills/hunt/triggers.json (single source of truth): an explicit vuln-type term injects a MANDATORY Skill(<hunt>) directive, a surface term (e.g. "login form", "upload field") a softer "consider Skill(...)". Treat a hard directive as a real instruction unless genuinely irrelevant (say why in one line). When you SKIP a fingerprint-routed hunt (correctly, or because another hunt already covers it), write the one-line reason to targets/<eng>/log.md (or Deadends.md) so the close-out drift-count separates a real miss from a correct skip. Edit triggers.json to change mappings, not this table; full mechanics (incl. leak-safe telemetry) in docs/auto-triggers.md.
Vuln-type rows (SSRF/XSS/SQLi/IDOR/RCE/auth/federation/injection/m365/vpn -> matching hunt skill) live in triggers.json, fired by the hook. Only the model-judged rows remain here:
| Condition | Skill |
|---|---|
| Starting recon on target (subdomains, endpoints, surface) | wiki-recon |
| "Is this valid?", "should I report?", finding needs confirmation | triage |
| Moving finding Research -> Completed | triage then evidence |
Engagement workflow (the driver is the plan). For any bb/pt/ctf engagement run Skill(bb-workflow),
Skill(pt-workflow), or Skill(ctf-workflow). 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. It is the single source of truth for the discipline this section describes: it ENFORCES as
gates G1 wiki/arsenal-first, G2 skill-first, G3 typed evidence, G4 deadend-first, G5 depth-first, G7
no-ask, G8 tool-first, plus pre-board recon (passes 0-4), the read-whole gate, the effort-ceiling stop
condition, OOB and two-account readiness, ban control, and budget/report-only. When it runs, follow its
next output literally. Health check on a new machine: Skill(campaign-health).
Execution loop (per offensive step, ALWAYS). The hooks are advisory and can misfire or go silent
(e.g. when the wiki-search MCP drops). During a campaign the driver above is the enforcement and the
steps below are what it sequences; off-campaign (driver unavailable, or a quick manual engagement) run
each step in order yourself, do not skip under momentum:
0. Board-first. Work targets/<eng>/Approach.md (the plan board) one open item ([ ]/[~])
at a time, marking [x] as each lands. In a campaign the driver generates this board and enforces
its gates: no exploit before the row's arsenal card (G1), no [x] without a poc/ image (G3), and
an exhausted vector goes [!] + one Deadends.md line then you move to the next open item, never
re-running [!] (G4); off-campaign, honor the board's own GATE 1/2/3 lines by hand.
Deliberately-off-board work is legitimate (following a writeup, or post-foothold manual
exploitation the driver can't plan): acknowledge a drift-guard nudge ONCE and continue, do
not re-run campaign.py next on every fire. The hook now backs off on its own (fires at streak
1-3 then rarely, silent post-foothold and post-SOLVED), so a repeated nudge is not expected.
- Wiki-first, reference-map before qmd (qmd is ~15-30s, so it is hint-driven). Before exploiting
a fingerprinted service/class: (a) FIRST read the mapped pages directly - the hunt skill's
## Wikisection (domain MOC + primary page + anchors) and one-hop from the MOC. That is an instantReadand answers the anticipated case with zero qmd latency. (b) Fireqmd_query/qmd_search(via thewiki-searchORcaveman-shrinkMCP) ONLY when you have a concrete hint the map does not cover - a specific sink/version/CVE, an observed escape (a<script>context, an SSRF-reaching function). Each call is slow, so it is a targeted deepen, not a blanket pre-attack step; equally, do NOT hand-roll from memory when a targeted qmd would answer.Skill(wiki-arsenal)still gives the fast parallel lookup ("deep" for the synthesized card). MCP-independent fallback:bash scripts/wiki-query.sh "<tech> exploit"(-kfor an exact CVE/tool string) wraps the SAME index. NEVER degrade to ad-hoc grep or skip the wiki. - Tools, not hand-rolls; then READ the output whole. Reach for the installed tool
(nmap/ffuf/nuclei/httpx/nxc/sqlmap/borg/...), never a hand-rolled
curl//dev/tcploop; if none fits, say why in one line. Enumerate NON-STANDARD installed tools (borg/borgmatic/restic/duplicity, backup + secret managers) as a loot/privesc lead - a leaked backup passphrase + a reused key beats grinding a hardened-container escape. Then READ what it returns END-TO-END - the full scan output, every fetched source /.js/ inline<script>/ buttononclick/href, each response - never let a keyword grep BE the read (just as step 1 never degrades wiki-lookup to grep). The initial attack vector repeatedly hides in an AJAX handler / commented route a narrowgrepskips. - Capture the request AND each landing, live.
capture.sh reqthe real request+response for every exploit/lead request, and screenshot each success topoc/the moment it lands (capture.sh ev/capture.sh tmux/shot.py), never at the end. Evidence is captured live now (no auto-card staging). NEVER hand-write / fabricate an evidence card. - Persist immediately. A host/cred/path/flag lands -> write
state.md/loot.md/Killchain.mdbefore the next move; a dead-end -> oneDeadends.mdline. - Close out. Objective landed (both flags, or a target-severity finding) -> set
## STATUS: SOLVEDin state.md at once, then run the per-type close-out chain the driver prints (campaign.py'scloseoutconfig, echoed by the bb/pt/ctf workflow skill). Run it exactly as printed.
Token control and real findings come from the same rule: do not repeat work.
- Scope-first. Read
targets/<eng>/scope.mdbefore acting. Never touch an out-of-scope target or use forbidden tooling (no_bruteforce/no_dos/passive_onlyflags). Thenext-moveanalyzer already filters out-of-scope hosts and suppresses spray/active probing per RoE; respect the same bounds in everything else. - State-first. Before any recon, spray, or exploit attempt, read the active engagement
state.md,loot.md,Killchain.md, andDeadends.md. Never re-run a documented dead-end or re-spray a known-failed cred without new input (new cred, new pivot, new payload class). - Stop condition. A vector is exhausted after a bounded effort (e.g. OOB sink: ~30-40 payloads zero callbacks; spray: full user x pass matrix once). On exhaustion: append one line to
Deadends.md+ updateKillchain.mdstatus, then switch vector. Do not grind, do not re-loop. - When stuck, call
Skill(redteamlead)BEFORE grinding (recurring, expensive miss). Two mechanical tells that a vector is the WRONG DOOR, not that the tooling needs another pass: the target starves under your own exploit loop (repeated000/timeout/empty-reply = you are DoSing it), or >=2 verified hashes fail the primary wordlist (the creds are out-of-band: an email/note/KeePass, a config, a second service). At either tell - or any "I'm stuck / which vector / should I keep hammering this / where do I go" - callSkill(redteamlead): it reads state+evidence+wiki and returns ranked directions with an explicit STOP. Engineering around a hostile channel (per-char verify-fix, min-of-2 sampling, gentler pacing) IS the tell you are on the wrong vector, not a reason to keep going. A/redteamleadreminder in the engagement prompt is a real instruction, not optional; not calling it while stuck for hours is a documented failure (a recent box: hours lost to a box-crashing blind-SQLi hash-grind while the real foothold was an unenumerated file-read/LFI - one RTL call would have surfaced it). The vector-doubt + widenrecon-capture.pynudges now surface this automatically. - Capture as you go. After a recon/cred tool runs, extract results into
state.md/loot.mdimmediately (state-first discipline: capture the moment a tool returns). Prose in chat is lost; tables persist across sessions and devices. - Tooling-first. Use the installed tool (nmap/ffuf/nuclei/nxc/linpeas), not a hand-rolled bash reimplementation - better output, fires the fingerprint router, and
recon-capture.pysnaps it to evidence. Hand-rolled bash only when no tool fits (say why). Enforced by thectf-box+hunt-*skills, not a runtime hook. - Read-first (recon AND post-foothold source-review), not grep. Before declaring any page/endpoint/file enumerated, READ its full source end-to-end: every
.jsbundle + inline<script>, every buttononclick/href, every returned response/config. A keyword grep is NOT a read: the initial attack vector repeatedly hides in an AJAX handler / commented route / alternate endpoint that a narrowgrep <keyword>skips (THM Buzz: the/fetchpickle sink lived in an unopeneddropdown.js). Use grep to LOCATE inside a huge file, then read the surrounding block; never let grep BE the read. This holds post-foothold, not only in recon: reading an app/service's SOURCE for the next hop (a route, a token, a sink) is a full top-to-bottomcatof each source file, not agrep -oE '<keyword>'mine of it (grep-mining a 271KBucp.jsfor token strings instead of reading it whole is the exact recurring miss). When you DELEGATE a gather/enum task to a sub-agent, the delegation prompt MUST carry this mandate verbatim -cateach source file in full, grep only to locate then read the block - because a cheap model defaults to grep-mining and skips the sink, and your prompt (not this file) is what governs it. Enforced by thectf-box+wiki-reconskills and by your own delegation prompts, not a runtime hook. - OOB-gate blind bugs. Blind SSRF/SSTI/SQLi claims need an out-of-band callback, never inference. Enforced per hunt skill.
- Delegate exploit EXECUTION to a haiku sub-agent (cost control, default). Opus stays on strategy, the board, wiki-first analysis, triage, and next-move; the fully-specified exploit/PoC/escalation RUN (copy-paste run, compile, spray, shell-driving, endpoint grinding) goes to a cheap haiku via
Skill(delegate)- dispatch, wait (no parallel duplicate), integrate the result. Don't burn Opus tokens hand-running exploit loops yourself. When the hand-off reads source/config, spell out read-first IN THE PROMPT (fullcatof each file, grep only to locate) - a cheap model grep-mines by default and your prompt is its only law. And a sub-agent's NEGATIVE ("empty/dead/rabbit-hole") is a HYPOTHESIS, not a fact: re-verify it yourself before it becomes a hard[!]/Deadends exclusion, doubly so when it gates the last open vector - a cheap model's "empty" is often a query/tooling mistake (a real miss: a haiku agent's "UCP voicemail empty" - it hit the AJAX endpoint, not the dashboard WIDGET that rendered the secret - got fossilized into "UCP=rabbit hole" and cost an hour+ chasing a nonexistent pspy/cron path). Delegate MECHANICAL/wait-heavy runs (pspy wait, brute, fixed-payload flag-read) to haiku; keep JUDGMENT-heavy enumeration (route/token discovery, "is this empty or am I querying it wrong") on the main model. - Reuse loot. Reuse captured creds across
state.mdhosts before researching new ones. Default/known creds first (look up vendor defaults via context7, see [[default-credentials]]); broad spraying of captured creds is a last resort, not an early or auto move. - Distill reusable knowledge. When an engagement yields a default cred or a reusable API request pattern, add the generic form (product + cred / endpoint + impact, no client specifics) to
wiki/cheatsheets/default-credentials.mdorapi-request-findings.md. Next engagement, check these first. Client specifics stay intargets/<eng>/. At close-out,Skill(learn)sweeps the whole completed engagement for any generic lesson still missing fromwiki/and promotes the delta through the leak-gated stage (wiki-stage.py) -> promote (wiki-promote.py) pipeline; run it once the engagement isSOLVEDand its walkthrough is assembled.
Output/mode plugins installed: ponytail (lazy-code discipline - YAGNI, stdlib/native first, shortest working diff) auto-activates at SessionStart via its own hook (level full; switch with /ponytail lite|full|ultra), and governs what you build, not prose. caveman (prose compression - terse output, drop articles/filler, fragments OK) is manual per session via /caveman.
SessionStart also auto-loads session/hot.md. No manual reads needed.
Engagement-state hooks (live via ~/.claude/vault-hooks symlink -> skills/hooks/). All fail open (any error -> allow, never trap). Policy: deterministic guards ENFORCE (deny the tool call); semantic reflexes ADVISE (inject a suggestion). Enforcement is reserved for no-judgement checks (scope/RoE) where blocking the wrong action costs zero tokens; judgement calls (wiki-first, tools-not-manual, intended-path) stay advisory because a false block wastes more time than it saves. Escape hatch for a bad block: touch skills/hooks/.enforce-off. Full mechanics in docs/auto-triggers.md; the behaviorally-relevant summary:
| Hook | Event | Effect |
|---|---|---|
engagement-init.py |
SessionStart | Self-heals the engagement file set; injects state summary + top next-moves + session cache + OOB HITs + drift warnings. |
hunt-trigger.py |
UserPromptSubmit | Routes to hunt skills from triggers.json (surfaces the relevant Skill; the skill carries the mandate); leak-safe telemetry to .trigger-fire.jsonl. Skips injected/non-prompt content. |
recon-capture.py |
PostToolUse/Bash | Routes detected tech -> the hunt Skill (playbook.json), auto-correlates OOB callbacks (waiting -> HIT), and fires a once-per-engagement GATE-1 wiki-first nudge when an exploit-shaped command runs while Approach.md Weaponize is undone. Framework-meta guard suppresses false fires. Advisory. |
scope-guard.py |
PreToolUse/Bash | ENFORCES (denies the command) on out-of-scope host/IP (CIDR-aware) or RoE-forbidden tooling. Fail-open; .enforce-off marker downgrades to advisory. |
session-guard.py |
PreToolUse/Write | Warns when a write would put a client marker into a generic session/* file. Advisory, never blocks. |
Register/repair the set per-device with bash setup/install-hooks.sh; engagement-init warns at SessionStart if a hook is unregistered (canonical set in scripts/check-hooks.py).
Active engagement set by targets/active.md. Create one with bash setup/new-engagement.sh <name> <pentest|bugbounty|ctf>. Per-type schema from setup/templates/<type>/; engagement_type in state.md frontmatter drives analyzer + self-heal. Pentest/bugbounty files: targets/<eng>/{state,loot,Killchain,Approach,log,scope,walkthrough,eval,Vuln-index,Deadends,oob}.md + ingest/ + poc/ (curated exploit/PoC/flag shots) (all self-healed by engagement-init). ctf files (lean, live-loop only): targets/<eng>/{state,loot,Approach,scope,Deadends}.md + ingest/ + poc/; Killchain.md/log.md stay pentest/bugbounty-only artifacts (a ctf's live attack chain lives in state.md's ## Chain/## Status sections instead), and walkthrough.md/eval.md/decisions.md self-create on demand at their trigger (close-out/Skill(learn)//redteamlead) rather than being scaffolded upfront. eval.md = per-engagement AGENT self-assessment (tokens/time/drift estimates), filled at close-out by Skill(learn). Approach.md = the wiki-wired plan board (phase checklist + ### 4a coverage table + the three GATE lines). Killchain.md = the evolving discovered attack chain (open/blocked attack-path rows + the Confirmed-chain header). walkthrough.md = full copy-pasteable boot-to-root reproduction (distinct from the terse log.md audit); log.md doubles as the per-engagement continuity cache (its newest block is surfaced at SessionStart, so client narrative goes there, never in generic session/hot.md). Missing wiki pages surfaced by scripts/wiki-gaps.py.
Framework subsystems (each is a script + an on-demand skill; detail in docs/auto-triggers.md):
| Subsystem | Entry point | Key rule |
|---|---|---|
| Ingest | ingest skill |
Drop raw output in targets/<eng>/ingest/; the skill synthesizes -> state/loot/Killchain then archives. |
| Next-move | scripts/next_move.py / next-move |
Ranks moves (type + scope aware). Update tables after acting so the next run re-ranks. |
| Fingerprint testing | scripts/playbook.json |
Maps tech -> targeted tests + hunt skill + the wiki/payloads/ arsenal. Extend both as you learn new tech. |
| Chaining | scripts/chains.json / next-move |
Data-driven finding -> pivot edges (horizontal complement to playbook's vertical fingerprint->test). A CONFIRMED/PARTIAL finding surfaces ranked pivot candidates; suggestions only, gate:oob edges need an operator callback first. Add edges, no code. |
| Coverage | Approach.md 4a table / coverage skill |
Per-asset untested classes live in the plan board's ### 4a table. Add a row with status [x] + a poc/ image when you test a class, or the gap recurs (next_move.py surfaces [gap] moves). |
| Finding quality | scripts/find-lint.py |
Findings scaffold from setup/templates/_find.md; run find-lint before /evidence and before a report. |
Client-data boundary (hard rule): all client/engagement specifics (hosts, IPs, creds, domains, findings, narrative) live ONLY under targets/<eng>/ (git-ignored). Never write them into session/*, wiki/, tracked docs/, scripts, or commit messages; per-engagement narrative goes to targets/<eng>/log.md (audit + continuity cache). session-guard.py advises on violations; run bash scripts/check-leaks.sh before sharing. Full detail: docs/sharing.md.
Per-machine hostnames and vault paths live in the git-ignored CLAUDE.local.md
(copy CLAUDE.local.example.md to create it), kept out of the published repo.
The path resolvers (setup/vault-path.sh) and hooks self-locate or read
OBSIDIAN_VAULT / QMD_VAULT, so a single-machine setup needs no local file.
@CLAUDE.local.md
TORCH/
├── CLAUDE.md <- this file (+ README.md, LICENSE)
├── targets/ <- engagements (PRIVATE, git-ignored; ALL client data lives here)
├── wiki/ <- knowledge base: techniques/ payloads/ tools/ cheatsheets/ (+ index, moc)
├── session/ <- hot.md (startup cache) · log.md (audit) · memory.md (editorial)
├── docs/ <- workflows, page-types, auto-triggers, virtual-machine, setup, sharing, conventions, layout
├── scripts/ <- automation (next_move, status, capture.sh, shot.py, lint-*, wiki-*, vm-*, burp/, ...)
├── setup/ <- bootstrap.sh, install-hooks.sh, install-skills.sh, new-engagement.sh, templates/, burp/
├── skills/ <- hunt/ (hunt-* + hunt-core) · workflow/ (triage/evidence/coverage/ingest/ctf-box/learn/walkthrough/...) · burp/ · wiki/ research/ disclosure/ code-review/ + hooks/
└── raw/ <- research/ · assets/ (read-only) · git/ (clones)
Full annotated tree + per-file notes: docs/layout.md.
Rules:
raw/is read-only. Exceptions: populateraw/git/via git clone (WSL only), andraw/research/<project>/research workspaces created bysetup/new-research.sh(theresearchskill writes loop state there). Research on public targets is not client data; client/engagement work still lives only undertargets/.wiki/andtargets/are fully owned by Claude. Create, update, and cross-reference freely.wiki/index.mdandsession/log.mdupdated after every ingest, query-that-produces-a-page, and lint pass (framework work only; client/engagement narrative goes totargets/<eng>/log.md).- Update
CLAUDE.mdwhen vault structure changes;docs/setup.mdfor machine/path changes;docs/conventions.mdfor editorial standards changes.
Read targets/TARGETS.md for the engagement playbook: FIND naming, severity definitions, directory structure, and the wiki integration rule.
Session end: Before closing any session, run pause-work (gsd:pause-work if the gsd plugin is installed on this machine, else do the steps manually). Generic/framework summary -> session/hot.md, session/log.md, session/memory.md (no client specifics). Client/engagement narrative -> targets/<eng>/log.md (audit + continuity cache) ONLY.
Full schema in docs/page-types.md. Skip rule: during ingest, read only the frontmatter first. If the ingest slug is already in sources:, skip the page entirely. Only read full content when you will update it.
Read docs/workflows.md before performing any ingest, target session, lint, or query. When a technique appears in multiple sources, synthesise all into one technique page; do not create one page per source.
- Brevity during engagements/tool-loops (output tokens are billed). When working a target (recon -> foothold -> privesc) or any multi-step tool loop, keep prose MINIMAL: one short line before a tool batch stating intent, and lead the next turn with the RESULT/finding, not a recap. No per-step paragraphs, no restating what a command will do (the command is shown), no narrating the plan you already gave. Full prose is for the deliverables that need it (a report, a walkthrough, a design/brainstorm, an explicit explanation the user asked for), not for the play-by-play. A 40-min box should not cost a paragraph per step.
- Never use em-dashes (
--). Use a comma, semicolon, or rewrite the sentence. (--is permitted inside code blocks as a CLI flag.) - Never use emojis.
- Do not narrate what you are doing with echo/printf inside commands (label banners, "now doing X" lines,
=== ... ===/== x ==/-- x --separators). You already explain each step in your normal response text, so echoing it into the command is duplicate noise, and the harness already shows every command with its own output. Run commands directly. - Concrete values, not shell variables, in target commands. The operator watches the live terminal, so write commands a human would type: real IPs/URLs/paths inline (
curl -s http://10.1.1.5:8080/api), notT=http://...; curl "$T/api"or$VARplaceholders. Reserve variables for genuinely repeated long secrets (a captured token/cookie). walkthrough.md is already var-free; hold live commands to the same bar. - Shell interaction: one command, clean output, NO markers (
docs/shell-interaction.md). Driving a live shell (reverse shell, interactive session, the Kali VM), the tooling already frames output for you:bash /root/vm.sh '<cmd>'and thevm-rsh.sh/win-rsh.shdrivers return the complete output of ONE command, echo stripped. So: one command per tool call; NEVER inject sentinel/marker/delimiter/nonce strings or split a literal to dodge the echo; don't chain unrelated actions; type it the way an operator would (plain$env:/$_- the driver escapes for the bridge, don't hand-encode); shortest command that answers the question. Output empty/weird -> PROBE with a barewhoami(a username = alive + the empty result was real; nothing = stuck, stop; a non-username = the reverse shell died back to the ATTACKER prompt, the false-RCE trap - re-pop it), never add instrumentation.$-heavy/multi-statement enum -> host a readable.ps1and run it in-memory via anIEX(DownloadString(...))cradle, not a marker-wrapped one-liner. - Send interesting requests to Burp, not just curl. When you confirm or want to probe a noteworthy request (SSRF, LFI, SQLi/injection, a deser payload, an auth bypass), push it into Burp Repeater via
Skill(hunt-burp)/ the Burp MCP (orscripts/capture.sh burpfor a PoC) so the operator can replay and inspect it manually. curl is fine for quick loops; the load-bearing exploit requests belong in Repeater for operator visibility. Prefer the NATIVE Burp MCP tools (mcp__burp__*) when connected; theburp-mcp-cli.pySSH bridge is the fallback (the native server only attaches at session start and will be absent if the VM was down then - a session restart re-attaches it). Brute/fuzz belongs in Intruder (send_to_intruder), not a hand-rolled loop, so the operator watches it live. - Burp-first does NOT stop at foothold (anti-drift). The recurring failure: land RCE/a shell, then abandon Burp for raw
curl/vm.sh/python-urllib scripts, and the operator loses all visual observation of the exploitation. Once a foothold lands, KEEP driving load-bearing requests through Burp Repeater (post-auth API calls, the injection that reads the flag, each privesc-relevant fetch) - the operator is watching Burp, not your terminal. A quick throwaway loop over the bridge is fine; the requests that MATTER (the ones you'd screenshot) go through Repeater to the end of the box. If you catch yourself scripting the whole post-foothold phase off-Burp, that IS the drift - stop and route it back. - Never add a
Co-Authored-Bytrailer, a "Generated with Claude Code" line, or any similar attribution footer to git commit messages or PR bodies. (Overrides the harness default that appends one.)
Never copy image embeds (![[Pasted image *.png]] or ) into wiki pages. Reconstruct commands as code blocks from context. Wiki pages must be image-free.