@gendigital/sage-opencode 0.12.0 → 0.13.0

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.
Files changed (31) hide show
  1. package/dist/mcp-server.cjs +38 -10
  2. package/dist/mcp-server.cjs.map +2 -2
  3. package/dist/tool-handler.d.ts.map +1 -1
  4. package/dist/tool-handler.js +5 -3
  5. package/dist/tool-handler.js.map +1 -1
  6. package/package.json +3 -3
  7. package/resources/threats/_macros.yaml +193 -0
  8. package/resources/threats/agent-layer.yaml +19 -1
  9. package/resources/threats/commands.yaml +165 -31
  10. package/resources/threats/credentials.yaml +24 -4
  11. package/resources/threats/dummy.yaml +30 -0
  12. package/resources/threats/files.yaml +38 -0
  13. package/resources/threats/mac-commands.yaml +118 -27
  14. package/resources/threats/mac-credentials.yaml +34 -8
  15. package/resources/threats/mac-files.yaml +20 -0
  16. package/resources/threats/mac-obfuscation.yaml +28 -6
  17. package/resources/threats/mac-persistence.yaml +30 -4
  18. package/resources/threats/mac-supply-chain.yaml +12 -3
  19. package/resources/threats/mitre.yaml +325 -62
  20. package/resources/threats/obfuscation.yaml +33 -8
  21. package/resources/threats/persistence.yaml +40 -5
  22. package/resources/threats/prompt-injection.yaml +58 -0
  23. package/resources/threats/self-defense.yaml +15 -2
  24. package/resources/threats/supply_chain.yaml +6 -1
  25. package/resources/threats/urls.yaml +10 -0
  26. package/resources/threats/win-commands.yaml +294 -60
  27. package/resources/threats/win-credentials.yaml +68 -9
  28. package/resources/threats/win-files.yaml +20 -0
  29. package/resources/threats/win-obfuscation.yaml +56 -8
  30. package/resources/threats/win-persistence.yaml +45 -7
  31. package/resources/threats/win-supply-chain.yaml +5 -1
@@ -4,10 +4,14 @@
4
4
 
5
5
  # --- Base64 decode piped to shell ---
6
6
  - id: "CLT-OBFUS-001"
7
+ version: 1
8
+ detection_name: "CMD:SageObfuscation-A [Heur]"
7
9
  category: tool
8
10
  severity: critical
9
11
  confidence: 0.95
10
- pattern: "base64\\s+(-d|--decode)\\s*\\|\\s*(bash|sh|zsh|ksh|dash)"
12
+ # {{CMD_POS}} + {{NOT_FILENAME}} on both sides of the pipe, same shape as
13
+ # CLT-CMD-009. Had no boundary at all.
14
+ pattern: "{{CMD_POS}}base64{{NOT_FILENAME}}\\s+(-d|--decode)\\s*\\|\\s*(?:{{SHELLS}}){{NOT_FILENAME}}"
11
15
  match_on: command
12
16
  title: "Base64 decode piped to shell execution"
13
17
  expires_at: null
@@ -15,10 +19,14 @@
15
19
 
16
20
  # --- Hex escape sequences in printf ---
17
21
  - id: "CLT-OBFUS-002"
22
+ version: 1
23
+ detection_name: "CMD:SageObfuscation-B [Heur]"
18
24
  category: tool
19
25
  severity: warning
20
26
  confidence: 0.60
21
- pattern: "printf\\s+[\"']\\\\x[0-9a-fA-F]{2}(\\\\x[0-9a-fA-F]{2}){3,}"
27
+ # {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-CMD-009. Had no
28
+ # boundary at all.
29
+ pattern: "{{CMD_POS}}printf{{NOT_FILENAME}}\\s+[\"']\\\\x[0-9a-fA-F]{2}(\\\\x[0-9a-fA-F]{2}){3,}"
22
30
  match_on: command
23
31
  title: "Hex escape sequences in printf (potential obfuscation)"
24
32
  expires_at: null
@@ -26,10 +34,12 @@
26
34
 
27
35
  # --- Reversed string piped to shell ---
28
36
  - id: "CLT-OBFUS-003"
37
+ version: 1
38
+ detection_name: "CMD:SageObfuscation-C [Heur]"
29
39
  category: tool
30
40
  severity: critical
31
41
  confidence: 0.90
32
- pattern: "\\|\\s*rev\\s*\\|\\s*(bash|sh|zsh|ksh|dash)"
42
+ pattern: "\\|\\s*rev\\s*\\|\\s*(?:{{SHELLS}})"
33
43
  match_on: command
34
44
  title: "Reversed string piped to shell execution"
35
45
  expires_at: null
@@ -37,10 +47,15 @@
37
47
 
38
48
  # --- Eval with decode ---
39
49
  - id: "CLT-OBFUS-004"
50
+ version: 1
51
+ detection_name: "CMD:SageObfuscation-D [Heur]"
40
52
  category: tool
41
53
  severity: critical
42
54
  confidence: 0.90
43
- pattern: "\\beval\\s+.*\\$\\(\\s*base64|python[3]?\\s+-c\\s+[\"'].*exec\\(.*decode"
55
+ # {{CMD_POS}} + {{NOT_FILENAME}} on both branches, same shape as
56
+ # CLT-CMD-009. `eval` had only a bare `\b`; `python` had no boundary at
57
+ # all.
58
+ pattern: "{{CMD_POS}}eval{{NOT_FILENAME}}\\s+.*\\$\\(\\s*base64|{{CMD_POS}}python[3]?{{NOT_FILENAME}}\\s+-c\\s+[\"'].*exec\\(.*decode"
44
59
  match_on: [command, content]
45
60
  title: "Eval with decode (obfuscated code execution)"
46
61
  expires_at: null
@@ -48,10 +63,12 @@
48
63
 
49
64
  # --- Shell metacharacter escaping ---
50
65
  - id: "CLT-OBFUS-005"
66
+ version: 1
67
+ detection_name: "CMD:SageObfuscation-E [Heur]"
51
68
  category: tool
52
69
  severity: warning
53
70
  confidence: 0.85
54
- pattern: "\\|\\s*[\\\\'\"]+(bash|sh|zsh|ksh|dash)[\\\\'\"]*(\\s|$)"
71
+ pattern: "\\|\\s*[\\\\'\"]+(?:{{SHELLS}})[\\\\'\"]*(\\s|$)"
55
72
  match_on: command
56
73
  title: "Shell metacharacter escaping to hide pipe target"
57
74
  expires_at: null
@@ -59,20 +76,24 @@
59
76
 
60
77
  # --- Alias/function redefinition ---
61
78
  - id: "CLT-OBFUS-006"
79
+ version: 1
80
+ detection_name: "CMD:SageObfuscation-F [Heur]"
62
81
  category: tool
63
82
  severity: warning
64
83
  confidence: 0.60
65
- pattern: "\\balias\\s+(bash|sh|zsh|curl|wget|nc|netcat|python|ruby|perl|node)="
84
+ pattern: "\\balias\\s+(?:{{SHELLS}}|curl|wget|nc|netcat|python|ruby|perl|node)="
66
85
  match_on: command
67
86
  title: "Alias redefinition of security-relevant command"
68
87
  expires_at: null
69
88
  revoked: false
70
89
 
71
90
  - id: "CLT-OBFUS-007"
91
+ version: 1
92
+ detection_name: "CMD:SageObfuscation-G [Heur]"
72
93
  category: tool
73
94
  severity: warning
74
95
  confidence: 0.60
75
- pattern: "\\b(function\\s+)?(bash|sh|curl|wget|nc|python|ruby|perl|node)\\s*\\(\\s*\\)"
96
+ pattern: "\\b(function\\s+)?(?:{{SHELLS}}|curl|wget|nc|python|ruby|perl|node)\\s*\\(\\s*\\)"
76
97
  match_on: command
77
98
  title: "Function redefinition of security-relevant command"
78
99
  expires_at: null
@@ -80,10 +101,14 @@
80
101
 
81
102
  # --- Python encoded payload execution ---
82
103
  - id: "CLT-OBFUS-008"
104
+ version: 1
105
+ detection_name: "CMD:SageObfuscation-H [Heur]"
83
106
  category: tool
84
107
  severity: critical
85
108
  confidence: 0.85
86
- pattern: "python[23]?\\s+-c\\s+[\"'].*\\b(exec|eval|compile|__import__)\\b.*\\b(base64|decode|decompress)\\b"
109
+ # {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-CMD-009. Had no
110
+ # boundary at all.
111
+ pattern: "{{CMD_POS}}python[23]?{{NOT_FILENAME}}\\s+-c\\s+[\"'].*\\b(exec|eval|compile|__import__)\\b.*\\b(base64|decode|decompress)\\b"
87
112
  match_on: command
88
113
  title: "Python encoded payload execution via -c"
89
114
  expires_at: null
@@ -4,10 +4,16 @@
4
4
 
5
5
  # --- Shell RC file modification ---
6
6
  - id: "CLT-PERSIST-001"
7
+ version: 1
8
+ detection_name: "CMD:SagePersistence-A [Heur]"
7
9
  category: tool
8
10
  severity: warning
9
11
  confidence: 0.60
10
- pattern: "(>>|>)\\s*~?/?(\\$HOME/)?\\.?(bashrc|zshrc|profile|bash_profile|zprofile|zshenv)"
12
+ # Exact dotfile basename required; an unbounded alternation matched `profile`
13
+ # as a prefix of longer names (`cat > profile.py`). The directory prefix is
14
+ # scoped to home forms so unrelated locations (`/tmp/.profile`,
15
+ # `./fixtures/.bashrc`) are not startup files and do not match.
16
+ pattern: "(?:>>|>)\\s*(?:(?:~|\\$HOME|/home/[^/\\s]+|/Users/[^/\\s]+)/)?\\.(?:bashrc|zshrc|zprofile|zshenv|bash_profile|profile)(?![\\w.-])"
11
17
  match_on: command
12
18
  title: "Write/append to shell RC file (persistence mechanism)"
13
19
  expires_at: null
@@ -15,10 +21,13 @@
15
21
 
16
22
  # --- Crontab manipulation ---
17
23
  - id: "CLT-PERSIST-002"
24
+ version: 1
25
+ detection_name: "CMD:SagePersistence-B [Heur]"
18
26
  category: tool
19
27
  severity: warning
20
28
  confidence: 0.60
21
- pattern: "\\bcrontab\\s+(-[er]|[^-])"
29
+ # {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-CMD-009.
30
+ pattern: "{{CMD_POS}}crontab{{NOT_FILENAME}}\\s+(-[er]|[^-])"
22
31
  match_on: command
23
32
  title: "Crontab manipulation (list, edit, or remove scheduled tasks)"
24
33
  expires_at: null
@@ -26,6 +35,8 @@
26
35
 
27
36
  # --- Cron directory writes ---
28
37
  - id: "CLT-PERSIST-003"
38
+ version: 1
39
+ detection_name: "CMD:SagePersistence-C [Heur]"
29
40
  category: tool
30
41
  severity: warning
31
42
  confidence: 0.60
@@ -37,10 +48,15 @@
37
48
 
38
49
  # --- systemd service manipulation ---
39
50
  - id: "CLT-PERSIST-005"
51
+ version: 1
52
+ detection_name: "CMD:SagePersistence-E [Heur]"
40
53
  category: tool
41
54
  severity: warning
42
55
  confidence: 0.60
43
- pattern: "\\bsystemctl\\s+(enable|start)\\b|/etc/systemd/system/"
56
+ # {{CMD_POS}} + {{NOT_FILENAME}} on the systemctl branch, same shape as
57
+ # CLT-CMD-009. The path-literal branch is left as-is -- it's a path
58
+ # mention, not a "program executing" check.
59
+ pattern: "{{CMD_POS}}systemctl{{NOT_FILENAME}}\\s+(enable|start)\\b|/etc/systemd/system/"
44
60
  match_on: command
45
61
  title: "systemd service enable/start or unit file write"
46
62
  expires_at: null
@@ -48,6 +64,8 @@
48
64
 
49
65
  # --- SSH authorized_keys modification ---
50
66
  - id: "CLT-PERSIST-006"
67
+ version: 1
68
+ detection_name: "CMD:SagePersistence-F [Heur]"
51
69
  category: tool
52
70
  severity: critical
53
71
  confidence: 0.95
@@ -59,10 +77,22 @@
59
77
 
60
78
  # --- Echo/printf append to shell RC files ---
61
79
  - id: "CLT-PERSIST-007"
80
+ version: 1
81
+ detection_name: "CMD:SagePersistence-G [Heur]"
62
82
  category: tool
63
83
  severity: critical
64
84
  confidence: 0.90
65
- pattern: "(echo|printf)\\s+.*>>\\s*~?/?(\\$HOME/)?\\.?(bashrc|zshrc|profile|bash_profile)"
85
+ # Deliberately narrower than CLT-PERSIST-001: this rule got the dot
86
+ # requirement and the trailing boundary, but not 001's home-directory path
87
+ # prefix. Widening it was out of scope for the false-positive fix that added
88
+ # that prefix, because confidence 0.90 denies at default sensitivity where
89
+ # 001's 0.60 only asks. Consequence: `>> /home/user/.bashrc` is matched by 001
90
+ # and not here. Unify only with intent.
91
+ #
92
+ # {{CMD_POS}} + {{NOT_FILENAME}} added separately: the verb alternation had
93
+ # no boundary at all, so `myecho evil >> ~/.bashrc` matched "echo" as a bare
94
+ # substring of "myecho".
95
+ pattern: "{{CMD_POS}}(echo|printf){{NOT_FILENAME}}\\s+.*>>\\s*~?/?(\\$HOME/)?\\.(bashrc|zshrc|profile|bash_profile)(?![\\w.-])"
66
96
  match_on: command
67
97
  title: "Echo/printf append to shell RC file (code injection persistence)"
68
98
  expires_at: null
@@ -70,10 +100,15 @@
70
100
 
71
101
  # --- at job scheduling ---
72
102
  - id: "CLT-PERSIST-008"
103
+ version: 1
104
+ detection_name: "CMD:SagePersistence-H [Heur]"
73
105
  category: tool
74
106
  severity: warning
75
107
  confidence: 0.60
76
- pattern: "\\bat\\b\\s+(-f\\s+|now|midnight|noon|teatime)"
108
+ # {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-CMD-009. The bare `\bat\b`
109
+ # boundary let a two-letter word match inside quoted prose or a search
110
+ # command (`grep -rn "at now" schedule.log`).
111
+ pattern: "{{CMD_POS}}at{{NOT_FILENAME}}\\s+(-f\\s+|now|midnight|noon|teatime)"
77
112
  match_on: command
78
113
  title: "At-job scheduling (persistence)"
79
114
  expires_at: null
@@ -9,6 +9,8 @@
9
9
  # The most common PI pattern family. Well-established attack surface.
10
10
 
11
11
  - id: "CLT-PI-001"
12
+ version: 1
13
+ detection_name: "Other:SagePromptInjection-A [Heur]"
12
14
  category: prompt_injection
13
15
  severity: critical
14
16
  confidence: 0.90
@@ -20,6 +22,8 @@
20
22
  revoked: false
21
23
 
22
24
  - id: "CLT-PI-002"
25
+ version: 1
26
+ detection_name: "Other:SagePromptInjection-B [Heur]"
23
27
  category: prompt_injection
24
28
  severity: critical
25
29
  confidence: 0.90
@@ -31,6 +35,8 @@
31
35
  revoked: false
32
36
 
33
37
  - id: "CLT-PI-003"
38
+ version: 1
39
+ detection_name: "Other:SagePromptInjection-C [Heur]"
34
40
  category: prompt_injection
35
41
  severity: critical
36
42
  confidence: 0.90
@@ -42,6 +48,8 @@
42
48
  revoked: false
43
49
 
44
50
  - id: "CLT-PI-004"
51
+ version: 1
52
+ detection_name: "Other:SagePromptInjection-D [Heur]"
45
53
  category: prompt_injection
46
54
  severity: critical
47
55
  confidence: 0.90
@@ -53,6 +61,8 @@
53
61
  revoked: false
54
62
 
55
63
  - id: "CLT-PI-005"
64
+ version: 1
65
+ detection_name: "Other:SagePromptInjection-E [Heur]"
56
66
  category: prompt_injection
57
67
  severity: warning
58
68
  confidence: 0.85
@@ -67,6 +77,8 @@
67
77
  # Attempts to reassign the AI's identity or role.
68
78
 
69
79
  - id: "CLT-PI-010"
80
+ version: 1
81
+ detection_name: "Other:SagePromptInjection-J [Heur]"
70
82
  category: prompt_injection
71
83
  severity: critical
72
84
  confidence: 0.90
@@ -78,6 +90,8 @@
78
90
  revoked: false
79
91
 
80
92
  - id: "CLT-PI-011"
93
+ version: 1
94
+ detection_name: "Other:SagePromptInjection-K [Heur]"
81
95
  category: prompt_injection
82
96
  severity: warning
83
97
  confidence: 0.85
@@ -92,6 +106,8 @@
92
106
  # an activation prefix (pretend/act as/you are) before the persona name.
93
107
 
94
108
  - id: "CLT-PI-012"
109
+ version: 1
110
+ detection_name: "Other:SagePromptInjection-L [Heur]"
95
111
  category: prompt_injection
96
112
  severity: warning
97
113
  confidence: 0.85
@@ -103,6 +119,8 @@
103
119
  revoked: false
104
120
 
105
121
  - id: "CLT-PI-013"
122
+ version: 1
123
+ detection_name: "Other:SagePromptInjection-M [Heur]"
106
124
  category: prompt_injection
107
125
  severity: warning
108
126
  confidence: 0.85
@@ -117,6 +135,8 @@
117
135
  # Attempts to disable safety mechanisms.
118
136
 
119
137
  - id: "CLT-PI-020"
138
+ version: 1
139
+ detection_name: "Other:SagePromptInjection-T [Heur]"
120
140
  category: prompt_injection
121
141
  severity: critical
122
142
  confidence: 0.85
@@ -128,6 +148,8 @@
128
148
  revoked: false
129
149
 
130
150
  - id: "CLT-PI-021"
151
+ version: 1
152
+ detection_name: "Other:SagePromptInjection-U [Heur]"
131
153
  category: prompt_injection
132
154
  severity: warning
133
155
  confidence: 0.85
@@ -139,6 +161,8 @@
139
161
  revoked: false
140
162
 
141
163
  - id: "CLT-PI-022"
164
+ version: 1
165
+ detection_name: "Other:SagePromptInjection-V [Heur]"
142
166
  category: prompt_injection
143
167
  severity: warning
144
168
  confidence: 0.80
@@ -150,6 +174,8 @@
150
174
  revoked: false
151
175
 
152
176
  - id: "CLT-PI-023"
177
+ version: 1
178
+ detection_name: "Other:SagePromptInjection-W [Heur]"
153
179
  category: prompt_injection
154
180
  severity: critical
155
181
  confidence: 0.90
@@ -164,6 +190,8 @@
164
190
  # Instructions to hide activity from the user.
165
191
 
166
192
  - id: "CLT-PI-030"
193
+ version: 1
194
+ detection_name: "Other:SagePromptInjection-AD [Heur]"
167
195
  category: prompt_injection
168
196
  severity: critical
169
197
  confidence: 0.90
@@ -178,6 +206,8 @@
178
206
  # Attempts to extract the system prompt or instructions.
179
207
 
180
208
  - id: "CLT-PI-040"
209
+ version: 1
210
+ detection_name: "Other:SagePromptInjection-AN [Heur]"
181
211
  category: prompt_injection
182
212
  severity: warning
183
213
  confidence: 0.85
@@ -189,6 +219,8 @@
189
219
  revoked: false
190
220
 
191
221
  - id: "CLT-PI-041"
222
+ version: 1
223
+ detection_name: "Other:SagePromptInjection-AO [Heur]"
192
224
  category: prompt_injection
193
225
  severity: warning
194
226
  confidence: 0.85
@@ -200,6 +232,8 @@
200
232
  revoked: false
201
233
 
202
234
  - id: "CLT-PI-042"
235
+ version: 1
236
+ detection_name: "Other:SagePromptInjection-AP [Heur]"
203
237
  category: prompt_injection
204
238
  severity: warning
205
239
  confidence: 0.85
@@ -211,6 +245,8 @@
211
245
  revoked: false
212
246
 
213
247
  - id: "CLT-PI-043"
248
+ version: 1
249
+ detection_name: "Other:SagePromptInjection-AQ [Heur]"
214
250
  category: prompt_injection
215
251
  severity: warning
216
252
  confidence: 0.85
@@ -225,6 +261,8 @@
225
261
  # Injection hiding in HTML, markdown, or JSON structures.
226
262
 
227
263
  - id: "CLT-PI-050"
264
+ version: 1
265
+ detection_name: "Other:SagePromptInjection-AX [Heur]"
228
266
  category: prompt_injection
229
267
  severity: warning
230
268
  confidence: 0.85
@@ -239,6 +277,8 @@
239
277
  # for keywords appearing within 20 chars of the opening tag.
240
278
 
241
279
  - id: "CLT-PI-051"
280
+ version: 1
281
+ detection_name: "Other:SagePromptInjection-AY [Heur]"
242
282
  category: prompt_injection
243
283
  severity: warning
244
284
  confidence: 0.85
@@ -251,6 +291,8 @@
251
291
  revoked: false
252
292
 
253
293
  - id: "CLT-PI-052"
294
+ version: 1
295
+ detection_name: "Other:SagePromptInjection-AZ [Heur]"
254
296
  category: prompt_injection
255
297
  severity: warning
256
298
  confidence: 0.85
@@ -269,6 +311,8 @@
269
311
  # Fake conversation turn markers to confuse the model.
270
312
 
271
313
  - id: "CLT-PI-060"
314
+ version: 1
315
+ detection_name: "Other:SagePromptInjection-BH [Heur]"
272
316
  category: prompt_injection
273
317
  severity: warning
274
318
  confidence: 0.85
@@ -280,6 +324,8 @@
280
324
  revoked: false
281
325
 
282
326
  - id: "CLT-PI-061"
327
+ version: 1
328
+ detection_name: "Other:SagePromptInjection-BI [Heur]"
283
329
  category: prompt_injection
284
330
  severity: warning
285
331
  confidence: 0.85
@@ -294,6 +340,8 @@
294
340
  # Obfuscated injection attempts.
295
341
 
296
342
  - id: "CLT-PI-070"
343
+ version: 1
344
+ detection_name: "Other:SagePromptInjection-BR [Heur]"
297
345
  category: prompt_injection
298
346
  severity: warning
299
347
  confidence: 0.60
@@ -309,6 +357,8 @@
309
357
  # are NOT PI — these only match when combined with credential targets.
310
358
 
311
359
  - id: "CLT-PI-080"
360
+ version: 1
361
+ detection_name: "Other:SagePromptInjection-CB [Heur]"
312
362
  category: prompt_injection
313
363
  severity: warning
314
364
  confidence: 0.80
@@ -320,6 +370,8 @@
320
370
  revoked: false
321
371
 
322
372
  - id: "CLT-PI-081"
373
+ version: 1
374
+ detection_name: "Other:SagePromptInjection-CC [Heur]"
323
375
  category: prompt_injection
324
376
  severity: warning
325
377
  confidence: 0.80
@@ -339,6 +391,8 @@
339
391
  # Sage-specific modifications to each rule are noted in its comment block.
340
392
 
341
393
  - id: "CLT-PI-091"
394
+ version: 1
395
+ detection_name: "Other:SagePromptInjection-CM [Heur]"
342
396
  category: prompt_injection
343
397
  severity: warning
344
398
  confidence: 0.85
@@ -356,6 +410,8 @@
356
410
  # precision signal.
357
411
 
358
412
  - id: "CLT-PI-092"
413
+ version: 1
414
+ detection_name: "Other:SagePromptInjection-CN [Heur]"
359
415
  category: prompt_injection
360
416
  severity: warning
361
417
  confidence: 0.85
@@ -372,6 +428,8 @@
372
428
  # capitalized variants (Act/You/Pretend/Be) to cover sentence-start phrasing.
373
429
 
374
430
  - id: "CLT-PI-093"
431
+ version: 1
432
+ detection_name: "Other:SagePromptInjection-CO [Heur]"
375
433
  category: prompt_injection
376
434
  severity: warning
377
435
  confidence: 0.85
@@ -6,10 +6,16 @@
6
6
 
7
7
  # Delete .sage directory
8
8
  - id: "CLT-SELF-001"
9
+ version: 1
10
+ detection_name: "CMD:SageSelfDefense-A [Heur]"
9
11
  category: self_defense
10
12
  severity: critical
11
13
  confidence: 0.60
12
- pattern: "(rm|del|rmdir|rd|Remove-Item|unlink)\\s.*\\.sage(\\s|[\\\\/]|$)"
14
+ # {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-CMD-009. The bare
15
+ # verb alternation fired on prose warning against the deletion (this is
16
+ # Sage's own self-protection rule, so an agent merely explaining not to
17
+ # delete .sage would self-trigger it).
18
+ pattern: "{{CMD_POS}}(rm|del|rmdir|rd|Remove-Item|unlink){{NOT_FILENAME}}\\s.*\\.sage(\\s|[\\\\/]|$)"
13
19
  case_insensitive: true
14
20
  match_on: command
15
21
  title: "Attempt to delete Sage configuration directory"
@@ -18,6 +24,8 @@
18
24
 
19
25
  # Access Sage config files
20
26
  - id: "CLT-SELF-002"
27
+ version: 1
28
+ detection_name: "FN:SageSelfDefense-B [Heur]"
21
29
  category: self_defense
22
30
  severity: warning
23
31
  confidence: 0.60
@@ -29,10 +37,13 @@
29
37
 
30
38
  # Delete Claude Code hook or plugin config
31
39
  - id: "CLT-SELF-003"
40
+ version: 1
41
+ detection_name: "CMD:SageSelfDefense-C [Heur]"
32
42
  category: self_defense
33
43
  severity: warning
34
44
  confidence: 0.60
35
- pattern: "(rm|del|Remove-Item|unlink)\\s.*\\.claude[\\\\/].*(hooks\\.json|installed_plugins)"
45
+ # {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-SELF-001 above.
46
+ pattern: "{{CMD_POS}}(rm|del|Remove-Item|unlink){{NOT_FILENAME}}\\s.*\\.claude[\\\\/].*(hooks\\.json|installed_plugins)"
36
47
  case_insensitive: true
37
48
  match_on: command
38
49
  title: "Attempt to delete Claude Code hook or plugin configuration"
@@ -41,6 +52,8 @@
41
52
 
42
53
  # Disable Sage security features via config
43
54
  - id: "CLT-SELF-004"
55
+ version: 1
56
+ detection_name: "Other:SageSelfDefense-D [Heur]"
44
57
  category: self_defense
45
58
  severity: warning
46
59
  confidence: 0.60
@@ -4,10 +4,15 @@
4
4
 
5
5
  # --- Install scripts piped to shell ---
6
6
  - id: "CLT-SUPPLY-001"
7
+ version: 1
8
+ detection_name: "CMD:SageSupplyChain-A [Heur]"
7
9
  category: supply_chain
8
10
  severity: warning
9
11
  confidence: 0.85
10
- pattern: "(curl|wget)\\s+.*install.*\\|\\s*(bash|sh|zsh|sudo\\s+bash|sudo\\s+sh)"
12
+ # {{CMD_POS}} + {{NOT_FILENAME}} on both the fetcher and the destination
13
+ # shell, same shape as CLT-CMD-009. The bare pattern fired on prose merely
14
+ # describing the technique.
15
+ pattern: "{{CMD_POS}}(curl|wget){{NOT_FILENAME}}\\s+.*install.*\\|\\s*(bash|sh|zsh|sudo\\s+bash|sudo\\s+sh){{NOT_FILENAME}}"
11
16
  match_on: command
12
17
  title: "Install script piped to shell (supply chain risk)"
13
18
  expires_at: null
@@ -5,6 +5,8 @@
5
5
 
6
6
  # --- Known malware hosting patterns ---
7
7
  - id: "CLT-URL-001"
8
+ version: 1
9
+ detection_name: "FN:SageUrl-A [Heur]"
8
10
  category: network_egress
9
11
  severity: critical
10
12
  confidence: 0.85
@@ -16,6 +18,8 @@
16
18
 
17
19
  # --- Paste sites used for C2 ---
18
20
  - id: "CLT-URL-002"
21
+ version: 1
22
+ detection_name: "FN:SageUrl-B [Heur]"
19
23
  category: network_egress
20
24
  severity: warning
21
25
  confidence: 0.60
@@ -26,6 +30,8 @@
26
30
  revoked: false
27
31
 
28
32
  - id: "CLT-URL-003"
33
+ version: 1
34
+ detection_name: "FN:SageUrl-C [Heur]"
29
35
  category: network_egress
30
36
  severity: warning
31
37
  confidence: 0.60
@@ -40,6 +46,8 @@
40
46
  # (10/8, 172.16/12, 192.168/16), and link-local (169.254/16) ranges,
41
47
  # which are common in local development and rarely indicate C2 traffic.
42
48
  - id: "CLT-URL-004"
49
+ version: 1
50
+ detection_name: "FN:SageUrl-D [Heur]"
43
51
  category: network_egress
44
52
  severity: warning
45
53
  confidence: 0.60
@@ -51,6 +59,8 @@
51
59
 
52
60
  # --- Executable downloads ---
53
61
  - id: "CLT-URL-005"
62
+ version: 1
63
+ detection_name: "FN:SageUrl-E [Heur]"
54
64
  category: network_egress
55
65
  severity: warning
56
66
  confidence: 0.60