Skip to content

Commit b5c88c3

Browse files
roikolrafaeldtinoco
authored andcommitted
signature: add dynamic_code_loading.go sig
1 parent 904ace4 commit b5c88c3

File tree

3 files changed

+179
-0
lines changed

3 files changed

+179
-0
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"github.com/aquasecurity/tracee/signatures/helpers"
6+
"github.com/aquasecurity/tracee/types/detect"
7+
"github.com/aquasecurity/tracee/types/protocol"
8+
"github.com/aquasecurity/tracee/types/trace"
9+
)
10+
11+
type DynamicCodeLoading struct {
12+
cb detect.SignatureHandler
13+
alertText string
14+
}
15+
16+
func (sig *DynamicCodeLoading) Init(cb detect.SignatureHandler) error {
17+
sig.cb = cb
18+
sig.alertText = "Protection changed from W+E to E!"
19+
return nil
20+
}
21+
22+
func (sig *DynamicCodeLoading) GetMetadata() (detect.SignatureMetadata, error) {
23+
return detect.SignatureMetadata{
24+
ID: "TRC-4",
25+
Version: "1",
26+
Name: "Dynamic code loading detected",
27+
Description: "Possible dynamic code loading was detected as the binary's memory is both writable and executable. Writing to an executable allocated memory region could be a technique used by adversaries to run code undetected and without dropping executables.",
28+
Properties: map[string]interface{}{
29+
"Severity": 2,
30+
"Category": "defense-evasion",
31+
"Technique": "Software Packing",
32+
"Kubernetes_Technique": "",
33+
"id": "attack-pattern--deb98323-e13f-4b0c-8d94-175379069062",
34+
"external_id": "T1027.002",
35+
},
36+
}, nil
37+
}
38+
39+
func (sig *DynamicCodeLoading) GetSelectedEvents() ([]detect.SignatureEventSelector, error) {
40+
return []detect.SignatureEventSelector{
41+
{Source: "tracee", Name: "mem_prot_alert", Origin: "*"},
42+
}, nil
43+
}
44+
45+
func (sig *DynamicCodeLoading) OnEvent(event protocol.Event) error {
46+
47+
eventObj, ok := event.Payload.(trace.Event)
48+
if !ok {
49+
return fmt.Errorf("invalid event")
50+
}
51+
52+
switch eventObj.EventName {
53+
54+
case "mem_prot_alert":
55+
56+
alert, err := helpers.GetTraceeStringArgumentByName(eventObj, "alert")
57+
if err != nil {
58+
return err
59+
}
60+
61+
if alert == sig.alertText {
62+
metadata, err := sig.GetMetadata()
63+
if err != nil {
64+
return err
65+
}
66+
sig.cb(detect.Finding{
67+
SigMetadata: metadata,
68+
Event: event,
69+
Data: nil,
70+
})
71+
}
72+
73+
}
74+
75+
return nil
76+
}
77+
78+
func (sig *DynamicCodeLoading) OnSignal(s detect.Signal) error {
79+
return nil
80+
}
81+
func (sig *DynamicCodeLoading) Close() {}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
6+
"github.com/aquasecurity/tracee/signatures/signaturestest"
7+
"github.com/aquasecurity/tracee/types/detect"
8+
"github.com/aquasecurity/tracee/types/trace"
9+
"github.com/stretchr/testify/assert"
10+
"github.com/stretchr/testify/require"
11+
)
12+
13+
func TestDynamicCodeLoading(t *testing.T) {
14+
testCases := []struct {
15+
Name string
16+
Events []trace.Event
17+
Findings map[string]detect.Finding
18+
}{
19+
{
20+
Name: "should trigger detection",
21+
Events: []trace.Event{
22+
{
23+
EventName: "mem_prot_alert",
24+
Args: []trace.Argument{
25+
{
26+
ArgMeta: trace.ArgMeta{
27+
Name: "alert",
28+
},
29+
Value: interface{}("Protection changed from W+E to E!"),
30+
},
31+
},
32+
},
33+
},
34+
Findings: map[string]detect.Finding{
35+
"TRC-4": {
36+
Data: nil,
37+
Event: trace.Event{
38+
EventName: "mem_prot_alert",
39+
Args: []trace.Argument{
40+
{
41+
ArgMeta: trace.ArgMeta{
42+
Name: "alert",
43+
},
44+
Value: interface{}("Protection changed from W+E to E!"),
45+
},
46+
},
47+
}.ToProtocol(),
48+
SigMetadata: detect.SignatureMetadata{
49+
ID: "TRC-4",
50+
Version: "1",
51+
Name: "Dynamic code loading detected",
52+
Description: "Possible dynamic code loading was detected as the binary's memory is both writable and executable. Writing to an executable allocated memory region could be a technique used by adversaries to run code undetected and without dropping executables.",
53+
Properties: map[string]interface{}{
54+
"Severity": 2,
55+
"Category": "defense-evasion",
56+
"Technique": "Software Packing",
57+
"Kubernetes_Technique": "",
58+
"id": "attack-pattern--deb98323-e13f-4b0c-8d94-175379069062",
59+
"external_id": "T1027.002",
60+
},
61+
},
62+
},
63+
},
64+
},
65+
{
66+
Name: "should not trigger detection - wrong alert",
67+
Events: []trace.Event{
68+
{
69+
EventName: "mem_prot_alert",
70+
Args: []trace.Argument{
71+
{
72+
ArgMeta: trace.ArgMeta{
73+
Name: "alert",
74+
},
75+
Value: interface{}("Protection changed to Executable!"),
76+
},
77+
},
78+
},
79+
},
80+
Findings: map[string]detect.Finding{},
81+
},
82+
}
83+
84+
for _, tc := range testCases {
85+
t.Run(tc.Name, func(t *testing.T) {
86+
holder := signaturestest.FindingsHolder{}
87+
sig := DynamicCodeLoading{}
88+
sig.Init(holder.OnFinding)
89+
90+
for _, e := range tc.Events {
91+
err := sig.OnEvent(e.ToProtocol())
92+
require.NoError(t, err)
93+
}
94+
assert.Equal(t, tc.Findings, holder.GroupBySigID())
95+
})
96+
}
97+
}

signatures/golang/export.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,5 @@ var ExportedSignatures = []detect.Signature{
2828
&PtraceCodeInjection{},
2929
&ProcessVmWriteCodeInjection{},
3030
&DiskMount{},
31+
&DynamicCodeLoading{},
3132
}

0 commit comments

Comments
 (0)