@gendigital/sage-openclaw 0.4.4 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -7
- package/dist/index.cjs +2154 -496
- package/dist/index.cjs.map +4 -4
- package/openclaw.plugin.json +1 -1
- package/package.json +18 -2
- package/resources/threats/commands.yaml +51 -1
- package/resources/threats/credentials.yaml +2 -2
- package/resources/threats/files.yaml +14 -22
- package/resources/threats/mac-commands.yaml +355 -0
- package/resources/threats/mac-credentials.yaml +99 -0
- package/resources/threats/mac-files.yaml +124 -0
- package/resources/threats/mac-obfuscation.yaml +92 -0
- package/resources/threats/mac-persistence.yaml +117 -0
- package/resources/threats/mac-supply-chain.yaml +40 -0
- package/resources/threats/obfuscation.yaml +12 -0
- package/resources/threats/persistence.yaml +13 -13
- package/resources/threats/self-defense.yaml +2 -2
- package/resources/threats/win-files.yaml +11 -11
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gendigital/sage-openclaw",
|
|
3
3
|
"license": "Apache-2.0",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.5.3",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Safety for Agents — ADR layer for OpenClaw",
|
|
7
7
|
"main": "./dist/index.cjs",
|
|
@@ -19,8 +19,13 @@
|
|
|
19
19
|
"sync:assets": "node scripts/sync-assets.mjs",
|
|
20
20
|
"test": "vitest run"
|
|
21
21
|
},
|
|
22
|
+
"optionalDependencies": {
|
|
23
|
+
"koffi": "^2.9.0"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@sage/core": "workspace:*"
|
|
27
|
+
},
|
|
22
28
|
"devDependencies": {
|
|
23
|
-
"@sage/core": "workspace:*",
|
|
24
29
|
"@types/node": "^22.0.0",
|
|
25
30
|
"esbuild": "^0.25.0",
|
|
26
31
|
"typescript": "^5.9.0",
|
|
@@ -34,6 +39,17 @@
|
|
|
34
39
|
"engines": {
|
|
35
40
|
"node": ">=18"
|
|
36
41
|
},
|
|
42
|
+
"keywords": [
|
|
43
|
+
"openclaw",
|
|
44
|
+
"openclaw-plugin",
|
|
45
|
+
"security",
|
|
46
|
+
"adr",
|
|
47
|
+
"agent-security",
|
|
48
|
+
"safety",
|
|
49
|
+
"malware-detection",
|
|
50
|
+
"skill",
|
|
51
|
+
"ai-safety"
|
|
52
|
+
],
|
|
37
53
|
"publishConfig": {
|
|
38
54
|
"access": "public"
|
|
39
55
|
}
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
severity: critical
|
|
67
67
|
confidence: 0.95
|
|
68
68
|
action: block
|
|
69
|
-
pattern: "\\brm\\s+(-[a-zA-Z]*f[a-zA-Z]*\\s+)?(-[a-zA-Z]*r[a-zA-Z]*\\s+)
|
|
69
|
+
pattern: "\\brm\\s+(-[a-zA-Z]*f[a-zA-Z]*\\s+)?(-[a-zA-Z]*r[a-zA-Z]*\\s+)?/(\\s|$|[;&|*])|\\brm\\s+(-[a-zA-Z]*r[a-zA-Z]*\\s+)?(-[a-zA-Z]*f[a-zA-Z]*\\s+)?/(\\s|$|[;&|*])|\\brm\\s+-[a-zA-Z]*rf[a-zA-Z]*\\s+/(\\s|$|[;&|*])"
|
|
70
70
|
match_on: command
|
|
71
71
|
title: "Recursive forced deletion from root"
|
|
72
72
|
expires_at: null
|
|
@@ -255,3 +255,53 @@
|
|
|
255
255
|
title: "Loop executing shell or download commands"
|
|
256
256
|
expires_at: null
|
|
257
257
|
revoked: false
|
|
258
|
+
|
|
259
|
+
# --- Cross-platform reverse shells (scripting languages) ---
|
|
260
|
+
|
|
261
|
+
# Python socket reverse shell
|
|
262
|
+
- id: "CLT-CMD-023"
|
|
263
|
+
category: tool
|
|
264
|
+
severity: critical
|
|
265
|
+
confidence: 0.90
|
|
266
|
+
action: block
|
|
267
|
+
pattern: "python[23]?\\s+-c.*socket.*connect.*(\\/bin\\/zsh|\\/bin\\/sh|\\/bin\\/bash)"
|
|
268
|
+
match_on: command
|
|
269
|
+
title: "Python reverse shell via socket"
|
|
270
|
+
expires_at: null
|
|
271
|
+
revoked: false
|
|
272
|
+
|
|
273
|
+
# Ruby TCPSocket reverse shell
|
|
274
|
+
- id: "CLT-CMD-024"
|
|
275
|
+
category: tool
|
|
276
|
+
severity: critical
|
|
277
|
+
confidence: 0.90
|
|
278
|
+
action: block
|
|
279
|
+
pattern: "ruby\\s+-e.*TCPSocket.*exec.*(\\/bin\\/zsh|\\/bin\\/sh)"
|
|
280
|
+
match_on: command
|
|
281
|
+
title: "Ruby reverse shell via TCPSocket"
|
|
282
|
+
expires_at: null
|
|
283
|
+
revoked: false
|
|
284
|
+
|
|
285
|
+
# zsh -c reverse shell pattern
|
|
286
|
+
- id: "CLT-CMD-025"
|
|
287
|
+
category: tool
|
|
288
|
+
severity: critical
|
|
289
|
+
confidence: 0.90
|
|
290
|
+
action: block
|
|
291
|
+
pattern: "\\bzsh\\s+-c\\b.*\\b(exec|socket|/dev/tcp)\\b"
|
|
292
|
+
match_on: command
|
|
293
|
+
title: "Zsh reverse shell pattern"
|
|
294
|
+
expires_at: null
|
|
295
|
+
revoked: false
|
|
296
|
+
|
|
297
|
+
# --- Recursive deletion of critical system directories ---
|
|
298
|
+
- id: "CLT-CMD-026"
|
|
299
|
+
category: tool
|
|
300
|
+
severity: critical
|
|
301
|
+
confidence: 0.95
|
|
302
|
+
action: block
|
|
303
|
+
pattern: "\\brm\\s+(-[a-zA-Z]+\\s+)*-[a-zA-Z]*[rR][a-zA-Z]*(\\s+-[a-zA-Z]+)*\\s+/(home|Users|etc|usr|var|boot|bin|sbin|lib|lib64|opt|root|System|Applications|Library|Volumes|private|mnt)\\b/?(\\s|$|[;&|])"
|
|
304
|
+
match_on: command
|
|
305
|
+
title: "Recursive deletion of critical system directory"
|
|
306
|
+
expires_at: null
|
|
307
|
+
revoked: false
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
severity: high
|
|
33
33
|
confidence: 0.80
|
|
34
34
|
action: require_approval
|
|
35
|
-
pattern: "(>>|>)\\s*\\.env(\\.local|\\.production|\\.staging|\\.development)?\\b"
|
|
35
|
+
pattern: "(>>|>)\\s*\\.env(?!\\S*\\.(example|sample|template|dist)\\b)(\\.local|\\.production|\\.prod|\\.staging|\\.stage|\\.development|\\.dev|\\.test)?\\b"
|
|
36
36
|
match_on: command
|
|
37
37
|
title: "Write/append to .env file (potential credential exposure)"
|
|
38
38
|
expires_at: null
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
severity: high
|
|
45
45
|
confidence: 0.80
|
|
46
46
|
action: require_approval
|
|
47
|
-
pattern: "\\b(cat|less|more|head|tail)\\s+.*(\\.(env|
|
|
47
|
+
pattern: "\\b(cat|less|more|head|tail)\\s+.*(\\.(env(?!\\S*\\.(example|sample|template|dist)\\b)(\\.(local|production|prod|staging|stage|development|dev|test))?)|credentials|\\.aws/credentials|\\.ssh/id_rsa|\\.ssh/id_ed25519|\\.netrc|\\.pgpass)"
|
|
48
48
|
match_on: command
|
|
49
49
|
title: "Reading credential or secret file"
|
|
50
50
|
expires_at: null
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Sensitive file path threat patterns for Sage
|
|
2
2
|
# Author: Gen Digital Inc.
|
|
3
3
|
# License: DRL-1.1 (see threats/LICENSE)
|
|
4
|
-
# Detects Write/Edit operations targeting security-sensitive files
|
|
4
|
+
# Detects Read/Write/Edit/Delete operations targeting security-sensitive files
|
|
5
5
|
|
|
6
6
|
# --- System auth files ---
|
|
7
7
|
- id: "CLT-FILE-001"
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
action: block
|
|
12
12
|
pattern: "(/etc/passwd|/etc/shadow|/etc/sudoers)"
|
|
13
13
|
match_on: file_path
|
|
14
|
-
title: "
|
|
14
|
+
title: "Access system authentication file"
|
|
15
15
|
expires_at: null
|
|
16
16
|
revoked: false
|
|
17
17
|
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
action: block
|
|
24
24
|
pattern: "\\.ssh/authorized_keys"
|
|
25
25
|
match_on: file_path
|
|
26
|
-
title: "
|
|
26
|
+
title: "Access SSH authorized_keys (unauthorized access persistence)"
|
|
27
27
|
expires_at: null
|
|
28
28
|
revoked: false
|
|
29
29
|
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
action: require_approval
|
|
36
36
|
pattern: "\\.ssh/(id_rsa|id_ed25519|id_ecdsa|id_dsa|config)$"
|
|
37
37
|
match_on: file_path
|
|
38
|
-
title: "
|
|
38
|
+
title: "Access SSH key or config file"
|
|
39
39
|
expires_at: null
|
|
40
40
|
revoked: false
|
|
41
41
|
|
|
@@ -47,19 +47,7 @@
|
|
|
47
47
|
action: require_approval
|
|
48
48
|
pattern: "\\.(bashrc|zshrc|profile|bash_profile|zprofile|zshenv)$"
|
|
49
49
|
match_on: file_path
|
|
50
|
-
title: "
|
|
51
|
-
expires_at: null
|
|
52
|
-
revoked: false
|
|
53
|
-
|
|
54
|
-
# --- macOS LaunchAgents/LaunchDaemons ---
|
|
55
|
-
- id: "CLT-FILE-005"
|
|
56
|
-
category: tool
|
|
57
|
-
severity: high
|
|
58
|
-
confidence: 0.90
|
|
59
|
-
action: block
|
|
60
|
-
pattern: "(LaunchAgents|LaunchDaemons)/.*\\.plist$"
|
|
61
|
-
match_on: file_path
|
|
62
|
-
title: "Write to macOS LaunchAgent/LaunchDaemon plist"
|
|
50
|
+
title: "Access shell RC file (persistence mechanism)"
|
|
63
51
|
expires_at: null
|
|
64
52
|
revoked: false
|
|
65
53
|
|
|
@@ -71,7 +59,7 @@
|
|
|
71
59
|
action: require_approval
|
|
72
60
|
pattern: "(/etc/cron\\.(d|daily|hourly|weekly|monthly)/|/var/spool/cron/)"
|
|
73
61
|
match_on: file_path
|
|
74
|
-
title: "
|
|
62
|
+
title: "Access cron directory"
|
|
75
63
|
expires_at: null
|
|
76
64
|
revoked: false
|
|
77
65
|
|
|
@@ -83,19 +71,23 @@
|
|
|
83
71
|
action: require_approval
|
|
84
72
|
pattern: "/etc/systemd/system/"
|
|
85
73
|
match_on: file_path
|
|
86
|
-
title: "
|
|
74
|
+
title: "Access systemd service unit file"
|
|
87
75
|
expires_at: null
|
|
88
76
|
revoked: false
|
|
89
77
|
|
|
90
78
|
# --- Credential/env files ---
|
|
79
|
+
# NOTE: Uses allowlist approach (explicit suffix enumeration) unlike CLT-CRED-003's
|
|
80
|
+
# denylist approach (negative lookahead). This means unknown suffixes like .env.ci
|
|
81
|
+
# match CRED-003 but not FILE-008 — intentional, since file_path matching is more
|
|
82
|
+
# targeted than command-string matching.
|
|
91
83
|
- id: "CLT-FILE-008"
|
|
92
84
|
category: secrets
|
|
93
85
|
severity: high
|
|
94
86
|
confidence: 0.85
|
|
95
87
|
action: require_approval
|
|
96
|
-
pattern: "(\\.env(\\.local|\\.production|\\.staging|\\.development)?|\\.aws/credentials|\\.netrc|\\.pgpass)$"
|
|
88
|
+
pattern: "((^|[\\/\\\\])\\.env(\\.local|\\.production|\\.prod|\\.staging|\\.stage|\\.development|\\.dev|\\.test)?|\\.aws/credentials|\\.netrc|\\.pgpass)$"
|
|
97
89
|
match_on: file_path
|
|
98
|
-
title: "
|
|
90
|
+
title: "Access credential or environment file"
|
|
99
91
|
expires_at: null
|
|
100
92
|
revoked: false
|
|
101
93
|
|
|
@@ -107,6 +99,6 @@
|
|
|
107
99
|
action: require_approval
|
|
108
100
|
pattern: "\\.git/hooks/"
|
|
109
101
|
match_on: file_path
|
|
110
|
-
title: "
|
|
102
|
+
title: "Access git hook (potential code execution on git events)"
|
|
111
103
|
expires_at: null
|
|
112
104
|
revoked: false
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
# macOS command threat patterns for Sage
|
|
2
|
+
# Author: Gen Digital Inc.
|
|
3
|
+
# License: DRL-1.1 (see threats/LICENSE)
|
|
4
|
+
# Covers: osascript RCE, macOS LOLBins, destructive ops, defense evasion, privesc, reverse shells
|
|
5
|
+
|
|
6
|
+
# --- osascript Remote Code Execution ---
|
|
7
|
+
|
|
8
|
+
# osascript -e 'do shell script' (AppleScript shell execution)
|
|
9
|
+
- id: "CLT-MAC-CMD-001"
|
|
10
|
+
category: tool
|
|
11
|
+
severity: critical
|
|
12
|
+
confidence: 0.95
|
|
13
|
+
action: block
|
|
14
|
+
pattern: "\\bosascript\\b.*-e.*do shell script"
|
|
15
|
+
case_insensitive: true
|
|
16
|
+
match_on: command
|
|
17
|
+
title: "AppleScript shell execution via osascript -e"
|
|
18
|
+
expires_at: null
|
|
19
|
+
revoked: false
|
|
20
|
+
|
|
21
|
+
# osascript -l JavaScript (JXA execution)
|
|
22
|
+
- id: "CLT-MAC-CMD-002"
|
|
23
|
+
category: tool
|
|
24
|
+
severity: critical
|
|
25
|
+
confidence: 0.90
|
|
26
|
+
action: block
|
|
27
|
+
pattern: "\\bosascript\\b.*-l\\s+JavaScript"
|
|
28
|
+
case_insensitive: true
|
|
29
|
+
match_on: command
|
|
30
|
+
title: "JavaScript for Automation (JXA) execution via osascript"
|
|
31
|
+
expires_at: null
|
|
32
|
+
revoked: false
|
|
33
|
+
|
|
34
|
+
# Pipe to osascript (stdin AppleScript execution)
|
|
35
|
+
- id: "CLT-MAC-CMD-003"
|
|
36
|
+
category: tool
|
|
37
|
+
severity: critical
|
|
38
|
+
confidence: 0.90
|
|
39
|
+
action: block
|
|
40
|
+
pattern: "\\|\\s*osascript"
|
|
41
|
+
match_on: command
|
|
42
|
+
title: "Piped input to osascript (stdin AppleScript execution)"
|
|
43
|
+
expires_at: null
|
|
44
|
+
revoked: false
|
|
45
|
+
|
|
46
|
+
# osascript loading script file from remote download
|
|
47
|
+
- id: "CLT-MAC-CMD-004"
|
|
48
|
+
category: tool
|
|
49
|
+
severity: critical
|
|
50
|
+
confidence: 0.90
|
|
51
|
+
action: block
|
|
52
|
+
pattern: "(curl|wget).*\\|.*osascript|osascript.*(curl|wget)"
|
|
53
|
+
case_insensitive: true
|
|
54
|
+
match_on: command
|
|
55
|
+
title: "Remote script download piped to osascript"
|
|
56
|
+
expires_at: null
|
|
57
|
+
revoked: false
|
|
58
|
+
|
|
59
|
+
# --- open command abuse ---
|
|
60
|
+
|
|
61
|
+
# open -a Terminal (launch Terminal with script)
|
|
62
|
+
- id: "CLT-MAC-CMD-005"
|
|
63
|
+
category: tool
|
|
64
|
+
severity: high
|
|
65
|
+
confidence: 0.80
|
|
66
|
+
action: require_approval
|
|
67
|
+
pattern: "\\bopen\\s+-a\\s+Terminal"
|
|
68
|
+
match_on: command
|
|
69
|
+
title: "Launch Terminal application via open -a"
|
|
70
|
+
expires_at: null
|
|
71
|
+
revoked: false
|
|
72
|
+
|
|
73
|
+
# open with hidden/background flags
|
|
74
|
+
- id: "CLT-MAC-CMD-006"
|
|
75
|
+
category: tool
|
|
76
|
+
severity: high
|
|
77
|
+
confidence: 0.85
|
|
78
|
+
action: require_approval
|
|
79
|
+
pattern: "\\bopen\\s+(-[jg]|--hide|--background)"
|
|
80
|
+
match_on: command
|
|
81
|
+
title: "Launch application hidden/background via open"
|
|
82
|
+
expires_at: null
|
|
83
|
+
revoked: false
|
|
84
|
+
|
|
85
|
+
# --- macOS LOLBins ---
|
|
86
|
+
|
|
87
|
+
# dscl user/group manipulation
|
|
88
|
+
- id: "CLT-MAC-CMD-007"
|
|
89
|
+
category: tool
|
|
90
|
+
severity: high
|
|
91
|
+
confidence: 0.85
|
|
92
|
+
action: require_approval
|
|
93
|
+
pattern: "\\bdscl\\b.*(-create|-delete|-passwd|-append)"
|
|
94
|
+
match_on: command
|
|
95
|
+
title: "Directory Services user/group manipulation via dscl"
|
|
96
|
+
expires_at: null
|
|
97
|
+
revoked: false
|
|
98
|
+
|
|
99
|
+
# networksetup proxy/DNS manipulation
|
|
100
|
+
- id: "CLT-MAC-CMD-008"
|
|
101
|
+
category: tool
|
|
102
|
+
severity: high
|
|
103
|
+
confidence: 0.85
|
|
104
|
+
action: require_approval
|
|
105
|
+
pattern: "\\bnetworksetup\\b.*(-setwebproxy|-setsocksfirewallproxy|-setdnsservers|-setautoproxyurl)"
|
|
106
|
+
case_insensitive: true
|
|
107
|
+
match_on: command
|
|
108
|
+
title: "Network proxy/DNS manipulation via networksetup"
|
|
109
|
+
expires_at: null
|
|
110
|
+
revoked: false
|
|
111
|
+
|
|
112
|
+
# systemsetup enabling remote access
|
|
113
|
+
- id: "CLT-MAC-CMD-009"
|
|
114
|
+
category: tool
|
|
115
|
+
severity: critical
|
|
116
|
+
confidence: 0.90
|
|
117
|
+
action: block
|
|
118
|
+
pattern: "\\bsystemsetup\\b.*(-setremotelogin\\s+on|-setwakeonnetworkaccess\\s+on)"
|
|
119
|
+
case_insensitive: true
|
|
120
|
+
match_on: command
|
|
121
|
+
title: "Enable remote login/wake via systemsetup"
|
|
122
|
+
expires_at: null
|
|
123
|
+
revoked: false
|
|
124
|
+
|
|
125
|
+
# kickstart ARD remote management
|
|
126
|
+
- id: "CLT-MAC-CMD-010"
|
|
127
|
+
category: tool
|
|
128
|
+
severity: critical
|
|
129
|
+
confidence: 0.90
|
|
130
|
+
action: block
|
|
131
|
+
pattern: "kickstart.*-activate.*-configure"
|
|
132
|
+
case_insensitive: true
|
|
133
|
+
match_on: command
|
|
134
|
+
title: "Apple Remote Desktop activation via kickstart"
|
|
135
|
+
expires_at: null
|
|
136
|
+
revoked: false
|
|
137
|
+
|
|
138
|
+
# installer -pkg -target / (silent package install)
|
|
139
|
+
- id: "CLT-MAC-CMD-011"
|
|
140
|
+
category: tool
|
|
141
|
+
severity: high
|
|
142
|
+
confidence: 0.85
|
|
143
|
+
action: require_approval
|
|
144
|
+
pattern: "\\binstaller\\b.*-pkg.*-target"
|
|
145
|
+
case_insensitive: true
|
|
146
|
+
match_on: command
|
|
147
|
+
title: "Silent package install via installer command"
|
|
148
|
+
expires_at: null
|
|
149
|
+
revoked: false
|
|
150
|
+
|
|
151
|
+
# hdiutil mount remote DMG
|
|
152
|
+
- id: "CLT-MAC-CMD-012"
|
|
153
|
+
category: tool
|
|
154
|
+
severity: high
|
|
155
|
+
confidence: 0.85
|
|
156
|
+
action: require_approval
|
|
157
|
+
pattern: "\\bhdiutil\\b.*\\b(attach|mount)\\b.*https?://"
|
|
158
|
+
case_insensitive: true
|
|
159
|
+
match_on: command
|
|
160
|
+
title: "Mount remote DMG via hdiutil"
|
|
161
|
+
expires_at: null
|
|
162
|
+
revoked: false
|
|
163
|
+
|
|
164
|
+
# pkgutil --forget (package receipt manipulation)
|
|
165
|
+
- id: "CLT-MAC-CMD-013"
|
|
166
|
+
category: tool
|
|
167
|
+
severity: high
|
|
168
|
+
confidence: 0.80
|
|
169
|
+
action: require_approval
|
|
170
|
+
pattern: "\\bpkgutil\\b.*--forget"
|
|
171
|
+
match_on: command
|
|
172
|
+
title: "Package receipt removal via pkgutil --forget"
|
|
173
|
+
expires_at: null
|
|
174
|
+
revoked: false
|
|
175
|
+
|
|
176
|
+
# --- Destructive Operations ---
|
|
177
|
+
|
|
178
|
+
# diskutil eraseDisk
|
|
179
|
+
- id: "CLT-MAC-CMD-014"
|
|
180
|
+
category: tool
|
|
181
|
+
severity: critical
|
|
182
|
+
confidence: 0.95
|
|
183
|
+
action: block
|
|
184
|
+
pattern: "\\bdiskutil\\b.*\\b(eraseDisk|partitionDisk|secureErase)\\b"
|
|
185
|
+
match_on: command
|
|
186
|
+
title: "Disk erase/partition via diskutil"
|
|
187
|
+
expires_at: null
|
|
188
|
+
revoked: false
|
|
189
|
+
|
|
190
|
+
# tmutil delete (Time Machine backup deletion — ransomware indicator)
|
|
191
|
+
- id: "CLT-MAC-CMD-015"
|
|
192
|
+
category: tool
|
|
193
|
+
severity: critical
|
|
194
|
+
confidence: 0.95
|
|
195
|
+
action: block
|
|
196
|
+
pattern: "\\btmutil\\b.*\\b(delete|disable)\\b"
|
|
197
|
+
match_on: command
|
|
198
|
+
title: "Time Machine backup deletion/disable via tmutil (ransomware indicator)"
|
|
199
|
+
expires_at: null
|
|
200
|
+
revoked: false
|
|
201
|
+
|
|
202
|
+
# --- Defense Evasion ---
|
|
203
|
+
|
|
204
|
+
# spctl --master-disable (Gatekeeper disable)
|
|
205
|
+
- id: "CLT-MAC-CMD-016"
|
|
206
|
+
category: tool
|
|
207
|
+
severity: critical
|
|
208
|
+
confidence: 0.95
|
|
209
|
+
action: block
|
|
210
|
+
pattern: "\\bspctl\\b.*--master-disable"
|
|
211
|
+
match_on: command
|
|
212
|
+
title: "Gatekeeper disable via spctl --master-disable"
|
|
213
|
+
expires_at: null
|
|
214
|
+
revoked: false
|
|
215
|
+
|
|
216
|
+
# csrutil disable (SIP disable)
|
|
217
|
+
- id: "CLT-MAC-CMD-017"
|
|
218
|
+
category: tool
|
|
219
|
+
severity: critical
|
|
220
|
+
confidence: 0.95
|
|
221
|
+
action: block
|
|
222
|
+
pattern: "\\bcsrutil\\b.*\\bdisable\\b"
|
|
223
|
+
match_on: command
|
|
224
|
+
title: "System Integrity Protection disable via csrutil"
|
|
225
|
+
expires_at: null
|
|
226
|
+
revoked: false
|
|
227
|
+
|
|
228
|
+
# defaults write LSQuarantine (quarantine flag disable)
|
|
229
|
+
- id: "CLT-MAC-CMD-018"
|
|
230
|
+
category: tool
|
|
231
|
+
severity: critical
|
|
232
|
+
confidence: 0.90
|
|
233
|
+
action: block
|
|
234
|
+
pattern: "\\bdefaults\\b.*\\bwrite\\b.*LSQuarantine"
|
|
235
|
+
case_insensitive: true
|
|
236
|
+
match_on: command
|
|
237
|
+
title: "Quarantine flag disable via defaults write LSQuarantine"
|
|
238
|
+
expires_at: null
|
|
239
|
+
revoked: false
|
|
240
|
+
|
|
241
|
+
# xattr -d com.apple.quarantine (quarantine removal)
|
|
242
|
+
- id: "CLT-MAC-CMD-019"
|
|
243
|
+
category: tool
|
|
244
|
+
severity: high
|
|
245
|
+
confidence: 0.85
|
|
246
|
+
action: require_approval
|
|
247
|
+
pattern: "\\bxattr\\b.*-d.*com\\.apple\\.quarantine"
|
|
248
|
+
match_on: command
|
|
249
|
+
title: "Quarantine attribute removal via xattr"
|
|
250
|
+
expires_at: null
|
|
251
|
+
revoked: false
|
|
252
|
+
|
|
253
|
+
# pfctl -d (packet filter / firewall disable)
|
|
254
|
+
- id: "CLT-MAC-CMD-020"
|
|
255
|
+
category: tool
|
|
256
|
+
severity: critical
|
|
257
|
+
confidence: 0.90
|
|
258
|
+
action: block
|
|
259
|
+
pattern: "\\bpfctl\\b.*\\s-d\\b"
|
|
260
|
+
match_on: command
|
|
261
|
+
title: "Packet filter (firewall) disable via pfctl -d"
|
|
262
|
+
expires_at: null
|
|
263
|
+
revoked: false
|
|
264
|
+
|
|
265
|
+
# tccutil reset (TCC privacy permissions reset)
|
|
266
|
+
- id: "CLT-MAC-CMD-021"
|
|
267
|
+
category: tool
|
|
268
|
+
severity: critical
|
|
269
|
+
confidence: 0.90
|
|
270
|
+
action: block
|
|
271
|
+
pattern: "\\btccutil\\b.*\\breset\\b"
|
|
272
|
+
match_on: command
|
|
273
|
+
title: "TCC privacy permissions reset via tccutil"
|
|
274
|
+
expires_at: null
|
|
275
|
+
revoked: false
|
|
276
|
+
|
|
277
|
+
# launchctl unload security daemons
|
|
278
|
+
- id: "CLT-MAC-CMD-022"
|
|
279
|
+
category: tool
|
|
280
|
+
severity: critical
|
|
281
|
+
confidence: 0.90
|
|
282
|
+
action: block
|
|
283
|
+
pattern: "\\blaunchctl\\b.*\\b(unload|bootout)\\b.*(com\\.apple\\.MRT|com\\.apple\\.XProtect|com\\.apple\\.security)"
|
|
284
|
+
case_insensitive: true
|
|
285
|
+
match_on: command
|
|
286
|
+
title: "Unload macOS security daemon via launchctl"
|
|
287
|
+
expires_at: null
|
|
288
|
+
revoked: false
|
|
289
|
+
|
|
290
|
+
# defaults write to disable macOS security features
|
|
291
|
+
- id: "CLT-MAC-CMD-023"
|
|
292
|
+
category: tool
|
|
293
|
+
severity: critical
|
|
294
|
+
confidence: 0.90
|
|
295
|
+
action: block
|
|
296
|
+
pattern: "\\bdefaults\\b.*\\bwrite\\b.*(com\\.apple\\.Finder\\s+AppleShowAllFiles|com\\.apple\\.LaunchServices\\s+LSQuarantine|com\\.apple\\.loginwindow)"
|
|
297
|
+
case_insensitive: true
|
|
298
|
+
match_on: command
|
|
299
|
+
title: "Modify macOS security-related defaults"
|
|
300
|
+
expires_at: null
|
|
301
|
+
revoked: false
|
|
302
|
+
|
|
303
|
+
# --- Privilege Escalation ---
|
|
304
|
+
|
|
305
|
+
# dscl . -passwd (change user password)
|
|
306
|
+
- id: "CLT-MAC-CMD-024"
|
|
307
|
+
category: tool
|
|
308
|
+
severity: critical
|
|
309
|
+
confidence: 0.90
|
|
310
|
+
action: block
|
|
311
|
+
pattern: "\\bdscl\\b.*\\s-passwd\\b"
|
|
312
|
+
match_on: command
|
|
313
|
+
title: "User password change via dscl"
|
|
314
|
+
expires_at: null
|
|
315
|
+
revoked: false
|
|
316
|
+
|
|
317
|
+
# dseditgroup add user to admin
|
|
318
|
+
- id: "CLT-MAC-CMD-025"
|
|
319
|
+
category: tool
|
|
320
|
+
severity: critical
|
|
321
|
+
confidence: 0.95
|
|
322
|
+
action: block
|
|
323
|
+
pattern: "\\bdseditgroup\\b.*-o\\s+edit.*-a.*admin"
|
|
324
|
+
match_on: command
|
|
325
|
+
title: "Add user to admin group via dseditgroup"
|
|
326
|
+
expires_at: null
|
|
327
|
+
revoked: false
|
|
328
|
+
|
|
329
|
+
# createhomedir — create home directory for arbitrary user
|
|
330
|
+
- id: "CLT-MAC-CMD-026"
|
|
331
|
+
category: tool
|
|
332
|
+
severity: high
|
|
333
|
+
confidence: 0.80
|
|
334
|
+
action: require_approval
|
|
335
|
+
pattern: "\\bcreatehomedir\\b"
|
|
336
|
+
match_on: command
|
|
337
|
+
title: "Create home directory for user via createhomedir"
|
|
338
|
+
expires_at: null
|
|
339
|
+
revoked: false
|
|
340
|
+
|
|
341
|
+
# Reverse shells (Python, Ruby, zsh) moved to commands.yaml (CLT-CMD-023..025)
|
|
342
|
+
|
|
343
|
+
# --- Clipboard / Screen Capture ---
|
|
344
|
+
|
|
345
|
+
# screencapture to remote or hidden location
|
|
346
|
+
- id: "CLT-MAC-CMD-027"
|
|
347
|
+
category: tool
|
|
348
|
+
severity: high
|
|
349
|
+
confidence: 0.80
|
|
350
|
+
action: require_approval
|
|
351
|
+
pattern: "\\bscreencapture\\b.*(-x|-C)"
|
|
352
|
+
match_on: command
|
|
353
|
+
title: "Silent screen capture via screencapture"
|
|
354
|
+
expires_at: null
|
|
355
|
+
revoked: false
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# macOS credential exposure threat patterns for Sage
|
|
2
|
+
# Author: Gen Digital Inc.
|
|
3
|
+
# License: DRL-1.1 (see threats/LICENSE)
|
|
4
|
+
|
|
5
|
+
# Keychain password extraction (find-generic-password)
|
|
6
|
+
- id: "CLT-MAC-CRED-001"
|
|
7
|
+
category: secrets
|
|
8
|
+
severity: critical
|
|
9
|
+
confidence: 0.95
|
|
10
|
+
action: block
|
|
11
|
+
pattern: "\\bsecurity\\b.*\\bfind-generic-password\\b.*-w"
|
|
12
|
+
match_on: command
|
|
13
|
+
title: "Keychain password extraction via security find-generic-password"
|
|
14
|
+
expires_at: null
|
|
15
|
+
revoked: false
|
|
16
|
+
|
|
17
|
+
# Keychain internet password extraction
|
|
18
|
+
- id: "CLT-MAC-CRED-002"
|
|
19
|
+
category: secrets
|
|
20
|
+
severity: critical
|
|
21
|
+
confidence: 0.95
|
|
22
|
+
action: block
|
|
23
|
+
pattern: "\\bsecurity\\b.*\\bfind-internet-password\\b.*-w"
|
|
24
|
+
match_on: command
|
|
25
|
+
title: "Keychain internet password extraction via security find-internet-password"
|
|
26
|
+
expires_at: null
|
|
27
|
+
revoked: false
|
|
28
|
+
|
|
29
|
+
# Keychain dump
|
|
30
|
+
- id: "CLT-MAC-CRED-003"
|
|
31
|
+
category: secrets
|
|
32
|
+
severity: critical
|
|
33
|
+
confidence: 0.95
|
|
34
|
+
action: block
|
|
35
|
+
pattern: "\\bsecurity\\b.*\\bdump-keychain\\b"
|
|
36
|
+
match_on: command
|
|
37
|
+
title: "Full keychain dump via security dump-keychain"
|
|
38
|
+
expires_at: null
|
|
39
|
+
revoked: false
|
|
40
|
+
|
|
41
|
+
# Keychain unlock with plaintext password
|
|
42
|
+
- id: "CLT-MAC-CRED-004"
|
|
43
|
+
category: secrets
|
|
44
|
+
severity: critical
|
|
45
|
+
confidence: 0.90
|
|
46
|
+
action: block
|
|
47
|
+
pattern: "\\bsecurity\\b.*\\bunlock-keychain\\b.*-p"
|
|
48
|
+
match_on: command
|
|
49
|
+
title: "Keychain unlock with plaintext password"
|
|
50
|
+
expires_at: null
|
|
51
|
+
revoked: false
|
|
52
|
+
|
|
53
|
+
# Keychain export
|
|
54
|
+
- id: "CLT-MAC-CRED-005"
|
|
55
|
+
category: secrets
|
|
56
|
+
severity: high
|
|
57
|
+
confidence: 0.85
|
|
58
|
+
action: require_approval
|
|
59
|
+
pattern: "\\bsecurity\\b.*\\bexport\\b.*-k"
|
|
60
|
+
match_on: command
|
|
61
|
+
title: "Keychain item export via security export"
|
|
62
|
+
expires_at: null
|
|
63
|
+
revoked: false
|
|
64
|
+
|
|
65
|
+
# Keychain deletion
|
|
66
|
+
- id: "CLT-MAC-CRED-006"
|
|
67
|
+
category: secrets
|
|
68
|
+
severity: critical
|
|
69
|
+
confidence: 0.90
|
|
70
|
+
action: block
|
|
71
|
+
pattern: "\\bsecurity\\b.*\\bdelete-keychain\\b"
|
|
72
|
+
match_on: command
|
|
73
|
+
title: "Keychain deletion via security delete-keychain"
|
|
74
|
+
expires_at: null
|
|
75
|
+
revoked: false
|
|
76
|
+
|
|
77
|
+
# Directory Services auth data read
|
|
78
|
+
- id: "CLT-MAC-CRED-007"
|
|
79
|
+
category: secrets
|
|
80
|
+
severity: high
|
|
81
|
+
confidence: 0.85
|
|
82
|
+
action: require_approval
|
|
83
|
+
pattern: "\\bdscl\\b.*-read.*(AuthenticationAuthority|Password|ShadowHash)"
|
|
84
|
+
match_on: command
|
|
85
|
+
title: "Read user authentication data via dscl"
|
|
86
|
+
expires_at: null
|
|
87
|
+
revoked: false
|
|
88
|
+
|
|
89
|
+
# Direct Keychain SQLite access
|
|
90
|
+
- id: "CLT-MAC-CRED-008"
|
|
91
|
+
category: secrets
|
|
92
|
+
severity: critical
|
|
93
|
+
confidence: 0.90
|
|
94
|
+
action: block
|
|
95
|
+
pattern: "\\bsqlite3\\b.*(/Library/Keychains/|login\\.keychain)"
|
|
96
|
+
match_on: command
|
|
97
|
+
title: "Direct Keychain database access via sqlite3"
|
|
98
|
+
expires_at: null
|
|
99
|
+
revoked: false
|