@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.
- package/LICENSE +661 -0
- package/README.md +281 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +703 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/scanner/batch.d.ts +12 -0
- package/dist/scanner/batch.d.ts.map +1 -0
- package/dist/scanner/batch.js +104 -0
- package/dist/scanner/batch.js.map +1 -0
- package/dist/scanner/bundler.d.ts +35 -0
- package/dist/scanner/bundler.d.ts.map +1 -0
- package/dist/scanner/bundler.js +120 -0
- package/dist/scanner/bundler.js.map +1 -0
- package/dist/scanner/cache.d.ts +45 -0
- package/dist/scanner/cache.d.ts.map +1 -0
- package/dist/scanner/cache.js +153 -0
- package/dist/scanner/cache.js.map +1 -0
- package/dist/scanner/cache.test.d.ts +2 -0
- package/dist/scanner/cache.test.d.ts.map +1 -0
- package/dist/scanner/cache.test.js +149 -0
- package/dist/scanner/cache.test.js.map +1 -0
- package/dist/scanner/capabilities.d.ts +29 -0
- package/dist/scanner/capabilities.d.ts.map +1 -0
- package/dist/scanner/capabilities.js +217 -0
- package/dist/scanner/capabilities.js.map +1 -0
- package/dist/scanner/checks/ast.d.ts +3 -0
- package/dist/scanner/checks/ast.d.ts.map +1 -0
- package/dist/scanner/checks/ast.js +469 -0
- package/dist/scanner/checks/ast.js.map +1 -0
- package/dist/scanner/checks/ast.test.d.ts +2 -0
- package/dist/scanner/checks/ast.test.d.ts.map +1 -0
- package/dist/scanner/checks/ast.test.js +389 -0
- package/dist/scanner/checks/ast.test.js.map +1 -0
- package/dist/scanner/checks/behavioral.d.ts +3 -0
- package/dist/scanner/checks/behavioral.d.ts.map +1 -0
- package/dist/scanner/checks/behavioral.js +367 -0
- package/dist/scanner/checks/behavioral.js.map +1 -0
- package/dist/scanner/checks/blocklist.d.ts +3 -0
- package/dist/scanner/checks/blocklist.d.ts.map +1 -0
- package/dist/scanner/checks/blocklist.js +32 -0
- package/dist/scanner/checks/blocklist.js.map +1 -0
- package/dist/scanner/checks/blocklist.test.d.ts +2 -0
- package/dist/scanner/checks/blocklist.test.d.ts.map +1 -0
- package/dist/scanner/checks/blocklist.test.js +74 -0
- package/dist/scanner/checks/blocklist.test.js.map +1 -0
- package/dist/scanner/checks/chains.d.ts +35 -0
- package/dist/scanner/checks/chains.d.ts.map +1 -0
- package/dist/scanner/checks/chains.js +505 -0
- package/dist/scanner/checks/chains.js.map +1 -0
- package/dist/scanner/checks/chains.test.d.ts +2 -0
- package/dist/scanner/checks/chains.test.d.ts.map +1 -0
- package/dist/scanner/checks/chains.test.js +250 -0
- package/dist/scanner/checks/chains.test.js.map +1 -0
- package/dist/scanner/checks/dataflow.d.ts +3 -0
- package/dist/scanner/checks/dataflow.d.ts.map +1 -0
- package/dist/scanner/checks/dataflow.js +316 -0
- package/dist/scanner/checks/dataflow.js.map +1 -0
- package/dist/scanner/checks/dependencies.d.ts +13 -0
- package/dist/scanner/checks/dependencies.d.ts.map +1 -0
- package/dist/scanner/checks/dependencies.js +225 -0
- package/dist/scanner/checks/dependencies.js.map +1 -0
- package/dist/scanner/checks/dependencies.test.d.ts +2 -0
- package/dist/scanner/checks/dependencies.test.d.ts.map +1 -0
- package/dist/scanner/checks/dependencies.test.js +248 -0
- package/dist/scanner/checks/dependencies.test.js.map +1 -0
- package/dist/scanner/checks/finding-quality.test.d.ts +8 -0
- package/dist/scanner/checks/finding-quality.test.d.ts.map +1 -0
- package/dist/scanner/checks/finding-quality.test.js +164 -0
- package/dist/scanner/checks/finding-quality.test.js.map +1 -0
- package/dist/scanner/checks/ioc.d.ts +20 -0
- package/dist/scanner/checks/ioc.d.ts.map +1 -0
- package/dist/scanner/checks/ioc.js +234 -0
- package/dist/scanner/checks/ioc.js.map +1 -0
- package/dist/scanner/checks/ioc.test.d.ts +2 -0
- package/dist/scanner/checks/ioc.test.d.ts.map +1 -0
- package/dist/scanner/checks/ioc.test.js +298 -0
- package/dist/scanner/checks/ioc.test.js.map +1 -0
- package/dist/scanner/checks/manifest.d.ts +6 -0
- package/dist/scanner/checks/manifest.d.ts.map +1 -0
- package/dist/scanner/checks/manifest.js +123 -0
- package/dist/scanner/checks/manifest.js.map +1 -0
- package/dist/scanner/checks/manifest.test.d.ts +2 -0
- package/dist/scanner/checks/manifest.test.d.ts.map +1 -0
- package/dist/scanner/checks/manifest.test.js +108 -0
- package/dist/scanner/checks/manifest.test.js.map +1 -0
- package/dist/scanner/checks/obfuscation.d.ts +3 -0
- package/dist/scanner/checks/obfuscation.d.ts.map +1 -0
- package/dist/scanner/checks/obfuscation.js +432 -0
- package/dist/scanner/checks/obfuscation.js.map +1 -0
- package/dist/scanner/checks/obfuscation.test.d.ts +2 -0
- package/dist/scanner/checks/obfuscation.test.d.ts.map +1 -0
- package/dist/scanner/checks/obfuscation.test.js +399 -0
- package/dist/scanner/checks/obfuscation.test.js.map +1 -0
- package/dist/scanner/checks/package.d.ts +17 -0
- package/dist/scanner/checks/package.d.ts.map +1 -0
- package/dist/scanner/checks/package.js +422 -0
- package/dist/scanner/checks/package.js.map +1 -0
- package/dist/scanner/checks/package.test.d.ts +2 -0
- package/dist/scanner/checks/package.test.d.ts.map +1 -0
- package/dist/scanner/checks/package.test.js +518 -0
- package/dist/scanner/checks/package.test.js.map +1 -0
- package/dist/scanner/checks/patterns.d.ts +5 -0
- package/dist/scanner/checks/patterns.d.ts.map +1 -0
- package/dist/scanner/checks/patterns.js +251 -0
- package/dist/scanner/checks/patterns.js.map +1 -0
- package/dist/scanner/checks/patterns.test.d.ts +2 -0
- package/dist/scanner/checks/patterns.test.d.ts.map +1 -0
- package/dist/scanner/checks/patterns.test.js +147 -0
- package/dist/scanner/checks/patterns.test.js.map +1 -0
- package/dist/scanner/checks/unicode.d.ts +3 -0
- package/dist/scanner/checks/unicode.d.ts.map +1 -0
- package/dist/scanner/checks/unicode.js +247 -0
- package/dist/scanner/checks/unicode.js.map +1 -0
- package/dist/scanner/checks/unicode.test.d.ts +2 -0
- package/dist/scanner/checks/unicode.test.d.ts.map +1 -0
- package/dist/scanner/checks/unicode.test.js +202 -0
- package/dist/scanner/checks/unicode.test.js.map +1 -0
- package/dist/scanner/checks/yara.d.ts +23 -0
- package/dist/scanner/checks/yara.d.ts.map +1 -0
- package/dist/scanner/checks/yara.js +349 -0
- package/dist/scanner/checks/yara.js.map +1 -0
- package/dist/scanner/checks/yara.test.d.ts +2 -0
- package/dist/scanner/checks/yara.test.d.ts.map +1 -0
- package/dist/scanner/checks/yara.test.js +126 -0
- package/dist/scanner/checks/yara.test.js.map +1 -0
- package/dist/scanner/constants.d.ts +18 -0
- package/dist/scanner/constants.d.ts.map +1 -0
- package/dist/scanner/constants.js +37 -0
- package/dist/scanner/constants.js.map +1 -0
- package/dist/scanner/detection-coverage.test.d.ts +2 -0
- package/dist/scanner/detection-coverage.test.d.ts.map +1 -0
- package/dist/scanner/detection-coverage.test.js +216 -0
- package/dist/scanner/detection-coverage.test.js.map +1 -0
- package/dist/scanner/download.d.ts +76 -0
- package/dist/scanner/download.d.ts.map +1 -0
- package/dist/scanner/download.js +339 -0
- package/dist/scanner/download.js.map +1 -0
- package/dist/scanner/download.test.d.ts +2 -0
- package/dist/scanner/download.test.d.ts.map +1 -0
- package/dist/scanner/download.test.js +149 -0
- package/dist/scanner/download.test.js.map +1 -0
- package/dist/scanner/index.d.ts +8 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +167 -0
- package/dist/scanner/index.js.map +1 -0
- package/dist/scanner/index.test.d.ts +2 -0
- package/dist/scanner/index.test.d.ts.map +1 -0
- package/dist/scanner/index.test.js +71 -0
- package/dist/scanner/index.test.js.map +1 -0
- package/dist/scanner/loaders/zoo.d.ts +3 -0
- package/dist/scanner/loaders/zoo.d.ts.map +1 -0
- package/dist/scanner/loaders/zoo.js +112 -0
- package/dist/scanner/loaders/zoo.js.map +1 -0
- package/dist/scanner/types.d.ts +118 -0
- package/dist/scanner/types.d.ts.map +1 -0
- package/dist/scanner/types.js +2 -0
- package/dist/scanner/types.js.map +1 -0
- package/dist/scanner/utils.d.ts +14 -0
- package/dist/scanner/utils.d.ts.map +1 -0
- package/dist/scanner/utils.js +25 -0
- package/dist/scanner/utils.js.map +1 -0
- package/dist/scanner/vsix.d.ts +6 -0
- package/dist/scanner/vsix.d.ts.map +1 -0
- package/dist/scanner/vsix.js +213 -0
- package/dist/scanner/vsix.js.map +1 -0
- package/dist/scanner/vsix.test.d.ts +2 -0
- package/dist/scanner/vsix.test.d.ts.map +1 -0
- package/dist/scanner/vsix.test.js +355 -0
- package/dist/scanner/vsix.test.js.map +1 -0
- package/package.json +60 -0
- package/zoo/blocklist/extensions.json +201 -0
- package/zoo/iocs/blockchain-extensions.txt +21 -0
- package/zoo/iocs/c2-domains.txt +50 -0
- package/zoo/iocs/c2-ips.txt +24 -0
- package/zoo/iocs/hashes.txt +47 -0
- package/zoo/iocs/malicious-npm.txt +85 -0
- package/zoo/iocs/wallets.txt +18 -0
- package/zoo/signatures/yara/README.md +46 -0
- package/zoo/signatures/yara/blockchain_c2.yar +48 -0
- package/zoo/signatures/yara/code_execution.yar +165 -0
- package/zoo/signatures/yara/credential_harvesting.yar +116 -0
- package/zoo/signatures/yara/crypto_wallet_targeting.yar +92 -0
- package/zoo/signatures/yara/data_exfiltration.yar +207 -0
- package/zoo/signatures/yara/google_calendar_c2.yar +187 -0
- package/zoo/signatures/yara/messaging_c2.yar +103 -0
- package/zoo/signatures/yara/multi_stage_attacks.yar +331 -0
- package/zoo/signatures/yara/obfuscation_patterns.yar +208 -0
- package/zoo/signatures/yara/powershell_attacks.yar +116 -0
- package/zoo/signatures/yara/rat_capabilities.yar +243 -0
- package/zoo/signatures/yara/self_propagation.yar +239 -0
- package/zoo/signatures/yara/unicode_stealth.yar +48 -0
- package/zoo/signatures/yara/websocket_c2.yar +83 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Known legitimate blockchain development extensions
|
|
2
|
+
# These extensions legitimately reference wallet addresses and contract addresses
|
|
3
|
+
# Format: publisher.name (one per line)
|
|
4
|
+
|
|
5
|
+
# Solidity development
|
|
6
|
+
AckeeBlockchain.tools-for-solidity
|
|
7
|
+
JuanBlanco.solidity
|
|
8
|
+
NomicFoundation.hardhat-solidity
|
|
9
|
+
tintinweb.solidity-visual-auditor
|
|
10
|
+
tintinweb.vscode-solidity-language
|
|
11
|
+
tintinweb.vscode-solidity-flattener
|
|
12
|
+
tintinweb.graphviz-interactive-preview
|
|
13
|
+
tintinweb.vscode-ethover
|
|
14
|
+
tintinweb.vscode-vyper
|
|
15
|
+
|
|
16
|
+
# Security audit tools
|
|
17
|
+
trailofbits.vscode-weaudit
|
|
18
|
+
|
|
19
|
+
# Web3 development
|
|
20
|
+
AureliaEffect.aelf-contract-build
|
|
21
|
+
AureliaEffect.aelf-contract-deploy
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# VS Code Extension Malware C2 Domains
|
|
2
|
+
# Format: domain[.]tld # Campaign - Notes
|
|
3
|
+
# All domains defanged with [.] for safety
|
|
4
|
+
#
|
|
5
|
+
# Submit new domains via PR or issue
|
|
6
|
+
|
|
7
|
+
# FAMOUS CHOLLIMA / Contagious Interview (Vercel hosted)
|
|
8
|
+
vscodesettings03rgg[.]vercel[.]app # FAMOUS CHOLLIMA - C2
|
|
9
|
+
mylocationapi03[.]vercel[.]app # FAMOUS CHOLLIMA - C2
|
|
10
|
+
ip-check-wh-notification[.]vercel[.]app # FAMOUS CHOLLIMA - C2
|
|
11
|
+
chainlink-api-v3[.]com # FAMOUS CHOLLIMA - BeaverTail payload delivery (via HTTP error responses)
|
|
12
|
+
|
|
13
|
+
# HardHatRAT Campaign
|
|
14
|
+
api[.]npoint[.]io # HardHatRAT - JSON payload hosting (legitimate service abused)
|
|
15
|
+
freeipapi[.]com # HardHatRAT - Victim IP lookup (legitimate service abused)
|
|
16
|
+
|
|
17
|
+
# TigerJack Campaign
|
|
18
|
+
ab498[.]pythonanywhere[.]com # TigerJack - Data exfiltration
|
|
19
|
+
api[.]codex[.]jaagrav[.]in # TigerJack - C2
|
|
20
|
+
|
|
21
|
+
# SnowShoNo Campaign
|
|
22
|
+
niggboo[.]com # SnowShoNo - PowerShell payload download
|
|
23
|
+
|
|
24
|
+
# Evelyn Stealer Campaign
|
|
25
|
+
syn1112223334445556667778889990[.]org # Evelyn - HTTP C2 server
|
|
26
|
+
server09[.]mentality[.]cloud # Evelyn - FTP exfiltration server
|
|
27
|
+
|
|
28
|
+
# GlassWorm Campaign - Blockchain C2
|
|
29
|
+
# Solana RPC endpoints used for C2 (legitimate service abused)
|
|
30
|
+
# Attacker wallet: 28PKnu7RzizxBzFPoLp69HLXp9bJL3JFtT2s5QzHsEA2
|
|
31
|
+
calendar[.]app[.]google/M2ZCvM8ULL56PD1d6 # GlassWorm - Google Calendar backup C2
|
|
32
|
+
|
|
33
|
+
# GlassWorm C2 IPs (defanged)
|
|
34
|
+
217[.]69[.]3[.]218 # GlassWorm - Primary C2
|
|
35
|
+
217[.]69[.]11[.]60 # GlassWorm - Payload download (from stage2.dec.js)
|
|
36
|
+
199[.]247[.]10[.]166 # GlassWorm - Secondary C2
|
|
37
|
+
140[.]82[.]52[.]31 # GlassWorm - Exfiltration endpoint
|
|
38
|
+
199[.]247[.]13[.]106 # GlassWorm - Exfiltration endpoint
|
|
39
|
+
65[.]20[.]99[.]82 # GlassWorm - Data exfiltration /wall endpoint (from stage2.dec.js)
|
|
40
|
+
|
|
41
|
+
# Discord Webhook Exfiltration (legitimate service abused)
|
|
42
|
+
discord[.]com/api/webhooks # Multiple campaigns - Data exfiltration via webhooks
|
|
43
|
+
|
|
44
|
+
# Generic suspicious patterns to monitor
|
|
45
|
+
# (Any extension connecting to these types of services warrants investigation)
|
|
46
|
+
# - *.vercel.app with suspicious names
|
|
47
|
+
# - *.pythonanywhere.com
|
|
48
|
+
# - *.npoint.io
|
|
49
|
+
# - *.replit.co
|
|
50
|
+
# - discord.com/api/webhooks (common exfil method)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# VS Code Extension Malware C2 IP Addresses
|
|
2
|
+
# Format: IP:PORT # Campaign - Hosting Provider - Notes
|
|
3
|
+
#
|
|
4
|
+
# Submit new IPs via PR or issue
|
|
5
|
+
|
|
6
|
+
# GlassWorm Campaign
|
|
7
|
+
217.69.11.60 # GlassWorm - Primary C2
|
|
8
|
+
45.32.151.157 # GlassWorm - Wave 4 macOS C2
|
|
9
|
+
45.32.150.251 # GlassWorm - Wave 4 macOS C2
|
|
10
|
+
|
|
11
|
+
# FAMOUS CHOLLIMA / Contagious Interview (Eurohoster)
|
|
12
|
+
103.65.230.50 # FAMOUS CHOLLIMA - Eurohoster
|
|
13
|
+
103.65.230.100 # FAMOUS CHOLLIMA - Eurohoster
|
|
14
|
+
148.227.170.199 # FAMOUS CHOLLIMA - Eurohoster
|
|
15
|
+
138.226.220.187 # FAMOUS CHOLLIMA - Eurohoster
|
|
16
|
+
146.70.253.107:1224 # FAMOUS CHOLLIMA - InvisibleFerret Python stager download
|
|
17
|
+
146.70.253.107:2242 # FAMOUS CHOLLIMA - InvisibleFerret RAT C2
|
|
18
|
+
172.86.116.178:5918 # FAMOUS CHOLLIMA - BeaverTail socket.io exfiltration
|
|
19
|
+
172.86.116.178:5978 # FAMOUS CHOLLIMA - BeaverTail socket.io exfiltration
|
|
20
|
+
|
|
21
|
+
# HardHatRAT Campaign (Hetzner)
|
|
22
|
+
95.216.37.186:5000 # HardHatRAT - Hetzner - Socket.IO WebSocket C2
|
|
23
|
+
95.216.37.186:3011 # HardHatRAT - Hetzner - HTTP data exfiltration
|
|
24
|
+
95.216.37.186:3000 # HardHatRAT - Hetzner - Admin panel
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# VS Code Extension Malware Hashes
|
|
2
|
+
# Format: SHA256 # Campaign - Description
|
|
3
|
+
#
|
|
4
|
+
# Submit new hashes via PR or issue
|
|
5
|
+
|
|
6
|
+
# GlassWorm Campaign (Nov 2025)
|
|
7
|
+
6ebeb188f3cc3b647c4460c0b8e41b75d057747c662f4cd7912d77deaccfd2f2 # GlassWorm - os.node Windows DLL (Rust implant)
|
|
8
|
+
fb07743d139f72fca4616b01308f1f705f02fda72988027bc68e9316655eadda # GlassWorm - darwin.node macOS Dylib (Rust implant)
|
|
9
|
+
9212a99a7730b9ee306e804af358955c3104e5afce23f7d5a207374482ab2f8f # GlassWorm - extension.js loader
|
|
10
|
+
c32379e4567a926aa0d35d8123718e2ebeb15544a83a5b1da0269db5829d5ece # GlassWorm - Decrypted C2 payload
|
|
11
|
+
|
|
12
|
+
# HardHatRAT Campaign (Jan 2026) - npm delivery
|
|
13
|
+
8e8823d8c2a44512bb8abdaeeb5dd5d187950fd07bf008f89f8005103834a98d # HardHatRAT - tailwindcss-forms-kit-1.0.6.tgz
|
|
14
|
+
e96c208c0503b8556c4c245cf693576cf142174b6f7a9e7066768876bc041697 # HardHatRAT - index.js loader
|
|
15
|
+
e7071063f8cc743023889f71d070b60d3932079b2fdd75290d68c3188ac6b303 # HardHatRAT - encoded payload
|
|
16
|
+
da6e9835f90b417c6c8f532287eabb78701dd746388f0c3bfe1fc6be0221d6ec # HardHatRAT - decoded payload
|
|
17
|
+
1c8c1a693209c310e9089eb2d5713dc00e8d19f335bde34c68f6e30bccfbe781 # HardHatRAT - secondary payload (PyInstaller)
|
|
18
|
+
e39c91f0a14d6aa7788249bb80091160bab39b64cb9b5e2b311cf7493fd9ab0b # HardHatRAT - Python keylogger
|
|
19
|
+
|
|
20
|
+
# FAMOUS CHOLLIMA / Contagious Interview (Dec 2025)
|
|
21
|
+
72602e4f621b642b823ff25a2326dc6a2edc772572a4ccafd5993b42c081cd79 # FAMOUS CHOLLIMA - Malicious ZIP archive
|
|
22
|
+
a2b35d436db39682e7a5ec13e4d8b940e8e743864aad8eb9088290061e25dd59 # FAMOUS CHOLLIMA - tasks.json
|
|
23
|
+
d52d99d0aa00c0b2df9044b31dde81ec9ef5dce6389b1d61ead6fffd6a1bff3b # FAMOUS CHOLLIMA - settings.json
|
|
24
|
+
3a3b1d5fa23d9eb98b0f53ef9b8db56d759e8c34c85edbb8fc38e1e8b2eb30fb # FAMOUS CHOLLIMA - dl.py stager
|
|
25
|
+
|
|
26
|
+
# Related samples (VTI pivoting)
|
|
27
|
+
825ebf26a7df821478282c5d1cff868da9fcbe51934113d4b0444acc5fd94077 # HardHatRAT - related sample
|
|
28
|
+
bf2bed6b6ab8df8c6c076572024fd5a6ebeb571ecef30dfbc5dbbf9d9e87aad2 # HardHatRAT - related sample
|
|
29
|
+
5671cd2f328ed4276385a9e6d3bcc33328efaa45197e1d5717d0b0027caf00ac # HardHatRAT - NvidiaDriverUpdate related
|
|
30
|
+
f2db7770a017f37ff4c17c409de72161e84f1aea784a9a4d523070d799754bc6 # HardHatRAT - NvidiaDriverUpdate related
|
|
31
|
+
|
|
32
|
+
# Evelyn Stealer Campaign (Dec 2025)
|
|
33
|
+
369479bd9a248c9448705c222d81ff1a0143343a138fc38fc0ea00f54fcc1598 # Evelyn - Lightshot.dll first-stage downloader
|
|
34
|
+
92af258d13494f208ccf76f53a36f288060543f02ed438531e0675b85da00430 # Evelyn - iknowyou.model second-stage injector
|
|
35
|
+
aba7133f975a0788dd2728b4bbb1d7d948e50571a033a1e8f47a2691e98600c5 # Evelyn - EvelynStealer.exe final payload
|
|
36
|
+
74e43a0175179a0a04361faaaaf05eb1e6b84adca69e4f446ef82c0a5d1923d5 # Evelyn - abe_decrypt.dll browser injection
|
|
37
|
+
|
|
38
|
+
# MalwareBazaar samples - GlassWorm extended
|
|
39
|
+
bb68992f6aa2d3f316322e88d9e71491a38e95fd3a27f48084c66b9c210bd17d # GlassWorm - react-native-vscode.1.13.1.vsix (full malicious extension)
|
|
40
|
+
68e5fb92a7d7d182306a025010c77ae2cd89c39031cced13f9686a9f34671041 # GlassWorm - f_ex86.node.decoded (Rust DLL, pre-decryption)
|
|
41
|
+
a9a6a03bd6958710aeacc2a23860a7f7f0d09497fef85fe658ac5406734061f8 # GlassWorm - priskinski.theme-allhallowseve-remake-1.0.0.vsix (ReversingLabs Dec2025)
|
|
42
|
+
|
|
43
|
+
# Zoo samples (GitHub sources)
|
|
44
|
+
2cdaee2863396e558f17503ad290163d513acbc3c2ca2dbfa6852c2e064ca9f1 # SnowShoNo - PowerShell downloader (obfuscated)
|
|
45
|
+
6674b3505ac23b2354230d691b9e18c2dda74a66f76bb0df724286cb9b23581c # ECM3401 - Extension Attack Suite .vsix
|
|
46
|
+
837174f9426d244d5a6f153f147812cea84ad22acec79c6be48e6c7a2eb8b2ed # ECM3401 - Malicious API Extension .vsix
|
|
47
|
+
15afd43b543760a9a7849140ebf3425658d92aeaca596634fcfd385fae724046 # ECM3401 - Example API Extension .vsix
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Known Malicious npm Packages
|
|
2
|
+
# Format: package-name # Campaign - Notes
|
|
3
|
+
# Submit new packages via PR or issue
|
|
4
|
+
|
|
5
|
+
# FAMOUS CHOLLIMA (North Korea - Contagious Interview Campaign)
|
|
6
|
+
# These packages target developers via fake job interviews
|
|
7
|
+
tailwindcss-forms-kit # FAMOUS CHOLLIMA - typosquat tailwindcss-forms
|
|
8
|
+
tailwindcss-kit # FAMOUS CHOLLIMA - typosquat
|
|
9
|
+
postcss-transform-classes # FAMOUS CHOLLIMA - typosquat postcss-modules
|
|
10
|
+
sass-extract # FAMOUS CHOLLIMA - bundled malware
|
|
11
|
+
@nicol-dev/my-vite-package # FAMOUS CHOLLIMA - malicious vite plugin
|
|
12
|
+
|
|
13
|
+
# Historical Supply Chain Attacks
|
|
14
|
+
event-stream # 2018 - flatmap-stream backdoor targeting Copay wallet
|
|
15
|
+
ua-parser-js # 2021 - cryptominer injection
|
|
16
|
+
coa # 2021 - compromised maintainer
|
|
17
|
+
rc # 2021 - compromised maintainer
|
|
18
|
+
colors # 2022 - sabotage by maintainer
|
|
19
|
+
faker # 2022 - sabotage by maintainer
|
|
20
|
+
node-ipc # 2022 - protestware with data corruption
|
|
21
|
+
|
|
22
|
+
# Typosquatting Attacks
|
|
23
|
+
crossenv # Typosquat of cross-env
|
|
24
|
+
cross-env.js # Typosquat of cross-env
|
|
25
|
+
d3.js # Typosquat of d3
|
|
26
|
+
fabric.js # Typosquat of fabric
|
|
27
|
+
ffmepg # Typosquat of ffmpeg
|
|
28
|
+
gruntcli # Typosquat of grunt-cli
|
|
29
|
+
http-proxy.js # Typosquat of http-proxy
|
|
30
|
+
jquery.js # Typosquat of jquery
|
|
31
|
+
mariadb # Typosquat of mariasql
|
|
32
|
+
mongose # Typosquat of mongoose
|
|
33
|
+
mssql.js # Typosquat of mssql
|
|
34
|
+
mssql-node # Typosquat of mssql
|
|
35
|
+
mysqljs # Typosquat of mysql
|
|
36
|
+
node-fabric # Typosquat of fabric
|
|
37
|
+
node-opencv # Typosquat of opencv
|
|
38
|
+
node-opensl # Typosquat of openssl
|
|
39
|
+
node-openssl # Typosquat of openssl
|
|
40
|
+
node-sqlite # Typosquat of sqlite3
|
|
41
|
+
node-tkinter # Typosquat of tkinter
|
|
42
|
+
nodecaffe # Typosquat of caffe
|
|
43
|
+
nodefabric # Typosquat of fabric
|
|
44
|
+
nodeffmpeg # Typosquat of ffmpeg
|
|
45
|
+
nodemailer-js # Typosquat of nodemailer
|
|
46
|
+
nodemssql # Typosquat of mssql
|
|
47
|
+
noderequest # Typosquat of request
|
|
48
|
+
nodesass # Typosquat of node-sass
|
|
49
|
+
nodesqlite # Typosquat of sqlite3
|
|
50
|
+
opencv.js # Typosquat of opencv
|
|
51
|
+
openssl.js # Typosquat of openssl
|
|
52
|
+
proxy.js # Typosquat of http-proxy
|
|
53
|
+
shadowsock # Typosquat of shadowsocks
|
|
54
|
+
smb # Typosquat of samba
|
|
55
|
+
sqlite.js # Typosquat of sqlite3
|
|
56
|
+
sqliter # Typosquat of sqlite3
|
|
57
|
+
sqlserver # Typosquat of mssql
|
|
58
|
+
tkinter # Typosquat of python tkinter wrapper
|
|
59
|
+
lodahs # Typosquat of lodash
|
|
60
|
+
lodashs # Typosquat of lodash
|
|
61
|
+
loadsh # Typosquat of lodash
|
|
62
|
+
lodaash # Typosquat of lodash
|
|
63
|
+
|
|
64
|
+
# Socket.dev Tracked Malware
|
|
65
|
+
express-cookie # 2024 - credential harvester
|
|
66
|
+
express-session-parser # 2024 - credential harvester
|
|
67
|
+
node-hide-console-windows # 2024 - spyware
|
|
68
|
+
axios-retry-enhanced # 2024 - data exfiltration
|
|
69
|
+
react-native-scrollpageviewtest # 2024 - crypto stealer
|
|
70
|
+
lottie-rn # 2024 - data exfiltration
|
|
71
|
+
|
|
72
|
+
# VS Code Extension Related
|
|
73
|
+
vscode-darcula # Discord token stealer (npm dependency used by malicious extension)
|
|
74
|
+
@nicol-dev/vscode-theme # FAMOUS CHOLLIMA - malicious VS Code theme dependency
|
|
75
|
+
|
|
76
|
+
# Electron/Desktop App Targeting
|
|
77
|
+
electron-chromedriver-test # 2023 - reverse shell
|
|
78
|
+
electron-native-notify-test # 2023 - data exfiltration
|
|
79
|
+
|
|
80
|
+
# AI/LLM Tool Typosquats (emerging trend 2025)
|
|
81
|
+
openai-api # Typosquat of openai
|
|
82
|
+
chatgpt-api # Typosquat - not official
|
|
83
|
+
gpt-3-encoder # Typosquat
|
|
84
|
+
langchain-core # Typosquat - not official
|
|
85
|
+
anthropic-api # Typosquat - not official
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# VS Code Extension Malware Cryptocurrency Wallets
|
|
2
|
+
# Format: CURRENCY ADDRESS # Campaign - Notes
|
|
3
|
+
#
|
|
4
|
+
# These wallets are used by attackers for:
|
|
5
|
+
# - C2 communication (blockchain-based C2)
|
|
6
|
+
# - Receiving stolen funds
|
|
7
|
+
# - Cryptominer payouts
|
|
8
|
+
#
|
|
9
|
+
# Submit new wallets via PR or issue
|
|
10
|
+
|
|
11
|
+
# GlassWorm Campaign - Solana Blockchain C2
|
|
12
|
+
SOL BjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC # GlassWorm - Primary C2 wallet (transaction memos contain commands)
|
|
13
|
+
|
|
14
|
+
# Add wallet addresses here as they are discovered
|
|
15
|
+
# Format examples:
|
|
16
|
+
# BTC 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa # Campaign - Description
|
|
17
|
+
# ETH 0x742d35Cc6634C0532925a3b844Bc9e7595f8fE42 # Campaign - Description
|
|
18
|
+
# SOL ADDRESS # Campaign - Description
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# YARA Rules for VS Code Extension Malware
|
|
2
|
+
|
|
3
|
+
Detection signatures for scanning extensions.
|
|
4
|
+
|
|
5
|
+
## External Rules
|
|
6
|
+
|
|
7
|
+
We recommend using the Knostic GlassWorm YARA rules:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
git clone https://github.com/knostic/open-tools.git
|
|
11
|
+
cp open-tools/glassworm_yara/*.yar zoo/signatures/yara/
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### Knostic Rule Files
|
|
15
|
+
|
|
16
|
+
| File | Rules | Purpose |
|
|
17
|
+
| ----------------------------- | ----- | ---------------------------------------------------- |
|
|
18
|
+
| `unicode_stealth.yar` | 2 | Invisible Unicode characters, zero-width obfuscation |
|
|
19
|
+
| `blockchain_c2.yar` | 3 | Solana RPC C2, memo field parsing |
|
|
20
|
+
| `credential_harvesting.yar` | 5 | NPM/GitHub/OpenVSX/SSH credential theft |
|
|
21
|
+
| `google_calendar_c2.yar` | 4 | Calendar API abuse for C2 |
|
|
22
|
+
| `crypto_wallet_targeting.yar` | 4 | Wallet extension targeting, seed extraction |
|
|
23
|
+
| `rat_capabilities.yar` | 5 | SOCKS proxy, VNC, remote execution |
|
|
24
|
+
| `self_propagation.yar` | 5 | Automated publishing, worm propagation |
|
|
25
|
+
|
|
26
|
+
Source: https://github.com/knostic/open-tools/tree/main/glassworm_yara
|
|
27
|
+
|
|
28
|
+
## Custom Rules
|
|
29
|
+
|
|
30
|
+
Add custom YARA rules to this directory. Follow naming convention:
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
{campaign}_{detection_type}.yar
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Example: `tigerjack_keylogger.yar`
|
|
37
|
+
|
|
38
|
+
## Usage
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Scan with YARA
|
|
42
|
+
yara -r zoo/signatures/yara/ path/to/extension/
|
|
43
|
+
|
|
44
|
+
# With vsix-audit (planned)
|
|
45
|
+
vsix-audit scan extension.vsix --yara zoo/signatures/yara/
|
|
46
|
+
```
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/*
|
|
2
|
+
GlassWorm Blockchain C2 Detection
|
|
3
|
+
Detects Solana blockchain-based command and control infrastructure
|
|
4
|
+
|
|
5
|
+
IMPORTANT: These rules require SPECIFIC GlassWorm patterns, not just
|
|
6
|
+
Solana SDK usage. Many legitimate extensions use Solana.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
rule C2_JS_GlassWorm_Solana_Jan25 {
|
|
10
|
+
meta:
|
|
11
|
+
description = "Detects GlassWorm-style Solana blockchain C2 using transaction memos to receive and execute commands"
|
|
12
|
+
severity = "critical"
|
|
13
|
+
score = "90"
|
|
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
|
+
// Must use Solana SDK
|
|
20
|
+
$solana_import = "@solana/web3.js" ascii wide
|
|
21
|
+
|
|
22
|
+
// Must parse transaction memos (the C2 channel)
|
|
23
|
+
$memo_parse1 = "instructionData" ascii wide
|
|
24
|
+
$memo_parse2 = "transaction.memo" ascii wide
|
|
25
|
+
$memo_parse3 = "memoData" ascii wide
|
|
26
|
+
|
|
27
|
+
// Must decode hidden payload from memo
|
|
28
|
+
$decode1 = "atob" ascii wide
|
|
29
|
+
$decode2 = /Buffer\.from\([^,]+,\s*["']base64["']\)/ ascii wide
|
|
30
|
+
|
|
31
|
+
// Must fetch the decoded URL
|
|
32
|
+
$fetch = /fetch\s*\(/ ascii wide
|
|
33
|
+
|
|
34
|
+
// Code execution from fetched payload
|
|
35
|
+
$exec1 = "eval(" ascii wide
|
|
36
|
+
$exec2 = "new Function(" ascii wide
|
|
37
|
+
|
|
38
|
+
condition:
|
|
39
|
+
$solana_import and any of ($memo_parse*) and
|
|
40
|
+
any of ($decode*) and $fetch and any of ($exec*)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// REMOVED: GlassWorm_Blockchain_Memo_Parsing
|
|
44
|
+
// Too broad - legitimate Solana apps parse memos.
|
|
45
|
+
|
|
46
|
+
// REMOVED: GlassWorm_Dynamic_C2_Resolution
|
|
47
|
+
// Way too broad - matched "history" + "setInterval" + "fetch"
|
|
48
|
+
// which is virtually all web apps with periodic updates.
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Dynamic Code Execution Detection
|
|
3
|
+
Detects patterns for executing code from strings/encoded content
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
rule SUSP_JS_Eval_Base64_Jan25 {
|
|
7
|
+
meta:
|
|
8
|
+
description = "Detects eval() used with base64 decoding to execute hidden or obfuscated code"
|
|
9
|
+
severity = "critical"
|
|
10
|
+
score = 90
|
|
11
|
+
author = "vsix-audit"
|
|
12
|
+
date = "2025-01-29"
|
|
13
|
+
|
|
14
|
+
strings:
|
|
15
|
+
$eval = "eval(" ascii wide
|
|
16
|
+
|
|
17
|
+
// Base64 decode patterns
|
|
18
|
+
$decode1 = "atob(" ascii wide
|
|
19
|
+
$decode2 = /Buffer\.from\([^,]+,\s*["']base64["']\)/ ascii wide
|
|
20
|
+
$decode3 = "base64" ascii wide
|
|
21
|
+
|
|
22
|
+
condition:
|
|
23
|
+
$eval and any of ($decode*)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
rule SUSP_JS_Function_Constructor_Jan25 {
|
|
27
|
+
meta:
|
|
28
|
+
description = "Detects new Function() constructor that creates executable code from strings, equivalent to eval"
|
|
29
|
+
severity = "high"
|
|
30
|
+
score = 75
|
|
31
|
+
author = "vsix-audit"
|
|
32
|
+
date = "2025-01-29"
|
|
33
|
+
|
|
34
|
+
strings:
|
|
35
|
+
$func1 = /new\s+Function\s*\(\s*["'`]/ ascii wide
|
|
36
|
+
$func2 = /new\s+Function\s*\(\s*[a-zA-Z_]/ ascii wide
|
|
37
|
+
|
|
38
|
+
condition:
|
|
39
|
+
any of them
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
rule SUSP_JS_Eval_Charcode_Jan25 {
|
|
43
|
+
meta:
|
|
44
|
+
description = "Detects eval() combined with String.fromCharCode or hex escapes to hide malicious code"
|
|
45
|
+
severity = "critical"
|
|
46
|
+
score = 90
|
|
47
|
+
author = "vsix-audit"
|
|
48
|
+
date = "2025-01-29"
|
|
49
|
+
|
|
50
|
+
strings:
|
|
51
|
+
$eval = "eval(" ascii wide
|
|
52
|
+
|
|
53
|
+
// String construction
|
|
54
|
+
$build1 = "String.fromCharCode" ascii wide
|
|
55
|
+
$build2 = "charCodeAt" ascii wide
|
|
56
|
+
$build3 = /\\x[0-9a-fA-F]{2}/ ascii wide
|
|
57
|
+
|
|
58
|
+
condition:
|
|
59
|
+
$eval and any of ($build*)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
rule SUSP_JS_Indirect_Eval_Jan25 {
|
|
63
|
+
meta:
|
|
64
|
+
description = "Detects indirect eval access through global object like globalThis['eval'] to evade detection"
|
|
65
|
+
severity = "high"
|
|
66
|
+
score = 80
|
|
67
|
+
author = "vsix-audit"
|
|
68
|
+
date = "2025-01-29"
|
|
69
|
+
|
|
70
|
+
strings:
|
|
71
|
+
$indirect1 = "globalThis.eval" ascii wide
|
|
72
|
+
$indirect2 = "globalThis['eval']" ascii wide
|
|
73
|
+
$indirect3 = "global.eval" ascii wide
|
|
74
|
+
$indirect4 = "global['eval']" ascii wide
|
|
75
|
+
$indirect5 = "window.eval" ascii wide
|
|
76
|
+
$indirect6 = "window['eval']" ascii wide
|
|
77
|
+
$indirect7 = "this.eval" ascii wide
|
|
78
|
+
$indirect8 = "self.eval" ascii wide
|
|
79
|
+
$indirect9 = "(0,eval)" ascii wide
|
|
80
|
+
$indirect10 = "(1,eval)" ascii wide
|
|
81
|
+
|
|
82
|
+
condition:
|
|
83
|
+
any of them
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
rule SUSP_JS_Child_Process_Variable_Jan25 {
|
|
87
|
+
meta:
|
|
88
|
+
description = "Detects child_process execution with variable command input instead of static string literal"
|
|
89
|
+
severity = "medium"
|
|
90
|
+
score = 60
|
|
91
|
+
author = "vsix-audit"
|
|
92
|
+
date = "2025-01-29"
|
|
93
|
+
|
|
94
|
+
strings:
|
|
95
|
+
$cp1 = "child_process" ascii wide
|
|
96
|
+
$cp2 = "require('child_process')" ascii wide
|
|
97
|
+
$cp3 = "require(\"child_process\")" ascii wide
|
|
98
|
+
|
|
99
|
+
// Execution with template literal or variable
|
|
100
|
+
$exec1 = /\.exec\s*\(\s*`/ ascii wide
|
|
101
|
+
$exec2 = /\.execSync\s*\(\s*`/ ascii wide
|
|
102
|
+
$exec3 = /\.spawn\s*\(\s*[a-zA-Z_]/ ascii wide
|
|
103
|
+
$exec4 = /\.exec\s*\(\s*[a-zA-Z_]/ ascii wide
|
|
104
|
+
|
|
105
|
+
condition:
|
|
106
|
+
any of ($cp*) and any of ($exec*)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
rule SUSP_JS_Process_Binding_Jan25 {
|
|
110
|
+
meta:
|
|
111
|
+
description = "Detects access to Node.js internal process bindings that can bypass security restrictions"
|
|
112
|
+
severity = "high"
|
|
113
|
+
score = 85
|
|
114
|
+
author = "vsix-audit"
|
|
115
|
+
date = "2025-01-29"
|
|
116
|
+
|
|
117
|
+
strings:
|
|
118
|
+
$binding1 = "process.binding(" ascii wide
|
|
119
|
+
$binding2 = "process._linkedBinding(" ascii wide
|
|
120
|
+
$binding3 = "process.dlopen(" ascii wide
|
|
121
|
+
|
|
122
|
+
condition:
|
|
123
|
+
any of them
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
rule SUSP_JS_VM_Module_Jan25 {
|
|
127
|
+
meta:
|
|
128
|
+
description = "Detects Node.js vm module usage for code execution in sandboxes that can potentially be escaped"
|
|
129
|
+
severity = "medium"
|
|
130
|
+
score = 55
|
|
131
|
+
author = "vsix-audit"
|
|
132
|
+
date = "2025-01-29"
|
|
133
|
+
|
|
134
|
+
strings:
|
|
135
|
+
$vm1 = "require('vm')" ascii wide
|
|
136
|
+
$vm2 = "require(\"vm\")" ascii wide
|
|
137
|
+
$vm3 = "vm.runInThisContext" ascii wide
|
|
138
|
+
$vm4 = "vm.runInNewContext" ascii wide
|
|
139
|
+
$vm5 = "vm.Script" ascii wide
|
|
140
|
+
|
|
141
|
+
condition:
|
|
142
|
+
any of them
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
rule SUSP_JS_WebAssembly_Remote_Jan25 {
|
|
146
|
+
meta:
|
|
147
|
+
description = "Detects WebAssembly instantiation with remote or base64 source that could execute arbitrary code"
|
|
148
|
+
severity = "low"
|
|
149
|
+
score = 40
|
|
150
|
+
author = "vsix-audit"
|
|
151
|
+
date = "2025-01-29"
|
|
152
|
+
|
|
153
|
+
strings:
|
|
154
|
+
$wasm1 = "WebAssembly.instantiate" ascii wide
|
|
155
|
+
$wasm2 = "WebAssembly.compile" ascii wide
|
|
156
|
+
$wasm3 = "WebAssembly.Instance" ascii wide
|
|
157
|
+
|
|
158
|
+
// From network or encoded source
|
|
159
|
+
$source1 = "fetch(" ascii wide
|
|
160
|
+
$source2 = "atob(" ascii wide
|
|
161
|
+
$source3 = "base64" ascii wide
|
|
162
|
+
|
|
163
|
+
condition:
|
|
164
|
+
any of ($wasm*) and any of ($source*)
|
|
165
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/*
|
|
2
|
+
GlassWorm Credential Harvesting Detection
|
|
3
|
+
Detects patterns for harvesting NPM, GitHub, OpenVSX, Git, and SSH credentials
|
|
4
|
+
|
|
5
|
+
IMPORTANT: These rules are tuned to avoid false positives on legitimate code.
|
|
6
|
+
Legitimate SSH tools, Git integrations, and package managers will use these
|
|
7
|
+
APIs. We require MULTIPLE strong indicators to fire.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
rule MAL_JS_GlassWorm_NPM_Token_Theft_Jan25 {
|
|
11
|
+
meta:
|
|
12
|
+
description = "Detects GlassWorm-style NPM token theft that reads .npmrc file and exfiltrates credentials"
|
|
13
|
+
severity = "high"
|
|
14
|
+
score = "85"
|
|
15
|
+
author = "vsix-audit"
|
|
16
|
+
date = "2025-01-29"
|
|
17
|
+
reference = "https://www.koi.security/blog/glassworm-first-self-propagating-worm-using-invisible-code-hits-openvsx-marketplace"
|
|
18
|
+
|
|
19
|
+
strings:
|
|
20
|
+
// Must specifically target .npmrc file
|
|
21
|
+
$npmrc_path = /\.npmrc/ ascii wide
|
|
22
|
+
$homedir = "os.homedir" ascii wide
|
|
23
|
+
|
|
24
|
+
// Must read the file
|
|
25
|
+
$read = "readFile" ascii wide
|
|
26
|
+
|
|
27
|
+
// Must do something suspicious with the token
|
|
28
|
+
$exfil1 = /fetch\s*\(\s*["'][^"']*["']\s*,\s*\{[^}]*body/ ascii wide
|
|
29
|
+
$exfil2 = "axios.post" ascii wide
|
|
30
|
+
$exfil3 = "discord.com/api/webhooks" ascii wide
|
|
31
|
+
$exfil4 = "discordapp.com/api/webhooks" ascii wide
|
|
32
|
+
|
|
33
|
+
condition:
|
|
34
|
+
$npmrc_path and $homedir and $read and any of ($exfil*)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
rule MAL_JS_GlassWorm_SSH_Key_Theft_Jan25 {
|
|
38
|
+
meta:
|
|
39
|
+
description = "Detects GlassWorm-style SSH private key theft that reads id_rsa/ed25519 and exfiltrates"
|
|
40
|
+
severity = "critical"
|
|
41
|
+
score = "90"
|
|
42
|
+
author = "vsix-audit"
|
|
43
|
+
date = "2025-01-29"
|
|
44
|
+
reference = "https://www.koi.security/blog/glassworm-first-self-propagating-worm-using-invisible-code-hits-openvsx-marketplace"
|
|
45
|
+
|
|
46
|
+
strings:
|
|
47
|
+
// Must target SSH private key paths specifically
|
|
48
|
+
$ssh_key1 = "id_rsa" ascii wide
|
|
49
|
+
$ssh_key2 = "id_ed25519" ascii wide
|
|
50
|
+
$ssh_key3 = "id_ecdsa" ascii wide
|
|
51
|
+
|
|
52
|
+
// Must access home directory
|
|
53
|
+
$homedir = "os.homedir" ascii wide
|
|
54
|
+
|
|
55
|
+
// Must read the file
|
|
56
|
+
$read1 = "readFileSync" ascii wide
|
|
57
|
+
$read2 = "readFile" ascii wide
|
|
58
|
+
|
|
59
|
+
// Must have network exfiltration
|
|
60
|
+
$exfil1 = /fetch\s*\(\s*["'][^"']*["']\s*,\s*\{[^}]*body/ ascii wide
|
|
61
|
+
$exfil2 = "axios.post" ascii wide
|
|
62
|
+
$exfil3 = "discord.com/api/webhooks" ascii wide
|
|
63
|
+
$exfil4 = "https.request" ascii wide
|
|
64
|
+
|
|
65
|
+
// Encoding before exfil
|
|
66
|
+
$encode1 = "base64" ascii wide
|
|
67
|
+
$encode2 = "btoa" ascii wide
|
|
68
|
+
|
|
69
|
+
condition:
|
|
70
|
+
any of ($ssh_key*) and $homedir and any of ($read*) and
|
|
71
|
+
any of ($exfil*) and any of ($encode*)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
rule MAL_JS_GlassWorm_Browser_Credential_Theft_Jan25 {
|
|
75
|
+
meta:
|
|
76
|
+
description = "Detects GlassWorm-style browser credential theft targeting Chrome/Firefox Login Data files"
|
|
77
|
+
severity = "critical"
|
|
78
|
+
score = "95"
|
|
79
|
+
author = "vsix-audit"
|
|
80
|
+
date = "2025-01-29"
|
|
81
|
+
reference = "https://www.koi.security/blog/glassworm-first-self-propagating-worm-using-invisible-code-hits-openvsx-marketplace"
|
|
82
|
+
|
|
83
|
+
strings:
|
|
84
|
+
// Browser credential paths - very specific
|
|
85
|
+
$chrome_login = "Chrome/User Data/Default/Login Data" ascii wide nocase
|
|
86
|
+
$firefox_login = "Firefox/Profiles" ascii wide nocase
|
|
87
|
+
$edge_login = "Edge/User Data/Default/Login Data" ascii wide nocase
|
|
88
|
+
$brave_login = "BraveSoftware" ascii wide nocase
|
|
89
|
+
|
|
90
|
+
// Must copy or read these files
|
|
91
|
+
$copy1 = "copyFileSync" ascii wide
|
|
92
|
+
$copy2 = "createReadStream" ascii wide
|
|
93
|
+
$read = "readFileSync" ascii wide
|
|
94
|
+
|
|
95
|
+
// Network exfil
|
|
96
|
+
$exfil1 = /fetch\s*\(/ ascii wide
|
|
97
|
+
$exfil2 = /axios\s*\./ ascii wide
|
|
98
|
+
$exfil3 = /request\s*\(/ ascii wide
|
|
99
|
+
|
|
100
|
+
condition:
|
|
101
|
+
any of ($chrome_login, $firefox_login, $edge_login, $brave_login) and
|
|
102
|
+
any of ($copy*, $read) and any of ($exfil*)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// REMOVED: GlassWorm_Credential_Exfiltration
|
|
106
|
+
// This rule was too broad - it matched any code with POST + JSON.stringify + "token"
|
|
107
|
+
// which is virtually all web applications.
|
|
108
|
+
|
|
109
|
+
// REMOVED: GlassWorm_SSH_Credential_Harvesting
|
|
110
|
+
// Too broad - matched any SSH tooling. Replaced with GlassWorm_SSH_Key_Theft above.
|
|
111
|
+
|
|
112
|
+
// REMOVED: GlassWorm_GitHub_Credential_Harvesting
|
|
113
|
+
// Too broad for GitHub integrations.
|
|
114
|
+
|
|
115
|
+
// REMOVED: GlassWorm_OpenVSX_Credential_Harvesting
|
|
116
|
+
// Extensions that publish need these patterns legitimately.
|