Extend owned-fleet control with scheduled tasks, audit log, file browser, HTTPS beacon when WS drops, protocol tunnels, registry/autostart forge options, KEV exposure in full sys check with Telegram alerts, and UI/tests.
57 lines
1.5 KiB
Go
57 lines
1.5 KiB
Go
package alerts
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// kevExposurePayload mirrors agent KEVScanReport JSON.
|
|
type kevExposurePayload struct {
|
|
ExposedCount int `json:"exposed_count"`
|
|
CriticalCount int `json:"critical_count"`
|
|
LikelyCount int `json:"likely_count"`
|
|
RiskScore int `json:"risk_score"`
|
|
Summary string `json:"summary"`
|
|
Findings []struct {
|
|
CVE string `json:"cve"`
|
|
Name string `json:"name"`
|
|
Status string `json:"status"`
|
|
Severity string `json:"severity"`
|
|
Detail string `json:"detail"`
|
|
} `json:"findings"`
|
|
}
|
|
|
|
const EventKEVExposure = "kev_exposure"
|
|
|
|
// NotifyKEVFromSysCheck parses a full_sys_check message and sends Telegram if enabled.
|
|
func NotifyKEVFromSysCheck(n *Notifier, agentName, message string) {
|
|
if n == nil || strings.TrimSpace(message) == "" {
|
|
return
|
|
}
|
|
var report struct {
|
|
KEV *kevExposurePayload `json:"kev_exposure"`
|
|
}
|
|
if err := json.Unmarshal([]byte(message), &report); err != nil || report.KEV == nil {
|
|
return
|
|
}
|
|
k := report.KEV
|
|
if k.ExposedCount == 0 && k.CriticalCount == 0 {
|
|
return
|
|
}
|
|
s := n.settings()
|
|
if !s.Events.KEVExposure {
|
|
return
|
|
}
|
|
body := agentName + ": " + k.Summary
|
|
if body == agentName+": " {
|
|
body = agentName + ": KEV exposure indicators — exposed=" + strconv.Itoa(k.ExposedCount) + " critical=" + strconv.Itoa(k.CriticalCount)
|
|
}
|
|
for _, f := range k.Findings {
|
|
if f.Status == "exposed" && f.Severity == "critical" {
|
|
body += "\n• " + f.CVE + " " + f.Name
|
|
}
|
|
}
|
|
n.Emit(EventKEVExposure, "AetherForge KEV alert", body)
|
|
}
|