
mithril statically analyzes the contents of firmware and IoT software for embedded secrets, a firmware-aware SBOM, matched CVEs, licenses, and boot-security posture, entirely offline.
| Tool | nmatt0/mithril — offline static scanner for firmware contents: secrets, SBOM, CVEs, licenses, boot security, and weak public keys |
| Category | firmware / IoT static analysis and vulnerability scanning |
| Primary Use | Auditing unpacked firmware images during authorized IoT assessments: extracting secrets, generating CycloneDX/SPDX SBOMs, and matching components against a local CVE mirror |
| Safe Use | Intended for authorized penetration tests, firmware security reviews, and defensive supply-chain audits in lab environments; the tool itself performs no exploitation and makes no network calls at scan time |
| Telemetry Note | mithril is read-only and offline: only --fetch-db and --update-db touch the network, so defenders monitoring an engagement will see no scanning traffic — evidence of its use lives in the operator's filesystem, local database, and JSON output artifacts |
mithril from nmatt0 is a C++ static analyzer that examines the contents of firmware and IoT software — either a single file or an unpacked rootfs — rather than its container format. Where most firmware toolchains stop at identification and extraction, mithril picks up at the semantic layer: it hunts for embedded secrets and keys, reconstructs a software bill of materials, joins that SBOM against a local CVE mirror, identifies open-source licenses, and profiles boot-security posture across U-Boot environments, device trees, and FIT/AVB/UEFI verified boot. Every finding ships with its evidence and a confidence level, and the tool emits clean JSON via -j so scripts and LLM agents can consume it as readily as humans. At 334 stars and MIT-licensed, it is an actively documented project with an unusually precise README.
The README is explicit about the division of labor: mithril is the semantic companion to moria, which identifies and unpacks firmware. The canonical pipeline is moria -e firmware.bin producing a firmware.bin.extracted/ tree, then mithril firmware.bin.extracted/ over its contents. Importantly, there is no build-time dependency on moria — you can point mithril at any file or directory from any extraction workflow. This clean boundary means the tool slots into existing firmware assessment pipelines without forcing a toolchain swap, and the README's docs/engine-design.md documents how discovery actually works internally.
The SBOM pass is where mithril distinguishes itself from generic scanners. Beyond the obvious package databases (dpkg, opkg, apk, rpm), it recovers components from ELF version banners, versioned libc filenames, and the kernel banner — meaning it will identify openssl, busybox, or uClibc even in a stripped image with no package manager at all. Components are keyed on purl with CPE co-derived, and standard-format bills are written as sbom.cdx.json and sbom.spdx.json when you pass -C/--outdir. For auditors facing vendor firmware that ships as a bare squashfs with zero package metadata, this recovery layer is the difference between a real inventory and an empty report.
The CVE pass is deliberately designed to be owned end to end. It reads a local mirror under ~/.local/share/mithril/ (honoring $MITHRIL_DB), a compact memory-mapped index built from OSV.dev, the NVD 2.0 API, the CISA KEV catalog, and FIRST's EPSS scores. Matches record their certainty — exact version versus affected range versus CPE — stay release-precise where /etc/os-release allows, and are annotated with KEV and EPSS context. Kernel CVEs are triaged through a curated, version- and kconfig-gated checklist by default, with an opt-in --kernel-cves-full flag that lists every kernel.org CVE for the detected version, matched branch-aware. The README is refreshingly honest about scope: an empty kernel result means none of the curated set is in range, not that the kernel is clean.
That honesty extends into the secrets engine, which the README describes as riding a deterministic offline ladder: pattern for shape, then structural for parsed artifacts like a JWT or PEM key, then validated for recomputed checksums such as GitHub tokens and crypt hashes. mithril asserts well-formed, never live — it makes no network calls to verify a credential actually works, which is both a safety property and an operational constraint worth understanding. /etc/shadow and htpasswd hashes get classified with weak-algorithm and empty-password flags, and high-entropy KEY=… values, cloud keys, and private keys round out the scope. An empty result is framed as a real answer rather than a tool failure.
The --keys pass is arguably the most technically interesting component. For every recovered public key — certificates, SSH host and authorized keys, embedded keys — the tool checks whether the private half is obtainable. That includes fingerprint matches against a compiled-in corpus of hardcoded keys whose private half is public (the rapid7 ssh-badkeys set, the Vagrant insecure key, the compromised eMudhra intermediate CAs), the ROCA fingerprint check (CVE-2017-15361), undersized or broken RSA, and factoring recoveries: Fermat close primes, batch-GCD shared primes across the image, and Wiener small-d attacks. There is even an elliptic-curve analog that recovers near-zero EC private scalars via a bounded d*G search. All of this runs through a small in-tree bignum implementation, and the README is right to frame a hit as impersonation, login, or forgery rather than a mere cipher-suite weakness.
Network hygiene is a first-class design constraint. A scan makes no network calls at all; secrets, SBOM, and license analysis are fully offline, and only two commands ever touch the wire: mithril --fetch-db downloads a prebuilt, SHA-256-verified index rebuilt weekly, and mithril --update-db rebuilds the index from upstream feeds yourself if you want full control over provenance. Setting $NVD_API_KEY raises the NVD rate limit during rebuilds, and $MITHRIL_DB_URL lets you point at a mirror. The tool is explicitly air-gappable, which is exactly what you want when analyzing hostile vendor firmware or working in segmented lab environments. It is also engineered to be safe on hostile input: untrusted bytes flow through one bounds-checked reader, parsers degrade to clean errors rather than crashes, and the CVE index is memory-mapped so a scan never parses the whole database.
The boot-security pass (--boot) extracts defensive intelligence rather than exploitable findings: U-Boot environment variables, device tree details, FIT/AVB verified-boot state, and UEFI Secure Boot posture — the latter even from a raw AMI/EDK2 BIOS image, with details in docs/boot-security.md. For an assessor writing up whether a device can be modified persistently, this single pass answers questions that would otherwise require manual binwalk spelunking and device-tree cross-referencing. The license pass rounds things out with SPDX identification from SPDX-License-Identifier tags and LICENSE/COPYING/NOTICE text, useful for compliance review of vendor images.
Installation is refreshingly lean for a C++ project: no third-party libraries, just cmake -S . -B build -DCMAKE_BUILD_TYPE=Release, cmake --build build -j, and cmake --install build --prefix ~/.local — or a bare cp build/mithril ~/.local/bin. A sanitizer build is available via -DMT_SANITIZE=ON. Invocation follows the same economy: mithril <file|dir> runs every pass, naming any of --secrets/--sbom/--cve/--licenses/--boot/--keys runs just those, and mithril -j <dir> produces machine-readable output. Custom detection rules can be layered in with --rules my.json per docs/user-rules.md.
The default human CVE view is opinionated triage rather than exhaustive listing: only foothold-worthy component CVEs appear — those on CISA KEV, Critical-severity, or a hard floor of CVSS >= 7.0 with EPSS traction, low attack complexity, and real impact or a trending remote DoS — sorted worst-first. Mediums, local DoS, and high-complexity crypto issues are dropped unless you opt in with --component-cves-full. For authorized assessors prioritizing where to spend limited engagement hours, that curation philosophy mirrors how a senior operator would triage manually, and the JSON output always carries the complete set plus a component_cve_scan summary so automation can re-triage freely.
Where mithril fits in an authorized workflow is straightforward: it is the analysis stage after firmware acquisition and unpacking, the tool you run once you have bytes on disk and need to know what is inside them before touching the device. Its offline posture, hostile-input hardening, evidence-bearing findings, and confidence model make it equally valuable to defensive teams doing vendor risk assessment and supply-chain audit — generating an SPDX/CycloneDX SBOM from shipped firmware is a legitimate procurement and vulnerability-management activity that needs no engagement at all. The pairing with moria, the curated kernel checklist, and the leaked-key corpus all signal an author who has done real firmware work and encoded the tedious parts into a fast, reproducible binary.
nmatt0/mithril.Educational analysis for authorized security professionals. Use only in controlled, authorized environments.
Related coverage
0 comentários:
Post a Comment
Note: Only a member of this blog may post a comment.