Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
78b5738
test(detectors): add common test helpers
yanivagman Dec 9, 2025
047c1df
feat(detectors): migrate hooked_syscall to detector framework
yanivagman Nov 5, 2025
760a6c4
feat(detectors): migrate hooked_seq_ops to detector framework
yanivagman Nov 5, 2025
415d34a
feat(detectors): migrate anti_debugging_ptraceme signature to detecto…
yanivagman Nov 5, 2025
773eb5a
feat(detectors): migrate aslr_inspection signature to detector framework
yanivagman Nov 5, 2025
5f52c36
feat(detectors): migrate proc_kcore_read signature to detector framework
yanivagman Nov 5, 2025
d22ca6d
feat(detectors): migrate hidden_file_created signature to detector fr…
yanivagman Nov 5, 2025
acc0276
feat(detectors): migrate cgroup_notify_on_release_modification signat…
yanivagman Dec 9, 2025
2d83c2b
feat(detectors): migrate cgroup_release_agent_modification signature …
yanivagman Dec 9, 2025
1af93cb
feat(detectors): migrate core_pattern_modification signature to detector
yanivagman Dec 9, 2025
ab72644
feat(detectors): migrate default_loader_modification signature to det…
yanivagman Dec 9, 2025
636f952
feat(detectors): migrate disk_mount signature to detector
yanivagman Dec 9, 2025
7e72da1
feat(detectors): migrate docker_abuse signature to detector
yanivagman Dec 9, 2025
1e75c77
feat(detectors): migrate dropped_executable signature to detector
yanivagman Dec 9, 2025
e6636d7
feat(detectors): migrate dynamic_code_loading signature to detector
yanivagman Dec 9, 2025
7249167
feat(detectors): migrate fileless_execution signature to detector
yanivagman Dec 9, 2025
99ad57c
feat(detectors): migrate illegitimate_shell signature to detector
yanivagman Dec 9, 2025
720d550
feat(detectors): migrate k8s_service_account_token signature to detector
yanivagman Dec 9, 2025
ed7bb69
feat(detectors): migrate kernel_module_loading signature to detector
yanivagman Dec 9, 2025
2472b17
feat(detectors): migrate kubernetes_api_connection signature to detector
yanivagman Dec 9, 2025
1488d46
feat(detectors): migrate kubernetes_certificate_theft_attempt signatu…
yanivagman Dec 9, 2025
86aaede
feat(detectors): migrate ld_preload signature to detector
yanivagman Dec 9, 2025
07d500d
feat(detectors): migrate proc_fops_hooking signature to detector
yanivagman Dec 9, 2025
7979c6a
feat(detectors): migrate proc_mem_access signature to detector
yanivagman Dec 9, 2025
809b4e2
feat(detectors): migrate proc_mem_code_injection signature to detector
yanivagman Dec 9, 2025
780eae7
feat(detectors): migrate process_vm_write_code_injection signature to…
yanivagman Dec 9, 2025
59ab4ea
feat(detectors): migrate ptrace_code_injection signature to detector
yanivagman Dec 9, 2025
ebb908e
feat(detectors): migrate rcd_modification signature to detector
yanivagman Dec 9, 2025
909d314
feat(detectors): migrate sched_debug_recon signature to detector
yanivagman Dec 9, 2025
82e77f0
feat(detectors): migrate scheduled_task_modification signature to det…
yanivagman Dec 9, 2025
85371b1
feat(detectors): migrate stdio_over_socket signature to detector
yanivagman Dec 9, 2025
ffbb29e
feat(detectors): migrate sudoers_modification signature to detector
yanivagman Dec 9, 2025
62693b1
feat(detectors): migrate syscall_table_hooking signature to detector
yanivagman Dec 9, 2025
19433c5
feat(detectors): migrate system_request_key_config_modification signa…
yanivagman Dec 9, 2025
16767da
fix(tests): update e2e-kernel-test to work with detectors
yanivagman Dec 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion detectors/anti_debugging.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (d *AntiDebugging) GetDefinition() detection.DetectorDefinition {
},
},
ProducedEvent: v1beta1.EventDefinition{
Name: "anti_debugging_detector",
Name: "anti_debugging",
Description: "A process used anti-debugging techniques to block a debugger",
Version: &v1beta1.Version{
Major: 1,
Expand Down
2 changes: 1 addition & 1 deletion detectors/anti_debugging_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func TestAntiDebugging_GetDefinition(t *testing.T) {
assert.Equal(t, "request=0", def.Requirements.Events[0].DataFilters[0])

// Check produced event
assert.Equal(t, "anti_debugging_detector", def.ProducedEvent.Name)
assert.Equal(t, "anti_debugging", def.ProducedEvent.Name)
assert.Contains(t, def.ProducedEvent.Description, "anti-debugging")

// Check threat metadata matches original signature
Expand Down
101 changes: 101 additions & 0 deletions detectors/aslr_inspection.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package detectors

import (
"context"

"github.com/aquasecurity/tracee/api/v1beta1"
"github.com/aquasecurity/tracee/api/v1beta1/detection"
"github.com/aquasecurity/tracee/common/parsers"
)

func init() {
register(&AslrInspection{})
}

// AslrInspection detects inspection of ASLR configuration.
// Adversaries may inspect ASLR settings to understand memory layout randomization
// before attempting exploitation.
type AslrInspection struct {
logger detection.Logger
}

func (d *AslrInspection) GetDefinition() detection.DetectorDefinition {
// Build data filter for: pathname matches ASLR config file AND flags indicate read
// We use pathname filter directly, and IsFileRead logic requires checking O_RDONLY/O_RDWR
// O_RDONLY=0, O_WRONLY=1, O_RDWR=2, so read operations are flags where (flags&O_WRONLY)==0 or flags==O_RDWR
// However, simpler approach: filter for pathname and check flags in OnEvent since
// the filter syntax might not support complex flag bit operations

return detection.DetectorDefinition{
ID: "TRC-109",
Requirements: detection.DetectorRequirements{
Events: []detection.EventRequirement{
{
Name: "security_file_open",
Dependency: detection.DependencyRequired,
DataFilters: []string{
"pathname=/proc/sys/kernel/randomize_va_space",
},
},
},
},
ProducedEvent: v1beta1.EventDefinition{
Name: "aslr_inspection",
Description: "ASLR configuration was inspected",
Version: &v1beta1.Version{
Major: 1,
Minor: 0,
Patch: 0,
},
},
ThreatMetadata: &v1beta1.Threat{
Name: "ASLR inspection detected",
Description: "The ASLR (address space layout randomization) configuration was inspected. ASLR is used by Linux to prevent memory vulnerabilities. An adversary may want to inspect and change the ASLR configuration in order to avoid detection.",
Severity: v1beta1.Severity_INFO,
Mitre: &v1beta1.Mitre{
Tactic: &v1beta1.MitreTactic{
Name: "Privilege Escalation",
},
Technique: &v1beta1.MitreTechnique{
Id: "T1068",
Name: "Exploitation for Privilege Escalation",
},
},
Properties: map[string]string{
"Category": "privilege-escalation",
},
},
AutoPopulate: detection.AutoPopulateFields{
Threat: true,
DetectedFrom: true,
},
}
}

func (d *AslrInspection) Init(params detection.DetectorParams) error {
d.logger = params.Logger
d.logger.Debugw("AslrInspection detector initialized")
return nil
}

func (d *AslrInspection) OnEvent(ctx context.Context, event *v1beta1.Event) ([]detection.DetectorOutput, error) {
// DataFilter ensures pathname matches, but we still need to check if this is a read operation
flags, err := v1beta1.GetDataSafe[int64](event, "flags")
if err != nil {
// If flags are missing, we can't determine if this is a read - skip
return nil, nil
}

// Check if this is a read operation using the same logic as the original signature
if parsers.IsFileRead(int(flags)) {
return []detection.DetectorOutput{{Data: nil}}, nil
}

// Not a read operation, no detection
return nil, nil
}

func (d *AslrInspection) Close() error {
d.logger.Debugw("AslrInspection detector closed")
return nil
}
193 changes: 193 additions & 0 deletions detectors/aslr_inspection_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
package detectors

import (
"context"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/aquasecurity/tracee/api/v1beta1"
"github.com/aquasecurity/tracee/api/v1beta1/detection"
"github.com/aquasecurity/tracee/common/parsers"
)

func TestAslrInspection_GetDefinition(t *testing.T) {
detector := &AslrInspection{}
def := detector.GetDefinition()

assert.Equal(t, "TRC-109", def.ID)
assert.Len(t, def.Requirements.Events, 1)
assert.Equal(t, "security_file_open", def.Requirements.Events[0].Name)
assert.Equal(t, detection.DependencyRequired, def.Requirements.Events[0].Dependency)

// Verify data filter for ASLR config file
assert.Len(t, def.Requirements.Events[0].DataFilters, 1)
assert.Equal(t, "pathname=/proc/sys/kernel/randomize_va_space", def.Requirements.Events[0].DataFilters[0])

// Check produced event
assert.Equal(t, "aslr_inspection", def.ProducedEvent.Name)
assert.Contains(t, def.ProducedEvent.Description, "ASLR")

// Check threat metadata matches original signature
require.NotNil(t, def.ThreatMetadata)
assert.Equal(t, "ASLR inspection detected", def.ThreatMetadata.Name)
assert.Equal(t, v1beta1.Severity_INFO, def.ThreatMetadata.Severity)
assert.Equal(t, "privilege-escalation", def.ThreatMetadata.Properties["Category"])

require.NotNil(t, def.ThreatMetadata.Mitre)
assert.Equal(t, "Privilege Escalation", def.ThreatMetadata.Mitre.Tactic.Name)
assert.Equal(t, "T1068", def.ThreatMetadata.Mitre.Technique.Id)
assert.Equal(t, "Exploitation for Privilege Escalation", def.ThreatMetadata.Mitre.Technique.Name)
}

func TestAslrInspection_Init(t *testing.T) {
detector := &AslrInspection{}

params := detection.DetectorParams{
Logger: &mockLogger{},
DataStores: &mockDataStoreRegistry{},
}

err := detector.Init(params)
require.NoError(t, err)
}

func TestAslrInspection_OnEvent_ReadOperation(t *testing.T) {
detector := &AslrInspection{}

params := detection.DetectorParams{
Logger: &mockLogger{},
DataStores: &mockDataStoreRegistry{},
}

err := detector.Init(params)
require.NoError(t, err)

testCases := []struct {
name string
flags int
}{
{"O_RDONLY", int(parsers.O_RDONLY.Value())},
{"O_RDWR", int(parsers.O_RDWR.Value())},
}

ctx := context.Background()

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// DataFilter ensures pathname matches
inputEvent := &v1beta1.Event{
Id: v1beta1.EventId_security_file_open,
Data: []*v1beta1.EventValue{
v1beta1.NewStringValue("pathname", "/proc/sys/kernel/randomize_va_space"),
v1beta1.NewInt64Value("flags", int64(tc.flags)),
},
}

outputEvents, err := detector.OnEvent(ctx, inputEvent)

require.NoError(t, err)
require.Len(t, outputEvents, 1, "Should detect for %s", tc.name)
assert.NotNil(t, outputEvents[0])
})
}
}

func TestAslrInspection_OnEvent_WriteOperation(t *testing.T) {
detector := &AslrInspection{}

params := detection.DetectorParams{
Logger: &mockLogger{},
DataStores: &mockDataStoreRegistry{},
}

err := detector.Init(params)
require.NoError(t, err)

// Test write-only operation (should NOT trigger detection)
inputEvent := &v1beta1.Event{
Id: v1beta1.EventId_security_file_open,
Data: []*v1beta1.EventValue{
v1beta1.NewStringValue("pathname", "/proc/sys/kernel/randomize_va_space"),
v1beta1.NewInt64Value("flags", int64(parsers.O_WRONLY.Value())),
},
}

ctx := context.Background()
outputEvents, err := detector.OnEvent(ctx, inputEvent)

require.NoError(t, err)
assert.Len(t, outputEvents, 0, "Should not detect for write-only operation")
}

func TestAslrInspection_OnEvent_MissingFlags(t *testing.T) {
detector := &AslrInspection{}

params := detection.DetectorParams{
Logger: &mockLogger{},
DataStores: &mockDataStoreRegistry{},
}

err := detector.Init(params)
require.NoError(t, err)

// Event without flags argument
inputEvent := &v1beta1.Event{
Id: v1beta1.EventId_security_file_open,
Data: []*v1beta1.EventValue{
v1beta1.NewStringValue("pathname", "/proc/sys/kernel/randomize_va_space"),
},
}

ctx := context.Background()
outputEvents, err := detector.OnEvent(ctx, inputEvent)

// Should not error, just no detection
require.NoError(t, err)
assert.Len(t, outputEvents, 0)
}

func TestAslrInspection_OnEvent_MultipleReadOperations(t *testing.T) {
detector := &AslrInspection{}

params := detection.DetectorParams{
Logger: &mockLogger{},
DataStores: &mockDataStoreRegistry{},
}

err := detector.Init(params)
require.NoError(t, err)

ctx := context.Background()

// Multiple read operations should each trigger detection
for i := 0; i < 3; i++ {
inputEvent := &v1beta1.Event{
Id: v1beta1.EventId_security_file_open,
Data: []*v1beta1.EventValue{
v1beta1.NewStringValue("pathname", "/proc/sys/kernel/randomize_va_space"),
v1beta1.NewInt64Value("flags", int64(parsers.O_RDONLY.Value())),
},
}

outputEvents, err := detector.OnEvent(ctx, inputEvent)
require.NoError(t, err)
require.Len(t, outputEvents, 1, "Read operation %d should produce detection", i+1)
}
}

func TestAslrInspection_Close(t *testing.T) {
detector := &AslrInspection{}

params := detection.DetectorParams{
Logger: &mockLogger{},
DataStores: &mockDataStoreRegistry{},
}

err := detector.Init(params)
require.NoError(t, err)

err = detector.Close()
assert.NoError(t, err)
}
Loading