Dashboard ambient layer, comrade presence, Mission Deck and War Room, Emberwake supply chain, spread/docs publishing, fleet policy and modules API, CI docker mining, and refreshed USB pack.
12 KiB
Secure Local Payload Validation
End-to-end validation of a forged AetherForge agent without risking production keys or your daily driver. This playbook recommends one primary path and tiered alternatives.
Verdict: Docker Windows vs Disposable VM
| Environment | Server | Linux agent | Windows agent (full payload) |
|---|---|---|---|
| Host + Hyper-V VM (recommended) | ✅ devrun.bat on host |
✅ optional WSL2 VM | ✅ real Win32, WMI, USB, desktop, GPU |
| Linux Docker | ✅ Go binary in container | ✅ partial C2 + mining | ❌ cannot compile/run Windows agent features |
| Docker Desktop Windows containers | ⚠️ awkward (Server Core image) | N/A | ❌ poor fit — see below |
Why not Docker Windows for full payload tests?
Windows containers run on Windows Server Core (or similar) with a different kernel contract than desktop Windows:
- No interactive desktop — screenshots, clipboard, and many PowerShell UI calls fail or return empty.
- WMI USB subscriptions, autorun.inf, LNK spread, Defender tampering — require desktop-class Windows and often admin on a real session.
- GPU mining (T-Rex / TeamRedMiner) — no practical NVIDIA/AMD passthrough in Windows containers.
- USB propagation — container cannot see host removable drives the way a VM or bare metal can.
- WinRM / SMB lateral spread — needs a multi-machine lab network, not an isolated container namespace.
Honest recommendation: use Docker/Linux only for server + automated CI. For full Windows payload validation, use a disposable Hyper-V (or VMware) Windows 10/11 VM — or a dedicated second physical “burner” PC — then revert a snapshot when done.
Tiered Test Matrix
Tier 0 — Mining stack only (no C2, no payload)
Proves RandomX + pool worker + optional live Stratum on the dev machine.
cd agent
go run ./cmd/mine-validate -seconds 20 -threads 2
| Validates | Does not validate |
|---|---|
| RandomX engine, pool workers, live pool login | C2 WebSocket, forge bake, persistence, spread |
Note:
mine-validatemay spam[miner] hash error: randomx VM not initializedduring the multi-threaded pool phase while still reporting non-zero H/s and exiting 0. Treat non-zero hashrate + exit 0 as pass; investigate if exit code is 1.
Tier 1 — Automated CI (no real agent)
test.bat
Or faster (skip builds + Playwright):
.\scripts\test-suite.ps1 -SkipBuild -SkipE2E
| Phase | Coverage |
|---|---|
| Go server + agent unit/integration tests | API, forge, auth, pool, fusion |
| Vitest | Dashboard forms, preflight, offline gating |
Playwright (-SkipE2E off) |
Login smoke, mocked fleet UI |
Also with server already running:
.\scripts\smoke-test.ps1 -BaseUrl http://127.0.0.1:8989
Tier 2 — Server + Linux agent (same host, Linux VM, or Docker)
Good for C2 path, basic recon, mining install, systemd persistence — not Windows-only ops.
Option A — Docker (isolated bridge, recommended for CI)
# Automated proof (compose up + assert + teardown)
scripts/ci-docker-mining.sh # Linux / macOS / GHA
.\scripts\ci-docker-mining.ps1 # Windows + Docker Desktop
Or interactive:
docker compose -f docker/docker-compose.yml up --build
- Server on host port 18989; dashboard
testuser/testpass(seedocker/data/users.json). - Fleet secret
e2e-docker-fleet-secret-fixed001indocker/data/config.json+docker/agent-builtin.go. - Test wallet in
docker/data/config.jsonanddocker/agent-builtin.go(see E2E test address in security rules above). - Agent container has no internet egress — mines via server-broadcast jobs only.
- RandomX is pure Go (
go-randomx); agent image needs no CGO. - Assert logic:
GET /api/v1/health→GET /api/v1/agents(Basic auth) findsstatus=onlinewithhashrate_15s|1m|15m > 0, orGET /api/v1/dashboard/statsshowsonline_agents >= 1andtotal_hashrate > 0. Waits up to 3 minutes. - GitHub Actions:
.github/workflows/ci-docker-mining.ymlon every push (ubuntu-latest). - Verify manually: Fleet Roster shows
docker-e2e-linux; hashrate fields populate after ~30s. - Teardown:
docker compose -f docker/docker-compose.yml down --rmi local -v
Full notes: docker/README.md.
Option B — WSL2 / Linux VM
- Start server on host:
devrun.bat - Forge Linux amd64 worker pointing at
http://<host-lan-ip>:8989(VM must reach host; bind server to LAN or use Hyper-V Default Switch IP). - Run agent in WSL2 or a small Linux VM.
- Crucible:
sysinfo,pause/resume,get_log,list_dir(Linux file ops).
Tier 3 — Full Windows payload (primary E2E path)
Topology
┌─────────────────────────────┐ ┌──────────────────────────────┐
│ Host PC (control) │ LAN │ Disposable Win10/11 VM │
│ devrun.bat → :8989 │◄───────►│ forged test agent.exe │
│ data/ logs, builds, DB │ only │ snapshot "clean" → revert │
└─────────────────────────────┘ └──────────────────────────────┘
Security rules
-
Dedicated test data dir — e.g.
data-e2e\with freshusers.json; never copy productiondata\. -
Test wallet — use the repo's recommended E2E Monero address (public test wallet, not for production):
85JfUA9uyBZ2Kzv4ctoURyUYoYgpEu5QjQ8xSdiapFX8TpBHXkHwHQhBkxUxmoFKU85NH4dnSRBbiL8wSvcVmRqg4Wc9TrmSeeded automatically in
data-e2e/config.jsonbyscripts/e2e-validate.ps1and indocker/data/config.jsonfor Tier 2 Docker. Do not use your production wallet. -
Rotate fleet secret after tests if you ever pointed at shared
data\. -
No internet egress from VM (optional but ideal) — allow only host IP:8989 + pool Stratum if testing live shares.
-
Snapshot before forge run — revert VM when finished (“toss the machine”).
Step-by-Step: Tier 3 Playbook
1. Prepare isolated server data
$env:AETHERFORGE_E2E_USER = "testuser"
$env:AETHERFORGE_E2E_PASS = "testpass"
New-Item -ItemType Directory -Force -Path ".\data-e2e" | Out-Null
'{"testuser":"testpass"}' | Set-Content ".\data-e2e\users.json" -Encoding UTF8
Start server against that directory (from repo root):
bin\miner-server.exe -port 8989 -data .\data-e2e
Or use devrun.bat after pointing -data at data-e2e (or run .\scripts\e2e-validate.ps1 -PrepareOnly).
2. Calibrate for validation
In Calibrate (Settings):
| Setting | Test value |
|---|---|
| Server URL | http://<host-ip>:8989 (must match what the VM can reach) |
| Wallet | 85JfUA9uyBZ2Kzv4ctoURyUYoYgpEu5QjQ8xSdiapFX8TpBHXkHwHQhBkxUxmoFKU85NH4dnSRBbiL8wSvcVmRqg4Wc9Trm (or match data-e2e/config.json) |
file_logging |
true (required for get_log / data-e2e\logs\) |
| Stealth mode | off for first pass (easier debugging) |
| USB / share / auto-spread | off until spread is explicitly under test |
| Remote aggressive ops | on only in a VM snapshot you will revert |
agent_kill_after_days |
optional safety fuse (e.g. 1) |
3. Forge a test worker
In Forge:
- Target OS: Windows amd64
- Worker name:
e2e-validate - Enable only features you intend to test this session
- Download
e2e-validate.exe+ paireduninstall-e2e-validate.ps1
Or use the orchestrator script (API forge) after server is up:
.\scripts\e2e-validate.ps1 -ForgeAgent
4. Hyper-V VM setup (Windows)
# Example: Hyper-V Manager or PowerShell
# 1. Create Gen2 VM, 4 GB RAM, 40 GB disk
# 2. Internal or Default Switch network (host reachable)
# 3. Take snapshot named "clean-pre-agent"
# 4. Copy forged exe into VM (shared folder or ISO)
Before running the agent: snapshot name recorded, VM has no personal data, Defender policy acceptable for your lab.
5. Run agent in VM
- Execute forged exe once (install + connect).
- Confirm agent appears on dashboard Fleet Roster (online).
- Check server console for
[agent] authenticated.
6. Crucible command checklist
Run against the test agent. Tick as you go.
Core / mining
sysinfo— hostname, cores, RAMpause/resume/restart— miner controlconnectivity_probe— C2 + pool reachability JSONget_log— tail returnsminer.loglines
Recon (Windows)
ps,netstat,listen_portsipconfig,wifi,posture,patch_statusscreenshot(needs interactive logged-in desktop)camera_list/camera_snapshot(needs ffmpeg + camera)
Files (Windows)
list_dir—C:\Users\<user>\read_file— small text fileupload/downloadround-trip
Power / lifecycle
exec/powershell— benign echo commandreboot_machine— only if snapshot revert planneduninstallor rununinstall-*.ps1— M-10 checklist
Advanced (enable in forge + revert snapshot after)
get_wifi_passwords,defender_off,firewall_*- USB spread — second USB passthrough device
spread_now/ LAN spread — requires second lab VM
7. Collect logs
| Source | Path / action |
|---|---|
| Server stdout | devrun.bat window |
| Server agent log cache | data-e2e\logs\<agent-id>.log |
| Agent on disk | %LOCALAPPDATA%\<install-dir>\miner.log |
| Dashboard | Fleet → Remote Control → Fetch Log |
| API | GET /api/v1/agents/{id}/log?refresh=1 |
Get-ChildItem ".\data-e2e\logs\"
Get-Content ".\data-e2e\logs\<agent-id>.log" -Tail 100
8. Teardown (“toss the machine”)
- VM: Hyper-V → Revert to snapshot
clean-pre-agent(or delete VM). - Host: stop server; archive or delete
data-e2e\if no longer needed. - Network: remove any temporary firewall rules allowing VM→host:8989.
- Secrets: if production
data\was ever used, rotate fleet secret in Calibrate.
Quick orchestration
# Automated tiers 0–1 + instructions for tier 3
.\scripts\e2e-validate.ps1
# Tier 0 only
.\scripts\e2e-validate.ps1 -SkipAutomatedTests -SkipServerCheck
# Prepare test data + print checklist (no forge)
.\scripts\e2e-validate.ps1 -PrepareOnly
What each existing tool covers
| Tool | Tier | Scope |
|---|---|---|
agent/cmd/mine-validate |
0 | Mining only |
test.bat / scripts/test-suite.ps1 |
1 | Full automated suite |
scripts/smoke-test.ps1 |
1 | REST B-01–B-10 |
scripts/ci-docker-mining.sh / .ps1 |
2 | Docker Linux agent hashrate proof |
.github/workflows/ci-docker-mining.yml |
2 | GHA push gate |
server/web/e2e/*.spec.ts |
1 | Dashboard smoke (mocked WS) |
docs/TEST_RESULTS.md |
1–3 | Matrix IDs; M-01–M-09 manual |
devrun.bat |
2–3 | Build + launch control server |
| Forge + burner VM | 3 | Full payload |
Linux vs Windows agent capabilities (validation scope)
| Feature | Windows | Linux | macOS |
|---|---|---|---|
| RandomX CPU mining + dashboard hashrate | ✅ | ✅ | ✅ |
| GPU RVN mining | ✅ | stub (detect only) | stub |
| Screenshot | ✅ (GDI+) | ✅ (scrot/import/gnome-screenshot) | ✅ (screencapture) |
| Camera | ✅ (ffmpeg) | ✅ (V4L2/ffmpeg/fswebcam) | stub |
| Clipboard | ✅ | ✅ (xclip/pbpaste) | ✅ (pbpaste) |
| File browser Crucible | ✅ | ✅ | ✅ |
| Posture / syscheck | ✅ (WMI) | ✅ (ufw/systemd/apt) | partial |
| Firewall aggressive ops | ✅ (netsh) | ✅ (ufw/iptables) | stub |
| USB / WMI spread | ✅ | ❌ | ❌ |
| SMB / WinRM spread | ✅ | ❌ | ❌ |
| SSH lateral spread | ❌ | ✅ | ✅ |
| WiFi password harvest | ✅ | stub | stub |
| Defender off | ✅ | N/A (returns error) | N/A |
| systemd / LaunchAgent persistence | — | ✅ | ✅ |
| Idle-mode mining (CPU % sample) | ✅ | ✅ (fixed: /proc/stat) | ✅ (sysctl kern.cp_time) |
Use Tier 3 Windows VM when validating spread, GPU, screenshot, or aggressive ops. Use Tier 2 Linux for faster C2 regression on recon + mining.
References
- Automated test phases:
tests/README.md - Manual matrix IDs:
docs/TEST_RESULTS.md(M-01–M-10) - Known gaps:
PROBLEMS.md