Repository navigation
fix: recover SBOM components from monolithic non-ELF firmware - #34
Merged
Merged
Conversation
scan_binver was gated behind is_elf(), so a statically-linked image with no
ELF member (proprietary-OS / RTOS single-blob firmware) produced an empty
SBOM and empty CVE result even with a clear component banner present.
Scan non-ELF bytes too, but only when the whole tree is monolithic (no ELF
anywhere) and only with the distinctive-anchor signatures (raw_safe). A tree
with any ELF keeps the ELF-only behavior, so filesystem-based images are
unchanged, and zlib's ordinary-word anchors ("inflate "/"deflate ") stay
ELF-gated. The strict version patterns, including the openssl build-date
requirement (issue #7), are unchanged; this only lifts the restriction on
where they run.
Recovers e.g. OpenSSL from a monolithic router image (0 components -> openssl
plus its CVEs) while leaving every filesystem-based image byte-identical
across all passes. Covered by unit checks (the raw_safe subset, strict-date
rejection, ELF-path unchanged) and an integration test (monolithic recovery,
ELF-present skip, malformed/zlib rejection).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #33
Problem
scan_binverreturned immediately on non-ELF input, so the component version-banner matcher (openssl, busybox, dropbear, the TLS libs, ...) only ran on ELF files. Firmware shipped as a single statically-linked non-ELF image (proprietary-OS / RTOS routers, monolithic MCU images) got an empty SBOM, and the CVE pass reported nothing downstream of it, even when the image carried a clear version banner.Fix
Scan non-ELF bytes too, gated two ways so filesystem-based images are untouched:
scan_binvertakes ascan_nonelfflag;walk.cppsets it only when the tree has no ELF member anywhere (a cheap first-4-bytes peek, short-circuited on the first ELF). A tree with any ELF keeps the current ELF-only behavior.raw_safeflag; on raw bytes only the distinctive-anchor banners run. zlib (inflate/deflate, ordinary words) stays ELF-gated until it gets its own raw-bytes FP check.The strict version patterns are unchanged, including the openssl build-date requirement (issue #7): a corrupted-date banner is still rejected, not emitted with a bogus version. This change only lifts the ELF-only restriction on where the existing patterns run.
Result
On a monolithic router image carrying
OpenSSL 0.9.7b 10 Apr 2003, the SBOM goes from 0 components toopenssl 0.9.7b, and the CVE pass surfaces 75 matched CVEs (9 high-signal). A second monolithic image (OpenSSL 1.0.1j 15 Oct 2014) recovers likewise.Across a set of filesystem-based firmware images (jffs2 / ubi / full-flash, including one with 263 components), the component / CVE / secret / license / boot / key counts are byte-for-byte identical before and after, confirming filesystem trees are unaffected.
Tests
raw_safesubset (zlib stays ELF-gated on raw bytes, recovered inside an ELF), strict-date rejection on the raw path, the default (filesystem) path unchanged.test_sbom.py): a synthetic monolithic image recovers busybox + openssl; the same blob next to an ELF is not raw-scanned; malformed-date and zlib banners are rejected.