89 lines
2.4 KiB
Go
89 lines
2.4 KiB
Go
//go:build linux
|
|
|
|
package vulnprobe
|
|
|
|
import (
|
|
"os/exec"
|
|
"runtime"
|
|
"strings"
|
|
)
|
|
|
|
// ProbeHost gathers Linux LOTL recon via apt/dnf security listings (read-only).
|
|
func ProbeHost(listeningPorts map[int]bool, osVersion string) HostContext {
|
|
ctx := HostContext{
|
|
Platform: runtime.GOOS,
|
|
OSVersion: osVersion,
|
|
LastPatchDays: -1,
|
|
ListeningPorts: listeningPorts,
|
|
PackageVersions: map[string]string{},
|
|
}
|
|
ctx.SSHListening = listeningPorts[22] || listeningPorts[2222]
|
|
ctx.PackageVersions = linuxSecurityPackages()
|
|
return ctx
|
|
}
|
|
|
|
func linuxSecurityPackages() map[string]string {
|
|
out := map[string]string{}
|
|
if _, err := exec.LookPath("apt-get"); err == nil {
|
|
raw, err := exec.Command("apt-get", "-s", "upgrade").CombinedOutput()
|
|
if err == nil {
|
|
for _, line := range strings.Split(string(raw), "\n") {
|
|
line = strings.TrimSpace(line)
|
|
if strings.HasPrefix(line, "Inst ") {
|
|
fields := strings.Fields(line)
|
|
if len(fields) >= 2 {
|
|
out[fields[1]] = "pending-upgrade"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if list, err := exec.Command("apt", "list", "--upgradable").CombinedOutput(); err == nil {
|
|
for _, line := range strings.Split(string(list), "\n") {
|
|
if !strings.Contains(line, "/") || strings.HasPrefix(line, "Listing") {
|
|
continue
|
|
}
|
|
parts := strings.SplitN(line, "/", 2)
|
|
if len(parts) == 2 {
|
|
ver := strings.TrimSpace(strings.Split(parts[1], " ")[0])
|
|
out[parts[0]] = ver
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if _, err := exec.LookPath("dnf"); err == nil {
|
|
raw, err := exec.Command("dnf", "updateinfo", "list", "security").CombinedOutput()
|
|
if err == nil {
|
|
for _, line := range strings.Split(string(raw), "\n") {
|
|
if !strings.Contains(line, "CVE-") {
|
|
continue
|
|
}
|
|
fields := strings.Fields(line)
|
|
for _, f := range fields {
|
|
if strings.HasPrefix(f, "CVE-") {
|
|
out[f] = "security-advisory"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
func linuxPackageFindings(ctx HostContext) []VulnFinding {
|
|
var out []VulnFinding
|
|
for cve, note := range ctx.PackageVersions {
|
|
if !strings.HasPrefix(cve, "CVE-") {
|
|
continue
|
|
}
|
|
out = append(out, VulnFinding{
|
|
CVEID: cve,
|
|
Severity: "high",
|
|
Component: "linux package",
|
|
Patched: false,
|
|
ExploitableInFleetContext: ctx.SSHListening,
|
|
Detail: "dnf/apt security listing: " + note,
|
|
})
|
|
}
|
|
return out
|
|
}
|