Security Assessment Preset — DeepSeek Harness
Overview
This preset turns DSH into a multi-agent authorized offensive assessment: recon the estate, restore JS source maps, SAST first-party code (gated on real source), audit client-side libraries for known CVEs, run real DAST (crawl/params/nuclei/probes), test access control & auth across identities (IDOR/vertical/session/MFA), match versioned products to public advisories, chain primitives into an attack graph, and prove HIGH hops with one live request each. Reports carry an OWASP Top 10 coverage matrix.
It is not a header-and-CWE auditor. DNS and host mapping are the opening, not the deliverable.
Prerequisites
- DeepSeek Harness (dsh) installed
- Workspace sandbox permissions (
danger-full-accessfor network tools) - Authorization from the target system owner
jq,subfinder,nmap,nucleion PATH;retire(ornpx retire) for SCA;python3for harvest/SAST scripts. Optional:katana/hakrawler(DAST crawl),shuji(source-map unpack fallback)
For internal engagements (e.g. you work for sentnl.io), a message like
"I work for sentnl.io — internal testing authorized" counts as authorization.
The agent records it verbatim in scope.json.authorization; no separate letter needed.
Installation
~/.dsh/.agent-presets/security-assessment/
Restart DSH (or refresh the Web GUI) and pick Security Assessment, or:
dsh --agent-preset security-assessment
Usage
1. Start a session
Select the preset, then name a domain. That domain is the scope.
do an assessment on sentnl.io
Default in_scope: dns, http, port-scan, js-harvest, sast, sca, dast, access-auth, product-cve, verify, credential-testing.
credential-testing is now in the default offensive profile. Constrain it explicitly if needed:
do an assessment on sentnl.io
- In-scope: DNS, HTTP, port-scan, JS harvest, SAST, SCA, DAST, access-auth, product-cve, verify, credential-testing
- Out-of-scope: No DoS
Active phases (port scan, DAST, exploit replay, spraying, shell checks) obey scope.json.policy caps:
"policy": {
"rate_per_host_per_min": 30,
"max_exploit_attempts_per_host": 20,
"max_dast_requests_per_host": 500,
"max_shell_dwell_sec": 120,
"max_concurrent_active": 2,
"spray_attempts_per_account_per_hour": 3
}
A host that trips the circuit breaker (errors ≥10%, lockout, crash, alert) twice is abandoned and its paths tagged untested. Raise a cap by stating new values in the session message — the lead rewrites the policy and logs the change.
2. Planning
Lead starts in Assessment Planning Mode. The plan must include an attack tree (crown-jewel hosts and how primitives chain), not a vuln laundry list. Guardrail is "one proving request per hop", not "avoid touching the app".
3. Swarm
W1a Agent A subfinder
W1b B/C/D fingerprint + harvest + infra
W1c active port scan + service map (nmap + targeted scripts)
W1d restore source maps, extract API matrix (no /rest/rest/), probe extracted paths
W2a first-party SAST — gated on real source (upstream clone > restored maps; no source = secrets-only skip). 6 specialists; merge only if all agent-*.json exist
W2b Agent R SCA in parallel: map check (shuji fallback) → lib inventory → retire.js → OSV CVE match
W2c Agent Q DAST: surface → params → nuclei + targeted class probes (auth pass after cred)
W3 Agent M product intel — mandatory when any product is versioned; ingests sca/vulns.json
W4 Agent N attack graph (seeds from DAST + A04 business-logic hypotheses)
W5 cred I–L (default on; valid creds feed S + P + Q auth pass) — disable in scope.json if not wanted
W5b Agent Q authenticated DAST pass (optional); Agent S access/auth matrix (A01/A07/A02-token)
W6 Agent P active exploit verification + reverse-shell validation (graph + dast HIGH + authz bypass + valid creds)
W7 Agent O report.md incl. OWASP Top 10 coverage matrix (blocked until barrier=verified)
Artifacts live under assessment-output/{slug}/.
4. Review
report.md leads with proven attack paths. If access is gained, the report stores only: evidence filename/screenshot pointers + step-by-step reproduction. No secrets/session dumps in report body. Evidence pointers: dast/findings.jsonl, validation/pocs/, validation/access/, learning/cves.json, sca/vulns.json, harvest/restored/.
Architecture
Preset components
| File | Purpose |
|---|---|
agent.cordis.yml | Composition — tools, attacker persona, plan-mode structure |
preset.yml | Picker metadata |
skills/SKILL.md | Orchestration |
skills/workspace-contract/SKILL.md | assessment-output/{slug}/, barriers, lane I/O |
skills/recon/SKILL.md | DNS, HTTP/S, JS harvest, hypothesis-driven probes |
skills/sast/SKILL.md | Map restore, first-party Pass-A, specialists, merger — gated on real source |
skills/sca/SKILL.md | Agent R — library inventory (package.json mining + retire.js) → OSV CVE match |
skills/dast/SKILL.md | Agent Q — surface/params → nuclei + class probes → findings for N/P |
skills/access-auth/SKILL.md | Agent S — access control + auth matrix (A01/A07/A02-token) across identities |
skills/sast/scripts/restore_sourcemaps.py | .map → harvest/restored/{host}/{app,vendor} |
skills/sast/scripts/extract_api.py | API matrix without double-prefixing |
skills/product-intel/SKILL.md | Agent M — version → public advisory |
skills/attack-graph/SKILL.md | Agent N — operational chains |
skills/exploit-dev/SKILL.md | Agent P — smallest proving request per hop |
skills/credential-enum/SKILL.md | Spraying / CAPTCHA (default on; disable via scope) |
skills/reporting/SKILL.md | Report compiler; blocked until verified |
Barriers (monotonic)
scoped → recon-a → recon → ports → harvest → sast → sca → dast → intel → graph → cred → access → verified → reported
After harvest, the lead may fork B to probe new routes from JSON bodies. That is not a rewind. Agent O must not compile before verified.
Key capabilities
| Capability | DSH feature |
|---|---|
| Parallel swarm (≤8 / wave) | subagent spawn, background |
| Context-preserving follow-up | subagent_fork |
| Per-host fan-out | workflow |
| Per-product advisory loops | ralph (one product per loop) |
| Live probes | bash + tool-jobs |
| Advisory lookup | tool-web fetch |
How this is supposed to think
- Recon is cheap and you already do it well — keep it.
- Pick the host that pays (versioned product, maps served, no WAF), not 28× 503 vhosts.
- Restore maps. SAST
app/, skip webpack/React runtime. - Agent M must run if a version string exists. Empty
learning/is a failed run. - A chain is hops with requests, not three MEDIUMs glued with "if auth is bypassed".
- Prove the hop. GET the path. Record status. Stop. No payload packs, no DoS, no community-node installs.
Customization
Add a skill under skills/<name>/SKILL.md — auto-discovered.
Edit agent.cordis.yml for timeouts / ralph maxRounds / tool rows.
Mapping to Dream Security
| Dream concept | DSH |
|---|---|
| Agent A–S swarm | subagent spawn × 8 per wave |
| Core engine | this harness session |
| Local SAST | restore + inventory.py + pass_a_scan.py + specialists |
| Learning cycles | Agent M + ralph per product |
| Dynamic reallocation | lead forks B on new intel; N/P loop on failed hops |
| Reporting | report.md after verified |
Troubleshooting
tool "bash" is already registered: This preset uses only dsh-tool-bash. Do not add persistent-shell.
"Preset not found": Directory must be ~/.dsh/.agent-presets/security-assessment/ with agent.cordis.yml.
Sub-agent spawn fails: provider: spawn needs dsh-subagent-spawn-in-process or a subprocess backend.
Network tools missing:
apt-get install -y dnsutils curl openssl whois netcat-openbsd jq python3
# subfinder: operator-installed (go install or GitHub release)
O compiled without chains: that was the old bug. O is now blocked until validation/graph.json and validation/pocs/index.json exist (barrier=verified).
SAST is all React FPs: restore maps first; Pass-A skips vendor; do not merge without the six agent-*.json files.
Permission errors: danger-full-access. All writes under assessment-output/{slug}/.
