Generate a CycloneDX SBOM directly from an unpacked firmware root filesystem and flag components with known CVEs and EOL kernels.
IoT / OT / Embedded — firmware, buses, and device security.
pip install cognis-sbomb
sbomb scan . # → prioritized findings in seconds
Real, reproducible output from the tool — runs offline:
$ sbomb-emit --version
sbomb 0.1.0$ sbomb-emit --help
usage: sbomb [-h] [--version] {scan,match,feeds,mcp} ...
Generate a CycloneDX SBOM from an unpacked firmware rootfs and flag known-vuln components.
positional arguments:
{scan,match,feeds,mcp}
scan Scan an unpacked rootfs and emit an SBOM.
match Match components against the bundled 262k-record
offline OSV DB.
feeds Manage the bundled threat/vuln data feeds (osv, cisa-
kev).
mcp Run the MCP server (exposes scan/match/cve as agent
tools).
options:
-h, --help show this help message and exit
--version show program's version number and exit
examples:
# Human-readable table of components + vulns
sbomb scan ./rootfs
# CycloneDX JSON SBOM to stdout (pipe into CI / other tools)
sbomb scan ./rootfs --format json > sbom.json
# Write SBOM to a file and use as a CI gate (exit 1 if vulns found)
sbomb scan ./rootfs -o sbom.json && echo CLEAN
# Use your own offline vuln DB
sbomb scan ./rootfs --vuln-db my_cves.json --format jsonBlocks above are real
sbomboutput — reproduce them from a clone.
Sample result format (illustrative values — run on your own data for real findings):
{
"findings": [
{
"id": "123456",
"title": "Suspicious Network Traffic",
"description": "Potential malicious activity detected on port 443",
"created_by": "sbomb",
"created_at": "2023-02-15T14:30:00Z",
"updated_at": "2023-02-15T14:30:00Z"
}
]
}
- Why sbomb? · Features · Quick start · Example · Bundled 262k vuln DB · Data feeds · Architecture · AI stack · How it compares · Ports · Integrations · Install anywhere · Related · Contributing
sbomb walks an unpacked firmware rootfs, discovers components (dpkg/opkg/apk/os-release/busybox/python/npm), emits a CycloneDX SBOM, and flags known-vuln components. Exit 1 when vulns are found (unless suppressed).
-
Install
pip install sbomb
-
Scan an unpacked rootfs for a component + vuln table:
sbomb scan ./rootfs
-
Emit a CycloneDX 1.5 SBOM to stdout or a file:
sbomb scan ./rootfs --format json > sbom.json sbomb scan ./rootfs -o sbom.json -
Use your own offline vuln DB, or inventory only with
--no-vuln:sbomb scan ./rootfs --vuln-db my_cves.json --format json
-
Emit SARIF 2.1.0 for GitHub code-scanning / generic SAST ingestion:
sbomb scan ./rootfs --format sarif -o results.sarif # then upload results.sarif via github/codeql-action/upload-sarif -
Use in CI — the non-zero exit on vulns fails the build;
--no-failmakes it advisory-only:sbomb scan ./rootfs -o sbom.json || echo "known-vuln components present"
-
Match components against the bundled 262k-record OSV corpus (fully offline — see Bundled vulnerability database):
sbomb match ./rootfs # advisories per detected component sbomb match -p log4j-core # a single package sbomb match --cve CVE-2021-44228 # direct CVE/GHSA lookup
-
Serve sbomb to an AI agent over MCP (optional
mcpextra):pip install "cognis-sbomb[mcp]" && sbomb mcp # exposes sbomb_scan / sbomb_match / sbomb_cve
Regulatory tailwind (EU CRA / FDA premarket SBOM mandates) — single binary that turns a squashfs into a compliance artifact. Compliance-deadline urgency drives adoption.
sbomb is single-purpose, scriptable, and self-hostable: point it at a target, get prioritized results in the format your workflow already speaks (table · JSON · SARIF), gate CI on it, and let agents drive it over MCP.
-
✅ Version Compare
-
✅ Detect Dpkg
-
✅ Detect Opkg
-
✅ Detect Apk
-
✅ Detect Os Release
-
✅ Detect Busybox
-
✅ Detect Python Packages
-
✅ Detect Node Packages
-
✅ CISA KEV + OSV data-feed enrichment (edge / air-gap, offline-capable)
-
✅ Bundled 262,351-record real OSV corpus + offline
matchsubcommand (sbomb match, no network) -
✅ MCP server (
sbomb mcp) — drive scan/match/CVE-lookup from any AI agent -
✅ Runs on Linux/macOS/Windows · Docker · devcontainer
-
✅ Real, CI-verified ports in Python, JavaScript, Go, and Rust (
ports/) — each does the full rootfs→SBOM→CVE scan, not a stub
pip install cognis-sbomb
sbomb --version
sbomb scan . # scan current project
sbomb scan . --format json # machine-readable
sbomb scan . --fail-on high # CI gate (non-zero exit)
$ sbomb scan demos/02-debian-router/rootfs
COMPONENT VERSION SOURCE VULNS
---------------------------------------------
base-files 11.1+deb11u5 dpkg -
curl 7.74.0-1.3+deb11u3 dpkg CVE-2022-32207(critical)
dropbear 2022.83-1 dpkg -
openssl 1.1.1k-1+deb11u1 dpkg CVE-2021-3711(critical)
zlib1g 1:1.2.13.dfsg-1 dpkg -
5 components, 2 vulnerability finding(s). # exit code 1 (CI gate)
Eight runnable, verified scenarios live under demos/ — each is
a realistic unpacked firmware rootfs in the tool's real input formats plus a
SCENARIO.md (where the data came from, the run command, expected findings,
how to act). Every demo is exercised by tests/test_demos.py.
| Demo | Source | Outcome |
|---|---|---|
01-basic |
opkg + apk + python | openssl + zlib (exit 1) |
02-debian-router |
dpkg | openssl + curl (exit 1) |
03-alpine-ipcam |
apk | openssl 3.0.5 "Spooky SSL" (exit 1) |
04-busybox-banner |
busybox binary banner | busybox 1.31.1 (exit 1) |
05-node-gateway |
npm (nested) | vendored Log4Shell (exit 1) |
06-clean-device |
opkg (patched) | 0 findings (exit 0) |
07-custom-vulndb |
dpkg + opkg + --vuln-db |
org-policy DB (exit 1) |
08-multidistro |
every detector | 2 criticals (exit 1) |
09-feed-enrichment |
npm + CISA KEV + OSV (offline) | Log4Shell tagged [KEV], +OSV advisories |
python -m sbomb scan demos/05-node-gateway/rootfs # Log4Shell in node_modules
python -m sbomb scan demos/06-clean-device/rootfs # clean -> exit 0
python -m sbomb scan demos/03-alpine-ipcam/rootfs --format sarif -o cam.sarif
# offline data-feed enrichment (see "Data feeds" below)
COGNIS_FEEDS_CACHE=tests/fixtures/feeds \
python -m sbomb scan demos/05-node-gateway/rootfs --osv --kev --offlinesbomb ships sbomb/cognis_vulndb.jsonl.gz — 262,351 real vulnerability
records consolidated from OSV.dev across PyPI, npm, Go,
Maven, RubyGems, crates.io and NuGet. Each record carries its OSV/GHSA id,
CVE aliases, ecosystem, summary, CVSS severity vector, affected packages and
dates. The loader (sbomb/vulndb_local.py, VulnDB) is pure standard
library and reads the gzip directly — no network, no API key, no extra
deps — so it works the moment the repo is cloned and on fully air-gapped gear.
sbomb match ./rootfs # match every detected component
sbomb match -p log4j-core # match a single package
sbomb match --cve CVE-2021-44228 # look a CVE/GHSA up directly
sbomb match ./rootfs --format json # machine-readable
sbomb match ./rootfs --ecosystem-strict # cut cross-ecosystem name collisionsWorked example — Log4Shell really resolves out of the bundled corpus:
$ sbomb match -p log4j-core
Matched 1 component(s) against 262,351 bundled OSV records.
log4j-core [any] — 11 advisory(ies)
CVE-2021-44228 Maven Remote code injection in Log4j
CVE-2021-45046 Maven Incomplete fix for Apache Log4j vulnerability
CVE-2021-45105 Maven Improper Input Validation / Uncontrolled recursion
CVE-2021-44832 Maven Improper Input Validation and Injection in Apache Log4j2
CVE-2017-5645 Maven Deserialization of Untrusted Data in Log4j
...
1 component(s) carry 11 advisory(ies). # exit code 1 (CI gate)
from sbomb.vulndb_local import VulnDB
db = VulnDB()
db.count() # -> 262351
db.by_cve("CVE-2021-44228") # -> the Log4Shell Maven record
db.by_package("log4j-core") # -> short name resolves the group:artifact idTwo complementary matchers ship in the box:
| Matcher | Source | Version-gated? | Use |
|---|---|---|---|
sbomb scan (curated DB) |
core.DEFAULT_VULN_DB + --vuln-db |
✅ yes (range logic) | precise "this exact version is vulnerable" CI gate |
sbomb match (bundled corpus) |
cognis_vulndb.jsonl.gz (262k) |
name-level (advisories that name the package) | breadth — surface every advisory touching a component, offline |
Refresh / extend the corpus at the edge from NVD / OSV / GHSA with
python -m sbomb.datafeeds bulk (see the air-gap workflow below).
sbomb ships a standard-library ingestion layer (sbomb/datafeeds.py +
sbomb/feeds.py, catalog in sbomb/data_feeds_2026.json) that pulls real,
keyless, public vulnerability intelligence over HTTPS, caches it to disk, and
re-serves it offline so the tool keeps working on disconnected / edge /
air-gapped gear. This repo consumes two feeds from the catalog:
| Feed id | Source | URL | Use |
|---|---|---|---|
cisa-kev |
CISA Known Exploited Vulnerabilities | https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json |
Tag matched CVEs that are actively exploited ([KEV]); escalate them to SARIF error / security-severity 10.0 |
osv |
OSV.dev vulnerability query | https://api.osv.dev/v1/query |
Discover additional advisories per detected component (PyPI/npm/Debian/Alpine), beyond the bundled offline DB |
sbomb scan ./rootfs --kev # tag KEV-listed (actively-exploited) CVEs
sbomb scan ./rootfs --osv # add OSV.dev advisories per component
sbomb scan ./rootfs --osv --kev # bothKEV markers ride through to the outputs: a sbomb:known_exploited property on
the CycloneDX vulnerability, and a known-exploited tag + security-severity 10.0 + error level on the SARIF result (so GitHub code-scanning surfaces it
at the top).
sbomb feeds list # this tool's relevant feeds + cache age
sbomb feeds update cisa-kev # fetch + cache the live KEV catalog
sbomb feeds get cisa-kev --offline # print cached content, no network
sbomb feeds snapshot-export feeds.tar.gz # tar the cache for sneakernet
sbomb feeds snapshot-import feeds.tar.gz # load it on the air-gapped boxThe catalog is filtered to this tool's domain — feeds list/get only expose
cisa-kev and osv; other catalog feeds are rejected.
- On a connected host:
sbomb feeds update cisa-kevwarms the cache (COGNIS_FEEDS_CACHE, default~/.cache/cognis-feeds). OSV is a per-package query feed, so it is cached on demand duringscan --osv. sbomb feeds snapshot-export feeds.tar.gztars the cache flat.- Sneakernet the tarball into the disconnected enclave.
sbomb feeds snapshot-import feeds.tar.gz, then run any scan with--offline— feed data is served from the local cache and the network is never touched.
Tests are fully offline: tests/test_feeds.py points COGNIS_FEEDS_CACHE
at committed trimmed fixtures (tests/fixtures/feeds/) and asserts the network
is never reached.
flowchart LR
IN[target / manifest] --> P[sbomb<br/>checks + rules]
P --> OUT[findings (JSON / SARIF)]
sbomb is interoperable with every popular way of using AI:
-
MCP server —
sbomb mcp(Claude Desktop, Cursor, Cognis.Studio, uncensored-fleet) -
OpenAI-compatible / JSON — pipe
sbomb scan . --format jsoninto any agent or LLM -
LangChain · CrewAI · AutoGen · LlamaIndex — wrap the CLI/JSON as a tool in one line
-
CI / scripts — exit codes + SARIF for non-AI pipelines
The same firmware-rootfs scan surface is ported to JavaScript/Node, Go, and
Rust alongside the Python reference. These are not stubs: each port walks a
rootfs, runs every detector (dpkg/opkg/apk/os-release/busybox/python/npm),
matches against an embedded real-CVE DB with identical version-range logic, and
emits the same CycloneDX 1.5 shape — exiting 1 when vulns are found.
node ports/javascript/index.js ./rootfs # Node
cd ports/go && go run . ../../rootfs # Go (single static binary)
cd ports/rust && cargo run -- ../../rootfs # RustEvery port has its own test suite against the real demos/ fixtures, and all
three are built + tested on every push by
.github/workflows/ports.yml. See
ports/README.md.
| | Cognis sbomb | syft + cve-bin-tool |
|---|:---:|:---:|
| Self-hostable, no account | ✅ | varies |
| Single command, zero config | ✅ |
| JSON + SARIF for CI | ✅ | varies |
| MCP-native (AI agents) | ✅ | ❌ |
| Polyglot ports (JS/Go/Rust) | ✅ | ❌ |
| Open license | ✅ COCL | varies |
Built in the spirit of syft + cve-bin-tool, re-framed the Cognis way. Missing a credit? Open a PR.
Pipes into your stack: SARIF for code-scanning, JSON for anything, an MCP server (sbomb mcp) for AI agents, and a webhook forwarder for SIEM/Slack/Jira. See docs/INTEGRATIONS.md.
pip install "git+https://github.com/cognis-digital/sbomb.git" # pip (works today)
pipx install "git+https://github.com/cognis-digital/sbomb.git" # isolated CLI
uv tool install "git+https://github.com/cognis-digital/sbomb.git" # uv
pip install cognis-sbomb # PyPI (when published)
docker run --rm ghcr.io/cognis-digital/sbomb:latest --help # Docker
brew install cognis-digital/tap/sbomb # Homebrew tap
curl -fsSL https://raw.githubusercontent.com/cognis-digital/sbomb/main/install.sh | sh
| Linux | macOS | Windows | Docker | Cloud |
|---|---|---|---|---|
| scripts/setup-linux.sh | scripts/setup-macos.sh | scripts/setup-windows.ps1 | docker run ghcr.io/cognis-digital/sbomb | DEPLOY.md (AWS/Azure/GCP/k8s) |
-
fwxray— Diff two firmware images and surface exactly what changed: new binaries, flipped config flags, added certs, and shifted entropy regions. -
canzap— Replay, fuzz, and assert on CAN bus traffic from a .pcap or SocketCAN interface with a tiny YAML DSL. -
mqttspy— Passively map an MQTT broker: enumerate topics, detect unauthenticated writes, spot PII/secrets in payloads, and emit a risk report. -
uefiscan— Audit UEFI firmware dumps for missing Secure Boot keys, unsigned modules, S3 boot-script vulns, and known SMM threats. -
modpot— Spin up a high-interaction Modbus/DNP3 ICS honeypot that logs attacker register reads/writes as structured JSON. -
keyhunt— Scan firmware blobs and filesystem dumps for hardcoded private keys, API tokens, default creds, and weak RSA/ECC material.
Explore the suite → 🗂️ all 170+ tools · ⭐ awesome-cognis · 🔗 cognis-sources · 🤖 uncensored-fleet · 🧠 engram
PRs, new rules, and demo scenarios are welcome under the collaboration-pull model — see CONTRIBUTING.md and SECURITY.md.
{} composes with the 300+ tool Cognis suite — JSON in/out and a shared
OpenAI-compatible /v1 backbone. See INTEROP.md for the
suite map, composition patterns, and reference stacks.
Source-available under the Cognis Open Collaboration License (COCL) v1.0 — free for personal, internal-evaluation, research, and educational use; commercial / production use requires a license (licensing@cognis.digital). See LICENSE.
See Bundled vulnerability database — 262k real OSV records
above for the full write-up: sbomb/cognis_vulndb.jsonl.gz ships 262,351
real OSV vulnerabilities (PyPI/npm/Go/Maven/RubyGems/crates.io/NuGet) with
CVE/GHSA aliases, ecosystem, CVSS severity, affected packages and dates,
queried offline via the sbomb match subcommand or the pure-stdlib
vulndb_local.VulnDB loader (count/by_cve/by_package/search).