51 lines
1.3 KiB
Go
51 lines
1.3 KiB
Go
// 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
|
|
}
|