Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ jobs:

- name: Download dependencies
run: go mod download

- name: Fix go
run: go env -w GOTOOLCHAIN=go1.25.0+auto

- name: Run tests
run: go test ./...
Expand Down
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ spec:
description: "Description of what the rule detects"
expressions:
message: "CEL expression for alert message"
unique_id: "CEL expression for unique identifier"
rule_expression:
- event_type: "event_type_name"
uniqueId: "CEL expression for unique identifier"
ruleExpression:
- eventType: "eventType_name"
expression: "CEL expression for detection logic"
profile_dependency: 0 # 0=Required, 1=Optional, 2=NotRequired
profileDependency: 0 # 0=Required, 1=Optional, 2=NotRequired
severity: 1
support_policy: false
supportPolicy: false
tags:
- "tag1"
- "tag2"
Expand All @@ -47,11 +47,11 @@ spec:
| `id` | string | Unique rule identifier (format: R####) | Yes |
| `description` | string | Detailed description of the rule | Yes |
| `expressions.message` | string | CEL expression for alert message | Yes |
| `expressions.unique_id` | string | CEL expression for unique event ID | Yes |
| `expressions.rule_expression` | array | Array of detection expressions | Yes |
| `profile_dependency` | integer | Profile dependency level (0,1,2) | Yes |
| `expressions.uniqueId` | string | CEL expression for unique event ID | Yes |
| `expressions.ruleExpression` | array | Array of detection expressions | Yes |
| `profileDependency` | integer | Profile dependency level (0,1,2) | Yes |
| `severity` | integer | Rule severity level | Yes |
| `support_policy` | boolean | Whether rule supported by rule policy | Yes |
| `supportPolicy` | boolean | Whether rule supported by rule policy | Yes |
| `tags` | array | Array of tags for categorization | Yes |
| `state` | object | Rule state | No |

Expand Down
202 changes: 105 additions & 97 deletions go.mod

Large diffs are not rendered by default.

456 changes: 245 additions & 211 deletions go.sum

Large diffs are not rendered by default.

70 changes: 22 additions & 48 deletions pkg/rules/r0001-unexpected-process-launched/rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@ import (
"github.com/kubescape/storage/pkg/apis/softwarecomposition/v1beta1"
"github.com/stretchr/testify/require"

tracerexectype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/exec/types"
eventtypes "github.com/inspektor-gadget/inspektor-gadget/pkg/types"
objectcachev1 "github.com/kubescape/node-agent/pkg/objectcache/v1"
celengine "github.com/kubescape/node-agent/pkg/rulemanager/cel"
"github.com/kubescape/node-agent/pkg/rulemanager/cel/libraries/cache"
utils "github.com/kubescape/node-agent/pkg/utils"
common "github.com/kubescape/rulelibrary/pkg/common"
"github.com/kubescape/node-agent/pkg/utils"
"github.com/kubescape/rulelibrary/pkg/common"
)

func TestR0001UnexpectedProcessLaunched(t *testing.T) {
Expand All @@ -27,26 +25,15 @@ func TestR0001UnexpectedProcessLaunched(t *testing.T) {
t.Fatalf("Failed to load rule: %v", err)
}
// Create a process exec event
e := &events.ExecEvent{
Event: tracerexectype.Event{
Event: eventtypes.Event{
CommonData: eventtypes.CommonData{
K8s: eventtypes.K8sMetadata{
BasicK8sMetadata: eventtypes.BasicK8sMetadata{
ContainerName: "test",
},
},
Runtime: eventtypes.BasicRuntimeMetadata{
ContainerID: "test",
},
},
},
Pid: 1234,
Comm: "test-process",
Pcomm: "test-process",
ExePath: "/usr/bin/test-process",
Args: []string{"test-process", "arg1"},
},
e := &utils.StructEvent{
Args: []string{"test-process", "arg1"},
Comm: "test-process",
Container: "test",
ContainerID: "test",
EventType: utils.ExecveEventType,
ExePath: "/usr/bin/test-process",
Pcomm: "test-process",
Pid: 1234,
}

objCache := &objectcachev1.RuleObjectCacheMock{
Expand Down Expand Up @@ -74,8 +61,7 @@ func TestR0001UnexpectedProcessLaunched(t *testing.T) {
t.Fatalf("Failed to create CEL engine: %v", err)
}
enrichedEvent := &events.EnrichedEvent{
EventType: utils.ExecveEventType,
Event: e,
Event: e,
}

// Evaluate the rule
Expand Down Expand Up @@ -154,30 +140,18 @@ func BenchmarkEvaluateRuleNative(b *testing.B) {
TTL: 1 * time.Microsecond,
},
})
e := &events.ExecEvent{
Event: tracerexectype.Event{
Event: eventtypes.Event{
CommonData: eventtypes.CommonData{
K8s: eventtypes.K8sMetadata{
BasicK8sMetadata: eventtypes.BasicK8sMetadata{
ContainerName: "test",
},
},
Runtime: eventtypes.BasicRuntimeMetadata{
ContainerID: "test",
},
},
},
Pid: 1234,
Comm: "test-process",
Pcomm: "test-process",
ExePath: "/usr/bin/test-process",
Args: []string{"test-process", "arg1"},
},
e := &utils.StructEvent{
Container: "test",
ContainerID: "test",
EventType: utils.ExecveEventType,
Pid: 1234,
Comm: "test-process",
Pcomm: "test-process",
ExePath: "/usr/bin/test-process",
Args: []string{"test-process", "arg1"},
}
enrichedEvent := &events.EnrichedEvent{
EventType: utils.ExecveEventType,
Event: e,
Event: e,
}
ruleSpec, err := common.LoadRuleFromYAML("unexpected-process-launched.yaml")
require.NoError(b, err)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,24 @@ metadata:
app: kubescape
spec:
rules:
- name: "Unexpected process launched"
enabled: true
id: "R0001"
description: "Detects unexpected process launches that are not in the baseline"
expressions:
message: "'Unexpected process launched: ' + exec.comm + ' with PID ' + string(exec.pid)"
unique_id: "exec.comm + '_' + exec.exe_path"
rule_expression:
- event_type: "exec"
expression: "!ap.was_executed(exec.runtime.container_id, parse.get_exec_path(exec.args, exec.comm))"
profile_dependency: 0
severity: 1
support_policy: false
tags:
- "anomaly"
- "process"
- "exec"
- "applicationprofile"
- name: "Unexpected process launched"
enabled: true
id: "R0001"
description: "Detects unexpected process launches that are not in the baseline"
expressions:
message: "'Unexpected process launched: ' + event.comm + ' with PID ' + string(event.pid)"
uniqueId: "event.comm + '_' + event.exepath"
ruleExpression:
- eventType: "exec"
expression: "!ap.was_executed(event.containerId, parse.get_exec_path(event.args, event.comm))"
profileDependency: 0
severity: 1
supportPolicy: false
isTriggerAlert: true
mitreTactic: "TA0002"
mitreTechnique: "T1059"
tags:
- "anomaly"
- "process"
- "exec"
- "applicationprofile"
35 changes: 10 additions & 25 deletions pkg/rules/r0002-unexpected-file-access/rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,10 @@ import (
"github.com/kubescape/node-agent/pkg/utils"
"github.com/kubescape/storage/pkg/apis/softwarecomposition/v1beta1"

traceropentype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/open/types"
eventtypes "github.com/inspektor-gadget/inspektor-gadget/pkg/types"
objectcachev1 "github.com/kubescape/node-agent/pkg/objectcache/v1"
celengine "github.com/kubescape/node-agent/pkg/rulemanager/cel"
"github.com/kubescape/node-agent/pkg/rulemanager/cel/libraries/cache"
common "github.com/kubescape/rulelibrary/pkg/common"
"github.com/kubescape/rulelibrary/pkg/common"
)

func TestR0002UnexpectedFileAccess(t *testing.T) {
Expand All @@ -25,26 +23,14 @@ func TestR0002UnexpectedFileAccess(t *testing.T) {
t.Fatalf("Failed to load rule: %v", err)
}
// Create a file access event
e := &events.OpenEvent{
Event: traceropentype.Event{
Event: eventtypes.Event{
CommonData: eventtypes.CommonData{
K8s: eventtypes.K8sMetadata{
BasicK8sMetadata: eventtypes.BasicK8sMetadata{
ContainerName: "test",
},
},
Runtime: eventtypes.BasicRuntimeMetadata{
ContainerID: "test",
},
},
},
Pid: 1234,
Comm: "test",
Path: "/etc/test",
FullPath: "/etc/test",
Flags: []string{"O_RDONLY"},
},
e := &utils.StructEvent{
Comm: "test",
Container: "test",
ContainerID: "test",
EventType: utils.OpenEventType,
Flags: []string{"O_RDONLY"},
Path: "/etc/test",
Pid: 1234,
}

objCache := &objectcachev1.RuleObjectCacheMock{
Expand Down Expand Up @@ -73,8 +59,7 @@ func TestR0002UnexpectedFileAccess(t *testing.T) {
t.Fatalf("Failed to create CEL engine: %v", err)
}
enrichedEvent := &events.EnrichedEvent{
EventType: utils.OpenEventType,
Event: e,
Event: e,
}

ok, err := celEngine.EvaluateRule(enrichedEvent, ruleSpec.Rules[0].Expressions.RuleExpression)
Expand Down
75 changes: 39 additions & 36 deletions pkg/rules/r0002-unexpected-file-access/unexpected-file-access.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,42 @@ metadata:
app: kubescape
spec:
rules:
- name: "Files Access Anomalies in container"
enabled: false
id: "R0002"
description: "Detects unexpected file access that is not in the baseline"
expressions:
message: "'Unexpected file access detected: ' + open.comm + ' with PID ' + string(open.pid) + ' to ' + open.full_path"
unique_id: "open.comm + '_' + open.full_path"
rule_expression:
- event_type: "open"
expression: >
(open.full_path.startsWith('/etc/') ||
open.full_path.startsWith('/var/log/') ||
open.full_path.startsWith('/var/run/') ||
open.full_path.startsWith('/run/') ||
open.full_path.startsWith('/var/spool/cron/') ||
open.full_path.startsWith('/var/www/') ||
open.full_path.startsWith('/var/lib/') ||
open.full_path.startsWith('/opt/') ||
open.full_path.startsWith('/usr/local/') ||
open.full_path.startsWith('/app/') ||
open.full_path == '/.dockerenv' ||
open.full_path == '/proc/self/environ')
&&
!(open.full_path.startsWith('/run/secrets/kubernetes.io/serviceaccount') ||
open.full_path.startsWith('/var/run/secrets/kubernetes.io/serviceaccount') ||
open.full_path.startsWith('/tmp'))
&&
!ap.was_path_opened(open.runtime.container_id, open.full_path)
profile_dependency: 0
severity: 1
support_policy: false
tags:
- "anomaly"
- "file"
- "open"
- "applicationprofile"
- name: "Files Access Anomalies in container"
enabled: false
id: "R0002"
description: "Detects unexpected file access that is not in the baseline"
expressions:
message: "'Unexpected file access detected: ' + event.comm + ' with PID ' + string(event.pid) + ' to ' + event.path"
uniqueId: "event.comm + '_' + event.path"
ruleExpression:
- eventType: "open"
expression: >
(event.path.startsWith('/etc/') ||
event.path.startsWith('/var/log/') ||
event.path.startsWith('/var/run/') ||
event.path.startsWith('/run/') ||
event.path.startsWith('/var/spool/cron/') ||
event.path.startsWith('/var/www/') ||
event.path.startsWith('/var/lib/') ||
event.path.startsWith('/opt/') ||
event.path.startsWith('/usr/local/') ||
event.path.startsWith('/app/') ||
event.path == '/.dockerenv' ||
event.path == '/proc/self/environ')
&&
!(event.path.startsWith('/run/secrets/kubernetes.io/serviceaccount') ||
event.path.startsWith('/var/run/secrets/kubernetes.io/serviceaccount') ||
event.path.startsWith('/tmp'))
&&
!ap.was_path_opened(event.containerId, event.path)
profileDependency: 0
severity: 1
supportPolicy: false
isTriggerAlert: false
mitreTactic: "TA0009"
mitreTechnique: "T1005"
tags:
- "anomaly"
- "file"
- "open"
- "applicationprofile"
26 changes: 7 additions & 19 deletions pkg/rules/r0003-unexpected-system-call/rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@ import (
"time"

"github.com/goradd/maps"
eventtypes "github.com/inspektor-gadget/inspektor-gadget/pkg/types"
"github.com/kubescape/node-agent/pkg/config"
"github.com/kubescape/node-agent/pkg/ebpf/events"
"github.com/kubescape/node-agent/pkg/objectcache"
objectcachev1 "github.com/kubescape/node-agent/pkg/objectcache/v1"
celengine "github.com/kubescape/node-agent/pkg/rulemanager/cel"
"github.com/kubescape/node-agent/pkg/rulemanager/cel/libraries/cache"
"github.com/kubescape/node-agent/pkg/rulemanager/types"
"github.com/kubescape/node-agent/pkg/utils"
common "github.com/kubescape/rulelibrary/pkg/common"
"github.com/kubescape/rulelibrary/pkg/common"
"github.com/kubescape/storage/pkg/apis/softwarecomposition/v1beta1"
)

Expand All @@ -25,22 +23,13 @@ func TestR0003UnexpectedSystemCall(t *testing.T) {
}

// Create a syscall event
e := &types.SyscallEvent{
Event: eventtypes.Event{
CommonData: eventtypes.CommonData{
K8s: eventtypes.K8sMetadata{
BasicK8sMetadata: eventtypes.BasicK8sMetadata{
ContainerName: "test",
},
},
Runtime: eventtypes.BasicRuntimeMetadata{
ContainerID: "test",
},
},
},
e := &utils.StructEvent{
Comm: "test",
SyscallName: "test_syscall",
Container: "test",
ContainerID: "test",
EventType: utils.SyscallEventType,
Pid: 1234,
Syscall: "test_syscall",
}

objCache := &objectcachev1.RuleObjectCacheMock{
Expand Down Expand Up @@ -69,8 +58,7 @@ func TestR0003UnexpectedSystemCall(t *testing.T) {
t.Fatalf("Failed to create CEL engine: %v", err)
}
enrichedEvent := &events.EnrichedEvent{
EventType: utils.SyscallEventType,
Event: e,
Event: e,
}

// Evaluate the rule
Expand Down
Loading
Loading