enodia-sentinal/go-agent/internal/detectors/memory_obfuscation_test.go

69 lines
2.7 KiB
Go

// SPDX-License-Identifier: GPL-3.0-or-later
package detectors
import (
"testing"
"codeberg.org/anassaeneroi/enodia-sentinal/go-agent/internal/config"
"codeberg.org/anassaeneroi/enodia-sentinal/go-agent/internal/model"
)
func TestMemoryObfuscationMatchesPythonShapes(t *testing.T) {
cases := []struct {
name string
process model.Process
signature string
severity string
sid int
}{
{"memfd", model.Process{PID: 350, Comm: "hoxha", MemoryMaps: []model.MemoryMap{{
Start: 0x1000, End: 0x2000, Perms: "r-xp", Path: "/memfd:stage (deleted)",
}}}, "memory_obfuscation", "CRITICAL", SIDMemoryObfuscation},
{"anonymous-rwx", model.Process{PID: 351, Comm: "packer", MemoryMaps: []model.MemoryMap{{
Start: 0x3000, End: 0x4000, Perms: "rwxp",
}}}, "memory_obfuscation", "HIGH", SIDMemoryObfuscation},
{"hide-library", model.Process{PID: 352, Comm: "bash", MemoryMaps: []model.MemoryMap{{
Start: 0x5000, End: 0x6000, Perms: "r-xp", Path: "/usr/lib/libhide.so",
}}}, "process_hiding_library", "CRITICAL", SIDProcessHidingLibrary},
{"injection-library", model.Process{PID: 355, Comm: "sshd", MemoryMaps: []model.MemoryMap{{
Start: 0xb000, End: 0xc000, Perms: "r-xp", Path: "/tmp/libinject.so",
}}}, "process_injection_library", "HIGH", SIDProcessInjectionLibrary},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
alerts := MemoryObfuscation(model.State{Processes: []model.Process{tc.process}}, config.Default())
if len(alerts) != 1 {
t.Fatalf("expected one alert, got %#v", alerts)
}
if alerts[0].Signature != tc.signature || alerts[0].Severity != tc.severity || alerts[0].SID != tc.sid {
t.Fatalf("unexpected alert: %#v", alerts[0])
}
})
}
}
func TestMemoryObfuscationAllowlistsMatchPython(t *testing.T) {
cfg := config.Default()
if len(MemoryObfuscation(model.State{Processes: []model.Process{{
PID: 353, Comm: "node", MemoryMaps: []model.MemoryMap{{Perms: "rwxp"}},
}}}, cfg)) != 0 {
t.Fatal("generic executable mapping should honor the runtime allowlist")
}
cfg.MemoryObfuscationAllowPaths = []string{"/tmp/known-profiler/"}
if len(MemoryObfuscation(model.State{Processes: []model.Process{{
PID: 356, Comm: "python3", MemoryMaps: []model.MemoryMap{{
Perms: "r-xp", Path: "/tmp/known-profiler/libhook.so",
}},
}}}, cfg)) != 0 {
t.Fatal("configured mapping path should be silent")
}
alerts := MemoryObfuscation(model.State{Processes: []model.Process{{
PID: 354, Comm: "node", MemoryMaps: []model.MemoryMap{{
Perms: "r-xp", Path: "/tmp/libhide.so",
}},
}}}, config.Default())
if len(alerts) != 1 || alerts[0].Signature != "process_hiding_library" {
t.Fatalf("hide-library evidence must survive comm allowlist: %#v", alerts)
}
}