Repeatable shellcode runbooks for authorized testing
How to document encoder chains, network parameters, and export formats so retests do not turn into archaeology.
Ad-hoc shellcode generation does not scale across a team. Someone always asks "which LHOST was that?" three weeks later.
Runbooks are not bureaucracy. They are compression for brains.
What belongs in a runbook
Minimum fields I store:
- scope ticket or authorization reference
- target OS/arch and binary name
- payload type (exec, reverse TCP, custom import)
- network parameters (IP, port, interface)
- bad-char list and encoder order
- export format used in the injector
- SHA-256 of final bytes
Skip prose. Future readers want facts.
Separate config from bytes
Configs are shareable. Raw shellcode often is not.
In shellcodes, collections and saved presets help you reload OS/arch/payload choices without retyping. Pair that with hashes instead of pasting hex into Confluence.
Version your toolchain
Record:
- site version or git tag
- WASM module hash if you self-host
- browser profile name (sounds silly, extensions matter)
Retests fail when the toolchain changed silently.
Milestones as quality gates
The product tracks milestones like first copy, saved runbook, null-free build. Treat them as prompts, not gamification. A null-free milestone means you actually ran the constraint, not that you clicked a badge.
Review cadence
Before a retest:
- Reload runbook
- Regenerate bytes
- Compare hash to prior report appendix
- If different, document why (encoder update, parameter change)
If hashes differ without explanation, you lose credibility in front of a skeptical client.
Failure mode: runbook drift
Teams update the listener IP in the exploit script but not in the runbook. The next operator fires old shellcode at a decommissioned IP and declares the fix regressed.
Single source of truth. Builder config export beats scattered notes.
Legal and ops boundary
Runbooks make authorization auditable. They also make misuse obvious if someone runs a production preset against the wrong subnet. Tag environments explicitly: LAB vs STAGE vs PROD (prod should never appear, but people typo).