1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
package main
import (
"fmt"
"regexp"
"github.com/aquasecurity/tracee/signatures/helpers"
"github.com/aquasecurity/tracee/types/detect"
"github.com/aquasecurity/tracee/types/protocol"
"github.com/aquasecurity/tracee/types/trace"
)
type K8SServiceAccountToken struct {
cb detect.SignatureHandler
legitProcs []string
tokenPathPattern string
compiledRegex *regexp.Regexp
}
func (sig *K8SServiceAccountToken) Init(ctx detect.SignatureContext) error {
var err error
sig.cb = ctx.Callback
sig.legitProcs = []string{"flanneld", "kube-proxy", "etcd", "kube-apiserver", "coredns", "kube-controller", "kubectl"}
sig.tokenPathPattern = `secrets/kubernetes.io/serviceaccount.+token$`
sig.compiledRegex, err = regexp.Compile(sig.tokenPathPattern)
return err
}
func (sig *K8SServiceAccountToken) GetMetadata() (detect.SignatureMetadata, error) {
return detect.SignatureMetadata{
ID: "TRC-108",
Version: "1",
Name: "K8s service account token file read",
EventName: "k8s_service_account_token",
Description: "The Kubernetes service account token file was read on your container. This token is used to communicate with the Kubernetes API Server. Adversaries may try to communicate with the API Server to steal information and/or credentials, or even run more containers and laterally extend their grip on the systems.",
Properties: map[string]interface{}{
"Severity": 0,
"Category": "credential-access",
"Technique": "Exploitation for Credential Access",
"Kubernetes_Technique": "Container service account",
"id": "attack-pattern--9c306d8d-cde7-4b4c-b6e8-d0bb16caca36",
"external_id": "T1212",
},
}, nil
}
func (sig *K8SServiceAccountToken) GetSelectedEvents() ([]detect.SignatureEventSelector, error) {
return []detect.SignatureEventSelector{
{Source: "tracee", Name: "security_file_open", Origin: "container"},
}, nil
}
func (sig *K8SServiceAccountToken) OnEvent(event protocol.Event) error {
eventObj, ok := event.Payload.(trace.Event)
if !ok {
return fmt.Errorf("invalid event")
}
switch eventObj.EventName {
case "security_file_open":
// check process touching token is not on allow list
for _, legitProc := range sig.legitProcs {
if legitProc == eventObj.ProcessName {
return nil
}
}
pathname, err := helpers.GetTraceeStringArgumentByName(eventObj, "pathname")
if err != nil {
return err
}
flags, err := helpers.GetTraceeIntArgumentByName(eventObj, "flags")
if err != nil {
return err
}
if helpers.IsFileRead(flags) && sig.compiledRegex.MatchString(pathname) {
metadata, err := sig.GetMetadata()
if err != nil {
return err
}
sig.cb(&detect.Finding{
SigMetadata: metadata,
Event: event,
Data: nil,
})
}
}
return nil
}
func (sig *K8SServiceAccountToken) OnSignal(s detect.Signal) error {
return nil
}
func (sig *K8SServiceAccountToken) Close() {}
|