|
| 1 | +package main |
| 2 | + |
| 3 | +import ( |
| 4 | + "fmt" |
| 5 | + "strings" |
| 6 | + |
| 7 | + "github.com/aquasecurity/tracee/signatures/helpers" |
| 8 | + "github.com/aquasecurity/tracee/types/detect" |
| 9 | + "github.com/aquasecurity/tracee/types/protocol" |
| 10 | + "github.com/aquasecurity/tracee/types/trace" |
| 11 | +) |
| 12 | + |
| 13 | +type SudoersModification struct { |
| 14 | + cb detect.SignatureHandler |
| 15 | + sudoersFiles []string |
| 16 | + sudoersDirs []string |
| 17 | +} |
| 18 | + |
| 19 | +func (sig *SudoersModification) Init(cb detect.SignatureHandler) error { |
| 20 | + sig.cb = cb |
| 21 | + sig.sudoersFiles = []string{"/etc/sudoers", "/private/etc/sudoers"} |
| 22 | + sig.sudoersDirs = []string{"/etc/sudoers.d/", "/private/etc/sudoers.d/"} |
| 23 | + return nil |
| 24 | +} |
| 25 | + |
| 26 | +func (sig *SudoersModification) GetMetadata() (detect.SignatureMetadata, error) { |
| 27 | + return detect.SignatureMetadata{ |
| 28 | + ID: "TRC-116", |
| 29 | + Version: "1", |
| 30 | + Name: "Sudoers file modification detected", |
| 31 | + Description: "The sudoers file was modified. The sudoers file is a configuration file which controls the permissions and options of the sudo feature. Adversaries may alter the sudoers file to elevate privileges, execute commands as other users or spawn processes with higher privileges.", |
| 32 | + Properties: map[string]interface{}{ |
| 33 | + "Severity": 2, |
| 34 | + "Category": "privilege-escalation", |
| 35 | + "Technique": "Sudo and Sudo Caching", |
| 36 | + "Kubernetes_Technique": "", |
| 37 | + "id": "attack-pattern--1365fe3b-0f50-455d-b4da-266ce31c23b0", |
| 38 | + "external_id": "T1548.003", |
| 39 | + }, |
| 40 | + }, nil |
| 41 | +} |
| 42 | + |
| 43 | +func (sig *SudoersModification) GetSelectedEvents() ([]detect.SignatureEventSelector, error) { |
| 44 | + return []detect.SignatureEventSelector{ |
| 45 | + {Source: "tracee", Name: "security_file_open", Origin: "*"}, |
| 46 | + {Source: "tracee", Name: "security_inode_rename", Origin: "*"}, |
| 47 | + }, nil |
| 48 | +} |
| 49 | + |
| 50 | +func (sig *SudoersModification) OnEvent(event protocol.Event) error { |
| 51 | + |
| 52 | + eventObj, ok := event.Payload.(trace.Event) |
| 53 | + if !ok { |
| 54 | + return fmt.Errorf("invalid event") |
| 55 | + } |
| 56 | + |
| 57 | + path := "" |
| 58 | + |
| 59 | + switch eventObj.EventName { |
| 60 | + |
| 61 | + case "security_file_open": |
| 62 | + |
| 63 | + flags, err := helpers.GetTraceeStringArgumentByName(eventObj, "flags") |
| 64 | + if err != nil { |
| 65 | + return err |
| 66 | + } |
| 67 | + |
| 68 | + if helpers.IsFileWrite(flags) { |
| 69 | + pathname, err := helpers.GetTraceeStringArgumentByName(eventObj, "pathname") |
| 70 | + if err != nil { |
| 71 | + return err |
| 72 | + } |
| 73 | + |
| 74 | + path = pathname |
| 75 | + } |
| 76 | + |
| 77 | + case "security_inode_rename": |
| 78 | + |
| 79 | + newPath, err := helpers.GetTraceeStringArgumentByName(eventObj, "new_path") |
| 80 | + if err != nil { |
| 81 | + return err |
| 82 | + } |
| 83 | + |
| 84 | + path = newPath |
| 85 | + } |
| 86 | + |
| 87 | + for _, sudoersFile := range sig.sudoersFiles { |
| 88 | + if path == sudoersFile { |
| 89 | + return sig.match(event) |
| 90 | + } |
| 91 | + } |
| 92 | + |
| 93 | + for _, sudoersDir := range sig.sudoersDirs { |
| 94 | + if strings.HasPrefix(path, sudoersDir) { |
| 95 | + return sig.match(event) |
| 96 | + } |
| 97 | + } |
| 98 | + |
| 99 | + return nil |
| 100 | +} |
| 101 | + |
| 102 | +func (sig *SudoersModification) OnSignal(s detect.Signal) error { |
| 103 | + return nil |
| 104 | +} |
| 105 | +func (sig *SudoersModification) Close() {} |
| 106 | + |
| 107 | +func (sig *SudoersModification) match(event protocol.Event) error { |
| 108 | + metadata, err := sig.GetMetadata() |
| 109 | + if err != nil { |
| 110 | + return err |
| 111 | + } |
| 112 | + sig.cb(detect.Finding{ |
| 113 | + SigMetadata: metadata, |
| 114 | + Event: event, |
| 115 | + Data: nil, |
| 116 | + }) |
| 117 | + |
| 118 | + return nil |
| 119 | +} |
0 commit comments