feat(go): port socket detectors
This commit is contained in:
parent
fc9b5f0448
commit
c6f7219de8
23 changed files with 693 additions and 28 deletions
67
go-agent/internal/detectors/stealth_network.go
Normal file
67
go-agent/internal/detectors/stealth_network.go
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package detectors
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"codeberg.org/anassaeneroi/enodia-sentinal/go-agent/internal/config"
|
||||
"codeberg.org/anassaeneroi/enodia-sentinal/go-agent/internal/model"
|
||||
"codeberg.org/anassaeneroi/enodia-sentinal/go-agent/internal/netutil"
|
||||
)
|
||||
|
||||
var watchedSocketKinds = map[string]bool{
|
||||
"raw": true, "sctp": true, "dccp": true, "packet": true,
|
||||
"mptcp": true, "tipc": true, "xdp": true, "vsock": true,
|
||||
}
|
||||
|
||||
var alwaysHighSocketKinds = map[string]bool{"raw": true, "packet": true, "xdp": true}
|
||||
|
||||
var activeSocketStates = map[string]bool{
|
||||
"ESTAB": true, "LISTEN": true, "UNCONN": true, "CONNECTED": true,
|
||||
"SYN-SENT": true, "SYN-RECV": true,
|
||||
}
|
||||
|
||||
// StealthNetwork ports unusual socket-family detection (SID 100036).
|
||||
func StealthNetwork(state model.State, cfg config.Config) []model.Alert {
|
||||
alerts := make([]model.Alert, 0)
|
||||
for _, socket := range state.Sockets {
|
||||
kind := strings.ToLower(socket.Kind)
|
||||
// TCP/UDP belong to reverse-shell, egress, and listener detectors. This
|
||||
// detector is deliberately limited to less-common covert-channel paths.
|
||||
if !watchedSocketKinds[kind] || cfg.StealthNetworkAllowKinds[kind] {
|
||||
continue
|
||||
}
|
||||
if socket.Comm != "" && cfg.StealthNetworkAllowComms[socket.Comm] {
|
||||
continue
|
||||
}
|
||||
if socket.State != "" && !activeSocketStates[socket.State] {
|
||||
continue
|
||||
}
|
||||
severity := "MEDIUM"
|
||||
host, _ := netutil.SplitHostPort(socket.Peer)
|
||||
publicPeer := netutil.IsPublicIP(host) && !netutil.IPInCIDRs(host, cfg.EgressAllowCIDRs)
|
||||
// Raw/packet/XDP access, listeners, and public peers are immediately
|
||||
// high severity; inactive or locally scoped unusual families stay medium.
|
||||
if alwaysHighSocketKinds[kind] || socket.State == "LISTEN" || publicPeer {
|
||||
severity = "HIGH"
|
||||
}
|
||||
comm := socket.Comm
|
||||
if comm == "" {
|
||||
comm = "?"
|
||||
}
|
||||
alerts = append(alerts, model.Alert{
|
||||
SID: 100036,
|
||||
Severity: severity,
|
||||
Signature: "stealth_network",
|
||||
Classtype: "covert-channel",
|
||||
Key: socketKey(kind, socket),
|
||||
Detail: fmt.Sprintf(
|
||||
"%s socket state=%s local=%s peer=%s comm=%s pid=%s",
|
||||
kind, socket.State, socket.Local, socket.Peer, comm, optionalDisplayInt(socket.PID)),
|
||||
PIDs: alertPIDs(socket.PID),
|
||||
})
|
||||
}
|
||||
return alerts
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue