@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,432 @@
|
|
|
1
|
+
import { detectBundler } from "../bundler.js";
|
|
2
|
+
import { isScannable, SCANNABLE_EXTENSIONS_PATTERN, SCANNABLE_EXTENSIONS_UNICODE, } from "../constants.js";
|
|
3
|
+
import { findLineNumberByIndex } from "../utils.js";
|
|
4
|
+
// ============================================================================
|
|
5
|
+
// SHARED UTILITIES
|
|
6
|
+
// ============================================================================
|
|
7
|
+
/**
|
|
8
|
+
* Check if file is in node_modules (third-party dependencies).
|
|
9
|
+
* These are not extension code and generate many false positives.
|
|
10
|
+
*/
|
|
11
|
+
function isNodeModules(filename) {
|
|
12
|
+
return filename.includes("node_modules/") || filename.includes("node_modules\\");
|
|
13
|
+
}
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// ENTROPY ANALYSIS
|
|
16
|
+
// ============================================================================
|
|
17
|
+
/**
|
|
18
|
+
* Calculate Shannon entropy of a string.
|
|
19
|
+
* Higher entropy indicates more randomness, often a sign of obfuscation.
|
|
20
|
+
* Normal code: ~4.5 bits/char, obfuscated: >5.5
|
|
21
|
+
*/
|
|
22
|
+
function shannonEntropy(str) {
|
|
23
|
+
if (str.length === 0)
|
|
24
|
+
return 0;
|
|
25
|
+
const freq = {};
|
|
26
|
+
for (const char of str) {
|
|
27
|
+
freq[char] = (freq[char] ?? 0) + 1;
|
|
28
|
+
}
|
|
29
|
+
let entropy = 0;
|
|
30
|
+
const len = str.length;
|
|
31
|
+
for (const count of Object.values(freq)) {
|
|
32
|
+
const p = count / len;
|
|
33
|
+
entropy -= p * Math.log2(p);
|
|
34
|
+
}
|
|
35
|
+
return entropy;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Find high-entropy regions in code (potential obfuscation).
|
|
39
|
+
* Uses a sliding window approach.
|
|
40
|
+
*/
|
|
41
|
+
function findHighEntropyRegions(content, windowSize = 200, threshold = 5.5) {
|
|
42
|
+
const regions = [];
|
|
43
|
+
const step = 50;
|
|
44
|
+
for (let i = 0; i < content.length - windowSize; i += step) {
|
|
45
|
+
const window = content.slice(i, i + windowSize);
|
|
46
|
+
// Skip whitespace-heavy regions
|
|
47
|
+
const nonWhitespace = window.replace(/\s/g, "");
|
|
48
|
+
if (nonWhitespace.length < windowSize * 0.3)
|
|
49
|
+
continue;
|
|
50
|
+
const entropy = shannonEntropy(nonWhitespace);
|
|
51
|
+
if (entropy > threshold) {
|
|
52
|
+
// Merge with previous region if overlapping
|
|
53
|
+
const last = regions.at(-1);
|
|
54
|
+
if (last && i < last.end + step) {
|
|
55
|
+
last.end = i + windowSize;
|
|
56
|
+
last.entropy = Math.max(last.entropy, entropy);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
regions.push({ start: i, end: i + windowSize, entropy });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return regions;
|
|
64
|
+
}
|
|
65
|
+
function checkEntropy(contents) {
|
|
66
|
+
const findings = [];
|
|
67
|
+
const seenFindings = new Set();
|
|
68
|
+
for (const [filename, buffer] of contents.files) {
|
|
69
|
+
if (!isScannable(filename, SCANNABLE_EXTENSIONS_PATTERN))
|
|
70
|
+
continue;
|
|
71
|
+
// Skip node_modules - third-party deps generate many false positives
|
|
72
|
+
if (isNodeModules(filename))
|
|
73
|
+
continue;
|
|
74
|
+
const content = buffer.toString("utf8");
|
|
75
|
+
// Skip bundled code - minification naturally increases entropy
|
|
76
|
+
const bundlerInfo = detectBundler(content, filename);
|
|
77
|
+
if (bundlerInfo.isBundled)
|
|
78
|
+
continue;
|
|
79
|
+
const regions = findHighEntropyRegions(content);
|
|
80
|
+
if (regions.length === 0)
|
|
81
|
+
continue;
|
|
82
|
+
const key = `OBFUSCATION_HIGH_ENTROPY:${filename}`;
|
|
83
|
+
if (seenFindings.has(key))
|
|
84
|
+
continue;
|
|
85
|
+
seenFindings.add(key);
|
|
86
|
+
const firstRegion = regions[0];
|
|
87
|
+
if (!firstRegion)
|
|
88
|
+
continue;
|
|
89
|
+
const matches = regions.map((region) => ({
|
|
90
|
+
index: region.start,
|
|
91
|
+
matched: `Entropy: ${region.entropy.toFixed(2)} bits/char`,
|
|
92
|
+
score: Math.min(90, Math.floor(region.entropy * 15)),
|
|
93
|
+
}));
|
|
94
|
+
findings.push({
|
|
95
|
+
id: "OBFUSCATION_HIGH_ENTROPY",
|
|
96
|
+
title: "High entropy code region",
|
|
97
|
+
description: "Code region has unusually high Shannon entropy (randomness). This often indicates obfuscated or encoded content.",
|
|
98
|
+
severity: "medium",
|
|
99
|
+
category: "obfuscation",
|
|
100
|
+
location: {
|
|
101
|
+
file: filename,
|
|
102
|
+
line: findLineNumberByIndex(content, firstRegion.start),
|
|
103
|
+
},
|
|
104
|
+
metadata: {
|
|
105
|
+
matchCount: matches.length,
|
|
106
|
+
matched: matches[0]?.matched,
|
|
107
|
+
obfuscationScore: Math.max(...matches.map((m) => m.score)),
|
|
108
|
+
legitimateUses: ["Compressed data", "Base64 content", "Hash strings"],
|
|
109
|
+
redFlags: ["Near eval/Function", "Large continuous regions"],
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return findings;
|
|
114
|
+
}
|
|
115
|
+
// ============================================================================
|
|
116
|
+
// UNICODE HIDING DETECTION
|
|
117
|
+
// ============================================================================
|
|
118
|
+
function findLineAndColumn(content, index) {
|
|
119
|
+
const beforeMatch = content.slice(0, index);
|
|
120
|
+
const lines = beforeMatch.split("\n");
|
|
121
|
+
const line = lines.length;
|
|
122
|
+
const column = (lines.at(-1)?.length ?? 0) + 1;
|
|
123
|
+
return { line, column };
|
|
124
|
+
}
|
|
125
|
+
function getContext(content, index, length) {
|
|
126
|
+
const start = Math.max(0, index - 20);
|
|
127
|
+
const end = Math.min(content.length, index + length + 20);
|
|
128
|
+
let ctx = content.slice(start, end);
|
|
129
|
+
if (start > 0)
|
|
130
|
+
ctx = "..." + ctx;
|
|
131
|
+
if (end < content.length)
|
|
132
|
+
ctx = ctx + "...";
|
|
133
|
+
return ctx.replace(/[\n\r]/g, "\\n").slice(0, 80);
|
|
134
|
+
}
|
|
135
|
+
// Zero-width characters: U+200B-200D, U+FEFF
|
|
136
|
+
const ZERO_WIDTH_REGEX = /[\u200B-\u200D\uFEFF]/g;
|
|
137
|
+
// Variation selectors: U+FE00-FE0F (GlassWorm technique)
|
|
138
|
+
const VARIATION_SELECTOR_REGEX = /[\uFE00-\uFE0F]/g;
|
|
139
|
+
// Bidirectional overrides: U+202A-202E (Trojan Source attack)
|
|
140
|
+
const BIDI_OVERRIDE_REGEX = /[\u202A-\u202E]/g;
|
|
141
|
+
// Unicode escapes for ASCII: \u00XX where XX is 20-7E (printable ASCII)
|
|
142
|
+
const UNICODE_ASCII_ESCAPE_REGEX = /\\u00[2-7][0-9a-fA-F]/g;
|
|
143
|
+
// Cyrillic homoglyphs that look like Latin letters
|
|
144
|
+
const CYRILLIC_LOOKALIKE_REGEX = /[\u0430\u0441\u0435\u043E\u0440\u0445\u0443\u0410\u0412\u0421\u0415\u041D\u041A\u041C\u041E\u0420\u0422\u0425]/g;
|
|
145
|
+
// Additional invisible/confusable characters
|
|
146
|
+
const OTHER_INVISIBLE_REGEX = /[\u00AD\u034F\u115F\u1160\u17B4\u17B5\u180E\u2060-\u2064\u206A-\u206F]/g;
|
|
147
|
+
function detectUnicodePattern(content, regex, minMatches = 1) {
|
|
148
|
+
const matches = [];
|
|
149
|
+
const r = new RegExp(regex.source, regex.flags);
|
|
150
|
+
let match;
|
|
151
|
+
while ((match = r.exec(content)) !== null) {
|
|
152
|
+
const { line, column } = findLineAndColumn(content, match.index);
|
|
153
|
+
matches.push({
|
|
154
|
+
line,
|
|
155
|
+
column,
|
|
156
|
+
matched: match[0],
|
|
157
|
+
context: getContext(content, match.index, match[0].length),
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
return matches.length >= minMatches ? matches : [];
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Check if the file appears to be primarily i18n/localization content.
|
|
164
|
+
*/
|
|
165
|
+
function isI18nFile(filename, content) {
|
|
166
|
+
const i18nPatterns = [
|
|
167
|
+
/locales?\//i,
|
|
168
|
+
/i18n\//i,
|
|
169
|
+
/translations?\//i,
|
|
170
|
+
/lang\//i,
|
|
171
|
+
/messages/i,
|
|
172
|
+
/\.l10n\./i,
|
|
173
|
+
/nls\./i,
|
|
174
|
+
// moment locale files (e.g., moment/locale/ku.js)
|
|
175
|
+
/moment\/.*locale/i,
|
|
176
|
+
// Encoding tables (iconv-lite encodings/tables/*.js)
|
|
177
|
+
/encodings?\/(tables|sbcs)/i,
|
|
178
|
+
// HTML entities data
|
|
179
|
+
/entities\.json$/i,
|
|
180
|
+
// Emoji data files
|
|
181
|
+
/emoji\.json$/i,
|
|
182
|
+
// CLI spinners data
|
|
183
|
+
/spinners\.json$/i,
|
|
184
|
+
// Public Suffix List
|
|
185
|
+
/psl\//i,
|
|
186
|
+
// VS Code NLS localization files (package.nls.*.json)
|
|
187
|
+
/package\.nls\.[a-z]{2}(-[a-z]{2})?\.json$/i,
|
|
188
|
+
];
|
|
189
|
+
if (i18nPatterns.some((p) => p.test(filename))) {
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
if (filename.endsWith(".json")) {
|
|
193
|
+
const keyValuePairs = (content.match(/"[^"]+"\s*:\s*"[^"]+"/g) ?? []).length;
|
|
194
|
+
const lines = content.split("\n").length;
|
|
195
|
+
if (keyValuePairs / lines > 0.5 && keyValuePairs > 10) {
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// Persian (Farsi) and Arabic scripts use zero-width non-joiner (U+200C) legitimately
|
|
200
|
+
// for proper text rendering. Detect these scripts by their Unicode ranges.
|
|
201
|
+
const hasPersianArabicScript = /[\u0600-\u06FF\u0750-\u077F]/.test(content);
|
|
202
|
+
if (hasPersianArabicScript && filename.endsWith(".json")) {
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Check if file has legitimate RTL text support (math, diagrams, language files).
|
|
209
|
+
*/
|
|
210
|
+
function isRtlFile(filename) {
|
|
211
|
+
const rtlPatterns = [
|
|
212
|
+
/katex/i, // KaTeX math rendering
|
|
213
|
+
/mermaid/i, // Mermaid diagram library
|
|
214
|
+
/mathjax/i, // MathJax math rendering
|
|
215
|
+
/drawio.*\/(dia_he|dia_fa|dia_ar)/i, // DrawIO Hebrew/Farsi/Arabic language files
|
|
216
|
+
/_he\.txt$/i, // Hebrew language files
|
|
217
|
+
/_fa\.txt$/i, // Farsi language files
|
|
218
|
+
/_ar\.txt$/i, // Arabic language files
|
|
219
|
+
];
|
|
220
|
+
return rtlPatterns.some((p) => p.test(filename));
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Check if invisible characters are in proximity to execution patterns.
|
|
224
|
+
*/
|
|
225
|
+
function hasExecutionInProximity(content, invisibleIndex, proximityChars = 200) {
|
|
226
|
+
const start = Math.max(0, invisibleIndex - proximityChars);
|
|
227
|
+
const end = Math.min(content.length, invisibleIndex + proximityChars);
|
|
228
|
+
const region = content.slice(start, end);
|
|
229
|
+
const execPatterns = [
|
|
230
|
+
/eval\s*\(/i,
|
|
231
|
+
/Function\s*\(/i,
|
|
232
|
+
/exec\s*\(/i,
|
|
233
|
+
/spawn\s*\(/i,
|
|
234
|
+
/execSync\s*\(/i,
|
|
235
|
+
/child_process/i,
|
|
236
|
+
/\.\s*call\s*\(/,
|
|
237
|
+
/\.\s*apply\s*\(/,
|
|
238
|
+
/new\s+Function/i,
|
|
239
|
+
/atob\s*\(/i,
|
|
240
|
+
/Buffer\.from/i,
|
|
241
|
+
];
|
|
242
|
+
return execPatterns.some((p) => p.test(region));
|
|
243
|
+
}
|
|
244
|
+
// Rules that should be skipped for bundled code and node_modules
|
|
245
|
+
const SKIP_UNICODE_FOR_BUNDLED = new Set([
|
|
246
|
+
"ZERO_WIDTH_CHARS",
|
|
247
|
+
"CYRILLIC_HOMOGLYPH",
|
|
248
|
+
"OTHER_INVISIBLE_CHARS",
|
|
249
|
+
"UNICODE_ASCII_ESCAPE",
|
|
250
|
+
]);
|
|
251
|
+
// Rules that should be skipped for node_modules (third-party deps)
|
|
252
|
+
// Critical rules (VARIATION_SELECTOR, BIDI_OVERRIDE, INVISIBLE_CODE_EXECUTION) still run
|
|
253
|
+
const SKIP_UNICODE_FOR_NODE_MODULES = new Set([
|
|
254
|
+
"ZERO_WIDTH_CHARS",
|
|
255
|
+
"CYRILLIC_HOMOGLYPH",
|
|
256
|
+
"OTHER_INVISIBLE_CHARS",
|
|
257
|
+
"UNICODE_ASCII_ESCAPE",
|
|
258
|
+
"OBFUSCATION_HIGH_ENTROPY",
|
|
259
|
+
]);
|
|
260
|
+
const UNICODE_RULES = [
|
|
261
|
+
{
|
|
262
|
+
id: "ZERO_WIDTH_CHARS",
|
|
263
|
+
title: "Zero-width characters detected",
|
|
264
|
+
description: "File contains zero-width Unicode characters (U+200B-200D, U+FEFF). These invisible characters can hide malicious code or be used for steganography.",
|
|
265
|
+
severity: "high",
|
|
266
|
+
detect: (content, filename) => {
|
|
267
|
+
// Skip i18n files - Persian, Arabic, Kurdish etc. use U+200C (ZWNJ) legitimately
|
|
268
|
+
if (isI18nFile(filename, content))
|
|
269
|
+
return [];
|
|
270
|
+
return detectUnicodePattern(content, ZERO_WIDTH_REGEX, 3);
|
|
271
|
+
},
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
id: "VARIATION_SELECTOR",
|
|
275
|
+
title: "Unicode variation selectors detected (GlassWorm technique)",
|
|
276
|
+
description: "File contains many Unicode variation selectors (U+FE00-FE0F). GlassWorm malware uses these to hide executable code.",
|
|
277
|
+
severity: "critical",
|
|
278
|
+
detect: (content, filename) => {
|
|
279
|
+
// Skip emoji/entity data files that legitimately use variation selectors
|
|
280
|
+
const emojiDataPatterns = [
|
|
281
|
+
/emoji/i,
|
|
282
|
+
/entities/i,
|
|
283
|
+
/spinners/i,
|
|
284
|
+
/\.md$/i, // README files often have emoji
|
|
285
|
+
/gemoji/i, // GitHub emoji library
|
|
286
|
+
/twemoji/i, // Twitter emoji
|
|
287
|
+
/node-emoji/i, // node-emoji package
|
|
288
|
+
/unicode.*data/i, // Unicode data files
|
|
289
|
+
/emojis?\.(json|js|ts)$/i, // emoji data files
|
|
290
|
+
];
|
|
291
|
+
if (emojiDataPatterns.some((p) => p.test(filename)))
|
|
292
|
+
return [];
|
|
293
|
+
// If file contains many actual emoji characters, it's likely legitimate emoji data
|
|
294
|
+
// Emoji ranges: Emoticons, Dingbats, Symbols, Flags, etc.
|
|
295
|
+
// eslint-disable-next-line no-misleading-character-class
|
|
296
|
+
const emojiPattern = /[\u{1F300}-\u{1F9FF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}]/gu;
|
|
297
|
+
const emojiMatches = content.match(emojiPattern);
|
|
298
|
+
if (emojiMatches && emojiMatches.length > 100)
|
|
299
|
+
return [];
|
|
300
|
+
// GlassWorm uses hundreds of variation selectors; 50 is well above normal emoji use
|
|
301
|
+
return detectUnicodePattern(content, VARIATION_SELECTOR_REGEX, 50);
|
|
302
|
+
},
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
id: "BIDI_OVERRIDE",
|
|
306
|
+
title: "Bidirectional text override detected (Trojan Source)",
|
|
307
|
+
description: "File contains Unicode bidirectional override characters (U+202A-202E). This is the Trojan Source attack technique.",
|
|
308
|
+
severity: "critical",
|
|
309
|
+
detect: (content, filename) => {
|
|
310
|
+
// Skip files with legitimate RTL text support (math, diagrams, language files)
|
|
311
|
+
if (isRtlFile(filename))
|
|
312
|
+
return [];
|
|
313
|
+
return detectUnicodePattern(content, BIDI_OVERRIDE_REGEX, 1);
|
|
314
|
+
},
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
id: "UNICODE_ASCII_ESCAPE",
|
|
318
|
+
title: "Unicode escape sequences for ASCII characters",
|
|
319
|
+
description: "File uses Unicode escape sequences (\\u00XX) for normal ASCII characters. This is a common obfuscation technique.",
|
|
320
|
+
severity: "medium",
|
|
321
|
+
detect: (content) => detectUnicodePattern(content, UNICODE_ASCII_ESCAPE_REGEX, 5),
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
id: "CYRILLIC_HOMOGLYPH",
|
|
325
|
+
title: "Cyrillic homoglyph characters detected",
|
|
326
|
+
description: "File contains Cyrillic characters that visually resemble Latin letters. This can be used for homoglyph attacks.",
|
|
327
|
+
severity: "high",
|
|
328
|
+
detect: (content, filename) => {
|
|
329
|
+
if (filename.endsWith(".md") || filename.endsWith(".txt")) {
|
|
330
|
+
return [];
|
|
331
|
+
}
|
|
332
|
+
if (isI18nFile(filename, content)) {
|
|
333
|
+
return [];
|
|
334
|
+
}
|
|
335
|
+
return detectUnicodePattern(content, CYRILLIC_LOOKALIKE_REGEX, 1);
|
|
336
|
+
},
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
id: "OTHER_INVISIBLE_CHARS",
|
|
340
|
+
title: "Other invisible Unicode characters detected",
|
|
341
|
+
description: "File contains invisible Unicode characters (soft hyphens, combining marks, format controls).",
|
|
342
|
+
severity: "medium",
|
|
343
|
+
detect: (content) => detectUnicodePattern(content, OTHER_INVISIBLE_REGEX, 3),
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
id: "INVISIBLE_CODE_EXECUTION",
|
|
347
|
+
title: "Invisible characters near code execution",
|
|
348
|
+
description: "File contains many invisible Unicode characters in proximity to code execution functions. Strong indicator of hidden malicious code.",
|
|
349
|
+
severity: "critical",
|
|
350
|
+
detect: (content, filename) => {
|
|
351
|
+
if (isI18nFile(filename, content)) {
|
|
352
|
+
return [];
|
|
353
|
+
}
|
|
354
|
+
const suspiciousInvisible = new RegExp(`${VARIATION_SELECTOR_REGEX.source}|${BIDI_OVERRIDE_REGEX.source}`, "g");
|
|
355
|
+
const matches = detectUnicodePattern(content, suspiciousInvisible, 5);
|
|
356
|
+
return matches.filter((m) => {
|
|
357
|
+
const matchIndex = content.slice(0, m.line).split("\n").length > 1
|
|
358
|
+
? content
|
|
359
|
+
.split("\n")
|
|
360
|
+
.slice(0, m.line - 1)
|
|
361
|
+
.join("\n").length + m.column
|
|
362
|
+
: m.column;
|
|
363
|
+
return hasExecutionInProximity(content, matchIndex);
|
|
364
|
+
});
|
|
365
|
+
},
|
|
366
|
+
},
|
|
367
|
+
];
|
|
368
|
+
function checkUnicodeHiding(contents) {
|
|
369
|
+
const findings = [];
|
|
370
|
+
const seenFindings = new Set();
|
|
371
|
+
for (const [filename, buffer] of contents.files) {
|
|
372
|
+
if (!isScannable(filename, SCANNABLE_EXTENSIONS_UNICODE))
|
|
373
|
+
continue;
|
|
374
|
+
const content = buffer.toString("utf8");
|
|
375
|
+
const bundlerInfo = detectBundler(content, filename);
|
|
376
|
+
const inNodeModules = isNodeModules(filename);
|
|
377
|
+
for (const rule of UNICODE_RULES) {
|
|
378
|
+
// Skip non-critical rules for bundled code
|
|
379
|
+
if (bundlerInfo.isBundled && SKIP_UNICODE_FOR_BUNDLED.has(rule.id)) {
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
// Skip non-critical rules for node_modules (third-party deps)
|
|
383
|
+
if (inNodeModules && SKIP_UNICODE_FOR_NODE_MODULES.has(rule.id)) {
|
|
384
|
+
continue;
|
|
385
|
+
}
|
|
386
|
+
const matches = rule.detect(content, filename);
|
|
387
|
+
if (matches.length === 0)
|
|
388
|
+
continue;
|
|
389
|
+
const key = `${rule.id}:${filename}`;
|
|
390
|
+
if (seenFindings.has(key))
|
|
391
|
+
continue;
|
|
392
|
+
seenFindings.add(key);
|
|
393
|
+
const firstMatch = matches[0];
|
|
394
|
+
if (!firstMatch)
|
|
395
|
+
continue;
|
|
396
|
+
findings.push({
|
|
397
|
+
id: rule.id,
|
|
398
|
+
title: rule.title,
|
|
399
|
+
description: rule.description,
|
|
400
|
+
severity: rule.severity,
|
|
401
|
+
category: "obfuscation",
|
|
402
|
+
location: {
|
|
403
|
+
file: filename,
|
|
404
|
+
line: firstMatch.line,
|
|
405
|
+
column: firstMatch.column,
|
|
406
|
+
},
|
|
407
|
+
metadata: {
|
|
408
|
+
matchCount: matches.length,
|
|
409
|
+
firstMatch: firstMatch.context,
|
|
410
|
+
codePoints: matches
|
|
411
|
+
.slice(0, 5)
|
|
412
|
+
.map((m) => [...m.matched]
|
|
413
|
+
.map((c) => `U+${c.codePointAt(0)?.toString(16).toUpperCase().padStart(4, "0")}`)
|
|
414
|
+
.join(", ")),
|
|
415
|
+
},
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
return findings;
|
|
420
|
+
}
|
|
421
|
+
// ============================================================================
|
|
422
|
+
// MAIN EXPORT
|
|
423
|
+
// ============================================================================
|
|
424
|
+
export function checkObfuscation(contents) {
|
|
425
|
+
const findings = [];
|
|
426
|
+
// Check entropy in code files (1 rule - YARA can't calculate entropy)
|
|
427
|
+
findings.push(...checkEntropy(contents));
|
|
428
|
+
// Check Unicode hiding in all text files (7 rules)
|
|
429
|
+
findings.push(...checkUnicodeHiding(contents));
|
|
430
|
+
return findings;
|
|
431
|
+
}
|
|
432
|
+
//# sourceMappingURL=obfuscation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"obfuscation.js","sourceRoot":"","sources":["../../../src/scanner/checks/obfuscation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"obfuscation.test.d.ts","sourceRoot":"","sources":["../../../src/scanner/checks/obfuscation.test.ts"],"names":[],"mappings":""}
|