@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.
- package/dist/mcp-server.cjs +38 -10
- package/dist/mcp-server.cjs.map +2 -2
- package/dist/tool-handler.d.ts.map +1 -1
- package/dist/tool-handler.js +5 -3
- package/dist/tool-handler.js.map +1 -1
- package/package.json +3 -3
- package/resources/threats/_macros.yaml +193 -0
- package/resources/threats/agent-layer.yaml +19 -1
- package/resources/threats/commands.yaml +165 -31
- package/resources/threats/credentials.yaml +24 -4
- package/resources/threats/dummy.yaml +30 -0
- package/resources/threats/files.yaml +38 -0
- package/resources/threats/mac-commands.yaml +118 -27
- package/resources/threats/mac-credentials.yaml +34 -8
- package/resources/threats/mac-files.yaml +20 -0
- package/resources/threats/mac-obfuscation.yaml +28 -6
- package/resources/threats/mac-persistence.yaml +30 -4
- package/resources/threats/mac-supply-chain.yaml +12 -3
- package/resources/threats/mitre.yaml +325 -62
- package/resources/threats/obfuscation.yaml +33 -8
- package/resources/threats/persistence.yaml +40 -5
- package/resources/threats/prompt-injection.yaml +58 -0
- package/resources/threats/self-defense.yaml +15 -2
- package/resources/threats/supply_chain.yaml +6 -1
- package/resources/threats/urls.yaml +10 -0
- package/resources/threats/win-commands.yaml +294 -60
- package/resources/threats/win-credentials.yaml +68 -9
- package/resources/threats/win-files.yaml +20 -0
- package/resources/threats/win-obfuscation.yaml +56 -8
- package/resources/threats/win-persistence.yaml +45 -7
- package/resources/threats/win-supply-chain.yaml +5 -1
|
@@ -4,10 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
# cmdkey stored credentials
|
|
6
6
|
- id: "CLT-WIN-CRED-001"
|
|
7
|
+
version: 1
|
|
8
|
+
detection_name: "CMD:SageWindowsCredential-A [Heur]"
|
|
7
9
|
category: secrets
|
|
8
10
|
severity: warning
|
|
9
11
|
confidence: 0.60
|
|
10
|
-
|
|
12
|
+
# {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-CMD-009.
|
|
13
|
+
pattern: "{{CMD_POS}}[Cc]mdkey(?:\\.exe)?{{NOT_FILENAME}}\\s+/add:"
|
|
11
14
|
match_on: command
|
|
12
15
|
title: "Stored credential creation via cmdkey"
|
|
13
16
|
expires_at: null
|
|
@@ -15,10 +18,14 @@
|
|
|
15
18
|
|
|
16
19
|
# ConvertTo-SecureString with plaintext
|
|
17
20
|
- id: "CLT-WIN-CRED-002"
|
|
21
|
+
version: 1
|
|
22
|
+
detection_name: "CMD:SageWindowsCredential-B [Heur]"
|
|
18
23
|
category: secrets
|
|
19
24
|
severity: warning
|
|
20
25
|
confidence: 0.60
|
|
21
|
-
|
|
26
|
+
# {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-WIN-CMD-036. Had no
|
|
27
|
+
# boundary at all.
|
|
28
|
+
pattern: "{{CMD_POS}}[Cc]onvert[Tt]o-[Ss]ecure[Ss]tring{{NOT_FILENAME}}.*-[Aa]s[Pp]lain[Tt]ext"
|
|
22
29
|
match_on: command
|
|
23
30
|
title: "ConvertTo-SecureString with plaintext password"
|
|
24
31
|
expires_at: null
|
|
@@ -26,10 +33,16 @@
|
|
|
26
33
|
|
|
27
34
|
# Reading credential files on Windows (type, more, Get-Content)
|
|
28
35
|
- id: "CLT-WIN-CRED-003"
|
|
36
|
+
version: 1
|
|
37
|
+
detection_name: "CMD:SageWindowsCredential-C [Heur]"
|
|
29
38
|
category: secrets
|
|
30
39
|
severity: warning
|
|
31
40
|
confidence: 0.60
|
|
32
|
-
|
|
41
|
+
# {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-WIN-CMD-036. The old
|
|
42
|
+
# `(^|[^\w-])` boundary accepted any whitespace-delimited position (still
|
|
43
|
+
# excluding a `-type`-shaped flag, which the replacement preserves since
|
|
44
|
+
# {{CMD_POS}} has no valid boundary immediately before a hyphen either).
|
|
45
|
+
pattern: "{{CMD_POS}}(?:type|more|[Gg]et-[Cc]ontent){{NOT_FILENAME}}.*\\.(?:env|credentials|pgpass|netrc)(?=$|[.\\s\"'`;&|)<>])"
|
|
33
46
|
match_on: command
|
|
34
47
|
title: "Reading credential file via type/more/Get-Content"
|
|
35
48
|
expires_at: null
|
|
@@ -37,10 +50,14 @@
|
|
|
37
50
|
|
|
38
51
|
# [Environment]::SetEnvironmentVariable with credential keyword
|
|
39
52
|
- id: "CLT-WIN-CRED-004"
|
|
53
|
+
version: 1
|
|
54
|
+
detection_name: "CMD:SageWindowsCredential-D [Heur]"
|
|
40
55
|
category: secrets
|
|
41
56
|
severity: warning
|
|
42
57
|
confidence: 0.60
|
|
43
|
-
|
|
58
|
+
# {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-WIN-CMD-036. Had no
|
|
59
|
+
# boundary at all.
|
|
60
|
+
pattern: "{{CMD_POS}}\\[Environment\\]::SetEnvironmentVariable{{NOT_FILENAME}}.*([Pp]assword|[Ss]ecret|[Tt]oken|[Kk]ey)"
|
|
44
61
|
match_on: command
|
|
45
62
|
title: "Setting credential environment variable via .NET"
|
|
46
63
|
expires_at: null
|
|
@@ -48,6 +65,8 @@
|
|
|
48
65
|
|
|
49
66
|
# $env: credential assignment
|
|
50
67
|
- id: "CLT-WIN-CRED-005"
|
|
68
|
+
version: 1
|
|
69
|
+
detection_name: "CMD:SageWindowsCredential-E [Heur]"
|
|
51
70
|
category: secrets
|
|
52
71
|
severity: warning
|
|
53
72
|
confidence: 0.60
|
|
@@ -59,10 +78,28 @@
|
|
|
59
78
|
|
|
60
79
|
# Mimikatz / sekurlsa
|
|
61
80
|
- id: "CLT-WIN-CRED-006"
|
|
81
|
+
version: 1
|
|
82
|
+
detection_name: "CMD:SageWindowsCredential-F [Heur]"
|
|
62
83
|
category: secrets
|
|
63
84
|
severity: critical
|
|
64
85
|
confidence: 0.95
|
|
65
|
-
|
|
86
|
+
# Neither {{CMD_POS}} nor {{NOT_COMPOUND_LEFT}} fits here: real invocations
|
|
87
|
+
# routinely have "Mimikatz" as a SUFFIX of a compound name (the PowerSploit
|
|
88
|
+
# function `Invoke-Mimikatz`), not standalone -- {{CMD_POS}} requires a real
|
|
89
|
+
# boundary immediately before it, and {{NOT_COMPOUND_LEFT}} would reject the
|
|
90
|
+
# preceding hyphen, so either would break the single most common real-world
|
|
91
|
+
# invocation shape. `sekurlsa::` is a Mimikatz module reference that's
|
|
92
|
+
# always an argument to something, never itself in command position.
|
|
93
|
+
# {{NOT_AFTER_TEXT_CMD}} alone closes the reported gap (prose/search-command
|
|
94
|
+
# mentions) without touching either loose-substring-matching property.
|
|
95
|
+
# case_insensitive covers casing generally, so the term itself no longer
|
|
96
|
+
# needs hand-cased character classes -- and it must be set here regardless,
|
|
97
|
+
# since {{NOT_AFTER_TEXT_CMD}}'s denylist (Select-String, Write-Host, ...)
|
|
98
|
+
# is fixed-case and silently stops suppressing lowercase/mixed-case
|
|
99
|
+
# invocations without it. See CLT-WIN-PERSIST-008 for the same macro used
|
|
100
|
+
# the same way.
|
|
101
|
+
pattern: "{{NOT_AFTER_TEXT_CMD}}(?:mimikatz|sekurlsa::)"
|
|
102
|
+
case_insensitive: true
|
|
66
103
|
match_on: command
|
|
67
104
|
title: "Mimikatz credential dumping tool"
|
|
68
105
|
expires_at: null
|
|
@@ -70,10 +107,13 @@
|
|
|
70
107
|
|
|
71
108
|
# Registry hive export for credential theft
|
|
72
109
|
- id: "CLT-WIN-CRED-007"
|
|
110
|
+
version: 1
|
|
111
|
+
detection_name: "CMD:SageWindowsCredential-G [Heur]"
|
|
73
112
|
category: secrets
|
|
74
113
|
severity: critical
|
|
75
114
|
confidence: 0.95
|
|
76
|
-
|
|
115
|
+
# {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-CMD-009.
|
|
116
|
+
pattern: "{{CMD_POS}}reg(?:\\.exe)?{{NOT_FILENAME}}\\s+save\\b.*\\bHKLM\\\\(SAM|SYSTEM|SECURITY)\\b"
|
|
77
117
|
match_on: command
|
|
78
118
|
title: "Registry hive export for credential theft (reg save HKLM\\SAM/SYSTEM)"
|
|
79
119
|
expires_at: null
|
|
@@ -81,10 +121,19 @@
|
|
|
81
121
|
|
|
82
122
|
# LSASS credential dumping
|
|
83
123
|
- id: "CLT-WIN-CRED-008"
|
|
124
|
+
version: 1
|
|
125
|
+
detection_name: "CMD:SageWindowsCredential-H [Heur]"
|
|
84
126
|
category: secrets
|
|
85
127
|
severity: critical
|
|
86
128
|
confidence: 0.95
|
|
87
|
-
|
|
129
|
+
# {{CMD_POS}} + {{NOT_FILENAME}} on each leading verb, same shape as
|
|
130
|
+
# CLT-CMD-009. Optional `.exe` suffix ahead of {{NOT_FILENAME}}, same as
|
|
131
|
+
# CLT-MITRE-096 (tscon) -- otherwise `rundll32.exe` would fail to match,
|
|
132
|
+
# since {{NOT_FILENAME}} itself rejects a trailing dot. The internal
|
|
133
|
+
# `\blsass\b`/`\bcomsvcs\b`/`\bMiniDump\b` mentions are left as bare --
|
|
134
|
+
# only reachable once the leading verb has already matched at command
|
|
135
|
+
# position.
|
|
136
|
+
pattern: "{{CMD_POS}}(procdump|procdump64)(?:\\.exe)?{{NOT_FILENAME}}.*\\blsass\\b|{{CMD_POS}}rundll32(?:\\.exe)?{{NOT_FILENAME}}.*\\bcomsvcs(\\.dll)?\\b.*\\bMiniDump\\b"
|
|
88
137
|
match_on: command
|
|
89
138
|
title: "LSASS credential dumping (procdump/comsvcs.dll MiniDump)"
|
|
90
139
|
expires_at: null
|
|
@@ -92,10 +141,14 @@
|
|
|
92
141
|
|
|
93
142
|
# WLAN password extraction (ex CLT-TECH-034)
|
|
94
143
|
- id: "CLT-WIN-CRED-009"
|
|
144
|
+
version: 1
|
|
145
|
+
detection_name: "CMD:SageWindowsCredential-I [Heur]"
|
|
95
146
|
category: secrets
|
|
96
147
|
severity: warning
|
|
97
148
|
confidence: 0.60
|
|
98
|
-
|
|
149
|
+
# {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-CMD-009. Had no
|
|
150
|
+
# boundary at all.
|
|
151
|
+
pattern: "{{CMD_POS}}netsh(?:\\.exe)?{{NOT_FILENAME}}.*wlan.*show.*profiles.*key=clear"
|
|
99
152
|
case_insensitive: true
|
|
100
153
|
match_on: command
|
|
101
154
|
title: "WLAN password extraction via netsh"
|
|
@@ -104,13 +157,19 @@
|
|
|
104
157
|
|
|
105
158
|
# --- Windows copy/move/link of secret files ---
|
|
106
159
|
- id: "CLT-WIN-CRED-010"
|
|
160
|
+
version: 1
|
|
161
|
+
detection_name: "CMD:SageWindowsCredential-J [Heur]"
|
|
107
162
|
category: secrets
|
|
108
163
|
severity: warning
|
|
109
164
|
confidence: 0.60
|
|
110
165
|
# Protected files: .env*, .aws\credentials, .ssh\(id_rsa|id_ed25519|id_ecdsa|id_dsa),
|
|
111
166
|
# .netrc, .pgpass, .npmrc, .pypirc, key.properties, .docker\config.json,
|
|
112
167
|
# kubeconfig, .kube\config, master.key, credentials.yml
|
|
113
|
-
|
|
168
|
+
# {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-CMD-009. xcopy/robocopy
|
|
169
|
+
# are real standalone binaries and admit an optional `.exe` suffix; copy/
|
|
170
|
+
# mklink are cmd builtins and Copy-Item/Move-Item are cmdlets, neither of
|
|
171
|
+
# which has a `.exe` form.
|
|
172
|
+
pattern: "{{CMD_POS}}(copy|xcopy(?:\\.exe)?|robocopy(?:\\.exe)?|Copy-Item|Move-Item|mklink){{NOT_FILENAME}}.*(?<=[\\\\/\\s])(\\.env(?!\\S*\\.(example|sample|template|dist)\\b)(\\.\\w+)?(?=[\\s\\\\/]|$)|\\.aws[\\\\/]credentials|\\.ssh[\\\\/](id_rsa|id_ed25519|id_ecdsa|id_dsa)|\\.netrc|\\.pgpass|\\.npmrc|\\.pypirc|key\\.properties|\\.docker[\\\\/]config\\.json|kubeconfig|\\.kube[\\\\/]config|master\\.key|credentials\\.yml)"
|
|
114
173
|
case_insensitive: true
|
|
115
174
|
match_on: command
|
|
116
175
|
title: "Windows copy/move of credential or secret file"
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
# SAM/SECURITY/SYSTEM hive
|
|
7
7
|
- id: "CLT-WIN-FILE-001"
|
|
8
|
+
version: 1
|
|
9
|
+
detection_name: "FN:SageWindowsFile-A [Heur]"
|
|
8
10
|
category: secrets
|
|
9
11
|
severity: critical
|
|
10
12
|
confidence: 0.95
|
|
@@ -16,6 +18,8 @@
|
|
|
16
18
|
|
|
17
19
|
# NTDS.dit (Active Directory database)
|
|
18
20
|
- id: "CLT-WIN-FILE-002"
|
|
21
|
+
version: 1
|
|
22
|
+
detection_name: "FN:SageWindowsFile-B [Heur]"
|
|
19
23
|
category: secrets
|
|
20
24
|
severity: critical
|
|
21
25
|
confidence: 0.95
|
|
@@ -27,6 +31,8 @@
|
|
|
27
31
|
|
|
28
32
|
# Windows hosts file
|
|
29
33
|
- id: "CLT-WIN-FILE-003"
|
|
34
|
+
version: 1
|
|
35
|
+
detection_name: "FN:SageWindowsFile-C [Heur]"
|
|
30
36
|
category: tool
|
|
31
37
|
severity: warning
|
|
32
38
|
confidence: 0.60
|
|
@@ -38,6 +44,8 @@
|
|
|
38
44
|
|
|
39
45
|
# Startup folder
|
|
40
46
|
- id: "CLT-WIN-FILE-004"
|
|
47
|
+
version: 1
|
|
48
|
+
detection_name: "FN:SageWindowsFile-D [Heur]"
|
|
41
49
|
category: tool
|
|
42
50
|
severity: warning
|
|
43
51
|
confidence: 0.60
|
|
@@ -49,6 +57,8 @@
|
|
|
49
57
|
|
|
50
58
|
# Executable script in System32/SysWOW64
|
|
51
59
|
- id: "CLT-WIN-FILE-005"
|
|
60
|
+
version: 1
|
|
61
|
+
detection_name: "FN:SageWindowsFile-E [Heur]"
|
|
52
62
|
category: tool
|
|
53
63
|
severity: critical
|
|
54
64
|
confidence: 0.90
|
|
@@ -60,6 +70,8 @@
|
|
|
60
70
|
|
|
61
71
|
# Driver file in System32/drivers
|
|
62
72
|
- id: "CLT-WIN-FILE-006"
|
|
73
|
+
version: 1
|
|
74
|
+
detection_name: "FN:SageWindowsFile-F [Heur]"
|
|
63
75
|
category: tool
|
|
64
76
|
severity: critical
|
|
65
77
|
confidence: 0.90
|
|
@@ -71,6 +83,8 @@
|
|
|
71
83
|
|
|
72
84
|
# Task Scheduler directory
|
|
73
85
|
- id: "CLT-WIN-FILE-007"
|
|
86
|
+
version: 1
|
|
87
|
+
detection_name: "FN:SageWindowsFile-G [Heur]"
|
|
74
88
|
category: tool
|
|
75
89
|
severity: warning
|
|
76
90
|
confidence: 0.60
|
|
@@ -82,6 +96,8 @@
|
|
|
82
96
|
|
|
83
97
|
# SSH key or config file (Windows path)
|
|
84
98
|
- id: "CLT-WIN-FILE-008"
|
|
99
|
+
version: 1
|
|
100
|
+
detection_name: "FN:SageWindowsFile-H [Heur]"
|
|
85
101
|
category: secrets
|
|
86
102
|
severity: warning
|
|
87
103
|
confidence: 0.60
|
|
@@ -93,6 +109,8 @@
|
|
|
93
109
|
|
|
94
110
|
# AWS credentials file (Windows path)
|
|
95
111
|
- id: "CLT-WIN-FILE-009"
|
|
112
|
+
version: 1
|
|
113
|
+
detection_name: "FN:SageWindowsFile-I [Heur]"
|
|
96
114
|
category: secrets
|
|
97
115
|
severity: warning
|
|
98
116
|
confidence: 0.60
|
|
@@ -104,6 +122,8 @@
|
|
|
104
122
|
|
|
105
123
|
# Browser credential stores
|
|
106
124
|
- id: "CLT-WIN-FILE-010"
|
|
125
|
+
version: 1
|
|
126
|
+
detection_name: "FN:SageWindowsFile-J [Heur]"
|
|
107
127
|
category: secrets
|
|
108
128
|
severity: critical
|
|
109
129
|
confidence: 0.90
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
# PowerShell -EncodedCommand
|
|
6
6
|
- id: "CLT-WIN-OBFUS-001"
|
|
7
|
+
version: 1
|
|
8
|
+
detection_name: "CMD:SageWindowsObfuscation-A [Heur]"
|
|
7
9
|
category: tool
|
|
8
10
|
severity: critical
|
|
9
11
|
confidence: 0.95
|
|
@@ -15,10 +17,14 @@
|
|
|
15
17
|
|
|
16
18
|
# certutil -decode
|
|
17
19
|
- id: "CLT-WIN-OBFUS-002"
|
|
20
|
+
version: 1
|
|
21
|
+
detection_name: "CMD:SageWindowsObfuscation-B [Heur]"
|
|
18
22
|
category: tool
|
|
19
23
|
severity: warning
|
|
20
24
|
confidence: 0.60
|
|
21
|
-
|
|
25
|
+
# {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-CMD-009. Had no
|
|
26
|
+
# boundary at all.
|
|
27
|
+
pattern: "{{CMD_POS}}[Cc][Ee][Rr][Tt][Uu][Tt][Ii][Ll](?:\\.exe)?{{NOT_FILENAME}}\\s.*-decode"
|
|
22
28
|
match_on: command
|
|
23
29
|
title: "certutil base64 decode (obfuscation)"
|
|
24
30
|
expires_at: null
|
|
@@ -26,6 +32,8 @@
|
|
|
26
32
|
|
|
27
33
|
# Hidden PowerShell window
|
|
28
34
|
- id: "CLT-WIN-OBFUS-003"
|
|
35
|
+
version: 1
|
|
36
|
+
detection_name: "CMD:SageWindowsObfuscation-C [Heur]"
|
|
29
37
|
category: tool
|
|
30
38
|
severity: warning
|
|
31
39
|
confidence: 0.60
|
|
@@ -37,6 +45,8 @@
|
|
|
37
45
|
|
|
38
46
|
# Bypass + NoProfile combo
|
|
39
47
|
- id: "CLT-WIN-OBFUS-004"
|
|
48
|
+
version: 1
|
|
49
|
+
detection_name: "CMD:SageWindowsObfuscation-D [Heur]"
|
|
40
50
|
category: tool
|
|
41
51
|
severity: warning
|
|
42
52
|
confidence: 0.90
|
|
@@ -48,6 +58,8 @@
|
|
|
48
58
|
|
|
49
59
|
# [char] code obfuscation
|
|
50
60
|
- id: "CLT-WIN-OBFUS-005"
|
|
61
|
+
version: 1
|
|
62
|
+
detection_name: "CMD:SageWindowsObfuscation-E [Heur]"
|
|
51
63
|
category: tool
|
|
52
64
|
severity: warning
|
|
53
65
|
confidence: 0.60
|
|
@@ -59,6 +71,8 @@
|
|
|
59
71
|
|
|
60
72
|
# Security provider DLL injection via registry
|
|
61
73
|
- id: "CLT-WIN-OBFUS-006"
|
|
74
|
+
version: 1
|
|
75
|
+
detection_name: "CMD:SageWindowsObfuscation-F [Heur]"
|
|
62
76
|
category: tool
|
|
63
77
|
severity: critical
|
|
64
78
|
confidence: 0.90
|
|
@@ -70,10 +84,15 @@
|
|
|
70
84
|
|
|
71
85
|
# mshta VBScript execution (Execute, CreateObject, close patterns)
|
|
72
86
|
- id: "CLT-WIN-OBFUS-007"
|
|
87
|
+
version: 1
|
|
88
|
+
detection_name: "CMD:SageWindowsObfuscation-G [Heur]"
|
|
73
89
|
category: tool
|
|
74
90
|
severity: critical
|
|
75
91
|
confidence: 0.90
|
|
76
|
-
|
|
92
|
+
# {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-MITRE-096 (tscon),
|
|
93
|
+
# including the optional `.exe` suffix ahead of {{NOT_FILENAME}} (which
|
|
94
|
+
# itself rejects a trailing dot).
|
|
95
|
+
pattern: "{{CMD_POS}}mshta(?:\\.exe)?{{NOT_FILENAME}}.*\\bvbscript:(Execute|CreateObject|close\\s*\\()"
|
|
77
96
|
case_insensitive: true
|
|
78
97
|
match_on: command
|
|
79
98
|
title: "mshta VBScript execution (Execute/CreateObject obfuscation)"
|
|
@@ -82,10 +101,13 @@
|
|
|
82
101
|
|
|
83
102
|
# mshta javascript: eval execution
|
|
84
103
|
- id: "CLT-WIN-OBFUS-008"
|
|
104
|
+
version: 1
|
|
105
|
+
detection_name: "CMD:SageWindowsObfuscation-H [Heur]"
|
|
85
106
|
category: tool
|
|
86
107
|
severity: critical
|
|
87
108
|
confidence: 0.90
|
|
88
|
-
|
|
109
|
+
# {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-WIN-OBFUS-007.
|
|
110
|
+
pattern: "{{CMD_POS}}mshta(?:\\.exe)?{{NOT_FILENAME}}.*\\bjavascript:"
|
|
89
111
|
case_insensitive: true
|
|
90
112
|
match_on: command
|
|
91
113
|
title: "mshta JavaScript execution (LOLBin obfuscation)"
|
|
@@ -94,10 +116,15 @@
|
|
|
94
116
|
|
|
95
117
|
# wscript/cscript //E: engine override on non-script files
|
|
96
118
|
- id: "CLT-WIN-OBFUS-009"
|
|
119
|
+
version: 1
|
|
120
|
+
detection_name: "CMD:SageWindowsObfuscation-I [Heur]"
|
|
97
121
|
category: tool
|
|
98
122
|
severity: critical
|
|
99
123
|
confidence: 0.90
|
|
100
|
-
|
|
124
|
+
# {{CMD_POS}} + {{NOT_FILENAME}} instead of a leading bare alternation with
|
|
125
|
+
# no command-position boundary; {{NOT_FILENAME}} replaces the trailing
|
|
126
|
+
# `\b`, same effect but also rejects a trailing dot.
|
|
127
|
+
pattern: "{{CMD_POS}}(wscript|cscript)(?:\\.exe)?{{NOT_FILENAME}}.*//[Ee]:([Vv][Bb][Ss]cript|[Jj][Ss]cript)"
|
|
101
128
|
case_insensitive: true
|
|
102
129
|
match_on: command
|
|
103
130
|
title: "wscript/cscript script engine override (//E:VBScript evasion)"
|
|
@@ -106,6 +133,8 @@
|
|
|
106
133
|
|
|
107
134
|
# NTFS $INDEX_ALLOCATION folder creation (ex CLT-TECH-001)
|
|
108
135
|
- id: "CLT-WIN-OBFUS-010"
|
|
136
|
+
version: 1
|
|
137
|
+
detection_name: "CMD:SageWindowsObfuscation-J [Heur]"
|
|
109
138
|
category: tool
|
|
110
139
|
severity: warning
|
|
111
140
|
confidence: 0.60
|
|
@@ -118,6 +147,8 @@
|
|
|
118
147
|
|
|
119
148
|
# ADS bypass via type redirect or wmic process create (ex CLT-TECH-002)
|
|
120
149
|
- id: "CLT-WIN-OBFUS-011"
|
|
150
|
+
version: 1
|
|
151
|
+
detection_name: "CMD:SageWindowsObfuscation-K [Heur]"
|
|
121
152
|
category: tool
|
|
122
153
|
severity: warning
|
|
123
154
|
confidence: 0.60
|
|
@@ -130,6 +161,8 @@
|
|
|
130
161
|
|
|
131
162
|
# Dotdotdot hidden folder (ex CLT-TECH-003)
|
|
132
163
|
- id: "CLT-WIN-OBFUS-012"
|
|
164
|
+
version: 1
|
|
165
|
+
detection_name: "CMD:SageWindowsObfuscation-L [Heur]"
|
|
133
166
|
category: tool
|
|
134
167
|
severity: warning
|
|
135
168
|
confidence: 0.60
|
|
@@ -142,10 +175,15 @@
|
|
|
142
175
|
|
|
143
176
|
# cmd caret obfuscation (ex CLT-TECH-014)
|
|
144
177
|
- id: "CLT-WIN-OBFUS-013"
|
|
178
|
+
version: 1
|
|
179
|
+
detection_name: "CMD:SageWindowsObfuscation-M [Heur]"
|
|
145
180
|
category: tool
|
|
146
181
|
severity: warning
|
|
147
182
|
confidence: 0.60
|
|
148
|
-
|
|
183
|
+
# {{CMD_POS}} + {{NOT_FILENAME}} (with optional `.exe` suffix), same shape
|
|
184
|
+
# as CLT-MITRE-096. Had no boundary at all -- not even a `\b` -- so `cmd`
|
|
185
|
+
# matched as a bare substring of `cmdlet` or similar.
|
|
186
|
+
pattern: "{{CMD_POS}}cmd(?:\\.exe)?{{NOT_FILENAME}}.*([^\\^]\\^[a-z].*){5}"
|
|
149
187
|
case_insensitive: true
|
|
150
188
|
match_on: command
|
|
151
189
|
title: "cmd caret (^) obfuscation"
|
|
@@ -154,10 +192,13 @@
|
|
|
154
192
|
|
|
155
193
|
# cmd substring concatenation obfuscation (ex CLT-TECH-015)
|
|
156
194
|
- id: "CLT-WIN-OBFUS-014"
|
|
195
|
+
version: 1
|
|
196
|
+
detection_name: "CMD:SageWindowsObfuscation-N [Heur]"
|
|
157
197
|
category: tool
|
|
158
198
|
severity: warning
|
|
159
199
|
confidence: 0.60
|
|
160
|
-
|
|
200
|
+
# {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-WIN-OBFUS-013.
|
|
201
|
+
pattern: "{{CMD_POS}}cmd(?:\\.exe)?{{NOT_FILENAME}}.*(%[^%]+:~[^%]*%[a-z]*){2}"
|
|
161
202
|
case_insensitive: true
|
|
162
203
|
match_on: command
|
|
163
204
|
title: "cmd substring concatenation obfuscation"
|
|
@@ -166,10 +207,14 @@
|
|
|
166
207
|
|
|
167
208
|
# PowerShell backtick obfuscation (ex CLT-TECH-021)
|
|
168
209
|
- id: "CLT-WIN-OBFUS-015"
|
|
210
|
+
version: 1
|
|
211
|
+
detection_name: "CMD:SageWindowsObfuscation-O [Heur]"
|
|
169
212
|
category: tool
|
|
170
213
|
severity: warning
|
|
171
214
|
confidence: 0.60
|
|
172
|
-
|
|
215
|
+
# {{CMD_POS}} + {{NOT_FILENAME}} (with optional `.exe` suffix), same shape
|
|
216
|
+
# as CLT-MITRE-096. Had no boundary at all.
|
|
217
|
+
pattern: "{{CMD_POS}}powershell(?:\\.exe)?{{NOT_FILENAME}}.*(`[a-z].*){4}"
|
|
173
218
|
case_insensitive: true
|
|
174
219
|
match_on: command
|
|
175
220
|
title: "PowerShell backtick obfuscation"
|
|
@@ -178,10 +223,13 @@
|
|
|
178
223
|
|
|
179
224
|
# PowerShell XOR decryption (ex CLT-TECH-026)
|
|
180
225
|
- id: "CLT-WIN-OBFUS-016"
|
|
226
|
+
version: 1
|
|
227
|
+
detection_name: "CMD:SageWindowsObfuscation-P [Heur]"
|
|
181
228
|
category: tool
|
|
182
229
|
severity: warning
|
|
183
230
|
confidence: 0.60
|
|
184
|
-
|
|
231
|
+
# {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-WIN-OBFUS-015.
|
|
232
|
+
pattern: "{{CMD_POS}}powershell(?:\\.exe)?{{NOT_FILENAME}}.+-bxor\\s*['\"]"
|
|
185
233
|
case_insensitive: true
|
|
186
234
|
match_on: command
|
|
187
235
|
title: "PowerShell XOR decryption"
|
|
@@ -5,10 +5,13 @@
|
|
|
5
5
|
|
|
6
6
|
# Registry Run key via reg add
|
|
7
7
|
- id: "CLT-WIN-PERSIST-001"
|
|
8
|
+
version: 1
|
|
9
|
+
detection_name: "CMD:SageWindowsPersistence-A [Heur]"
|
|
8
10
|
category: tool
|
|
9
11
|
severity: critical
|
|
10
12
|
confidence: 0.90
|
|
11
|
-
|
|
13
|
+
# {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-CMD-009.
|
|
14
|
+
pattern: "{{CMD_POS}}[Rr][Ee][Gg](?:\\.exe)?{{NOT_FILENAME}}\\s+[Aa][Dd][Dd].*\\\\(Run|RunOnce)\\\\"
|
|
12
15
|
match_on: command
|
|
13
16
|
title: "Registry Run key persistence via reg add"
|
|
14
17
|
expires_at: null
|
|
@@ -16,10 +19,13 @@
|
|
|
16
19
|
|
|
17
20
|
# sc create/config service
|
|
18
21
|
- id: "CLT-WIN-PERSIST-002"
|
|
22
|
+
version: 1
|
|
23
|
+
detection_name: "CMD:SageWindowsPersistence-B [Heur]"
|
|
19
24
|
category: tool
|
|
20
25
|
severity: critical
|
|
21
26
|
confidence: 0.90
|
|
22
|
-
|
|
27
|
+
# {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-CMD-009.
|
|
28
|
+
pattern: "{{CMD_POS}}[Ss][Cc](?:\\.exe)?{{NOT_FILENAME}}\\s+(create|config).*binpath"
|
|
23
29
|
match_on: command
|
|
24
30
|
title: "Windows service creation/modification via sc"
|
|
25
31
|
expires_at: null
|
|
@@ -27,10 +33,13 @@
|
|
|
27
33
|
|
|
28
34
|
# schtasks /create
|
|
29
35
|
- id: "CLT-WIN-PERSIST-003"
|
|
36
|
+
version: 1
|
|
37
|
+
detection_name: "CMD:SageWindowsPersistence-C [Heur]"
|
|
30
38
|
category: tool
|
|
31
39
|
severity: warning
|
|
32
40
|
confidence: 0.60
|
|
33
|
-
|
|
41
|
+
# {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-CMD-009.
|
|
42
|
+
pattern: "{{CMD_POS}}[Ss][Cc][Hh][Tt][Aa][Ss][Kk][Ss](?:\\.exe)?{{NOT_FILENAME}}.*/[Cc]reate"
|
|
34
43
|
match_on: command
|
|
35
44
|
title: "Scheduled task creation via schtasks"
|
|
36
45
|
expires_at: null
|
|
@@ -38,10 +47,16 @@
|
|
|
38
47
|
|
|
39
48
|
# PowerShell New-ScheduledTask
|
|
40
49
|
- id: "CLT-WIN-PERSIST-004"
|
|
50
|
+
version: 1
|
|
51
|
+
detection_name: "CMD:SageWindowsPersistence-D [Heur]"
|
|
41
52
|
category: tool
|
|
42
53
|
severity: warning
|
|
43
54
|
confidence: 0.60
|
|
44
|
-
|
|
55
|
+
# {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-WIN-CMD-036. Had no
|
|
56
|
+
# boundary at all, so it matched inside the distinct, real cmdlets
|
|
57
|
+
# New-ScheduledTaskAction and New-ScheduledTaskTrigger even when the real
|
|
58
|
+
# New-ScheduledTask was never called.
|
|
59
|
+
pattern: "{{CMD_POS}}[Nn]ew-[Ss]cheduled[Tt]ask{{NOT_FILENAME}}"
|
|
45
60
|
match_on: command
|
|
46
61
|
title: "PowerShell scheduled task creation"
|
|
47
62
|
expires_at: null
|
|
@@ -49,10 +64,15 @@
|
|
|
49
64
|
|
|
50
65
|
# PowerShell Set-ItemProperty Run key
|
|
51
66
|
- id: "CLT-WIN-PERSIST-005"
|
|
67
|
+
version: 1
|
|
68
|
+
detection_name: "CMD:SageWindowsPersistence-E [Heur]"
|
|
52
69
|
category: tool
|
|
53
70
|
severity: critical
|
|
54
71
|
confidence: 0.90
|
|
55
|
-
|
|
72
|
+
# {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-WIN-CMD-036. Had no
|
|
73
|
+
# boundary at all, so it matched inside the distinct, real cmdlet
|
|
74
|
+
# Set-ItemPropertyValue even when Set-ItemProperty itself was never called.
|
|
75
|
+
pattern: "{{CMD_POS}}[Ss]et-[Ii]tem[Pp]roperty{{NOT_FILENAME}}.*\\\\(Run|RunOnce)\\\\"
|
|
56
76
|
match_on: command
|
|
57
77
|
title: "PowerShell Registry Run key persistence"
|
|
58
78
|
expires_at: null
|
|
@@ -60,10 +80,13 @@
|
|
|
60
80
|
|
|
61
81
|
# PowerShell New-Service
|
|
62
82
|
- id: "CLT-WIN-PERSIST-006"
|
|
83
|
+
version: 1
|
|
84
|
+
detection_name: "CMD:SageWindowsPersistence-F [Heur]"
|
|
63
85
|
category: tool
|
|
64
86
|
severity: warning
|
|
65
87
|
confidence: 0.60
|
|
66
|
-
|
|
88
|
+
# {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-WIN-CMD-036.
|
|
89
|
+
pattern: "{{CMD_POS}}[Nn]ew-[Ss]ervice{{NOT_FILENAME}}"
|
|
67
90
|
match_on: command
|
|
68
91
|
title: "PowerShell Windows service creation"
|
|
69
92
|
expires_at: null
|
|
@@ -71,6 +94,8 @@
|
|
|
71
94
|
|
|
72
95
|
# Startup folder path
|
|
73
96
|
- id: "CLT-WIN-PERSIST-007"
|
|
97
|
+
version: 1
|
|
98
|
+
detection_name: "CMD:SageWindowsPersistence-G [Heur]"
|
|
74
99
|
category: tool
|
|
75
100
|
severity: warning
|
|
76
101
|
confidence: 0.60
|
|
@@ -82,10 +107,23 @@
|
|
|
82
107
|
|
|
83
108
|
# WMI event subscription persistence
|
|
84
109
|
- id: "CLT-WIN-PERSIST-008"
|
|
110
|
+
version: 1
|
|
111
|
+
detection_name: "CMD:SageWindowsPersistence-H [Heur]"
|
|
85
112
|
category: tool
|
|
86
113
|
severity: critical
|
|
87
114
|
confidence: 0.90
|
|
88
|
-
|
|
115
|
+
# A WMI class name legitimately appears as an argument value (`-Class
|
|
116
|
+
# CommandLineEventConsumer`), so {{CMD_POS}} would break real detections —
|
|
117
|
+
# only the symmetric boundary guard applies here, plus {{NOT_FILENAME}}
|
|
118
|
+
# (instead of {{NOT_COMPOUND_RIGHT}}) to also reject a trailing dot
|
|
119
|
+
# (`CommandLineEventConsumer.md`) and {{NOT_AFTER_TEXT_CMD}} to reject a
|
|
120
|
+
# mention inside a search/print command (`grep "CommandLineEventConsumer"`)
|
|
121
|
+
# without gating on quotes, which would just hand an attacker a trivial
|
|
122
|
+
# evasion. See {{NOT_AFTER_TEXT_CMD}} in _macros.yaml for the full guard
|
|
123
|
+
# design and its accepted residual gap (an unlisted benign command still
|
|
124
|
+
# false-positives).
|
|
125
|
+
pattern: "{{NOT_AFTER_TEXT_CMD}}{{NOT_COMPOUND_LEFT}}(CommandLineEventConsumer|ActiveScriptEventConsumer){{NOT_FILENAME}}"
|
|
126
|
+
case_insensitive: true
|
|
89
127
|
match_on: command
|
|
90
128
|
title: "WMI event subscription persistence"
|
|
91
129
|
expires_at: null
|
|
@@ -4,10 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
# Install-Module without -RequiredVersion
|
|
6
6
|
- id: "CLT-WIN-SUPPLY-001"
|
|
7
|
+
version: 1
|
|
8
|
+
detection_name: "CMD:SageWindowsSupplyChain-A [Heur]"
|
|
7
9
|
category: supply_chain
|
|
8
10
|
severity: warning
|
|
9
11
|
confidence: 0.60
|
|
10
|
-
|
|
12
|
+
# {{CMD_POS}} + {{NOT_FILENAME}}, same shape as CLT-WIN-CMD-036. The bare
|
|
13
|
+
# cmdlet mention fired on prose merely describing the risk.
|
|
14
|
+
pattern: "{{CMD_POS}}[Ii]nstall-[Mm]odule{{NOT_FILENAME}}\\s+(?!.*-[Rr]equired[Vv]ersion)"
|
|
11
15
|
match_on: command
|
|
12
16
|
title: "PowerShell Install-Module without -RequiredVersion"
|
|
13
17
|
expires_at: null
|