@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,149 @@
|
|
|
1
|
+
import { mkdir, rm, writeFile } from "node:fs/promises";
|
|
2
|
+
import { homedir, platform } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
5
|
+
import { clearCache, ensureCacheDir, getCacheDir, getCachedPath, getCachedVersions, isCached, listCached, } from "./cache.js";
|
|
6
|
+
describe("getCacheDir", () => {
|
|
7
|
+
const originalEnv = process.env;
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
vi.resetModules();
|
|
10
|
+
process.env = { ...originalEnv };
|
|
11
|
+
});
|
|
12
|
+
afterEach(() => {
|
|
13
|
+
process.env = originalEnv;
|
|
14
|
+
});
|
|
15
|
+
it("returns macOS cache path on darwin", () => {
|
|
16
|
+
vi.mock("node:os", async () => {
|
|
17
|
+
const actual = await vi.importActual("node:os");
|
|
18
|
+
return {
|
|
19
|
+
...actual,
|
|
20
|
+
platform: () => "darwin",
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
// Re-import to get mocked version
|
|
24
|
+
const os = platform();
|
|
25
|
+
if (os === "darwin") {
|
|
26
|
+
const dir = getCacheDir();
|
|
27
|
+
expect(dir).toBe(join(homedir(), "Library", "Caches", "vsix-audit"));
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
it("respects XDG_CACHE_HOME on Linux", () => {
|
|
31
|
+
const os = platform();
|
|
32
|
+
if (os === "linux") {
|
|
33
|
+
process.env["XDG_CACHE_HOME"] = "/custom/cache";
|
|
34
|
+
// Need to re-import module to pick up env change
|
|
35
|
+
const dir = getCacheDir();
|
|
36
|
+
// On actual Linux with XDG set, should use it
|
|
37
|
+
expect(dir).toContain("vsix-audit");
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
it("falls back to ~/.cache on Linux without XDG_CACHE_HOME", () => {
|
|
41
|
+
const os = platform();
|
|
42
|
+
if (os === "linux") {
|
|
43
|
+
delete process.env["XDG_CACHE_HOME"];
|
|
44
|
+
const dir = getCacheDir();
|
|
45
|
+
expect(dir).toBe(join(homedir(), ".cache", "vsix-audit"));
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
it("returns a path containing vsix-audit", () => {
|
|
49
|
+
const dir = getCacheDir();
|
|
50
|
+
expect(dir).toContain("vsix-audit");
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
describe("getCachedPath", () => {
|
|
54
|
+
it("constructs correct path for marketplace extension", () => {
|
|
55
|
+
const path = getCachedPath("marketplace", "ms-python", "python", "2024.1.0");
|
|
56
|
+
expect(path).toContain("marketplace");
|
|
57
|
+
expect(path).toContain("ms-python.python-2024.1.0.vsix");
|
|
58
|
+
});
|
|
59
|
+
it("constructs correct path for openvsx extension", () => {
|
|
60
|
+
const path = getCachedPath("openvsx", "redhat", "java", "1.0.0");
|
|
61
|
+
expect(path).toContain("openvsx");
|
|
62
|
+
expect(path).toContain("redhat.java-1.0.0.vsix");
|
|
63
|
+
});
|
|
64
|
+
it("constructs correct path for cursor extension", () => {
|
|
65
|
+
const path = getCachedPath("cursor", "eamodio", "gitlens", "15.0.0");
|
|
66
|
+
expect(path).toContain("cursor");
|
|
67
|
+
expect(path).toContain("eamodio.gitlens-15.0.0.vsix");
|
|
68
|
+
});
|
|
69
|
+
it("handles extension names with dots", () => {
|
|
70
|
+
const path = getCachedPath("marketplace", "publisher", "ext.name", "1.0.0");
|
|
71
|
+
expect(path).toContain("publisher.ext.name-1.0.0.vsix");
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
describe("cache operations", () => {
|
|
75
|
+
let testCacheDir;
|
|
76
|
+
beforeEach(async () => {
|
|
77
|
+
// Create a temporary test cache directory
|
|
78
|
+
testCacheDir = join(getCacheDir(), "_test_" + Date.now());
|
|
79
|
+
await mkdir(testCacheDir, { recursive: true });
|
|
80
|
+
});
|
|
81
|
+
afterEach(async () => {
|
|
82
|
+
// Clean up test directory
|
|
83
|
+
await rm(testCacheDir, { recursive: true, force: true });
|
|
84
|
+
});
|
|
85
|
+
describe("isCached", () => {
|
|
86
|
+
it("returns false for non-existent extension", async () => {
|
|
87
|
+
const result = await isCached("marketplace", "nonexistent", "ext", "1.0.0");
|
|
88
|
+
expect(result).toBe(false);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
describe("listCached", () => {
|
|
92
|
+
it("returns empty array when cache is empty", async () => {
|
|
93
|
+
// This tests against the real cache dir, which may have extensions
|
|
94
|
+
// We just verify it returns an array
|
|
95
|
+
const result = await listCached();
|
|
96
|
+
expect(Array.isArray(result)).toBe(true);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
describe("clearCache", () => {
|
|
100
|
+
it("returns 0 when no extensions match pattern", async () => {
|
|
101
|
+
const deleted = await clearCache("nonexistent.*");
|
|
102
|
+
expect(deleted).toBe(0);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
describe("ensureCacheDir", () => {
|
|
106
|
+
it("creates marketplace cache directory", async () => {
|
|
107
|
+
const dir = await ensureCacheDir("marketplace");
|
|
108
|
+
expect(dir).toContain("marketplace");
|
|
109
|
+
});
|
|
110
|
+
it("creates openvsx cache directory", async () => {
|
|
111
|
+
const dir = await ensureCacheDir("openvsx");
|
|
112
|
+
expect(dir).toContain("openvsx");
|
|
113
|
+
});
|
|
114
|
+
it("creates cursor cache directory", async () => {
|
|
115
|
+
const dir = await ensureCacheDir("cursor");
|
|
116
|
+
expect(dir).toContain("cursor");
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
describe("getCachedVersions", () => {
|
|
120
|
+
it("returns empty array for non-existent extension", async () => {
|
|
121
|
+
const versions = await getCachedVersions("nonexistent", "ext");
|
|
122
|
+
expect(versions).toEqual([]);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
describe("cache with test files", () => {
|
|
127
|
+
let testCacheDir;
|
|
128
|
+
beforeEach(async () => {
|
|
129
|
+
// Create a unique test cache by manipulating env
|
|
130
|
+
testCacheDir = join(getCacheDir(), "_integration_test_" + Date.now());
|
|
131
|
+
});
|
|
132
|
+
afterEach(async () => {
|
|
133
|
+
await rm(testCacheDir, { recursive: true, force: true });
|
|
134
|
+
});
|
|
135
|
+
it("lists extensions in cache directory", async () => {
|
|
136
|
+
// Create test structure
|
|
137
|
+
const marketplaceDir = join(testCacheDir, "marketplace");
|
|
138
|
+
await mkdir(marketplaceDir, { recursive: true });
|
|
139
|
+
// Create a fake vsix file
|
|
140
|
+
const testVsix = join(marketplaceDir, "test-pub.test-ext-1.0.0.vsix");
|
|
141
|
+
await writeFile(testVsix, "fake vsix content");
|
|
142
|
+
// Since we can't easily mock getCacheDir in this test,
|
|
143
|
+
// we verify the parsing logic works by checking the file exists
|
|
144
|
+
const { stat } = await import("node:fs/promises");
|
|
145
|
+
const fileStat = await stat(testVsix);
|
|
146
|
+
expect(fileStat.size).toBeGreaterThan(0);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
//# sourceMappingURL=cache.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.test.js","sourceRoot":"","sources":["../../src/scanner/cache.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Finding } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Capability extraction from scanner findings.
|
|
4
|
+
*
|
|
5
|
+
* Aggregates findings into high-level capability buckets for quick
|
|
6
|
+
* understanding of what an extension can do.
|
|
7
|
+
*/
|
|
8
|
+
export interface Evidence {
|
|
9
|
+
file: string;
|
|
10
|
+
line?: number | undefined;
|
|
11
|
+
matched?: string | undefined;
|
|
12
|
+
}
|
|
13
|
+
export interface CapabilityInfo {
|
|
14
|
+
detected: boolean;
|
|
15
|
+
summary: string[];
|
|
16
|
+
evidence: Evidence[];
|
|
17
|
+
}
|
|
18
|
+
export interface Capabilities {
|
|
19
|
+
network: CapabilityInfo;
|
|
20
|
+
execution: CapabilityInfo;
|
|
21
|
+
fileAccess: CapabilityInfo;
|
|
22
|
+
credentials: CapabilityInfo;
|
|
23
|
+
obfuscation: CapabilityInfo;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Extract capabilities from scanner findings.
|
|
27
|
+
*/
|
|
28
|
+
export declare function extractCapabilities(findings: Finding[]): Capabilities;
|
|
29
|
+
//# sourceMappingURL=capabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../src/scanner/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C;;;;;GAKG;AAEH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,QAAQ,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,cAAc,CAAC;IACxB,SAAS,EAAE,cAAc,CAAC;IAC1B,UAAU,EAAE,cAAc,CAAC;IAC3B,WAAW,EAAE,cAAc,CAAC;IAC5B,WAAW,EAAE,cAAc,CAAC;CAC7B;AAiID;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,YAAY,CA2BrE"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
// Mapping of finding ID patterns to capabilities
|
|
2
|
+
const CAPABILITY_PATTERNS = {
|
|
3
|
+
network: [
|
|
4
|
+
/NETWORK/i,
|
|
5
|
+
/DISCORD/i,
|
|
6
|
+
/WEBHOOK/i,
|
|
7
|
+
/HTTP/i,
|
|
8
|
+
/WEBSOCKET/i,
|
|
9
|
+
/FETCH/i,
|
|
10
|
+
/AXIOS/i,
|
|
11
|
+
/SOCKET/i,
|
|
12
|
+
/EXFIL/i,
|
|
13
|
+
],
|
|
14
|
+
execution: [
|
|
15
|
+
/CHILD_PROCESS/i,
|
|
16
|
+
/EXEC/i,
|
|
17
|
+
/EVAL/i,
|
|
18
|
+
/SPAWN/i,
|
|
19
|
+
/POWERSHELL/i,
|
|
20
|
+
/SHELL/i,
|
|
21
|
+
/CMD/i,
|
|
22
|
+
/DROPPER/i,
|
|
23
|
+
/REVERSE_SHELL/i,
|
|
24
|
+
],
|
|
25
|
+
fileAccess: [
|
|
26
|
+
/FILE/i,
|
|
27
|
+
/READ/i,
|
|
28
|
+
/WRITE/i,
|
|
29
|
+
/HOME/i,
|
|
30
|
+
/PATH/i,
|
|
31
|
+
/STARTUP/i,
|
|
32
|
+
/PERSISTENCE/i,
|
|
33
|
+
/DROPPER/i,
|
|
34
|
+
],
|
|
35
|
+
credentials: [
|
|
36
|
+
/SSH/i,
|
|
37
|
+
/CREDENTIAL/i,
|
|
38
|
+
/WALLET/i,
|
|
39
|
+
/BROWSER_DATA/i,
|
|
40
|
+
/TOKEN/i,
|
|
41
|
+
/API_KEY/i,
|
|
42
|
+
/PASSWORD/i,
|
|
43
|
+
/SECRET/i,
|
|
44
|
+
/CRYPTO/i,
|
|
45
|
+
/KEY/i,
|
|
46
|
+
/NPM/i,
|
|
47
|
+
/ENV/i,
|
|
48
|
+
],
|
|
49
|
+
obfuscation: [
|
|
50
|
+
/OBFUSCATION/i,
|
|
51
|
+
/ENTROPY/i,
|
|
52
|
+
/HEX_/i,
|
|
53
|
+
/EVAL_ATOB/i,
|
|
54
|
+
/BASE64/i,
|
|
55
|
+
/UNICODE/i,
|
|
56
|
+
/INVISIBLE/i,
|
|
57
|
+
/HOMOGLYPH/i,
|
|
58
|
+
/ENCODED/i,
|
|
59
|
+
],
|
|
60
|
+
};
|
|
61
|
+
// Summary text generators based on finding IDs
|
|
62
|
+
const SUMMARY_GENERATORS = {
|
|
63
|
+
network: (ids) => {
|
|
64
|
+
const summaries = [];
|
|
65
|
+
if (ids.some((id) => /DISCORD|WEBHOOK/i.test(id)))
|
|
66
|
+
summaries.push("Discord webhooks");
|
|
67
|
+
if (ids.some((id) => /WEBSOCKET/i.test(id)))
|
|
68
|
+
summaries.push("WebSocket");
|
|
69
|
+
if (ids.some((id) => /NETWORK|HTTP|FETCH|AXIOS/i.test(id)))
|
|
70
|
+
summaries.push("HTTP client");
|
|
71
|
+
if (ids.some((id) => /SOCKET/i.test(id)))
|
|
72
|
+
summaries.push("Raw sockets");
|
|
73
|
+
return summaries.length ? summaries : ["Network activity"];
|
|
74
|
+
},
|
|
75
|
+
execution: (ids) => {
|
|
76
|
+
const summaries = [];
|
|
77
|
+
if (ids.some((id) => /CHILD_PROCESS|SPAWN|EXEC/i.test(id)))
|
|
78
|
+
summaries.push("Shell commands (child_process)");
|
|
79
|
+
if (ids.some((id) => /EVAL/i.test(id)))
|
|
80
|
+
summaries.push("Dynamic code (eval)");
|
|
81
|
+
if (ids.some((id) => /POWERSHELL/i.test(id)))
|
|
82
|
+
summaries.push("PowerShell");
|
|
83
|
+
if (ids.some((id) => /REVERSE_SHELL/i.test(id)))
|
|
84
|
+
summaries.push("Reverse shell pattern");
|
|
85
|
+
if (ids.some((id) => /DROPPER/i.test(id)))
|
|
86
|
+
summaries.push("Dropper pattern");
|
|
87
|
+
return summaries.length ? summaries : ["Code execution"];
|
|
88
|
+
},
|
|
89
|
+
fileAccess: (ids) => {
|
|
90
|
+
const summaries = [];
|
|
91
|
+
if (ids.some((id) => /SSH/i.test(id)))
|
|
92
|
+
summaries.push(".ssh directory");
|
|
93
|
+
if (ids.some((id) => /HOME/i.test(id)))
|
|
94
|
+
summaries.push("Home directory");
|
|
95
|
+
if (ids.some((id) => /STARTUP|BASHRC|PROFILE/i.test(id)))
|
|
96
|
+
summaries.push("Startup files");
|
|
97
|
+
if (ids.some((id) => /WRITE|PERSIST/i.test(id)))
|
|
98
|
+
summaries.push("File writes");
|
|
99
|
+
if (ids.some((id) => /READ/i.test(id)))
|
|
100
|
+
summaries.push("File reads");
|
|
101
|
+
return summaries.length ? summaries : ["File system access"];
|
|
102
|
+
},
|
|
103
|
+
credentials: (ids) => {
|
|
104
|
+
const summaries = [];
|
|
105
|
+
if (ids.some((id) => /SSH/i.test(id)))
|
|
106
|
+
summaries.push("SSH keys");
|
|
107
|
+
if (ids.some((id) => /WALLET|CRYPTO/i.test(id)))
|
|
108
|
+
summaries.push("Crypto wallets");
|
|
109
|
+
if (ids.some((id) => /BROWSER/i.test(id)))
|
|
110
|
+
summaries.push("Browser data");
|
|
111
|
+
if (ids.some((id) => /ENV/i.test(id)))
|
|
112
|
+
summaries.push("Environment variables");
|
|
113
|
+
if (ids.some((id) => /TOKEN|API_KEY/i.test(id)))
|
|
114
|
+
summaries.push("API tokens");
|
|
115
|
+
if (ids.some((id) => /NPM/i.test(id)))
|
|
116
|
+
summaries.push("npm credentials");
|
|
117
|
+
if (ids.some((id) => /GIT/i.test(id)))
|
|
118
|
+
summaries.push("Git credentials");
|
|
119
|
+
return summaries.length ? summaries : ["Sensitive data"];
|
|
120
|
+
},
|
|
121
|
+
obfuscation: (ids) => {
|
|
122
|
+
const summaries = [];
|
|
123
|
+
if (ids.some((id) => /ENTROPY/i.test(id)))
|
|
124
|
+
summaries.push("High entropy code");
|
|
125
|
+
if (ids.some((id) => /HEX_|BASE64|ENCODED/i.test(id)))
|
|
126
|
+
summaries.push("Encoded strings");
|
|
127
|
+
if (ids.some((id) => /UNICODE|INVISIBLE|HOMOGLYPH/i.test(id)))
|
|
128
|
+
summaries.push("Unicode manipulation");
|
|
129
|
+
if (ids.some((id) => /EVAL_ATOB/i.test(id)))
|
|
130
|
+
summaries.push("eval(atob()) pattern");
|
|
131
|
+
return summaries.length ? summaries : ["Code obfuscation"];
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Determine which capability a finding belongs to based on its ID.
|
|
136
|
+
*/
|
|
137
|
+
function getCapability(findingId) {
|
|
138
|
+
const caps = [];
|
|
139
|
+
for (const [cap, patterns] of Object.entries(CAPABILITY_PATTERNS)) {
|
|
140
|
+
if (patterns.some((p) => p.test(findingId))) {
|
|
141
|
+
caps.push(cap);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return caps;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Extract capabilities from scanner findings.
|
|
148
|
+
*/
|
|
149
|
+
export function extractCapabilities(findings) {
|
|
150
|
+
const capFindings = {
|
|
151
|
+
network: [],
|
|
152
|
+
execution: [],
|
|
153
|
+
fileAccess: [],
|
|
154
|
+
credentials: [],
|
|
155
|
+
obfuscation: [],
|
|
156
|
+
};
|
|
157
|
+
// Categorize findings by capability
|
|
158
|
+
for (const finding of findings) {
|
|
159
|
+
const caps = getCapability(finding.id);
|
|
160
|
+
for (const cap of caps) {
|
|
161
|
+
capFindings[cap].push(finding);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// Build capability info for each category
|
|
165
|
+
const capabilities = {
|
|
166
|
+
network: buildCapabilityInfo(capFindings.network, "network"),
|
|
167
|
+
execution: buildCapabilityInfo(capFindings.execution, "execution"),
|
|
168
|
+
fileAccess: buildCapabilityInfo(capFindings.fileAccess, "fileAccess"),
|
|
169
|
+
credentials: buildCapabilityInfo(capFindings.credentials, "credentials"),
|
|
170
|
+
obfuscation: buildCapabilityInfo(capFindings.obfuscation, "obfuscation"),
|
|
171
|
+
};
|
|
172
|
+
return capabilities;
|
|
173
|
+
}
|
|
174
|
+
function buildCapabilityInfo(findings, cap) {
|
|
175
|
+
if (findings.length === 0) {
|
|
176
|
+
return { detected: false, summary: [], evidence: [] };
|
|
177
|
+
}
|
|
178
|
+
const ids = [...new Set(findings.map((f) => f.id))];
|
|
179
|
+
const summary = SUMMARY_GENERATORS[cap](ids);
|
|
180
|
+
const evidence = [];
|
|
181
|
+
for (const f of findings) {
|
|
182
|
+
if (!f.location)
|
|
183
|
+
continue;
|
|
184
|
+
const ev = { file: f.location.file };
|
|
185
|
+
if (f.location.line !== undefined)
|
|
186
|
+
ev.line = f.location.line;
|
|
187
|
+
const matched = extractMatched(f);
|
|
188
|
+
if (matched)
|
|
189
|
+
ev.matched = matched;
|
|
190
|
+
evidence.push(ev);
|
|
191
|
+
if (evidence.length >= 10)
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
return { detected: true, summary, evidence };
|
|
195
|
+
}
|
|
196
|
+
function extractMatched(finding) {
|
|
197
|
+
const meta = finding.metadata;
|
|
198
|
+
if (!meta)
|
|
199
|
+
return undefined;
|
|
200
|
+
// Try to extract matched text from various metadata formats
|
|
201
|
+
if (typeof meta["matched"] === "string")
|
|
202
|
+
return meta["matched"];
|
|
203
|
+
const stages = meta["stages"];
|
|
204
|
+
if (Array.isArray(stages) && stages.length > 0) {
|
|
205
|
+
const stage = stages[0];
|
|
206
|
+
if (stage?.matched)
|
|
207
|
+
return stage.matched;
|
|
208
|
+
}
|
|
209
|
+
const source = meta["source"];
|
|
210
|
+
if (typeof source === "object" && source !== null) {
|
|
211
|
+
const src = source;
|
|
212
|
+
if (src?.matched)
|
|
213
|
+
return src.matched;
|
|
214
|
+
}
|
|
215
|
+
return undefined;
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/scanner/capabilities.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../../src/scanner/checks/ast.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,OAAO,EAAY,YAAY,EAAE,MAAM,aAAa,CAAC;AAggBnE,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,EAAE,CAuB1D"}
|