Check our work before you trust it
Your engineers and your lab will ask how a result was reached. These are the formats, processors, checks, rules and limits behind each analysis, so they can check it themselves.
On this page
Will it read our firmware image?
A tool that cannot open your image finds nothing, often without saying so. Images of up to 8 GiB are unpacked by the firmware engine's own readers, without external unpacking tools; every file system found is analysed, and what cannot be read is named.
| Family | Formats |
|---|---|
| Flash file systems | SquashFS 2 to 4 with every compression, UBI and UBIFS, and YAFFS2 |
| Disk images | ext4, FAT and EROFS, with MBR and GPT partition tables |
| Archives | cpio, tar, ZIP and Microsoft Cabinet |
| Compression | gzip, bzip2, xz, LZMA and zstd |
| Vendor headers | uImage, TRX, D-Link, AVM EVA and Dahua ZIP removed first; file systems found behind FIT, Seama, Netgear CHK and TP-Link headers; D-Link SHRS decrypted with its published key |
| Android | OTA payloads and boot images |
| Other vendor formats | MikroTik NPK |
| Microcontroller files | Intel HEX, S-record, UF2 and DfuSe, laid out as one flat image with its entry point and interrupt handlers |
| UEFI | Firmware volumes and capsules: every module, the Secure Boot keys and the revocation list. Volumes a vendor packs in its own format, such as Dell PFS, are coverage gaps |
| Kernels and release archives | Compressed Linux kernels unpacked to read their version, a bare kernel's initramfs, and the one firmware image a vendor release archive ships |
| Tested on sample files only | JFFS2, CramFS, RomFS, ext2, ext3, 7z, Android sparse images, LZO, lz4 and heatshrink streams, Rockchip and Ambarella images: read in our tests, not yet measured on a vendor's image |
How an image is unpacked
- Known vendor headers are removed first, then every reader tries the start of the image.
- File systems at other offsets are found by their signatures, including behind FIT, Seama, Netgear CHK and TP-Link headers.
- Containers inside containers are unpacked up to six levels deep; when nothing comes out, single-byte XOR keys are tried.
- ESP32 family, ESP8266, Cortex-M, other microcontroller images and raw MIPS builds of eCos or VxWorks are analysed as a whole, with the chip, the ESP-IDF version and the interrupt handlers.
Limits and safety
- Up to 8 GiB and 250,000 files per image. What was unpacked before a limit is still analysed, and the limit is reported.
- Zip, tar and decompression bombs are refused, and links stay inside the unpacked tree.
- Device nodes, pipes and sockets are removed and setuid bits cleared. Nothing unpacked is ever run.
- A format without a reader, encrypted content or a limit reached becomes a coverage gap, with the reason.
Does it understand our chip?
Much of the risk in a camera or router sits in its compiled programs, not its files. ELF programs are read for architecture, byte order, linked libraries, imports, exports and hardening. Programs of 22 instruction sets are then disassembled within a time budget, with a call graph, pseudo-code for their functions and the functions their entry points reach. Programs past the budget and instruction sets the disassembler does not cover, such as ARC, are coverage gaps. Where a program reads untrusted input (network, environment, NVRAM settings or web form fields) and passes it to a risky call, the engine reports a possible memory-safety, format-string or command-injection issue with its confidence and the path it followed, as a lead for your team to confirm.
| Architecture | Common in | What the engine reads |
|---|---|---|
| ARM, 32-bit and Thumb | IP cameras, NVRs, gateways, Cortex-M microcontrollers | ELF programs and libraries; Cortex-M images in raw, UF2, DfuSe and Intel HEX files, by their vector table |
| AArch64 | Newer cameras, NVRs and gateways | ELF programs and libraries |
| MIPS, 32 and 64-bit, both byte orders | Routers, Wi-Fi access points, older cameras | ELF programs and libraries; raw MIPS builds of eCos, VxWorks and other RTOSes |
| Xtensa | ESP32, ESP32-S2, ESP32-S3 and ESP8266 modules | ESP application and factory images, with the ESP-IDF version and the application's name |
| RISC-V | ESP32-C and ESP32-H series | ELF programs and libraries; ESP images with the ESP-IDF version |
| PowerPC | Networking and industrial equipment | ELF programs and libraries |
| x86 and x86-64 | NVR appliances, industrial PCs | ELF programs and libraries |
| SuperH, s390x, SPARC, m68k, MicroBlaze and Nios II | Specialist and older designs | ELF programs and libraries, measured on our test builds; SuperH also on a real image |
| AVR, MSP430, 8051, PIC16, PIC18, PIC24, dsPIC and TriCore | Motor control, sensors, metering and automotive controllers | Intel HEX and S-record images with their entry point and interrupt handlers, and AVR, MSP430 and TriCore ELF programs; of a banked 8051 image, the first 64 KB |
| ARC | Specialist designs | ELF programs read for architecture and libraries; not disassembled, shown as a coverage gap |
What is inside, and is any of it vulnerable?
A flaw in a library you did not write is still your flaw at the lab. Components come from package databases first (opkg, dpkg and apk), then from each binary's version strings, linked libraries and 76 signatures for common embedded software. The Linux kernel and U-Boot are read from their banners, and ESP-IDF from an ESP image's descriptor. Components past their upstream end of life are flagged.
Components with a package URL are matched against OSV's version ranges, the others against NVD's CPE ranges. Firmware and code use the same matching, and your team's decisions are kept when the data is refreshed.
What the 64 device checks test
A check that passes on missing data gives you false confidence before the lab. A check passes only when every test behind it ran and found nothing. Each result is pass, fail, needs evidence, not applicable or unassessed, with how it was tested and its evidence. The two runtime checks need the firmware's programs to run; the four UEFI checks apply to UEFI firmware and are not applicable on other images.
| Group | Checks |
|---|---|
| Credentials and keys |
|
| Cryptography |
|
| Binary hardening |
|
| Secure boot |
|
| Updates |
|
| Attack surface |
|
| Known vulnerabilities |
|
| Scripts and web interface |
|
| Runtime behaviour |
|
Behind them: binary hardening (NX, PIE, RELRO, stack canary, FORTIFY_SOURCE, stripped symbols, RPATH), dangerous imports as review leads, YARA rules for IoT malware and documented vendor backdoors, account databases, certificates, the update path and boot chain, UART, ADB and USB serial shells, and camera checks for streams and ONVIF without authentication. Services and ports come from configuration, init scripts and the programs present, not from a scan of a running device.
Default passwords and keys left in the image
A default password or a private key shared by every device fails a lab test and lets attackers in. Evidence is masked before results leave the engine, so a secret never shows in full.
Secrets
- In images: passwords, keys and tokens in binaries, scripts and configuration; shared private keys; empty passwords, weak hashes such as MD5 crypt and extra root accounts; default camera and ONVIF accounts.
- In code: 58 credential formats recognised by their shape, plus hard-coded passwords and connection strings, in every file up to 2 MiB outside .git, node_modules and virtual environments.
Crypto
- MD4, MD5, DES, 3DES, RC2, RC4, NULL cipher suites, SSL 2 and 3, and ECB mode are flagged; an algorithm inside a crypto library is kept as information.
- Certificates with RSA keys below 2048 bits, expired dates or MD5 and SHA-1 signatures are flagged.
- In source, mbedTLS, wolfSSL and OpenSSL settings that allow SSL 3.0 to TLS 1.1, weak cipher suites or test-only entropy are found.
What we read in your source code
Your source and build settings decide much of what ships in the image. 1,774 rules in 34 families, referencing 237 CWE entries; 322 of them trace untrusted input to a dangerous call, across files and up to three calls deep. The counts describe the engine's rules, not a detection rate.
| Family | What the rules look for | Rules |
|---|---|---|
| C | Selected memory, bounds, integer, format-string, command injection, wire-length copy, hidden shell, hard-coded credential and unsigned update patterns | 90 |
| C++ | Selected memory, bounds, filesystem, casts, concurrency, command injection, wire-length copy, hidden shell, hard-coded credential and unsigned update patterns | 91 |
| Lua and LuCI | Request input reaching shell commands, file paths, loaded code and pages in LuCI handlers and templates | 8 |
| ucode | Request input reaching shell commands and pages in OpenWrt ucode handlers | 2 |
| Shell scripts | CGI scripts that run request input, init scripts that open root shells, telnet or debuggers, blank-password logins, updates over plain HTTP, TFTP or FTP, eval, download-and-run, TLS and permission patterns | 24 |
| PHP | Selected Laravel and Symfony input handling, file upload, PDO, open redirect, session, shell script and mail argument patterns | 128 |
| JavaScript | Selected Node/Express input, template engine, prototype pollution, account route, quota, cache and device web interface patterns | 174 |
| Python | Selected web input (Django, Flask, FastAPI and others), file upload, ORM, serialization, cryptography, WebSocket origin and MicroPython device patterns | 190 |
| Rust | Selected unsafe code, input, process and filesystem patterns | 86 |
| Go | Selected standard-library, HTTP input (net/http, Gin, Echo, Fiber), GraphQL argument, SQL and session-lifecycle patterns | 131 |
| Kconfig | Linux kernel, U-Boot, BusyBox, Buildroot, ESP-IDF, Zephyr and MCUboot build configuration: signed boot and updates, flash encryption, hardening flags, debug shells and stubs, telnet, FTP and TFTP servers, root logins and TLS settings | 51 |
| Yocto and BitBake | Recipes, layers and image configuration: checksums not enforced, sources or shared state fetched without verification, telnet or rsh servers, remote debugging agents, root without a password and passwords set in clear | 12 |
| Build flags | Makefiles, CMake and Meson builds that turn off the stack protector, FORTIFY_SOURCE, PIE or RELRO, mark the stack executable, or download code over plain HTTP or with certificate checks off | 11 |
| Device trees and boot scripts | Device tree boot arguments, bootloader environments and boot scripts that start a root shell, and debug ports or debuggers left enabled | 3 |
| OpenWrt UCI | Shipped OpenWrt configuration: Dropbear root password logins and listening on every interface, WAN input accepted, the web interface over plain HTTP, open UPnP, weak or open Wi-Fi, Wi-Fi passwords in the image and consoles without a login | 9 |
| Device daemons | Telnet, inetd, FTP, Dropbear, dnsmasq, SNMP and device web server settings, Wi-Fi with WEP, WPA1, TKIP, a static WPS PIN or WPA3 without frame protection, firewall defaults, console root shells and services run as root | 35 |
| TLS library settings | mbedTLS, wolfSSL and OpenSSL settings: SSL 3.0 to TLS 1.1, NULL, RC4, 3DES and other weak cipher suites, small curves, test-only entropy, unchecked certificate dates and static key exchange | 17 |
For your companion app, cloud backend and their infrastructure
- Java174
- TypeScript167
- Kotlin113
- Dockerfile26
- Docker Compose16
- GitHub Actions27
- Dependency manifests21
- nginx28
- HTTP headers27
- Android manifest18
- CI pipelines16
- SSH configuration21
- HTML16
- Jenkins15
- PHP configuration13
- PHP templates6
- JavaScript templates8
Dependencies are read from manifests and lockfiles for npm, Go, PyPI, crates.io, Maven, Packagist, Conan. Firmware trees are read as firmware: OpenWrt's target/linux and a root file system's bin folders as source, init and CGI scripts without a .sh extension as shell, inline scripts in device web pages as JavaScript, and Arduino sketches as C++. Every scan says what it read, what it skipped and why. Nothing in the code is run, and the source is deleted once its scan finishes unless your agreement sets a period.
Running the firmware, in our lab
Emulation runs the firmware instead of only reading it. FDIE boots a whole Linux image under QEMU, checks that the device answers on the network, starts its services (web, SSH, telnet) and checks them live: open ports, web and TLS settings, default passwords, UPnP, SNMP and telnet. It also runs the image's programs one by one in a sandbox, and boots ESP32, ESP32-S3, ESP32-C3 and Cortex-M microcontroller firmware to its main loop.
An image encrypted with no public key runs once you give its key. ESP8266, ESP32-S2, ESP32-C2, ESP32-C5, ESP32-C6 and ESP32-P4 chips have no emulator yet, and files that are not firmware are reported as such. These are lab results, not a promise for every image.
Which requirements the checks decide, and which need you
No tool decides every requirement from a firmware file, and you should know which ones are left to you. Each framework's provisions in the app, by what decides them: the device checks alone, the checks with evidence from you, what the app already holds about the product, or your evidence alone.
| Framework | Provisions | Device checks | Checks help | Product data | Your evidence |
|---|---|---|---|---|---|
| TEC 31318 | 21 | 6 | 4 | 0 | 11 |
| Security of CCTV (ER: 01) | 30 | 4 | 8 | 1 | 17 |
| NCCS ITSAR | 312 | 5 | 73 | 0 | 234 |
| Cyber Resilience Act | 22 | 8 | 4 | 4 | 6 |
| EN 18031-1, -2 and -3 | 51 | 1 | 37 | 0 | 13 |
| prEN 40000 drafts | 104 | 0 | 20 | 5 | 79 |
| NIST IR 8425 | 33 | 0 | 8 | 2 | 23 |
| NIST IR 8259A | 22 | 0 | 7 | 0 | 15 |
| ETSI EN 303 645 | 78 | 14 | 11 | 1 | 52 |
| IEC 62443-4-2 | 47 | 0 | 8 | 0 | 39 |
How it fits a lab's test plan (OWASP FSTM)
Many labs plan a firmware assessment along OWASP's nine Firmware Security Testing Methodology stages. MAGDOX automates the static stages; the running device stays with your testers.
| Stage | In MAGDOX | What happens |
|---|---|---|
| 1. Information gathering and reconnaissance | Yours | You describe the product: device type, markets, support period and security contact. |
| 2. Obtaining firmware | Yours | You upload the image, or import it from a release on GitHub or GitLab. |
| 3. Analyzing firmware | Automatic | The image is hashed, its containers and vendor headers identified and its kernel version read. |
| 4. Extracting the filesystem | Automatic | FDIE's own readers unpack the file systems and archives. Anything they cannot read is listed as a coverage gap. |
| 5. Analyzing filesystem contents | Automatic | Components, secrets and default credentials, certificates and keys, configuration, network services, binary hardening, known-malware rules, disassembly of the programs and the 64 device checks. |
| 6. Emulating firmware | In development | Measured in our lab (Emulation, above); not in the app yet, where the analysis is static. |
| 7. Dynamic analysis | In development | Follows emulation. The two runtime device checks stay unassessed until then. |
| 8. Runtime analysis | Not covered | Needs the running device and a tester. |
| 9. Binary exploitation | Not covered | Exploitation stays with your testers. Disassembly, call graphs and reachability point them at the code that matters. |
Handing a camera to the ER: 01 lab
Since 9 April 2025, every CCTV camera model registered with BIS, other than analog cameras, needs an ER: 01 test report from a laboratory. From STQC's procedure and the BIS guidelines:
What the lab tests
- Exposed network services and the protocols the camera uses.
- Debug interfaces such as USB, UART, JTAG and SWD, disabled or protected.
- Whether memory and firmware can be extracted, and how data is stored and encrypted.
- The firmware update process, and keys and certificates unique to each device.
- The supply chain: the bill of materials and where the SoC and firmware come from.
What you hand in
- A technical construction file covering every applicable requirement, with its artefacts.
- A statement of compliance signed by a director of the company.
- Production samples or engineering boards with access probes, and the tools to load firmware.
- A test report for each lead model, naming the series models it covers. STQC's certificate is valid for three years, subject to surveillance audits.
Find out what the lab would flag in your firmware
A 45-minute call with our team. Bring one firmware image.