// SPDX-License-Identifier: GPL-3.0-or-later // Package detectors contains pure Go ports of Sentinel's poll detectors. package detectors import ( "fmt" "strings" "codeberg.org/anassaeneroi/enodia-sentinal/go-agent/internal/model" ) var suspiciousDeletedPrefixes = []string{"/tmp/", "/dev/shm/", "/var/tmp/", "/run/"} // DeletedExe ports enodia_sentinel.detectors.deleted_exe exactly: memfd-backed // executables always alert, while deleted executables alert only from writable // or runtime paths. func DeletedExe(state model.State) []model.Alert { alerts := make([]model.Alert, 0) for _, process := range state.Processes { if !isFileless(process.Exe) { continue } alerts = append(alerts, model.Alert{ SID: 100012, Severity: "CRITICAL", Signature: "deleted_exe", Classtype: "fileless-execution", Key: fmt.Sprintf("del:%d", process.PID), Detail: fmt.Sprintf( "pid=%d comm=%s exe=[%s]", process.PID, process.Comm, process.Exe), PIDs: []int{process.PID}, }) } return alerts } func isFileless(exe string) bool { if strings.Contains(exe, "memfd:") { return true } if !strings.Contains(exe, "(deleted)") { return false } for _, prefix := range suspiciousDeletedPrefixes { if strings.HasPrefix(exe, prefix) { return true } } return false }