feat: T1007 System Service Discovery - fixed allowlist probe in posture heartbeat
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -50,6 +51,9 @@ func collectPosture() *PostureReport {
|
||||
rp := probeUnixRebootPending()
|
||||
r.RebootPending = &rp
|
||||
|
||||
// ── T1007 Service Discovery ───────────────────────────────────────────────
|
||||
r.Services = probeUnixServices()
|
||||
|
||||
// ── Elevation ─────────────────────────────────────────────────────────────
|
||||
elevated := probeUnixElevated()
|
||||
r.AgentElevated = &elevated
|
||||
@@ -58,6 +62,79 @@ func collectPosture() *PostureReport {
|
||||
return r
|
||||
}
|
||||
|
||||
// selfServiceName returns the base name of the running binary (no extension).
|
||||
func selfServiceName() string {
|
||||
exe, err := os.Executable()
|
||||
if err != nil || exe == "" {
|
||||
return "aetherforge"
|
||||
}
|
||||
return filepath.Base(exe)
|
||||
}
|
||||
|
||||
// probeUnixServices checks a fixed allowlist via systemctl.
|
||||
// Only the services relevant to this project are queried (T1007-compliant).
|
||||
func probeUnixServices() []ServiceStatus {
|
||||
self := selfServiceName()
|
||||
allowlist := []string{"sshd", "ssh", "cloudflared", "wuauserv", "ufw", "fail2ban", self}
|
||||
|
||||
// Deduplicate
|
||||
seen := map[string]bool{}
|
||||
var names []string
|
||||
for _, n := range allowlist {
|
||||
if n != "" && !seen[n] {
|
||||
seen[n] = true
|
||||
names = append(names, n)
|
||||
}
|
||||
}
|
||||
|
||||
var out []ServiceStatus
|
||||
queried := map[string]bool{}
|
||||
for _, name := range names {
|
||||
if queried[name] {
|
||||
continue
|
||||
}
|
||||
queried[name] = true
|
||||
|
||||
status := "not_found"
|
||||
startType := "unknown"
|
||||
|
||||
// ActiveState
|
||||
if activeOut, err := exec.Command("systemctl", "is-active", name).CombinedOutput(); err == nil {
|
||||
active := strings.TrimSpace(string(activeOut))
|
||||
switch active {
|
||||
case "active":
|
||||
status = "running"
|
||||
case "inactive", "failed", "dead":
|
||||
status = "stopped"
|
||||
default:
|
||||
// service exists but is in an odd state
|
||||
if active != "unknown" {
|
||||
status = "stopped"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UnitFileState (start type)
|
||||
if enableOut, err := exec.Command("systemctl", "is-enabled", name).CombinedOutput(); err == nil || status != "not_found" {
|
||||
switch strings.TrimSpace(string(enableOut)) {
|
||||
case "enabled":
|
||||
startType = "auto"
|
||||
case "disabled":
|
||||
startType = "disabled"
|
||||
case "static", "manual":
|
||||
startType = "manual"
|
||||
}
|
||||
}
|
||||
|
||||
out = append(out, ServiceStatus{
|
||||
Name: name,
|
||||
Status: status,
|
||||
StartType: startType,
|
||||
})
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// probeUnixFirewall returns true if any host firewall appears active.
|
||||
func probeUnixFirewall() bool {
|
||||
if out, _ := exec.Command("ufw", "status").CombinedOutput(); strings.Contains(strings.ToLower(string(out)), "status: active") {
|
||||
|
||||
Reference in New Issue
Block a user