From 7533b2ed922f0904ec55ef4b59776cd4a0351b8d Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Thu, 20 Feb 2025 09:39:56 +0000 Subject: [PATCH] Imporving fileless execution detection and removing paths from sensetive paths Signed-off-by: Amit Schendel --- pkg/ruleengine/v1/helpers.go | 4 -- .../v1/r1000_exec_from_malicious_source.go | 1 - .../r1000_exec_from_malicious_source_test.go | 40 +++++++++++++++---- pkg/ruleengine/v1/r1005_fileless_execution.go | 6 ++- .../v1/r1005_fileless_execution_test.go | 21 ++-------- 5 files changed, 42 insertions(+), 30 deletions(-) diff --git a/pkg/ruleengine/v1/helpers.go b/pkg/ruleengine/v1/helpers.go index b05273f7..08589424 100644 --- a/pkg/ruleengine/v1/helpers.go +++ b/pkg/ruleengine/v1/helpers.go @@ -20,10 +20,6 @@ import ( // SensitiveFiles is a list of sensitive files that should not be accessed by the application unexpectedly. var SensitiveFiles = []string{ "/etc/shadow", - "/etc/sudoers", - "/etc/ssh/sshd_config", - "/etc/ssh/ssh_config", - "/etc/pam.d", } var ( diff --git a/pkg/ruleengine/v1/r1000_exec_from_malicious_source.go b/pkg/ruleengine/v1/r1000_exec_from_malicious_source.go index 38856669..e84f724d 100644 --- a/pkg/ruleengine/v1/r1000_exec_from_malicious_source.go +++ b/pkg/ruleengine/v1/r1000_exec_from_malicious_source.go @@ -61,7 +61,6 @@ func (rule *R1000ExecFromMaliciousSource) ProcessEvent(eventType utils.EventType var maliciousExecPathPrefixes = []string{ "/dev/shm", - "/proc/self", } execPath := GetExecFullPathFromEvent(execEvent) diff --git a/pkg/ruleengine/v1/r1000_exec_from_malicious_source_test.go b/pkg/ruleengine/v1/r1000_exec_from_malicious_source_test.go index 86340f5c..c301563e 100644 --- a/pkg/ruleengine/v1/r1000_exec_from_malicious_source_test.go +++ b/pkg/ruleengine/v1/r1000_exec_from_malicious_source_test.go @@ -39,13 +39,6 @@ func TestR1000ExecFromMaliciousSource(t *testing.T) { t.Errorf("Expected ruleResult to be nil since test is not a malicious exec") } - e.Comm = "/proc/self/fd/3" - - ruleResult = r.ProcessEvent(utils.ExecveEventType, e, &RuleObjectCacheMock{}) - if ruleResult == nil { - t.Errorf("Expected ruleResult since exec is malicious") - } - e.Cwd = "/" e.Comm = "/run.sh" @@ -90,4 +83,37 @@ func TestR1000ExecFromMaliciousSource(t *testing.T) { if ruleResult == nil { t.Errorf("Expected ruleResult since exec is malicious") } + + // Create an exec event simulating the motd scenario + e = &events.ExecEvent{ + Event: tracerexectype.Event{ + Event: eventtypes.Event{ + CommonData: eventtypes.CommonData{ + K8s: eventtypes.K8sMetadata{ + BasicK8sMetadata: eventtypes.BasicK8sMetadata{ + ContainerName: "test", + }, + }, + }, + }, + Comm: "50-motd-news", + Args: []string{"/bin/sh", "/etc/update-motd.d/50-motd-news", "--force"}, + ExePath: "/bin/sh", // The actual executable + Cwd: "/", + }, + } + + // This should not trigger a rule failure + ruleResult = r.ProcessEvent(utils.ExecveEventType, e, &RuleObjectCacheMock{}) + if ruleResult != nil { + t.Errorf("Got false positive alert for legitimate motd execution:\nCwd: %s\nExePath: %s\nArgs: %v", + e.Cwd, e.ExePath, e.Args) + } + + // For comparison, test a real malicious case + e.ExePath = "/dev/shm/malicious" + ruleResult = r.ProcessEvent(utils.ExecveEventType, e, &RuleObjectCacheMock{}) + if ruleResult == nil { + t.Errorf("Failed to detect actually malicious execution from /dev/shm") + } } diff --git a/pkg/ruleengine/v1/r1005_fileless_execution.go b/pkg/ruleengine/v1/r1005_fileless_execution.go index 3151a409..5b3a6323 100644 --- a/pkg/ruleengine/v1/r1005_fileless_execution.go +++ b/pkg/ruleengine/v1/r1005_fileless_execution.go @@ -63,6 +63,10 @@ func (rule *R1005FilelessExecution) ProcessEvent(eventType utils.EventType, even } func (rule *R1005FilelessExecution) handleExecveEvent(execEvent *events.ExecEvent) ruleengine.RuleFailure { + if !strings.Contains(execEvent.ExePath, "memfd") { + return nil + } + execFullPath := GetExecFullPathFromEvent(execEvent) execPathDir := filepath.Dir(execFullPath) @@ -111,7 +115,7 @@ func (rule *R1005FilelessExecution) handleExecveEvent(execEvent *events.ExecEven }, TriggerEvent: execEvent.Event.Event, RuleAlert: apitypes.RuleAlert{ - RuleDescription: fmt.Sprintf("Fileless execution detected: exec call \"%s\" is from a malicious source \"/proc/*/fd\"", execPathDir), + RuleDescription: fmt.Sprintf("Fileless execution detected: exec call \"%s\" is from a malicious source %s", execPathDir, execEvent.ExePath), }, RuntimeAlertK8sDetails: apitypes.RuntimeAlertK8sDetails{ PodName: execEvent.GetPod(), diff --git a/pkg/ruleengine/v1/r1005_fileless_execution_test.go b/pkg/ruleengine/v1/r1005_fileless_execution_test.go index dcd16d3c..d1bde593 100644 --- a/pkg/ruleengine/v1/r1005_fileless_execution_test.go +++ b/pkg/ruleengine/v1/r1005_fileless_execution_test.go @@ -14,6 +14,7 @@ func TestHandleExecveEvent(t *testing.T) { t.Run("Test with /proc/self/fd prefix", func(t *testing.T) { event := &tracerexectype.Event{ Cwd: "/proc/self/fd", + ExePath: "memfd:", UpperLayer: false, Ppid: 123, Pcomm: "test", @@ -30,23 +31,7 @@ func TestHandleExecveEvent(t *testing.T) { t.Run("Test with /proc//fd pattern", func(t *testing.T) { event := &tracerexectype.Event{ Cwd: "/proc/1/fd/7", - UpperLayer: false, - Ppid: 123, - Pcomm: "test", - Comm: "test", - Gid: 123, - Pid: 123, - Uid: 123, - } - execEvent := events.ExecEvent{Event: *event} - result := rule.handleExecveEvent(&execEvent) - assert.NotNil(t, result) - }) - - t.Run("Test with /proc//fd in ExePath", func(t *testing.T) { - event := &tracerexectype.Event{ - Cwd: "/normal/path", - ExePath: "/proc/1234/fd/3", + ExePath: "memfd:", UpperLayer: false, Ppid: 123, Pcomm: "test", @@ -111,6 +96,7 @@ func TestHandleExecveEvent(t *testing.T) { t.Run("Test with absolute path", func(t *testing.T) { event := &tracerexectype.Event{ Cwd: "/absolute/path", + ExePath: "memfd:", UpperLayer: false, Ppid: 123, Pcomm: "test", @@ -127,6 +113,7 @@ func TestHandleExecveEvent(t *testing.T) { t.Run("Test with deep /proc//fd nested path", func(t *testing.T) { event := &tracerexectype.Event{ Cwd: "/proc/12345/fd/123/nested/path", + ExePath: "memfd:", UpperLayer: false, Ppid: 123, Pcomm: "test",