Skip to content

feat(scanner+chain): fully automated scan → engagement → kill chain pipeline#17

Merged
Emperiusm merged 1 commit intomainfrom
feature/full-scan-chain-pipeline
Apr 17, 2026
Merged

feat(scanner+chain): fully automated scan → engagement → kill chain pipeline#17
Emperiusm merged 1 commit intomainfrom
feature/full-scan-chain-pipeline

Conversation

@Emperiusm
Copy link
Copy Markdown
Owner

Summary

Make the user-facing flow scan → chain rebuild → kill chain query fully automated. Before this PR, the pipeline broke in multiple places that required manual Python bridging to produce a single kill-chain result.

Bugs fixed

Symptom Root cause Fix
`opentools scan plan pentest-ground.com:6379` — "Cannot determine target type" `_is_network_target` only matched IP:port, never hostname:port Added hostname:port regex
network-recon profile failed with "nmap: not found" Assumed bare binaries on PATH Route through `docker exec nmap-mcp` with `{target_host}` / `{target_port}`
WebLogic scan missed its CVEs on web-quick No Java app server profile New `app-server` profile (whatweb + nuclei with weblogic/oracle/java/tomcat/jboss tags + nikto)
Scan completes, chain rebuild says "no findings to process" scan findings saved only to scans.db; engagement DB never populated New `engagement_bridge.py` — `scan run -e ` auto-imports after terminal state persist
Chain CLI sees no findings even after manual import Chain default DB path ~/.opentools/engagements.db, main CLI uses <repo>/engagements/opentools.db Chain default matches main CLI, falls back to home
Scanner profiles ignored by git .gitignore had profiles/ as profiling output rule Narrowed to /profiles/

New: app-server profile

id: app-server
target_types: [url]
phases:
  - fingerprint: whatweb
  - vuln-scan: nuclei -tags weblogic,oracle,java,tomcat,jboss,websphere
               + nikto

Live test results (after this PR, zero manual steps)

opentools engagement create pentest-ground-live --target pentest-ground.com --type pentest
opentools scan run https://pentest-ground.com:4280 -p web-quick -e pentest-ground-live  # 138 findings + imported
opentools scan run https://pentest-ground.com:5013 -p web-quick -e pentest-ground-live  # 31
opentools scan run https://pentest-ground.com:9000 -p web-quick -e pentest-ground-live  # 40
opentools scan run https://pentest-ground.com:81 -p web-quick -e pentest-ground-live    # 48
opentools scan run https://pentest-ground.com:7001 -p app-server -e pentest-ground-live # 35 (CVE-2023-21839 CRITICAL)
opentools scan run pentest-ground.com:6379 -p network-recon -e pentest-ground-live      # 1

opentools chain rebuild --engagement <id>
  # rebuild complete: 293 findings processed
  # 179 entities, 3819 relations

opentools chain query preset external-to-internal --engagement <id>
  # Oracle WebLogic Server - Remote Code Execution (critical)
  # Oracle Fusion Middleware WebLogic Admin Console - RCE (high)

opentools chain path domain:pentest-ground.com → url:.../LoginForm.jsp
  # Path 3: login-panel-detect → admin-rce → server-rce

Test plan

  • 33 existing CLI tests still pass
  • Fresh scans across all 6 targets produce findings and auto-import
  • Chain rebuild sees the imported findings
  • external-to-internal preset surfaces WebLogic RCE
  • chain path traces the full kill chain for WebLogic

🤖 Generated with Claude Code

…ipeline

Before this change the user-facing flow required several manual steps that
made "run a scan and see the attack chain" impossible without Python
one-liners. Running all 6 targets on pentest-ground.com end-to-end exposed
the breaks:

1. network-recon assumed bare `nmap` on PATH — the deployment only has
   `nmap-mcp` via Docker.
2. No profile existed for Java app servers like WebLogic — web-quick
   missed WebLogic-specific nuclei templates (weblogic, oracle, java, …).
3. `pentest-ground.com:6379` was rejected as an unknown target type;
   `_is_network_target` only matched IP:port, never hostname:port.
4. After a scan completed, findings landed in scans.db but nothing moved
   them into engagements.db's `findings` table, so chain rebuild,
   reports, and the dashboard all reported zero data.
5. Chain CLI defaulted to `~/.opentools/engagements.db` while the rest of
   the CLI used `<repo>/engagements/opentools.db` — findings written by
   one were invisible to the other.

## Changes

### Targeting (target.py + planner.py)
- `_is_network_target` now accepts `hostname:port` (dot-separated hostname
  + numeric port 1-65535). Enables TCP service targets like Redis.
- New `{target_port}` placeholder in planner template substitution.
  Defaults to `1-10000` when no port is specified so nmap `-p ` doesn't
  produce an empty flag.

### Profiles (profiles/network_recon.yaml + profiles/app_server.yaml)
- network-recon: now `docker exec nmap-mcp` with `{target_host}` /
  `{target_port}`. Works against Redis, SSH, any TCP service.
- app-server: NEW profile targeting WebLogic/Oracle/Tomcat/JBoss —
  whatweb fingerprint + nuclei tagged templates + nikto.

### Engagement bridge (scanner/engagement_bridge.py + scanner/scan_cli.py)
- `import_scan_findings` converts RawFinding rows into engagement
  Finding records, deduping by (scan_id, tool, title, file_path).
- `scan run -e <engagement>` automatically calls the bridge after
  terminal state is persisted. Output reports imported count.
- The engagement ref resolves by id / id-prefix / name — matches how
  the rest of the CLI accepts engagement references.

### DB path unification (chain/cli.py)
- `_default_db_path` now prefers `<plugin_dir>/../../engagements/opentools.db`
  (matching main CLI) and falls back to `~/.opentools/engagements.db`
  only when discovery fails.

### .gitignore
- Narrowed `profiles/` rule to `/profiles/` so the root-level profiling
  directory is still ignored but scanner profile YAMLs are tracked.

## Live verification

All six pentest-ground.com targets scanned with automatic engagement
import, chain rebuild, and kill-chain path queries:

  DVWA          (web-quick)    138 findings
  DVGA          (web-quick)     31 findings
  RestFlaw      (web-quick)     40 findings
  GuardianLeaks (web-quick)     48 findings
  ShadowLogic   (app-server)    35 findings  ← CVE-2023-21839 CRITICAL
  CipherHeart   (network-recon)  1 finding   (Redis TCP)

Total: 293 auto-imported → chain rebuild → 179 entities, 3819 relations.
`chain query preset external-to-internal` surfaces the WebLogic RCE
chain; `chain path domain:pentest-ground.com → url:…LoginForm.jsp`
yields the full attack progression (login panel detect → admin RCE →
server RCE).

## Tests

33 existing CLI tests still pass.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@Emperiusm Emperiusm merged commit 8667c0d into main Apr 17, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant