Adds the Tier-3 exploit driver — an MSFExploitDriver that plugs into
EpisodeRunner.on_phase, fires a Metasploit module against a target VM
via msfrpcd, watches for the resulting session, and stamps each
transition (exploit_fire, session_open, session_landing_probe,
sample_executed, session_dormant, session_killed) into the episode's
events.jsonl on the orchestrator's monotonic clock.
What landed:
- exploits/msfrpc.py — minimal msgpack-over-HTTPS client (auth,
module.execute, job/session lifecycle) so we don't depend on a
third-party MSF wrapper.
- exploits/driver.py — phase-to-msfrpc adapter; idempotent fire,
session-open polling with timeout, workload start/stop, teardown.
- exploits/modules.py + exploits/modules/vsftpd_234_backdoor.toml —
TOML module configs with {{ target_ip }} placeholders, replacing the
imperative .rc-script approach the README previously hinted at.
- vm/launch_target.sh — SLIRP+restrict=on launcher for the
intentionally-vulnerable target VM (host can reach guest via
hostfwd, guest cannot reach host or internet).
- tools/run_tier3_demo.py — end-to-end runner mirroring run_real_vm_demo.
- tests/test_exploits.py — 12 new tests against a fake MSFRpcClient,
including an integration test that drives a real EpisodeRunner.
Plumbing changes:
- EpisodeRunner._emit_event → public emit_event, so external drivers
share the runner's monotonic clock and events.jsonl.
- mkdir for episode_dir moved to __init__ so emit_event is callable
before run() (driver_setup fires pre-schedule).
Status: driver + tests pass (40/40); end-to-end against a live msfrpcd
+ Metasploitable2 image is the next bring-up step.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
92 lines
3 KiB
Markdown
92 lines
3 KiB
Markdown
# exploits/
|
|
|
|
The Tier-3 exploit driver — fires a Metasploit module against a
|
|
vulnerable target VM, watches for the resulting session, and stamps the
|
|
session-open transition into the episode's `events.jsonl` so the
|
|
labeler can mark `armed → infecting` honestly.
|
|
|
|
## Layout
|
|
|
|
```
|
|
exploits/
|
|
msfrpc.py tiny msgpack-over-HTTPS client for msfrpcd
|
|
driver.py MSFExploitDriver — plugged in as EpisodeRunner.on_phase
|
|
modules.py ModuleConfig + TOML loader
|
|
modules/
|
|
vsftpd_234_backdoor.toml first canned module (Metasploitable2)
|
|
...
|
|
```
|
|
|
|
## Module configs
|
|
|
|
Each `modules/*.toml` describes one Metasploit module — its path, the
|
|
options to set, and the payload to use. The driver reads these files
|
|
to drive `module.execute` over msfrpc.
|
|
|
|
```toml
|
|
description = "..."
|
|
[module]
|
|
type = "exploit" # exploit | auxiliary | post
|
|
path = "unix/ftp/vsftpd_234_backdoor"
|
|
|
|
[module.options]
|
|
RHOSTS = "{{ target_ip }}" # placeholder substituted at runtime
|
|
RPORT = 21
|
|
|
|
[payload]
|
|
path = "cmd/unix/interact"
|
|
[payload.options] # optional
|
|
# LHOST = "{{ target_ip }}"
|
|
|
|
[session]
|
|
type = "shell"
|
|
```
|
|
|
|
The only placeholder supported today is `{{ target_ip }}`. Add more in
|
|
`exploits/modules.py::ModuleConfig.render_options` when needed.
|
|
|
|
## Running
|
|
|
|
```sh
|
|
# 1. Start msfrpcd locally:
|
|
msfrpcd -P <password> -U msf -a 127.0.0.1 -p 55553
|
|
|
|
# 2. Drop a vulnerable target image at vm/images/<name>.qcow2 (e.g.
|
|
# Metasploitable2 — see docs/sources.md for sha256).
|
|
|
|
# 3. Drive an episode:
|
|
MSFRPC_PASSWORD=<password> uv run python tools/run_tier3_demo.py \
|
|
--module vsftpd_234_backdoor \
|
|
--target-port 21 \
|
|
--data-root data
|
|
```
|
|
|
|
The episode's `events.jsonl` will contain:
|
|
|
|
```
|
|
driver_setup — module + target snapshotted before fire
|
|
exploit_fire — module.execute issued
|
|
session_open — new session id observed in session.list
|
|
session_landing_probe — first command response (id) recorded
|
|
sample_executed — workload kicked off inside the session
|
|
session_dormant — workload killed
|
|
session_killed — session.stop at episode end
|
|
```
|
|
|
|
These pair with the standard phase labels in `labels.jsonl` so a
|
|
downstream loader can reconcile "what the orchestrator scheduled"
|
|
against "what actually happened on the wire".
|
|
|
|
## Adding a module
|
|
|
|
1. Drop a TOML at `exploits/modules/<name>.toml` per the schema above.
|
|
2. Pick a payload that works without a callback channel until the
|
|
`br-malware` bridge is in (see `vm/launch_target.sh` — SLIRP +
|
|
`restrict=on` blocks reverse-tcp by design). `cmd/unix/interact`
|
|
and other "session on the same socket" payloads are safe.
|
|
3. Drive a quick check: `uv run python tools/run_tier3_demo.py --module <name>`.
|
|
4. The new module is automatically picked up by `tools/run_tier3_demo.py`
|
|
via `--module <name>`; no driver code changes needed.
|
|
|
|
We do **not** author exploits or modify upstream Metasploit code. The
|
|
driver is a pure adapter from the project's phase machine to msfrpc.
|