How to Extract and Analyze Firmware Using Binwalk and EMBA Orchestration
TLDR: The reverse-skill repository provides a plug-and-play pipeline that uses Binwalk to recursively extract firmware filesystems and EMBA to perform static, dynamic, and fuzzing analysis, orchestrated via bash scripts that normalize outputs and auto-generate security reports.
This guide demonstrates how to extract and analyze firmware using Binwalk and EMBA orchestration within the reverse-skill framework. The repository delivers a modular, repeatable workflow for firmware triage that bridges automated extraction with deep security analysis, eliminating manual glue code between tools. All procedures reference the actual implementation files found in skills/firmware-pentest/ and the associated orchestration logic.
Understanding the Reverse-Skill Firmware Pipeline
The workflow treats firmware analysis as a two-stage pipeline: extraction (Binwalk) followed by security analysis (EMBA). A set of POSIX-compliant shell scripts handles directory normalization, architecture detection, and report collation.
Core Components
| Component | Purpose | Reference File |
|---|---|---|
| Binwalk | Automated extraction of filesystems, compression detection, and entropy visualization | skills/firmware-pentest/references/extraction-methodology.md |
| EMBA | Static/dynamic analysis, QEMU emulation, and AFL-based fuzzing | skills/firmware-pentest/references/emba-automated-analysis.md |
| Orchestration | Glues extraction to analysis, manages emba_work/ directories, and triggers report generation |
skills/firmware-pentest/SKILL.md |
Key Repository Files
skills/firmware-pentest/SKILL.md– Entry point describing the firmware-pentest skill and orchestration hooks.skills/pentest-tools/templates/scope.md– Template for defining targets, acquisition methods, and legal constraints.skills/MASTER-ROUTING.md– Defines cross-skill hooks allowing other modules (e.g.,binary-diff) to consume EMBA output.emba/config.json– Module configuration file for extending EMBA analysis capabilities.
Preparation and Scope Definition
Before executing tools, populate scope.md (located in skills/pentest-tools/templates/) with the target firmware image, SHA256 hashes, and any air-gapping requirements. This document acts as the source of truth for the orchestration script’s FW variable.
Phase 1: Firmware Extraction with Binwalk
Binwalk performs the initial triage by identifying signatures, unpacking nested archives, and visualizing entropy to spot encrypted blobs.
Recursive Unpacking Command
The orchestration script invokes Binwalk in module-aware recursive mode:
binwalk -e -M router_firmware.bin
-eextracts identified filesystems and archives into a directory.-Menables recursive scanning within extracted sub-directories (module-aware mode).
For targeted dumping of specific file types (e.g., PNG images or ZIP archives) during manual analysis, use the -D flag:
binwalk -e -M -D 'png:images' -D 'zip:archives' router_firmware.bin
Handling Extraction Output
Binwalk creates a directory named _{BASE}.extracted (e.g., _router_firmware.bin.extracted). The orchestration script renames this to ${BASE}.extracted immediately after extraction.
Key artifacts in this directory include:
- Raw unpacked root filesystems (e.g.,
squashfs-root/). entropy.png– A heat-map visualization indicating high-entropy regions (potential encryption or compressed data).- Binary blobs identified by magic signatures.
Before handing data to EMBA, the script scripts/normalize_extraction.py (referenced in SKILL.md) performs three tasks:
- Renames ambiguous folders to consistent UUIDs.
- Normalizes line endings in text-based configuration files.
- Generates
manifest.json, a machine-readable inventory of extracted paths and file types.
Phase 2: Automated Analysis with EMBA
EMBA consumes the normalized extraction directory and executes a configurable suite of security tests. It expects input via the -i flag pointing to a directory containing the rootfs.
Static Analysis Module
Run static checks without emulation to rapidly identify vulnerable libraries and hardcoded credentials:
emba -i emba_work --static-only
According to emba-automated-analysis.md, this phase executes file, strings, and objdump across the extracted binaries. It cross-references versions of OpenSSL, BusyBox, and other common embedded libraries against known CVE databases. Results are written to emba_work/static/.
Dynamic Emulation
If the firmware includes a kernel, EMBA can boot it inside QEMU:
emba -i emba_work --emulate
The orchestration layer automatically detects the correct QEMU architecture (qemu-system-<arch>) by parsing ELF headers discovered during the Binwalk phase. This eliminates manual specification of -M virt or CPU flags. The emulation uses a pre-configured initramfs to provide a controlled userspace environment.
Fuzzing and Network Stimulation
To test exposed services (HTTP, Telnet, UPnP) discovered during static analysis, invoke the AFL-based fuzzing harness:
emba -i emba_work --fuzz
This launches fuzzers against network-facing binaries and aggregates crash artifacts, hang logs, and coverage maps under emba_work/fuzz/.
Orchestrating the End-to-End Workflow
Rather than running commands manually, use the bundled run_firmware_analysis.sh script located in skills/firmware-pentest/. It implements the full pipeline with strict error handling (set -euo pipefail).
#!/usr/bin/env bash
set -euo pipefail
FW="$1"
BASE=$(basename "$FW")
EXTRACT_DIR="${BASE}.extracted"
# ---- Binwalk extraction -------------------------------------------------
binwalk -e -M "$FW"
mv "_${BASE}.extracted" "$EXTRACT_DIR"
# ---- Normalise extraction output ----------------------------------------
python3 scripts/normalize_extraction.py "$EXTRACT_DIR"
# ---- Prepare EMBA workdir ------------------------------------------------
EMBA_WORK="emba_work"
mkdir -p "$EMBA_WORK"
cp -r "$EXTRACT_DIR"/* "$EMBA_WORK/"
# ---- Run EMBA static analysis -------------------------------------------
emba -i "$EMBA_WORK" --static-only
# ---- Run EMBA dynamic emulation (if kernel detected) --------------------
if emba --detect-kernel "$EMBA_WORK"; then
emba -i "$EMBA_WORK" --emulate
fi
# ---- Optional fuzzing ----------------------------------------------------
emba -i "$EMBA_WORK" --fuzz
# ---- Collate results ----------------------------------------------------
scripts/collect_report.sh "$EMBA_WORK" "$BASE"
echo "✅ Analysis complete – see ./report/${BASE}_report.md"
Execute the orchestrator with:
bash skills/firmware-pentest/run_firmware_analysis.sh router_firmware.bin
Report Generation and Collateral
After analysis, scripts/collect_report.sh aggregates logs from emba_work/static/, emba_work/fuzz/, and QEMU screenshots into a unified report/ directory. The repository ships with Jinja2 markdown templates (referenced in docs/ARCHITECTURE.md) for final documentation:
from jinja2 import Environment, FileSystemLoader
import json, pathlib
env = Environment(loader=FileSystemLoader('templates'))
template = env.get_template('firmware_report.md.j2')
manifest = json.load(open('emba_work/manifest.json'))
report = template.render(manifest=manifest, emba_logs='emba_work/logs/')
pathlib.Path('report/firmware_report.md').write_text(report)
This produces a security assessment document suitable for stakeholder review, complete with file manifests, vulnerability tables, and fuzzing results.
Extending the Analysis Pipeline
The reverse-skill architecture supports modular extensions via two mechanisms:
- MASTER-ROUTING.md hooks – Other skills (e.g.,
hardware-security) can subscribe to theEMBA_COMPLETEevent and consumemanifest.jsonfor hardware-focused testing. - EMBA configuration JSON – Adding new analysis modules requires updating
emba/config.jsonand appending the module name to theMODULESarray inrun_firmware_analysis.sh.
Summary
- Binwalk (
-e -M) recursively unpacks firmware images and generates entropy heat-maps to identify compressed or encrypted regions. - EMBA performs triage via
--static-only, boots kernels with--emulateusing auto-detected QEMU architectures, and fuzzes services with--fuzz. - The
run_firmware_analysis.shorchestration script enforces a strict pipeline: extraction → normalization → EMBA analysis → report collation. - Normalization via
scripts/normalize_extraction.pyproducesmanifest.json, which feeds both EMBA and downstream reporting templates. - Results are aggregated under
report/using Jinja2 templates defined in the repository’sdocs/hierarchy.
Frequently Asked Questions
What is the difference between Binwalk and EMBA in this workflow?
Binwalk handles filesystem extraction and initial carving, producing raw artifacts and entropy visualizations. EMBA performs security-centric analysis—checking for vulnerable libraries, emulating firmware in QEMU, and fuzzing network services. The orchestration script bridges them by converting Binwalk’s *.extracted directory into EMBA’s expected emba_work/ input format.
How does the orchestration script detect the correct architecture for QEMU emulation?
The script parses ELF headers discovered during the Binwalk extraction phase to identify the target architecture (ARM, MIPS, x86, etc.). It passes this information to EMBA’s --emulate flag, which launches the appropriate qemu-system-<arch> binary without manual intervention, as documented in emba-automated-analysis.md.
Can I run Binwalk and EMBA manually without the orchestration script?
Yes. Manually run binwalk -e -M <firmware.bin>, rename _*.extracted to your preferred directory, and execute emba -i <dir> --static-only or --emulate. However, you will lose automatic normalization, manifest.json generation, and the conditional kernel detection logic that the orchestration layer provides.
Where are the vulnerability scan results stored in the EMBA output directory?
Static analysis findings, including vulnerable library versions and hardcoded credential alerts, are stored in emba_work/static/. Fuzzing crashes and network logs reside under emba_work/fuzz/. The collect_report.sh script aggregates these into the top-level report/ directory as Markdown and JSON artifacts.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →