@cyclonedx/cdxgen 9.6.0 → 9.7.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 +7 -8
- package/bin/cdxgen.js +1 -3
- package/bin/evinse.js +0 -0
- package/bin/verify.js +19 -0
- package/binary.js +166 -30
- package/data/queries-win.json +200 -0
- package/data/queries.json +166 -15
- package/display.js +14 -8
- package/docker.js +18 -1
- package/evinser.js +23 -32
- package/index.js +96 -18
- package/package.json +10 -8
- package/utils.js +159 -85
- package/utils.test.js +2 -2
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
cdxgen is a cli tool, library, [REPL](./ADVANCED.md) and server to create a valid and compliant [CycloneDX][cyclonedx-homepage] Software Bill-of-Materials (SBOM) containing an aggregate of all project dependencies for c/c++, node.js, php, python, ruby, rust, java, .Net, dart, haskell, elixir, and Go projects in JSON format. CycloneDX 1.5 is a lightweight SBOM specification that is easily created, human and machine-readable, and simple to parse.
|
|
6
6
|
|
|
7
|
-
When used with plugins, cdxgen could generate an
|
|
7
|
+
When used with plugins, cdxgen could generate an OBoM for Linux docker images and even VMs running Linux or Windows operating system. cdxgen also includes a tool called `evinse` that can generate component evidences and SaaSBoM for some languages.
|
|
8
8
|
|
|
9
9
|
NOTE:
|
|
10
10
|
|
|
@@ -127,9 +127,7 @@ Options:
|
|
|
127
127
|
-r, --recurse Recurse mode suitable for mono-repos. Defaults to
|
|
128
128
|
true. Pass --no-recurse to disable.
|
|
129
129
|
[boolean] [default: true]
|
|
130
|
-
-p, --print Print the SBoM as a table with tree.
|
|
131
|
-
true if output file is not specified with -o
|
|
132
|
-
[boolean]
|
|
130
|
+
-p, --print Print the SBoM as a table with tree. [boolean]
|
|
133
131
|
-c, --resolve-class Resolve class names for packages. jars only for n
|
|
134
132
|
ow. [boolean]
|
|
135
133
|
--deep Perform deep searches for components. Useful whil
|
|
@@ -294,6 +292,7 @@ cdxgen can retain the dependency tree under the `dependencies` attribute for a s
|
|
|
294
292
|
| MVN_CMD | Set to override maven command |
|
|
295
293
|
| MVN_ARGS | Set to pass additional arguments such as profile or settings to maven |
|
|
296
294
|
| MAVEN_HOME | Specify maven home |
|
|
295
|
+
| MAVEN_CENTRAL_URL | Specify URL of Maven Central for metadata fetching (e.g. when private repo is used) |
|
|
297
296
|
| GRADLE_CACHE_DIR | Specify gradle cache directory. Useful for class name resolving |
|
|
298
297
|
| GRADLE_MULTI_PROJECT_MODE | Unused. Automatically handled |
|
|
299
298
|
| GRADLE_ARGS | Set to pass additional arguments such as profile or settings to gradle (all tasks). Eg: --configuration runtimeClassPath |
|
|
@@ -366,17 +365,17 @@ systemctl --user start podman.socket
|
|
|
366
365
|
podman system service -t 0 &
|
|
367
366
|
```
|
|
368
367
|
|
|
369
|
-
### Generate
|
|
368
|
+
### Generate OBoM for a live system
|
|
370
369
|
|
|
371
|
-
You can use cdxgen to generate
|
|
370
|
+
You can use cdxgen to generate an OBoM for a live system or a VM for compliance and vulnerability management purposes by passing the argument `-t os`. Windows and Linux operating systems are supported in this mode.
|
|
372
371
|
|
|
373
372
|
```shell
|
|
374
373
|
cdxgen -t os
|
|
375
374
|
```
|
|
376
375
|
|
|
377
|
-
This feature is powered by osquery which is [installed](https://github.com/cyclonedx/cdxgen-plugins-bin/blob/main/build.sh#L8) along with the binary plugins. cdxgen would opportunistically try to detect as many components, apps and extensions as possible using the [default queries](queries.json). The process would take several minutes and result in an SBoM file with thousands of components.
|
|
376
|
+
This feature is powered by osquery which is [installed](https://github.com/cyclonedx/cdxgen-plugins-bin/blob/main/build.sh#L8) along with the binary plugins. cdxgen would opportunistically try to detect as many components, apps and extensions as possible using the [default queries](queries.json). The process would take several minutes and result in an SBoM file with thousands of components of various types such as operating-system, device-drivers, files, and data.
|
|
378
377
|
|
|
379
|
-
## Generating component
|
|
378
|
+
## Generating SaaSBoM and component evidences
|
|
380
379
|
|
|
381
380
|
See [evinse mode](./ADVANCED.md) in the advanced documentation.
|
|
382
381
|
|
package/bin/cdxgen.js
CHANGED
|
@@ -41,8 +41,7 @@ const args = yargs(hideBin(process.argv))
|
|
|
41
41
|
.option("print", {
|
|
42
42
|
alias: "p",
|
|
43
43
|
type: "boolean",
|
|
44
|
-
description:
|
|
45
|
-
"Print the SBoM as a table with tree. Defaults to true if output file is not specified with -o"
|
|
44
|
+
description: "Print the SBoM as a table with tree."
|
|
46
45
|
})
|
|
47
46
|
.option("resolve-class", {
|
|
48
47
|
alias: "c",
|
|
@@ -229,7 +228,6 @@ const checkPermissions = (filePath) => {
|
|
|
229
228
|
const bomNSData = (await createBom(filePath, options)) || {};
|
|
230
229
|
if (!args.output) {
|
|
231
230
|
args.output = "bom.json";
|
|
232
|
-
args.print = true;
|
|
233
231
|
}
|
|
234
232
|
if (
|
|
235
233
|
args.output &&
|
package/bin/evinse.js
CHANGED
|
File without changes
|
package/bin/verify.js
CHANGED
|
@@ -40,6 +40,25 @@ if (args.version) {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
const bomJson = JSON.parse(fs.readFileSync(args.input, "utf8"));
|
|
43
|
+
let hasInvalidComp = false;
|
|
44
|
+
// Validate any component signature
|
|
45
|
+
for (const comp of bomJson.components) {
|
|
46
|
+
if (comp.signature) {
|
|
47
|
+
const compSignature = comp.signature.value;
|
|
48
|
+
const validationResult = jws.verify(
|
|
49
|
+
compSignature,
|
|
50
|
+
comp.signature.algorithm,
|
|
51
|
+
fs.readFileSync(args.publicKey, "utf8")
|
|
52
|
+
);
|
|
53
|
+
if (!validationResult) {
|
|
54
|
+
console.log(`${comp["bom-ref"]} signature is invalid!`);
|
|
55
|
+
hasInvalidComp = true;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (hasInvalidComp) {
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
43
62
|
const bomSignature =
|
|
44
63
|
bomJson.signature && bomJson.signature.value
|
|
45
64
|
? bomJson.signature.value
|
package/binary.js
CHANGED
|
@@ -6,18 +6,18 @@ import { PackageURL } from "packageurl-js";
|
|
|
6
6
|
import { DEBUG_MODE } from "./utils.js";
|
|
7
7
|
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
|
-
import path from "node:path";
|
|
10
9
|
|
|
11
10
|
let url = import.meta.url;
|
|
12
11
|
if (!url.startsWith("file://")) {
|
|
13
12
|
url = new URL(`file://${import.meta.url}`).toString();
|
|
14
13
|
}
|
|
15
|
-
const dirName = import.meta ?
|
|
14
|
+
const dirName = import.meta ? dirname(fileURLToPath(url)) : __dirname;
|
|
16
15
|
|
|
17
16
|
const isWin = _platform() === "win32";
|
|
18
17
|
|
|
19
18
|
let platform = _platform();
|
|
20
19
|
let extn = "";
|
|
20
|
+
let pluginsBinSuffix = "";
|
|
21
21
|
if (platform == "win32") {
|
|
22
22
|
platform = "windows";
|
|
23
23
|
extn = ".exe";
|
|
@@ -31,6 +31,13 @@ switch (arch) {
|
|
|
31
31
|
case "x64":
|
|
32
32
|
arch = "amd64";
|
|
33
33
|
break;
|
|
34
|
+
case "arm64":
|
|
35
|
+
pluginsBinSuffix = "-arm64";
|
|
36
|
+
break;
|
|
37
|
+
case "ppc64":
|
|
38
|
+
arch = "ppc64le";
|
|
39
|
+
pluginsBinSuffix = "-ppc64";
|
|
40
|
+
break;
|
|
34
41
|
}
|
|
35
42
|
|
|
36
43
|
// Retrieve the cdxgen plugins directory
|
|
@@ -47,14 +54,20 @@ if (
|
|
|
47
54
|
if (
|
|
48
55
|
!CDXGEN_PLUGINS_DIR &&
|
|
49
56
|
existsSync(
|
|
50
|
-
join(
|
|
57
|
+
join(
|
|
58
|
+
dirName,
|
|
59
|
+
"node_modules",
|
|
60
|
+
"@cyclonedx",
|
|
61
|
+
"cdxgen-plugins-bin" + pluginsBinSuffix,
|
|
62
|
+
"plugins"
|
|
63
|
+
)
|
|
51
64
|
) &&
|
|
52
65
|
existsSync(
|
|
53
66
|
join(
|
|
54
67
|
dirName,
|
|
55
68
|
"node_modules",
|
|
56
69
|
"@cyclonedx",
|
|
57
|
-
"cdxgen-plugins-bin",
|
|
70
|
+
"cdxgen-plugins-bin" + pluginsBinSuffix,
|
|
58
71
|
"plugins",
|
|
59
72
|
"goversion"
|
|
60
73
|
)
|
|
@@ -64,7 +77,7 @@ if (
|
|
|
64
77
|
dirName,
|
|
65
78
|
"node_modules",
|
|
66
79
|
"@cyclonedx",
|
|
67
|
-
"cdxgen-plugins-bin",
|
|
80
|
+
"cdxgen-plugins-bin" + pluginsBinSuffix,
|
|
68
81
|
"plugins"
|
|
69
82
|
);
|
|
70
83
|
}
|
|
@@ -89,7 +102,7 @@ if (!CDXGEN_PLUGINS_DIR) {
|
|
|
89
102
|
const globalPlugins = join(
|
|
90
103
|
globalNodePath,
|
|
91
104
|
"@cyclonedx",
|
|
92
|
-
"cdxgen-plugins-bin",
|
|
105
|
+
"cdxgen-plugins-bin" + pluginsBinSuffix,
|
|
93
106
|
"plugins"
|
|
94
107
|
);
|
|
95
108
|
if (existsSync(globalPlugins)) {
|
|
@@ -181,6 +194,7 @@ const OS_DISTRO_ALIAS = {
|
|
|
181
194
|
"ubuntu-19.10": "eoan",
|
|
182
195
|
"ubuntu-20.04": "focal",
|
|
183
196
|
"ubuntu-20.10": "groovy",
|
|
197
|
+
"ubuntu-22.04": "jammy",
|
|
184
198
|
"ubuntu-23.04": "lunar",
|
|
185
199
|
"debian-14": "forky",
|
|
186
200
|
"debian-14.5": "forky",
|
|
@@ -266,6 +280,7 @@ export const getCargoAuditableInfo = (src) => {
|
|
|
266
280
|
|
|
267
281
|
export const getOSPackages = (src) => {
|
|
268
282
|
const pkgList = [];
|
|
283
|
+
const dependenciesList = [];
|
|
269
284
|
const allTypes = new Set();
|
|
270
285
|
if (TRIVY_BIN) {
|
|
271
286
|
let imageType = "image";
|
|
@@ -321,6 +336,60 @@ export const getOSPackages = (src) => {
|
|
|
321
336
|
rmSync(tempDir, { recursive: true, force: true });
|
|
322
337
|
}
|
|
323
338
|
}
|
|
339
|
+
const osReleaseData = {};
|
|
340
|
+
let osReleaseFile = undefined;
|
|
341
|
+
// Let's try to read the os-release file from various locations
|
|
342
|
+
if (existsSync(join(src, "etc", "os-release"))) {
|
|
343
|
+
osReleaseFile = join(src, "etc", "os-release");
|
|
344
|
+
} else if (existsSync(join(src, "usr", "lib", "os-release"))) {
|
|
345
|
+
osReleaseFile = join(src, "usr", "lib", "os-release");
|
|
346
|
+
}
|
|
347
|
+
if (osReleaseFile) {
|
|
348
|
+
const osReleaseInfo = readFileSync(
|
|
349
|
+
join(src, "usr", "lib", "os-release"),
|
|
350
|
+
"utf-8"
|
|
351
|
+
);
|
|
352
|
+
if (osReleaseInfo) {
|
|
353
|
+
osReleaseInfo.split("\n").forEach((l) => {
|
|
354
|
+
if (!l.startsWith("#") && l.includes("=")) {
|
|
355
|
+
const tmpA = l.split("=");
|
|
356
|
+
osReleaseData[tmpA[0]] = tmpA[1].replace(/"/g, "");
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
if (DEBUG_MODE) {
|
|
362
|
+
console.log(osReleaseData);
|
|
363
|
+
}
|
|
364
|
+
let distro_codename = osReleaseData["VERSION_CODENAME"] || "";
|
|
365
|
+
let distro_id = osReleaseData["ID"] || "";
|
|
366
|
+
let distro_id_like = osReleaseData["ID_LIKE"] || "";
|
|
367
|
+
let purl_type = "rpm";
|
|
368
|
+
switch (distro_id) {
|
|
369
|
+
case "debian":
|
|
370
|
+
case "ubuntu":
|
|
371
|
+
case "pop":
|
|
372
|
+
purl_type = "deb";
|
|
373
|
+
break;
|
|
374
|
+
default:
|
|
375
|
+
if (distro_id_like.includes("debian")) {
|
|
376
|
+
purl_type = "deb";
|
|
377
|
+
} else if (
|
|
378
|
+
distro_id_like.includes("rhel") ||
|
|
379
|
+
distro_id_like.includes("centos") ||
|
|
380
|
+
distro_id_like.includes("fedora")
|
|
381
|
+
) {
|
|
382
|
+
purl_type = "rpm";
|
|
383
|
+
}
|
|
384
|
+
break;
|
|
385
|
+
}
|
|
386
|
+
if (osReleaseData["VERSION_ID"]) {
|
|
387
|
+
distro_id = distro_id + "-" + osReleaseData["VERSION_ID"];
|
|
388
|
+
}
|
|
389
|
+
const tmpDependencies = {};
|
|
390
|
+
(tmpBom.dependencies || []).forEach((d) => {
|
|
391
|
+
tmpDependencies[d.ref] = d.dependsOn;
|
|
392
|
+
});
|
|
324
393
|
if (tmpBom && tmpBom.components) {
|
|
325
394
|
for (const comp of tmpBom.components) {
|
|
326
395
|
if (comp.purl) {
|
|
@@ -342,11 +411,11 @@ export const getOSPackages = (src) => {
|
|
|
342
411
|
) {
|
|
343
412
|
continue;
|
|
344
413
|
}
|
|
414
|
+
const origBomRef = comp["bom-ref"];
|
|
345
415
|
// Fix the group
|
|
346
416
|
let group = dirname(comp.name);
|
|
347
417
|
const name = basename(comp.name);
|
|
348
418
|
let purlObj = undefined;
|
|
349
|
-
let distro_codename = "";
|
|
350
419
|
if (group === ".") {
|
|
351
420
|
group = "";
|
|
352
421
|
}
|
|
@@ -360,19 +429,23 @@ export const getOSPackages = (src) => {
|
|
|
360
429
|
comp.group = group;
|
|
361
430
|
purlObj.namespace = group;
|
|
362
431
|
}
|
|
432
|
+
if (distro_id && distro_id.length) {
|
|
433
|
+
purlObj.qualifiers["distro"] = distro_id;
|
|
434
|
+
}
|
|
435
|
+
if (distro_codename && distro_codename.length) {
|
|
436
|
+
purlObj.qualifiers["distro_name"] = distro_codename;
|
|
437
|
+
}
|
|
363
438
|
// Bug fix for mageia and oracle linux
|
|
439
|
+
// Type is being returned as none for ubuntu as well!
|
|
364
440
|
if (purlObj.type === "none") {
|
|
365
|
-
purlObj["type"] =
|
|
441
|
+
purlObj["type"] = purl_type;
|
|
366
442
|
purlObj["namespace"] = "";
|
|
367
443
|
comp.group = "";
|
|
368
|
-
distro_codename = undefined;
|
|
369
444
|
if (comp.purl && comp.purl.includes(".mga")) {
|
|
370
445
|
purlObj["namespace"] = "mageia";
|
|
371
446
|
comp.group = "mageia";
|
|
372
447
|
purlObj.qualifiers["distro"] = "mageia";
|
|
373
448
|
distro_codename = "mga";
|
|
374
|
-
} else if (comp.purl && comp.purl.includes(".el8")) {
|
|
375
|
-
purlObj.qualifiers["distro"] = "el8";
|
|
376
449
|
}
|
|
377
450
|
comp.purl = new PackageURL(
|
|
378
451
|
purlObj.type,
|
|
@@ -412,25 +485,25 @@ export const getOSPackages = (src) => {
|
|
|
412
485
|
);
|
|
413
486
|
}
|
|
414
487
|
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
}
|
|
488
|
+
}
|
|
489
|
+
if (distro_codename !== "") {
|
|
490
|
+
allTypes.add(distro_codename);
|
|
491
|
+
allTypes.add(purlObj.namespace);
|
|
492
|
+
comp.purl = new PackageURL(
|
|
493
|
+
purlObj.type,
|
|
494
|
+
purlObj.namespace,
|
|
495
|
+
name,
|
|
496
|
+
purlObj.version,
|
|
497
|
+
purlObj.qualifiers,
|
|
498
|
+
purlObj.subpath
|
|
499
|
+
).toString();
|
|
500
|
+
comp["bom-ref"] = decodeURIComponent(comp.purl);
|
|
429
501
|
}
|
|
430
502
|
} catch (err) {
|
|
431
503
|
// continue regardless of error
|
|
432
504
|
}
|
|
433
505
|
}
|
|
506
|
+
// Fix licenses
|
|
434
507
|
if (
|
|
435
508
|
comp.licenses &&
|
|
436
509
|
Array.isArray(comp.licenses) &&
|
|
@@ -438,6 +511,17 @@ export const getOSPackages = (src) => {
|
|
|
438
511
|
) {
|
|
439
512
|
comp.licenses = [comp.licenses[0]];
|
|
440
513
|
}
|
|
514
|
+
// Fix hashes
|
|
515
|
+
if (
|
|
516
|
+
comp.hashes &&
|
|
517
|
+
Array.isArray(comp.hashes) &&
|
|
518
|
+
comp.hashes.length
|
|
519
|
+
) {
|
|
520
|
+
const hashContent = comp.hashes[0].content;
|
|
521
|
+
if (!hashContent || hashContent.length < 32) {
|
|
522
|
+
delete comp.hashes;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
441
525
|
const compProperties = comp.properties;
|
|
442
526
|
let srcName = undefined;
|
|
443
527
|
let srcVersion = undefined;
|
|
@@ -453,6 +537,14 @@ export const getOSPackages = (src) => {
|
|
|
453
537
|
}
|
|
454
538
|
delete comp.properties;
|
|
455
539
|
pkgList.push(comp);
|
|
540
|
+
const compDeps = retrieveDependencies(
|
|
541
|
+
tmpDependencies,
|
|
542
|
+
origBomRef,
|
|
543
|
+
comp
|
|
544
|
+
);
|
|
545
|
+
if (compDeps) {
|
|
546
|
+
dependenciesList.push(compDeps);
|
|
547
|
+
}
|
|
456
548
|
// If there is a source package defined include it as well
|
|
457
549
|
if (srcName && srcVersion && srcName !== comp.name) {
|
|
458
550
|
const newComp = Object.assign({}, comp);
|
|
@@ -474,10 +566,43 @@ export const getOSPackages = (src) => {
|
|
|
474
566
|
}
|
|
475
567
|
}
|
|
476
568
|
}
|
|
477
|
-
return { osPackages: pkgList, allTypes: Array.from(allTypes) };
|
|
478
569
|
}
|
|
479
570
|
}
|
|
480
|
-
return {
|
|
571
|
+
return {
|
|
572
|
+
osPackages: pkgList,
|
|
573
|
+
dependenciesList,
|
|
574
|
+
allTypes: Array.from(allTypes)
|
|
575
|
+
};
|
|
576
|
+
};
|
|
577
|
+
|
|
578
|
+
const retrieveDependencies = (tmpDependencies, origBomRef, comp) => {
|
|
579
|
+
try {
|
|
580
|
+
const tmpDependsOn = tmpDependencies[origBomRef] || [];
|
|
581
|
+
const dependsOn = new Set();
|
|
582
|
+
tmpDependsOn.forEach((d) => {
|
|
583
|
+
try {
|
|
584
|
+
const compPurl = PackageURL.fromString(comp.purl);
|
|
585
|
+
const tmpPurl = PackageURL.fromString(d.replace("none", compPurl.type));
|
|
586
|
+
tmpPurl.type = compPurl.type;
|
|
587
|
+
tmpPurl.namespace = compPurl.namespace;
|
|
588
|
+
if (compPurl.qualifiers) {
|
|
589
|
+
if (compPurl.qualifiers.distro_name) {
|
|
590
|
+
tmpPurl.qualifiers.distro_name = compPurl.qualifiers.distro_name;
|
|
591
|
+
}
|
|
592
|
+
if (compPurl.qualifiers.distro) {
|
|
593
|
+
tmpPurl.qualifiers.distro = compPurl.qualifiers.distro;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
dependsOn.add(decodeURIComponent(tmpPurl.toString()));
|
|
597
|
+
} catch (e) {
|
|
598
|
+
// ignore
|
|
599
|
+
}
|
|
600
|
+
});
|
|
601
|
+
return { ref: comp["bom-ref"], dependsOn: Array.from(dependsOn).sort() };
|
|
602
|
+
} catch (e) {
|
|
603
|
+
// ignore
|
|
604
|
+
}
|
|
605
|
+
return undefined;
|
|
481
606
|
};
|
|
482
607
|
|
|
483
608
|
export const executeOsQuery = (query) => {
|
|
@@ -487,10 +612,11 @@ export const executeOsQuery = (query) => {
|
|
|
487
612
|
}
|
|
488
613
|
const args = ["--json", query];
|
|
489
614
|
if (DEBUG_MODE) {
|
|
490
|
-
console.log("
|
|
615
|
+
console.log("Executing", OSQUERY_BIN, args.join(" "));
|
|
491
616
|
}
|
|
492
617
|
const result = spawnSync(OSQUERY_BIN, args, {
|
|
493
|
-
encoding: "utf-8"
|
|
618
|
+
encoding: "utf-8",
|
|
619
|
+
maxBuffer: 50 * 1024 * 1024
|
|
494
620
|
});
|
|
495
621
|
if (result.status !== 0 || result.error) {
|
|
496
622
|
if (DEBUG_MODE && result.error) {
|
|
@@ -502,7 +628,17 @@ export const executeOsQuery = (query) => {
|
|
|
502
628
|
if (stdout) {
|
|
503
629
|
const cmdOutput = Buffer.from(stdout).toString();
|
|
504
630
|
if (cmdOutput !== "") {
|
|
505
|
-
|
|
631
|
+
try {
|
|
632
|
+
return JSON.parse(cmdOutput);
|
|
633
|
+
} catch (err) {
|
|
634
|
+
// ignore
|
|
635
|
+
if (DEBUG_MODE) {
|
|
636
|
+
console.log("Unable to parse the output from query", query);
|
|
637
|
+
console.log(
|
|
638
|
+
"This could be due to the amount of data returned or the query being invalid for the given platform."
|
|
639
|
+
);
|
|
640
|
+
}
|
|
641
|
+
}
|
|
506
642
|
}
|
|
507
643
|
return undefined;
|
|
508
644
|
}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
{
|
|
2
|
+
"win_version": {
|
|
3
|
+
"query": "select tb1.name, tb1.build_version, (case when (arch like '%-bit') then concat('x', replace(arch,'-bit', '')) else arch end) as arch, 'Microsoft' as publisher, tb2.version from (select name, version as build_version, arch from os_version) tb1,(select data as version from registry where path = 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\DisplayVersion') tb2;",
|
|
4
|
+
"name": "win_version",
|
|
5
|
+
"description": "Retrieves the name, version number, build version, and arch of the target Windows system.",
|
|
6
|
+
"purlType": "swid",
|
|
7
|
+
"componentType": "operating-system"
|
|
8
|
+
},
|
|
9
|
+
"kernel_info": {
|
|
10
|
+
"query": "select * from kernel_info;",
|
|
11
|
+
"name": "os-image",
|
|
12
|
+
"description": "Retrieves information from the current kernel in the target system.",
|
|
13
|
+
"purlType": "swid"
|
|
14
|
+
},
|
|
15
|
+
"chrome_extensions": {
|
|
16
|
+
"query": "select chrome_extensions.* from users join chrome_extensions using (uid);",
|
|
17
|
+
"description": "Retrieves the list of extensions for Chrome in the target system.",
|
|
18
|
+
"purlType": "swid"
|
|
19
|
+
},
|
|
20
|
+
"firefox_addons": {
|
|
21
|
+
"query": "select firefox_addons.* from users join firefox_addons using (uid);",
|
|
22
|
+
"description": "Retrieves the list of addons for Firefox in the target system.",
|
|
23
|
+
"purlType": "swid"
|
|
24
|
+
},
|
|
25
|
+
"browser_plugins": {
|
|
26
|
+
"query": "select browser_plugins.* from users join browser_plugins using (uid);",
|
|
27
|
+
"description": "Retrieves the list of C/NPAPI browser plugin in the target system.",
|
|
28
|
+
"purlType": "swid"
|
|
29
|
+
},
|
|
30
|
+
"ie_extensions": {
|
|
31
|
+
"query": "select ie_extensions.* from users join ie_extensions using (uid);",
|
|
32
|
+
"description": "Retrieves the list of extensions for IE in the target system.",
|
|
33
|
+
"purlType": "swid"
|
|
34
|
+
},
|
|
35
|
+
"opera_extensions": {
|
|
36
|
+
"query": "select opera_extensions.* from users join opera_extensions using (uid);",
|
|
37
|
+
"description": "Retrieves the list of extensions for opera in the target system.",
|
|
38
|
+
"purlType": "swid"
|
|
39
|
+
},
|
|
40
|
+
"safari_extensions": {
|
|
41
|
+
"query": "select safari_extensions.* from users join safari_extensions using (uid);",
|
|
42
|
+
"description": "Retrieves the list of extensions for safari in the target system.",
|
|
43
|
+
"purlType": "swid"
|
|
44
|
+
},
|
|
45
|
+
"python_packages": {
|
|
46
|
+
"query": "select * from python_packages;",
|
|
47
|
+
"description": "Python packages installed on system.",
|
|
48
|
+
"purlType": "pypi"
|
|
49
|
+
},
|
|
50
|
+
"windows_programs": {
|
|
51
|
+
"query": "select * from programs;",
|
|
52
|
+
"description": "Retrieves the list of products as they are installed by Windows Installer in the target Windows system.",
|
|
53
|
+
"purlType": "swid"
|
|
54
|
+
},
|
|
55
|
+
"windows_patches": {
|
|
56
|
+
"query": "select * from patches;",
|
|
57
|
+
"description": "Retrieves all the information for the current windows drivers in the target Windows system.",
|
|
58
|
+
"purlType": "swid"
|
|
59
|
+
},
|
|
60
|
+
"windows_drivers": {
|
|
61
|
+
"query": "select * from drivers;",
|
|
62
|
+
"description": "Retrieves all the information for the current windows drivers in the target Windows system.",
|
|
63
|
+
"purlType": "swid"
|
|
64
|
+
},
|
|
65
|
+
"windows_shared_resources": {
|
|
66
|
+
"query": "select * from shared_resources;",
|
|
67
|
+
"description": "Retrieves the list of shared resources in the target Windows system.",
|
|
68
|
+
"purlType": "swid",
|
|
69
|
+
"componentType": "data"
|
|
70
|
+
},
|
|
71
|
+
"appcompat_shims": {
|
|
72
|
+
"query": "SELECT * FROM appcompat_shims WHERE description!='EMET_Database' AND executable NOT IN ('setuphost.exe','setupprep.exe','iisexpress.exe');",
|
|
73
|
+
"description": "Appcompat shims (.sdb files) installed on Windows hosts.",
|
|
74
|
+
"purlType": "swid",
|
|
75
|
+
"componentType": "data"
|
|
76
|
+
},
|
|
77
|
+
"system_info_snapshot": {
|
|
78
|
+
"query": "SELECT * FROM system_info;",
|
|
79
|
+
"description": "System info snapshot query.",
|
|
80
|
+
"purlType": "swid",
|
|
81
|
+
"componentType": "data"
|
|
82
|
+
},
|
|
83
|
+
"pipes_snapshot": {
|
|
84
|
+
"query": "SELECT processes.path, processes.cmdline, processes.uid, processes.on_disk, pipes.name, pid FROM pipes JOIN processes USING (pid);",
|
|
85
|
+
"description": "Pipes snapshot query.",
|
|
86
|
+
"purlType": "swid",
|
|
87
|
+
"componentType": "data"
|
|
88
|
+
},
|
|
89
|
+
"services_snapshot": {
|
|
90
|
+
"query": "SELECT * FROM services;",
|
|
91
|
+
"description": "Services snapshot query.",
|
|
92
|
+
"purlType": "swid",
|
|
93
|
+
"componentType": "data"
|
|
94
|
+
},
|
|
95
|
+
"wmi_cli_event_consumers": {
|
|
96
|
+
"query": "SELECT * FROM wmi_cli_event_consumers;",
|
|
97
|
+
"description": "WMI CommandLineEventConsumer, which can be used for persistence on Windows. See https://www.blackhat.com/docs/us-15/materials/us-15-Graeber-Abusing-Windows-Management-Instrumentation-WMI-To-Build-A-Persistent%20Asynchronous-And-Fileless-Backdoor-wp.pdf for more details.",
|
|
98
|
+
"purlType": "swid",
|
|
99
|
+
"componentType": "data"
|
|
100
|
+
},
|
|
101
|
+
"wmi_filter_consumer_binding": {
|
|
102
|
+
"query": "SELECT * FROM wmi_filter_consumer_binding;",
|
|
103
|
+
"description": "Lists the relationship between event consumers and filters.",
|
|
104
|
+
"purlType": "swid",
|
|
105
|
+
"componentType": "data"
|
|
106
|
+
},
|
|
107
|
+
"wmi_cli_event_consumers_snapshot": {
|
|
108
|
+
"query": "SELECT * FROM wmi_cli_event_consumers;",
|
|
109
|
+
"description": "Snapshot query for WMI event consumers.",
|
|
110
|
+
"purlType": "swid",
|
|
111
|
+
"componentType": "data"
|
|
112
|
+
},
|
|
113
|
+
"certificates": {
|
|
114
|
+
"query": "SELECT * FROM certificates WHERE path != 'Other People';",
|
|
115
|
+
"description": "List all certificates in the trust store.",
|
|
116
|
+
"purlType": "swid",
|
|
117
|
+
"componentType": "data"
|
|
118
|
+
},
|
|
119
|
+
"wmi_event_filters": {
|
|
120
|
+
"query": "SELECT * FROM wmi_event_filters;",
|
|
121
|
+
"description": "Lists WMI event filters.",
|
|
122
|
+
"purlType": "swid",
|
|
123
|
+
"componentType": "data"
|
|
124
|
+
},
|
|
125
|
+
"etc_hosts": {
|
|
126
|
+
"query": "SELECT * FROM etc_hosts;",
|
|
127
|
+
"description": "List the contents of the Windows hosts file.",
|
|
128
|
+
"purlType": "swid",
|
|
129
|
+
"componentType": "data"
|
|
130
|
+
},
|
|
131
|
+
"scheduled_tasks": {
|
|
132
|
+
"query": "SELECT * FROM scheduled_tasks;",
|
|
133
|
+
"description": "List all scheduled_tasks.",
|
|
134
|
+
"purlType": "swid",
|
|
135
|
+
"componentType": "data"
|
|
136
|
+
},
|
|
137
|
+
"chocolatey_packages": {
|
|
138
|
+
"query": "SELECT * FROM chocolatey_packages;",
|
|
139
|
+
"description": "List all chocolatey_packages.",
|
|
140
|
+
"purlType": "chocolatey"
|
|
141
|
+
},
|
|
142
|
+
"npm_packages": {
|
|
143
|
+
"query": "SELECT * FROM npm_packages;",
|
|
144
|
+
"description": "List all npm_packages.",
|
|
145
|
+
"purlType": "npm"
|
|
146
|
+
},
|
|
147
|
+
"atom_packages": {
|
|
148
|
+
"query": "SELECT * FROM atom_packages;",
|
|
149
|
+
"description": "List all atom_packages.",
|
|
150
|
+
"purlType": "atom"
|
|
151
|
+
},
|
|
152
|
+
"startup_items": {
|
|
153
|
+
"query": "SELECT * FROM startup_items;",
|
|
154
|
+
"description": "List all startup_items.",
|
|
155
|
+
"purlType": "swid",
|
|
156
|
+
"componentType": "data"
|
|
157
|
+
},
|
|
158
|
+
"routes": {
|
|
159
|
+
"query": "SELECT * FROM routes;",
|
|
160
|
+
"description": "List all routes.",
|
|
161
|
+
"purlType": "swid",
|
|
162
|
+
"componentType": "data"
|
|
163
|
+
},
|
|
164
|
+
"listening_ports": {
|
|
165
|
+
"query": "SELECT * FROM listening_ports;",
|
|
166
|
+
"description": "List all listening_ports.",
|
|
167
|
+
"purlType": "swid",
|
|
168
|
+
"componentType": "data"
|
|
169
|
+
},
|
|
170
|
+
"processes": {
|
|
171
|
+
"query": "SELECT * FROM processes;",
|
|
172
|
+
"description": "List all processes.",
|
|
173
|
+
"purlType": "swid",
|
|
174
|
+
"componentType": "data"
|
|
175
|
+
},
|
|
176
|
+
"process_open_sockets": {
|
|
177
|
+
"query": "SELECT * FROM process_open_sockets;",
|
|
178
|
+
"description": "List all process_open_sockets.",
|
|
179
|
+
"purlType": "swid",
|
|
180
|
+
"componentType": "data"
|
|
181
|
+
},
|
|
182
|
+
"windows_update_history": {
|
|
183
|
+
"query": "SELECT * FROM windows_update_history;",
|
|
184
|
+
"description": "List all windows_update_history.",
|
|
185
|
+
"purlType": "swid",
|
|
186
|
+
"componentType": "data"
|
|
187
|
+
},
|
|
188
|
+
"windows_optional_features": {
|
|
189
|
+
"query": "SELECT * FROM windows_optional_features;",
|
|
190
|
+
"description": "List all windows_optional_features.",
|
|
191
|
+
"purlType": "swid",
|
|
192
|
+
"componentType": "data"
|
|
193
|
+
},
|
|
194
|
+
"windows_firewall_rules": {
|
|
195
|
+
"query": "SELECT * FROM windows_firewall_rules;",
|
|
196
|
+
"description": "List all windows_firewall_rules.",
|
|
197
|
+
"purlType": "swid",
|
|
198
|
+
"componentType": "data"
|
|
199
|
+
}
|
|
200
|
+
}
|