@trailofbits/vsix-audit 0.1.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 (197) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +281 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +703 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/index.d.ts +3 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +4 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/scanner/batch.d.ts +12 -0
  12. package/dist/scanner/batch.d.ts.map +1 -0
  13. package/dist/scanner/batch.js +104 -0
  14. package/dist/scanner/batch.js.map +1 -0
  15. package/dist/scanner/bundler.d.ts +35 -0
  16. package/dist/scanner/bundler.d.ts.map +1 -0
  17. package/dist/scanner/bundler.js +120 -0
  18. package/dist/scanner/bundler.js.map +1 -0
  19. package/dist/scanner/cache.d.ts +45 -0
  20. package/dist/scanner/cache.d.ts.map +1 -0
  21. package/dist/scanner/cache.js +153 -0
  22. package/dist/scanner/cache.js.map +1 -0
  23. package/dist/scanner/cache.test.d.ts +2 -0
  24. package/dist/scanner/cache.test.d.ts.map +1 -0
  25. package/dist/scanner/cache.test.js +149 -0
  26. package/dist/scanner/cache.test.js.map +1 -0
  27. package/dist/scanner/capabilities.d.ts +29 -0
  28. package/dist/scanner/capabilities.d.ts.map +1 -0
  29. package/dist/scanner/capabilities.js +217 -0
  30. package/dist/scanner/capabilities.js.map +1 -0
  31. package/dist/scanner/checks/ast.d.ts +3 -0
  32. package/dist/scanner/checks/ast.d.ts.map +1 -0
  33. package/dist/scanner/checks/ast.js +469 -0
  34. package/dist/scanner/checks/ast.js.map +1 -0
  35. package/dist/scanner/checks/ast.test.d.ts +2 -0
  36. package/dist/scanner/checks/ast.test.d.ts.map +1 -0
  37. package/dist/scanner/checks/ast.test.js +389 -0
  38. package/dist/scanner/checks/ast.test.js.map +1 -0
  39. package/dist/scanner/checks/behavioral.d.ts +3 -0
  40. package/dist/scanner/checks/behavioral.d.ts.map +1 -0
  41. package/dist/scanner/checks/behavioral.js +367 -0
  42. package/dist/scanner/checks/behavioral.js.map +1 -0
  43. package/dist/scanner/checks/blocklist.d.ts +3 -0
  44. package/dist/scanner/checks/blocklist.d.ts.map +1 -0
  45. package/dist/scanner/checks/blocklist.js +32 -0
  46. package/dist/scanner/checks/blocklist.js.map +1 -0
  47. package/dist/scanner/checks/blocklist.test.d.ts +2 -0
  48. package/dist/scanner/checks/blocklist.test.d.ts.map +1 -0
  49. package/dist/scanner/checks/blocklist.test.js +74 -0
  50. package/dist/scanner/checks/blocklist.test.js.map +1 -0
  51. package/dist/scanner/checks/chains.d.ts +35 -0
  52. package/dist/scanner/checks/chains.d.ts.map +1 -0
  53. package/dist/scanner/checks/chains.js +505 -0
  54. package/dist/scanner/checks/chains.js.map +1 -0
  55. package/dist/scanner/checks/chains.test.d.ts +2 -0
  56. package/dist/scanner/checks/chains.test.d.ts.map +1 -0
  57. package/dist/scanner/checks/chains.test.js +250 -0
  58. package/dist/scanner/checks/chains.test.js.map +1 -0
  59. package/dist/scanner/checks/dataflow.d.ts +3 -0
  60. package/dist/scanner/checks/dataflow.d.ts.map +1 -0
  61. package/dist/scanner/checks/dataflow.js +316 -0
  62. package/dist/scanner/checks/dataflow.js.map +1 -0
  63. package/dist/scanner/checks/dependencies.d.ts +13 -0
  64. package/dist/scanner/checks/dependencies.d.ts.map +1 -0
  65. package/dist/scanner/checks/dependencies.js +225 -0
  66. package/dist/scanner/checks/dependencies.js.map +1 -0
  67. package/dist/scanner/checks/dependencies.test.d.ts +2 -0
  68. package/dist/scanner/checks/dependencies.test.d.ts.map +1 -0
  69. package/dist/scanner/checks/dependencies.test.js +248 -0
  70. package/dist/scanner/checks/dependencies.test.js.map +1 -0
  71. package/dist/scanner/checks/finding-quality.test.d.ts +8 -0
  72. package/dist/scanner/checks/finding-quality.test.d.ts.map +1 -0
  73. package/dist/scanner/checks/finding-quality.test.js +164 -0
  74. package/dist/scanner/checks/finding-quality.test.js.map +1 -0
  75. package/dist/scanner/checks/ioc.d.ts +20 -0
  76. package/dist/scanner/checks/ioc.d.ts.map +1 -0
  77. package/dist/scanner/checks/ioc.js +234 -0
  78. package/dist/scanner/checks/ioc.js.map +1 -0
  79. package/dist/scanner/checks/ioc.test.d.ts +2 -0
  80. package/dist/scanner/checks/ioc.test.d.ts.map +1 -0
  81. package/dist/scanner/checks/ioc.test.js +298 -0
  82. package/dist/scanner/checks/ioc.test.js.map +1 -0
  83. package/dist/scanner/checks/manifest.d.ts +6 -0
  84. package/dist/scanner/checks/manifest.d.ts.map +1 -0
  85. package/dist/scanner/checks/manifest.js +123 -0
  86. package/dist/scanner/checks/manifest.js.map +1 -0
  87. package/dist/scanner/checks/manifest.test.d.ts +2 -0
  88. package/dist/scanner/checks/manifest.test.d.ts.map +1 -0
  89. package/dist/scanner/checks/manifest.test.js +108 -0
  90. package/dist/scanner/checks/manifest.test.js.map +1 -0
  91. package/dist/scanner/checks/obfuscation.d.ts +3 -0
  92. package/dist/scanner/checks/obfuscation.d.ts.map +1 -0
  93. package/dist/scanner/checks/obfuscation.js +432 -0
  94. package/dist/scanner/checks/obfuscation.js.map +1 -0
  95. package/dist/scanner/checks/obfuscation.test.d.ts +2 -0
  96. package/dist/scanner/checks/obfuscation.test.d.ts.map +1 -0
  97. package/dist/scanner/checks/obfuscation.test.js +399 -0
  98. package/dist/scanner/checks/obfuscation.test.js.map +1 -0
  99. package/dist/scanner/checks/package.d.ts +17 -0
  100. package/dist/scanner/checks/package.d.ts.map +1 -0
  101. package/dist/scanner/checks/package.js +422 -0
  102. package/dist/scanner/checks/package.js.map +1 -0
  103. package/dist/scanner/checks/package.test.d.ts +2 -0
  104. package/dist/scanner/checks/package.test.d.ts.map +1 -0
  105. package/dist/scanner/checks/package.test.js +518 -0
  106. package/dist/scanner/checks/package.test.js.map +1 -0
  107. package/dist/scanner/checks/patterns.d.ts +5 -0
  108. package/dist/scanner/checks/patterns.d.ts.map +1 -0
  109. package/dist/scanner/checks/patterns.js +251 -0
  110. package/dist/scanner/checks/patterns.js.map +1 -0
  111. package/dist/scanner/checks/patterns.test.d.ts +2 -0
  112. package/dist/scanner/checks/patterns.test.d.ts.map +1 -0
  113. package/dist/scanner/checks/patterns.test.js +147 -0
  114. package/dist/scanner/checks/patterns.test.js.map +1 -0
  115. package/dist/scanner/checks/unicode.d.ts +3 -0
  116. package/dist/scanner/checks/unicode.d.ts.map +1 -0
  117. package/dist/scanner/checks/unicode.js +247 -0
  118. package/dist/scanner/checks/unicode.js.map +1 -0
  119. package/dist/scanner/checks/unicode.test.d.ts +2 -0
  120. package/dist/scanner/checks/unicode.test.d.ts.map +1 -0
  121. package/dist/scanner/checks/unicode.test.js +202 -0
  122. package/dist/scanner/checks/unicode.test.js.map +1 -0
  123. package/dist/scanner/checks/yara.d.ts +23 -0
  124. package/dist/scanner/checks/yara.d.ts.map +1 -0
  125. package/dist/scanner/checks/yara.js +349 -0
  126. package/dist/scanner/checks/yara.js.map +1 -0
  127. package/dist/scanner/checks/yara.test.d.ts +2 -0
  128. package/dist/scanner/checks/yara.test.d.ts.map +1 -0
  129. package/dist/scanner/checks/yara.test.js +126 -0
  130. package/dist/scanner/checks/yara.test.js.map +1 -0
  131. package/dist/scanner/constants.d.ts +18 -0
  132. package/dist/scanner/constants.d.ts.map +1 -0
  133. package/dist/scanner/constants.js +37 -0
  134. package/dist/scanner/constants.js.map +1 -0
  135. package/dist/scanner/detection-coverage.test.d.ts +2 -0
  136. package/dist/scanner/detection-coverage.test.d.ts.map +1 -0
  137. package/dist/scanner/detection-coverage.test.js +216 -0
  138. package/dist/scanner/detection-coverage.test.js.map +1 -0
  139. package/dist/scanner/download.d.ts +76 -0
  140. package/dist/scanner/download.d.ts.map +1 -0
  141. package/dist/scanner/download.js +339 -0
  142. package/dist/scanner/download.js.map +1 -0
  143. package/dist/scanner/download.test.d.ts +2 -0
  144. package/dist/scanner/download.test.d.ts.map +1 -0
  145. package/dist/scanner/download.test.js +149 -0
  146. package/dist/scanner/download.test.js.map +1 -0
  147. package/dist/scanner/index.d.ts +8 -0
  148. package/dist/scanner/index.d.ts.map +1 -0
  149. package/dist/scanner/index.js +167 -0
  150. package/dist/scanner/index.js.map +1 -0
  151. package/dist/scanner/index.test.d.ts +2 -0
  152. package/dist/scanner/index.test.d.ts.map +1 -0
  153. package/dist/scanner/index.test.js +71 -0
  154. package/dist/scanner/index.test.js.map +1 -0
  155. package/dist/scanner/loaders/zoo.d.ts +3 -0
  156. package/dist/scanner/loaders/zoo.d.ts.map +1 -0
  157. package/dist/scanner/loaders/zoo.js +112 -0
  158. package/dist/scanner/loaders/zoo.js.map +1 -0
  159. package/dist/scanner/types.d.ts +118 -0
  160. package/dist/scanner/types.d.ts.map +1 -0
  161. package/dist/scanner/types.js +2 -0
  162. package/dist/scanner/types.js.map +1 -0
  163. package/dist/scanner/utils.d.ts +14 -0
  164. package/dist/scanner/utils.d.ts.map +1 -0
  165. package/dist/scanner/utils.js +25 -0
  166. package/dist/scanner/utils.js.map +1 -0
  167. package/dist/scanner/vsix.d.ts +6 -0
  168. package/dist/scanner/vsix.d.ts.map +1 -0
  169. package/dist/scanner/vsix.js +213 -0
  170. package/dist/scanner/vsix.js.map +1 -0
  171. package/dist/scanner/vsix.test.d.ts +2 -0
  172. package/dist/scanner/vsix.test.d.ts.map +1 -0
  173. package/dist/scanner/vsix.test.js +355 -0
  174. package/dist/scanner/vsix.test.js.map +1 -0
  175. package/package.json +60 -0
  176. package/zoo/blocklist/extensions.json +201 -0
  177. package/zoo/iocs/blockchain-extensions.txt +21 -0
  178. package/zoo/iocs/c2-domains.txt +50 -0
  179. package/zoo/iocs/c2-ips.txt +24 -0
  180. package/zoo/iocs/hashes.txt +47 -0
  181. package/zoo/iocs/malicious-npm.txt +85 -0
  182. package/zoo/iocs/wallets.txt +18 -0
  183. package/zoo/signatures/yara/README.md +46 -0
  184. package/zoo/signatures/yara/blockchain_c2.yar +48 -0
  185. package/zoo/signatures/yara/code_execution.yar +165 -0
  186. package/zoo/signatures/yara/credential_harvesting.yar +116 -0
  187. package/zoo/signatures/yara/crypto_wallet_targeting.yar +92 -0
  188. package/zoo/signatures/yara/data_exfiltration.yar +207 -0
  189. package/zoo/signatures/yara/google_calendar_c2.yar +187 -0
  190. package/zoo/signatures/yara/messaging_c2.yar +103 -0
  191. package/zoo/signatures/yara/multi_stage_attacks.yar +331 -0
  192. package/zoo/signatures/yara/obfuscation_patterns.yar +208 -0
  193. package/zoo/signatures/yara/powershell_attacks.yar +116 -0
  194. package/zoo/signatures/yara/rat_capabilities.yar +243 -0
  195. package/zoo/signatures/yara/self_propagation.yar +239 -0
  196. package/zoo/signatures/yara/unicode_stealth.yar +48 -0
  197. package/zoo/signatures/yara/websocket_c2.yar +83 -0
@@ -0,0 +1,243 @@
1
+ /*
2
+ GlassWorm RAT Capabilities Detection
3
+ Detects Remote Access Trojan patterns including SOCKS proxy, VNC, and remote execution
4
+ Based on GlassWorm RAT capabilities for persistent access
5
+ */
6
+
7
+ rule RAT_JS_GlassWorm_SOCKS_Proxy_Jan25 {
8
+ meta:
9
+ description = "Detects GlassWorm-style SOCKS proxy server deployment for network tunneling and pivoting"
10
+ severity = "high"
11
+ score = "85"
12
+ author = "vsix-audit"
13
+ date = "2025-01-29"
14
+ reference = "https://www.koi.security/blog/glassworm-first-self-propagating-worm-using-invisible-code-hits-openvsx-marketplace"
15
+
16
+ strings:
17
+ // SOCKS proxy patterns
18
+ $socks_proxy = "socks" nocase ascii wide
19
+ $socks_server = "socksServer" ascii wide
20
+ $socks_proxy_server = "socksProxyServer" ascii wide
21
+ $socks5 = "socks5" nocase ascii wide
22
+ $socks4 = "socks4" nocase ascii wide
23
+
24
+ // Network server creation
25
+ $create_server = "createServer" ascii wide
26
+ $net_create_server = "net.createServer" ascii wide
27
+ $http_create_server = "http.createServer" ascii wide
28
+ $https_create_server = "https.createServer" ascii wide
29
+
30
+ // Proxy configuration
31
+ $proxy_config = "proxyConfig" ascii wide
32
+ $proxy_server = "proxyServer" ascii wide
33
+ $proxy_port = "proxyPort" ascii wide
34
+ $proxy_host = "proxyHost" ascii wide
35
+
36
+ // Network binding
37
+ $listen = "listen" ascii wide
38
+ $bind = "bind" ascii wide
39
+ $port = "port" ascii wide
40
+ $host = "host" ascii wide
41
+
42
+ // SOCKS protocol
43
+ $socks_auth = "socksAuth" ascii wide
44
+ $socks_connect = "socksConnect" ascii wide
45
+ $socks_relay = "socksRelay" ascii wide
46
+
47
+ condition:
48
+ // High confidence: SOCKS proxy + server creation + network binding
49
+ (any of ($socks_proxy, $socks_server, $socks_proxy_server, $socks5, $socks4)) and
50
+ (any of ($create_server, $net_create_server, $http_create_server, $https_create_server)) and
51
+ (any of ($listen, $bind, $port, $host, $proxy_config, $proxy_server, $proxy_port, $proxy_host, $socks_auth, $socks_connect, $socks_relay))
52
+ }
53
+
54
+ rule RAT_JS_GlassWorm_VNC_Install_Jan25 {
55
+ meta:
56
+ description = "Detects GlassWorm-style VNC or HVNC installation for remote desktop access and control"
57
+ severity = "high"
58
+ score = "90"
59
+ author = "vsix-audit"
60
+ date = "2025-01-29"
61
+ reference = "https://www.koi.security/blog/glassworm-first-self-propagating-worm-using-invisible-code-hits-openvsx-marketplace"
62
+
63
+ strings:
64
+ // VNC patterns
65
+ $vnc = "vnc" nocase ascii wide
66
+ $hvnc = "hvnc" nocase ascii wide
67
+ $tightvnc = "tightvnc" nocase ascii wide
68
+ $ultravnc = "ultravnc" nocase ascii wide
69
+ $realvnc = "realvnc" nocase ascii wide
70
+
71
+ // VNC installation
72
+ $vnc_install = "vncInstall" ascii wide
73
+ $vnc_setup = "vncSetup" ascii wide
74
+ $vnc_configure = "vncConfigure" ascii wide
75
+ $vnc_start = "vncStart" ascii wide
76
+
77
+ // VNC server
78
+ $vnc_server = "vncServer" ascii wide
79
+ $vnc_daemon = "vncDaemon" ascii wide
80
+ $vnc_service = "vncService" ascii wide
81
+
82
+ // Remote desktop access
83
+ $remote_desktop = "remoteDesktop" ascii wide
84
+ $desktop_sharing = "desktopSharing" ascii wide
85
+ $screen_sharing = "screenSharing" ascii wide
86
+ $remote_access = "remoteAccess" ascii wide
87
+
88
+ // VNC configuration
89
+ $vnc_password = "vncPassword" ascii wide
90
+ $vnc_port = "vncPort" ascii wide
91
+ $vnc_display = "vncDisplay" ascii wide
92
+
93
+ condition:
94
+ // High confidence: VNC installation + server setup + remote access
95
+ (any of ($vnc, $hvnc, $tightvnc, $ultravnc, $realvnc)) and
96
+ (any of ($vnc_install, $vnc_setup, $vnc_configure, $vnc_start, $vnc_server, $vnc_daemon, $vnc_service)) and
97
+ (any of ($remote_desktop, $desktop_sharing, $screen_sharing, $remote_access, $vnc_password, $vnc_port, $vnc_display))
98
+ }
99
+
100
+ rule RAT_JS_GlassWorm_Remote_Exec_Jan25 {
101
+ meta:
102
+ description = "Detects GlassWorm-style remote command execution infrastructure with network-triggered shell access"
103
+ severity = "critical"
104
+ score = "95"
105
+ author = "vsix-audit"
106
+ date = "2025-01-29"
107
+ reference = "https://www.koi.security/blog/glassworm-first-self-propagating-worm-using-invisible-code-hits-openvsx-marketplace"
108
+
109
+ strings:
110
+ // Command execution patterns
111
+ $exec = "exec" ascii wide
112
+ $spawn = "spawn" ascii wide
113
+ $execFile = "execFile" ascii wide
114
+ $execSync = "execSync" ascii wide
115
+
116
+ // Child process creation
117
+ $child_process = "child_process" ascii wide
118
+ $fork = "fork" ascii wide
119
+ $spawn_process = "spawnProcess" ascii wide
120
+
121
+ // Remote command execution
122
+ $remote_exec = "remoteExec" ascii wide
123
+ $remote_command = "remoteCommand" ascii wide
124
+ $remote_shell = "remoteShell" ascii wide
125
+ $remote_cmd = "remoteCmd" ascii wide
126
+
127
+ // Command and control
128
+ $command_control = "commandControl" ascii wide
129
+ $cmd_control = "cmdControl" ascii wide
130
+ $shell_control = "shellControl" ascii wide
131
+
132
+ // Network command execution
133
+ $net_exec = "netExec" ascii wide
134
+ $socket_exec = "socketExec" ascii wide
135
+ $tcp_exec = "tcpExec" ascii wide
136
+
137
+ // Command parsing
138
+ $parse_command = "parseCommand" ascii wide
139
+ $execute_command = "executeCommand" ascii wide
140
+ $run_command = "runCommand" ascii wide
141
+
142
+ condition:
143
+ // Critical: Command execution + remote capabilities + network communication
144
+ (any of ($exec, $spawn, $execFile, $execSync, $child_process, $fork, $spawn_process)) and
145
+ (any of ($remote_exec, $remote_command, $remote_shell, $remote_cmd, $command_control, $cmd_control, $shell_control)) and
146
+ (any of ($net_exec, $socket_exec, $tcp_exec, $parse_command, $execute_command, $run_command))
147
+ }
148
+
149
+ rule RAT_JS_GlassWorm_Persistent_Backdoor_Jan25 {
150
+ meta:
151
+ description = "Detects GlassWorm-style persistent backdoor using registry, services, or scheduled tasks"
152
+ severity = "high"
153
+ score = "90"
154
+ author = "vsix-audit"
155
+ date = "2025-01-29"
156
+ reference = "https://www.koi.security/blog/glassworm-first-self-propagating-worm-using-invisible-code-hits-openvsx-marketplace"
157
+
158
+ strings:
159
+ // Persistence mechanisms
160
+ $persistence = "persistence" ascii wide
161
+ $backdoor = "backdoor" ascii wide
162
+ $persistent = "persistent" ascii wide
163
+ $survive_reboot = "surviveReboot" ascii wide
164
+
165
+ // Registry persistence (Windows)
166
+ $reg_run = "regRun" ascii wide
167
+ $registry_run = "registryRun" ascii wide
168
+ $startup_key = "startupKey" ascii wide
169
+ $auto_start = "autoStart" ascii wide
170
+
171
+ // Service installation
172
+ $service_install = "serviceInstall" ascii wide
173
+ $service_create = "serviceCreate" ascii wide
174
+ $service_start = "serviceStart" ascii wide
175
+ $service_auto = "serviceAuto" ascii wide
176
+
177
+ // Scheduled tasks
178
+ $scheduled_task = "scheduledTask" ascii wide
179
+ $cron_job = "cronJob" ascii wide
180
+ $task_scheduler = "taskScheduler" ascii wide
181
+
182
+ // Startup folder
183
+ $startup_folder = "startupFolder" ascii wide
184
+ $startup_shortcut = "startupShortcut" ascii wide
185
+ $startup_link = "startupLink" ascii wide
186
+
187
+ // Hidden files
188
+ $hidden_file = "hiddenFile" ascii wide
189
+ $system_file = "systemFile" ascii wide
190
+ $temp_file = "tempFile" ascii wide
191
+
192
+ condition:
193
+ // High confidence: Persistence + registry/service manipulation + hidden files
194
+ (any of ($persistence, $backdoor, $persistent, $survive_reboot)) and
195
+ (any of ($reg_run, $registry_run, $startup_key, $auto_start, $service_install, $service_create, $service_start, $service_auto, $scheduled_task, $cron_job, $task_scheduler)) and
196
+ (any of ($startup_folder, $startup_shortcut, $startup_link, $hidden_file, $system_file, $temp_file))
197
+ }
198
+
199
+ rule RAT_JS_GlassWorm_Network_Recon_Jan25 {
200
+ meta:
201
+ description = "Detects GlassWorm-style network reconnaissance with port scanning and lateral movement capabilities"
202
+ severity = "medium"
203
+ score = "75"
204
+ author = "vsix-audit"
205
+ date = "2025-01-29"
206
+ reference = "https://www.koi.security/blog/glassworm-first-self-propagating-worm-using-invisible-code-hits-openvsx-marketplace"
207
+
208
+ strings:
209
+ // Network scanning
210
+ $network_scan = "networkScan" ascii wide
211
+ $port_scan = "portScan" ascii wide
212
+ $host_scan = "hostScan" ascii wide
213
+ $network_discovery = "networkDiscovery" ascii wide
214
+
215
+ // Network enumeration
216
+ $enumerate_hosts = "enumerateHosts" ascii wide
217
+ $discover_hosts = "discoverHosts" ascii wide
218
+ $scan_network = "scanNetwork" ascii wide
219
+ $map_network = "mapNetwork" ascii wide
220
+
221
+ // Lateral movement
222
+ $lateral_movement = "lateralMovement" ascii wide
223
+ $pivot = "pivot" ascii wide
224
+ $jump_host = "jumpHost" ascii wide
225
+ $relay = "relay" ascii wide
226
+
227
+ // Network tools
228
+ $nmap = "nmap" ascii wide
229
+ $ping = "ping" ascii wide
230
+ $traceroute = "traceroute" ascii wide
231
+ $netstat = "netstat" ascii wide
232
+
233
+ // Network protocols
234
+ $tcp_scan = "tcpScan" ascii wide
235
+ $udp_scan = "udpScan" ascii wide
236
+ $icmp_scan = "icmpScan" ascii wide
237
+
238
+ condition:
239
+ // Detect network reconnaissance with scanning tools
240
+ (any of ($network_scan, $port_scan, $host_scan, $network_discovery, $enumerate_hosts, $discover_hosts, $scan_network, $map_network)) and
241
+ (any of ($lateral_movement, $pivot, $jump_host, $relay, $nmap, $ping, $traceroute, $netstat)) and
242
+ (any of ($tcp_scan, $udp_scan, $icmp_scan))
243
+ }
@@ -0,0 +1,239 @@
1
+ /*
2
+ GlassWorm Self-Propagation Detection
3
+ Detects worm self-propagation patterns including automated publishing and credential reuse
4
+ Based on GlassWorm worm behavior for autonomous spread
5
+ */
6
+
7
+ rule MAL_JS_GlassWorm_Auto_Publish_Jan25 {
8
+ meta:
9
+ description = "Detects GlassWorm-style automated package publishing using stolen credentials for worm propagation"
10
+ severity = "high"
11
+ score = "85"
12
+ author = "vsix-audit"
13
+ date = "2025-01-29"
14
+ reference = "https://www.koi.security/blog/glassworm-first-self-propagating-worm-using-invisible-code-hits-openvsx-marketplace"
15
+
16
+ strings:
17
+ // Package publishing
18
+ $npm_publish = "npm publish" ascii wide
19
+ $yarn_publish = "yarn publish" ascii wide
20
+ $publish_package = "publishPackage" ascii wide
21
+ $auto_publish = "autoPublish" ascii wide
22
+
23
+ // Extension publishing
24
+ $vsce_publish = "vsce publish" ascii wide
25
+ $extension_publish = "extensionPublish" ascii wide
26
+ $marketplace_publish = "marketplacePublish" ascii wide
27
+ $openvsx_publish = "openvsxPublish" ascii wide
28
+
29
+ // Automated publishing
30
+ $automated_publish = "automatedPublish" ascii wide
31
+ $auto_upload = "autoUpload" ascii wide
32
+ $batch_publish = "batchPublish" ascii wide
33
+ $mass_publish = "massPublish" ascii wide
34
+
35
+ // Credential usage
36
+ $use_credentials = "useCredentials" ascii wide
37
+ $auth_publish = "authPublish" ascii wide
38
+ $token_publish = "tokenPublish" ascii wide
39
+ $credential_publish = "credentialPublish" ascii wide
40
+
41
+ // Publishing APIs
42
+ $npm_api = "npmApi" ascii wide
43
+ $github_api = "githubApi" ascii wide
44
+ $openvsx_api = "openvsxApi" ascii wide
45
+ $marketplace_api = "marketplaceApi" ascii wide
46
+
47
+ condition:
48
+ // High confidence: Automated publishing + credential usage + API access
49
+ (any of ($npm_publish, $yarn_publish, $publish_package, $auto_publish, $vsce_publish, $extension_publish, $marketplace_publish, $openvsx_publish)) and
50
+ (any of ($automated_publish, $auto_upload, $batch_publish, $mass_publish)) and
51
+ (any of ($use_credentials, $auth_publish, $token_publish, $credential_publish, $npm_api, $github_api, $openvsx_api, $marketplace_api))
52
+ }
53
+
54
+ rule MAL_JS_GlassWorm_Credential_Reuse_Jan25 {
55
+ meta:
56
+ description = "Detects GlassWorm-style credential reuse pattern for compromising multiple accounts"
57
+ severity = "high"
58
+ score = "80"
59
+ author = "vsix-audit"
60
+ date = "2025-01-29"
61
+ reference = "https://www.koi.security/blog/glassworm-first-self-propagating-worm-using-invisible-code-hits-openvsx-marketplace"
62
+
63
+ strings:
64
+ // Credential validation
65
+ $validate_credentials = "validateCredentials" ascii wide
66
+ $test_credentials = "testCredentials" ascii wide
67
+ $check_credentials = "checkCredentials" ascii wide
68
+ $verify_credentials = "verifyCredentials" ascii wide
69
+
70
+ // Credential reuse
71
+ $reuse_credentials = "reuseCredentials" ascii wide
72
+ $credential_reuse = "credentialReuse" ascii wide
73
+ $reuse_auth = "reuseAuth" ascii wide
74
+ $reuse_token = "reuseToken" ascii wide
75
+
76
+ // Multiple account access
77
+ $multi_account = "multiAccount" ascii wide
78
+ $batch_account = "batchAccount" ascii wide
79
+ $bulk_account = "bulkAccount" ascii wide
80
+ $mass_account = "massAccount" ascii wide
81
+
82
+ // Account enumeration
83
+ $enumerate_accounts = "enumerateAccounts" ascii wide
84
+ $list_accounts = "listAccounts" ascii wide
85
+ $scan_accounts = "scanAccounts" ascii wide
86
+ $discover_accounts = "discoverAccounts" ascii wide
87
+
88
+ // Credential rotation
89
+ $rotate_credentials = "rotateCredentials" ascii wide
90
+ $credential_rotation = "credentialRotation" ascii wide
91
+ $auth_rotation = "authRotation" ascii wide
92
+
93
+ condition:
94
+ // Detect credential validation with reuse patterns
95
+ (any of ($validate_credentials, $test_credentials, $check_credentials, $verify_credentials)) and
96
+ (any of ($reuse_credentials, $credential_reuse, $reuse_auth, $reuse_token)) and
97
+ (any of ($multi_account, $batch_account, $bulk_account, $mass_account, $enumerate_accounts, $list_accounts, $scan_accounts, $discover_accounts, $rotate_credentials, $credential_rotation, $auth_rotation))
98
+ }
99
+
100
+ rule MAL_JS_GlassWorm_Git_Automation_Jan25 {
101
+ meta:
102
+ description = "Detects GlassWorm-style automated git operations for spreading malicious code to repositories"
103
+ severity = "high"
104
+ score = "85"
105
+ author = "vsix-audit"
106
+ date = "2025-01-29"
107
+ reference = "https://www.koi.security/blog/glassworm-first-self-propagating-worm-using-invisible-code-hits-openvsx-marketplace"
108
+
109
+ strings:
110
+ // Git automation
111
+ $git_automation = "gitAutomation" ascii wide
112
+ $auto_git = "autoGit" ascii wide
113
+ $git_bot = "gitBot" ascii wide
114
+ $automated_git = "automatedGit" ascii wide
115
+
116
+ // Git operations
117
+ $git_commit = "git commit" ascii wide
118
+ $git_push = "git push" ascii wide
119
+ $git_pull = "git pull" ascii wide
120
+ $git_clone = "git clone" ascii wide
121
+
122
+ // Automated git workflow
123
+ $git_workflow = "gitWorkflow" ascii wide
124
+ $auto_commit = "autoCommit" ascii wide
125
+ $auto_push = "autoPush" ascii wide
126
+ $batch_git = "batchGit" ascii wide
127
+
128
+ // Repository manipulation
129
+ $repo_manipulate = "repoManipulate" ascii wide
130
+ $repo_inject = "repoInject" ascii wide
131
+ $repo_contaminate = "repoContaminate" ascii wide
132
+ $repo_infect = "repoInfect" ascii wide
133
+
134
+ // Git hooks
135
+ $git_hooks = "gitHooks" ascii wide
136
+ $pre_commit = "preCommit" ascii wide
137
+ $post_commit = "postCommit" ascii wide
138
+ $pre_push = "prePush" ascii wide
139
+
140
+ condition:
141
+ // Detect git automation with repository manipulation
142
+ (any of ($git_automation, $auto_git, $git_bot, $automated_git, $git_commit, $git_push, $git_pull, $git_clone)) and
143
+ (any of ($git_workflow, $auto_commit, $auto_push, $batch_git)) and
144
+ (any of ($repo_manipulate, $repo_inject, $repo_contaminate, $repo_infect, $git_hooks, $pre_commit, $post_commit, $pre_push))
145
+ }
146
+
147
+ rule MAL_JS_GlassWorm_Worm_Propagation_Jan25 {
148
+ meta:
149
+ description = "Detects GlassWorm-style worm self-replication and autonomous propagation mechanisms"
150
+ severity = "critical"
151
+ score = "95"
152
+ author = "vsix-audit"
153
+ date = "2025-01-29"
154
+ reference = "https://www.koi.security/blog/glassworm-first-self-propagating-worm-using-invisible-code-hits-openvsx-marketplace"
155
+
156
+ strings:
157
+ // Worm patterns
158
+ $worm = "worm" ascii wide
159
+ $propagate = "propagate" ascii wide
160
+ $spread = "spread" ascii wide
161
+ $infect = "infect" ascii wide
162
+
163
+ // Self-replication
164
+ $self_replicate = "selfReplicate" ascii wide
165
+ $self_copy = "selfCopy" ascii wide
166
+ $self_propagate = "selfPropagate" ascii wide
167
+ $auto_replicate = "autoReplicate" ascii wide
168
+
169
+ // Propagation vectors
170
+ $propagation_vector = "propagationVector" ascii wide
171
+ $spread_vector = "spreadVector" ascii wide
172
+ $infection_vector = "infectionVector" ascii wide
173
+ $attack_vector = "attackVector" ascii wide
174
+
175
+ // Autonomous behavior
176
+ $autonomous = "autonomous" ascii wide
177
+ $self_sustaining = "selfSustaining" ascii wide
178
+ $self_contained = "selfContained" ascii wide
179
+ $independent = "independent" ascii wide
180
+
181
+ // Worm lifecycle
182
+ $worm_lifecycle = "wormLifecycle" ascii wide
183
+ $infection_cycle = "infectionCycle" ascii wide
184
+ $propagation_cycle = "propagationCycle" ascii wide
185
+ $spread_cycle = "spreadCycle" ascii wide
186
+
187
+ condition:
188
+ // Critical: Worm behavior + self-replication + autonomous operation
189
+ (any of ($worm, $propagate, $spread, $infect)) and
190
+ (any of ($self_replicate, $self_copy, $self_propagate, $auto_replicate)) and
191
+ (any of ($propagation_vector, $spread_vector, $infection_vector, $attack_vector, $autonomous, $self_sustaining, $self_contained, $independent, $worm_lifecycle, $infection_cycle, $propagation_cycle, $spread_cycle))
192
+ }
193
+
194
+ rule MAL_JS_GlassWorm_Supply_Chain_Abuse_Jan25 {
195
+ meta:
196
+ description = "Detects GlassWorm-style supply chain abuse through package ecosystem and dependency injection"
197
+ severity = "high"
198
+ score = "90"
199
+ author = "vsix-audit"
200
+ date = "2025-01-29"
201
+ reference = "https://www.koi.security/blog/glassworm-first-self-propagating-worm-using-invisible-code-hits-openvsx-marketplace"
202
+
203
+ strings:
204
+ // Supply chain patterns
205
+ $supply_chain = "supplyChain" ascii wide
206
+ $package_chain = "packageChain" ascii wide
207
+ $dependency_chain = "dependencyChain" ascii wide
208
+ $repo_chain = "repoChain" ascii wide
209
+
210
+ // Package ecosystem abuse
211
+ $ecosystem_abuse = "ecosystemAbuse" ascii wide
212
+ $package_abuse = "packageAbuse" ascii wide
213
+ $registry_abuse = "registryAbuse" ascii wide
214
+ $marketplace_abuse = "marketplaceAbuse" ascii wide
215
+
216
+ // Dependency injection
217
+ $dependency_inject = "dependencyInject" ascii wide
218
+ $package_inject = "packageInject" ascii wide
219
+ $repo_inject = "repoInject" ascii wide
220
+ $chain_inject = "chainInject" ascii wide
221
+
222
+ // Automated compromise
223
+ $auto_compromise = "autoCompromise" ascii wide
224
+ $batch_compromise = "batchCompromise" ascii wide
225
+ $mass_compromise = "massCompromise" ascii wide
226
+ $bulk_compromise = "bulkCompromise" ascii wide
227
+
228
+ // Trust exploitation
229
+ $trust_exploit = "trustExploit" ascii wide
230
+ $trust_abuse = "trustAbuse" ascii wide
231
+ $reputation_abuse = "reputationAbuse" ascii wide
232
+ $legitimacy_abuse = "legitimacyAbuse" ascii wide
233
+
234
+ condition:
235
+ // Detect supply chain abuse with automated compromise
236
+ (any of ($supply_chain, $package_chain, $dependency_chain, $repo_chain)) and
237
+ (any of ($ecosystem_abuse, $package_abuse, $registry_abuse, $marketplace_abuse)) and
238
+ (any of ($dependency_inject, $package_inject, $repo_inject, $chain_inject, $auto_compromise, $batch_compromise, $mass_compromise, $bulk_compromise, $trust_exploit, $trust_abuse, $reputation_abuse, $legitimacy_abuse))
239
+ }
@@ -0,0 +1,48 @@
1
+ /*
2
+ GlassWorm Unicode Stealth Detection
3
+ Detects invisible Unicode variation selectors used to hide malicious code
4
+
5
+ IMPORTANT: This rule requires MANY variation selectors plus eval/Function.
6
+ A few zero-width characters are normal in i18n bundles.
7
+ */
8
+
9
+ rule MAL_JS_GlassWorm_Unicode_Stealth_Jan25 {
10
+ meta:
11
+ description = "Detects GlassWorm-style invisible Unicode variation selectors used to hide malicious code"
12
+ severity = "critical"
13
+ score = "95"
14
+ author = "vsix-audit"
15
+ date = "2025-01-29"
16
+ reference = "https://www.koi.security/blog/glassworm-first-self-propagating-worm-using-invisible-code-hits-openvsx-marketplace"
17
+
18
+ strings:
19
+ // UTF-8 encoded variation selectors (U+FE00-U+FE0F)
20
+ // Note: These are 3-byte UTF-8 sequences EF B8 80 through EF B8 8F
21
+ $vs_utf8 = { EF B8 (80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 8A | 8B | 8C | 8D | 8E | 8F) }
22
+
23
+ // Code execution patterns - must have eval or Function
24
+ $eval = "eval(" ascii wide
25
+ $function = "new Function(" ascii wide
26
+
27
+ // Decode patterns that are used to extract the hidden code
28
+ $decode1 = "String.fromCharCode" ascii wide
29
+ $decode2 = "charCodeAt" ascii wide
30
+
31
+ // Zero-width space (U+200B) - used in obfuscation
32
+ $zws = { E2 80 8B }
33
+
34
+ // Zero-width non-joiner (U+200C) and joiner (U+200D)
35
+ $zwc = { E2 80 (8C | 8D) }
36
+
37
+ condition:
38
+ // Require VERY MANY variation selectors (50+) for standalone detection
39
+ // Normal i18n/emoji bundles have < 30, malware has hundreds
40
+ (#vs_utf8 > 50 and any of ($eval, $function)) or
41
+ // Or: moderate VS count + both eval AND decode (full chain)
42
+ (#vs_utf8 > 20 and any of ($eval, $function) and any of ($decode*)) or
43
+ // Or: many zero-width chars + eval (different obfuscation style)
44
+ ((#zws + #zwc) > 30 and any of ($eval, $function))
45
+ }
46
+
47
+ // REMOVED: GlassWorm_Suspicious_Code_Gaps
48
+ // This rule was removed earlier - it matched any code with whitespace.
@@ -0,0 +1,83 @@
1
+ /*
2
+ WebSocket C2 Detection
3
+ Detects WebSocket-based command and control patterns
4
+ */
5
+
6
+ rule C2_JS_WebSocket_Command_Exec_Jan25 {
7
+ meta:
8
+ description = "Detects WebSocket C2 pattern with message handler triggering child_process command execution"
9
+ severity = "high"
10
+ score = 80
11
+ author = "vsix-audit"
12
+ date = "2025-01-30"
13
+
14
+ strings:
15
+ // WebSocket creation
16
+ $ws1 = "new WebSocket(" ascii wide
17
+ $ws2 = "WebSocket(" ascii wide
18
+ $ws3 = "ws://" ascii wide
19
+ $ws4 = "wss://" ascii wide
20
+
21
+ // Message handling (specific patterns)
22
+ $msg1 = ".onmessage" ascii wide
23
+ $msg2 = ".on('message'" ascii wide
24
+ $msg3 = ".on(\"message\"" ascii wide
25
+
26
+ // Command execution via child_process (not just setTimeout)
27
+ $exec_cp = "child_process" ascii wide
28
+ $exec_method1 = ".exec(" ascii wide
29
+ $exec_method2 = ".spawn(" ascii wide
30
+ $exec_sync1 = "execSync" ascii wide
31
+ $exec_sync2 = "spawnSync" ascii wide
32
+
33
+ // Eval from message (dangerous pattern)
34
+ $eval_msg = "eval(" ascii wide
35
+
36
+ // C2-specific patterns
37
+ $c2_cmd = "command" ascii wide
38
+ $c2_shell = "shell" ascii wide nocase
39
+ $c2_run = "runCommand" ascii wide
40
+
41
+ condition:
42
+ // WebSocket + message handler + child_process execution
43
+ any of ($ws*) and any of ($msg*) and
44
+ (
45
+ // Direct child_process usage with exec/spawn method
46
+ ($exec_cp and any of ($exec_method*, $exec_sync*)) or
47
+ // Eval from WebSocket (rare in legit code)
48
+ ($eval_msg and any of ($c2_cmd, $c2_shell, $c2_run))
49
+ )
50
+ }
51
+
52
+ rule RAT_JS_WebSocket_Reverse_Shell_Jan25 {
53
+ meta:
54
+ description = "Detects WebSocket reverse shell with shell process stdin/stdout piped through socket"
55
+ severity = "critical"
56
+ score = 95
57
+ author = "vsix-audit"
58
+ date = "2025-01-30"
59
+
60
+ strings:
61
+ // WebSocket creation
62
+ $ws1 = "new WebSocket(" ascii wide
63
+ $ws2 = "WebSocket(" ascii wide
64
+ $ws3 = "ws://" ascii wide
65
+ $ws4 = "wss://" ascii wide
66
+
67
+ // Shell paths
68
+ $shell1 = "/bin/sh" ascii wide
69
+ $shell2 = "/bin/bash" ascii wide
70
+ $shell3 = "/bin/zsh" ascii wide
71
+ $shell4 = "cmd.exe" ascii wide
72
+ $shell5 = "powershell" ascii wide nocase
73
+
74
+ // Stream piping (connecting shell to socket)
75
+ $pipe1 = ".pipe(" ascii wide
76
+ $pipe2 = "stdin" ascii wide
77
+ $pipe3 = "stdout" ascii wide
78
+ $pipe4 = "stderr" ascii wide
79
+ $pipe5 = ".send(" ascii wide
80
+
81
+ condition:
82
+ any of ($ws*) and any of ($shell*) and 2 of ($pipe*)
83
+ }