Skip to main content

firmware-acquisition

Systematic firmware extraction from IoT and embedded targets — vendor portals, OTA interception, SPI flash dumping with flashrom/CH341A, eMMC chip-off, and UART/JTAG console dumps. Covers the full acquisition chain from zero hardware access to a raw binary ready for static analysis.

跳到安装

来源信息

仓库
BitterSecurity/Decepticon
最近来源活动
2026年5月30日 11:59
检测到的 SKILL.md 语言
英语
星标
5,565
分支
1,053

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
firmware-acquisition
description
Systematic firmware extraction from IoT and embedded targets — vendor portals, OTA interception, SPI flash dumping with flashrom/CH341A, eMMC chip-off, and UART/JTAG console dumps. Covers the full acquisition chain from zero hardware access to a raw binary ready for static analysis.
allowed-tools
Bash Read Write
metadata
{"subdomain":"iot","when_to_use":"firmware dump, SPI flash, eMMC chip-off, UART dump, JTAG dump, OTA capture, flashrom, CH341A, vendor firmware portal, firmware extraction, flash read","tags":"iot, firmware, spi, emmc, uart, jtag, flashrom, ch341a, ota, acquisition, embedded","mitre_attack":"T1542, T1601, T1592.002"}
# Firmware Acquisition > Acquire a binary image of the target's firmware before any static analysis. > Work through the acquisition tiers in order — cheapest and least invasive first. > Each tier degrades hardware less and preserves the device's operational state. ## Prerequisites - Device PCB photographed (top + bottom). Mark: SoC part number, flash chip marking, debug pad pattern (UART = 4-pin row; JTAG = TAP header or test points). - Identify flash type from silkscreen or datasheet: SPI NOR (SOIC-8/WSON), SPI NAND, eMMC (BGA-153/169), parallel NOR/NAND. - Bench tools staged: CH341A programmer + SOIC-8 clip, BusPirate / J-Link / SEGGER J-Trace, USB-UART adapter (CP2102 / FT232), multimeter for UART baud sniffing. --- ## Tier 0 — Vendor Portal / OTA Proxy (no hardware needed) ### 0a. Vendor download portal ```bash # Check common firmware CDN patterns curl -sI "https://firmware.vendor.com/latest/<model>.bin" curl -sI "https://downloads.vendor.com/firmware/<model>/<version>.tar.gz" # Scrape firmware release page for direct links wget -r -l1 -nd -A "*.bin,*.tar.gz,*.zip,*.img" \ "https://www.vendor.com/support/firmware/<model>" # Checksum-verify before unpacking sha256sum <fw.bin> ``` ### 0b. OTA interception (MITM the device's update check) ```bash # 1. ARP-spoof the device to route its traffic through your machine sudo arpspoof -i eth0 -t <device_ip> <gateway_ip> & sudo arpspoof -i eth0 -t <gateway_ip> <device_ip> & # 2. Forward all traffic except OTA traffic; intercept OTA with mitmproxy sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8080 mitmproxy --mode transparent --set ssl_insecure=true -w /tmp/ota_capture.mitm # 3. Trigger an OTA check from the device (power cycle or companion app) # 4. Inspect intercepted traffic; export firmware binary mitmdump -r /tmp/ota_capture.mitm -w /tmp/ota_fw.bin \ --set flow_detail=3 '~t application/octet-stream or ~t application/x-gzip' # 5. Decrypt if AES-encrypted OTA (key often in companion app resources) openssl enc -d -aes-128-cbc -K <hex_key> -iv <hex_iv> -in /tmp/ota_fw.bin -out /tmp/fw_plain.bin ``` ### 0c. Companion-app embedded firmware ```bash # APK often bundles the firmware binary or partial images apktool d companion.apk -o companion_decompiled/ find companion_decompiled/ -name "*.bin" -o -name "*.fw" -o -name "*.img" | xargs file grep -r "firmware\|update\|download\|cdn" companion_decompiled/assets/ --include="*.js" ``` --- ## Tier 1 — UART Console Dump UART is the fastest hardware path: non-destructive, works while device is powered. ### 1a. Identify UART pins ``` Typical 4-pin UART header: VCC | GND | TX | RX Probe each with multimeter (DC, 3.3 V idle = TX candidate). Baud detect: minicom -D /dev/ttyUSB0 -b 115200 (try 9600, 57600, 115200, 460800). ``` ```bash # Baud-rate autoprobe with sigrok / baudrate.py python3 baudrate.py /dev/ttyUSB0 # https://github.com/devttys0/baudrate # Or with screen – step through common rates for baud in 9600 19200 38400 57600 115200 230400 460800 921600; do echo "Testing $baud..."; screen /dev/ttyUSB0 $baud; done ``` ### 1b. Interrupt boot and dump from U-Boot ```bash # Connect: GND → GND, RX(USB) → TX(device), TX(USB) → RX(device) screen /dev/ttyUSB0 115200 # Power on device; press any key within 1-3s to break into U-Boot # At U-Boot prompt: locate kernel + rootfs partition offsets => printenv => mtdparts # shows flash map (e.g. 0x00000000 kernel 0x200000, rootfs 0x600000) # Dump via XMODEM to host => loady 0x80000000 # load address in RAM => md.b 0x80000000 0x200000 # memory-display: prints hex to terminal # Capture terminal output → convert hex dump → binary: python3 -c " import sys, re data = open('uart_hexdump.txt').read() chunks = re.findall(r':\s+((?:[0-9a-fA-F]{8} ){1,4})', data) raw = bytes.fromhex(''.join(''.join(c.split()) for c in chunks)) open('fw_from_uart.bin','wb').write(raw)" ``` ### 1c. Full flash dump via UART + tftp ```bash # If U-Boot has tftp + nand/sf commands: => setenv ipaddr 192.168.1.100 => setenv serverip 192.168.1.10 => sf probe; sf read 0x80000000 0x0 0x1000000 # read 16MB SPI NOR into RAM => tftp 0x80000000 flash_full.bin # upload to your tftp server # On your host: python3 -m py3tftp -p 69 --ip 0.0.0.0 ``` --- ## Tier 2 — JTAG / SWD Debug Interface ### 2a. OpenOCD + J-Link SWD dump (ARM Cortex-M) ```bash openocd -f interface/jlink.cfg -f target/stm32f4x.cfg \ -c "init; halt; dump_image /tmp/flash.bin 0x08000000 0x100000; shutdown" # Adjust start address and size per datasheet (STM32F4: 1 MB @ 0x08000000) ``` ### 2b. JTAG boundary-scan enumeration (MIPS/ARM application processors) ```bash # UrJTAG or JTAGulator to identify IR length + IDCODE jtag> cable jtagkey jtag> detect jtag> print chain # Identify MIPS/ARM AP; attach GDB via OpenOCD gdb-multiarch vmlinux (gdb) target remote :3333 (gdb) monitor halt (gdb) dump binary memory /tmp/mem.bin 0x80000000 0x90000000 # DRAM range ``` ### 2c. JTAG boundary-scan via eBBoot / Segger ```bash # Segger J-Flash CLI for known targets: JFlash -openprj target.jflash -readchip /tmp/flash_full.bin -exit ``` --- ## Tier 3 — SPI NOR Flash Dump (CH341A + flashrom) Most cost-effective hardware method for 8-pin SPI NOR chips. ### 3a. In-circuit dump (device powered off, clip attached) ```bash # Connect SOIC-8 clip to CH341A programmer # Identify chip: run flashrom probe first sudo flashrom -p ch341a_spi --verbose 2>&1 | grep -E "Found|Matched|chip" # Dump (use the exact chip name from probe output) sudo flashrom -p ch341a_spi -c "MX25L12835F" -r /tmp/flash_dump.bin sudo flashrom -p ch341a_spi -c "MX25L12835F" -r /tmp/flash_dump2.bin # Verify both reads match (disk corruption / clip contact issue otherwise) sha256sum /tmp/flash_dump.bin /tmp/flash_dump2.bin cmp /tmp/flash_dump.bin /tmp/flash_dump2.bin && echo "MATCH" || echo "MISMATCH — re-seat clip" ``` ### 3b. Troubleshooting in-circuit reads ``` Symptom: flashrom sees 0x00 or 0xFF → chip held in reset by SoC pull-downs. Fix: power-cycle with clip attached BEFORE the SoC powers up (race the SoC). Or: locate HOLD# / WP# pins, tie to VCC; CS# must go low only from CH341A. If SoC fights the bus: desolder for Tier 4. ``` ### 3c. SPI NAND / eMMC alternative: python-flashrom / serprog ```bash # For SPI NAND (Winbond W25Nxxxx), use nandwrite flow: # 1. Use flashrom with serprog (Raspberry Pi as SPI master): sudo flashrom -p serprog:dev=/dev/ttyUSB0:4000000 -c "W25N01GV" -r /tmp/nand.bin # 2. Extract with nanddump equivalent for raw bin: binwalk -e /tmp/nand.bin # handles OOB stripping for most NAND dumps ``` --- ## Tier 4 — eMMC Chip-Off Last resort: BGA desoldering, direct eMMC reader. Destructive to PCB. ### 4a. Chip-off procedure ``` 1. Hot-air rework (350 °C, 60 L/min): heat BGA from below; lift with vacuum. 2. Clean pads with flux + wick. 3. Reflow eMMC onto BGA breakout board (eMMC adapter): - SD-to-eMMC: Allwinner eMMC reader, Emuelec adapter, or custom PCB. 4. Insert into card reader that supports eMMC protocol. ``` ### 4b. Dump with dd / usbimager ```bash # Identify device node (dmesg after plugging in) dmesg | tail -20 | grep sd lsblk -d /dev/sdb # confirm size matches eMMC spec # Full raw dump sudo dd if=/dev/sdb of=/tmp/emmc_full.img bs=512 status=progress conv=noerror,sync sha256sum /tmp/emmc_full.img > /tmp/emmc_full.img.sha256 # Partition inspection fdisk -l /tmp/emmc_full.img file /tmp/emmc_full.img # Mount individual partition (offset in sectors from fdisk output) sudo mount -o loop,offset=$((512*2048)) /tmp/emmc_full.img /mnt/emmc_p1 ``` --- ## Evidence Store all artifacts under `/workspace/evidence/iot/<target>/firmware/`: ```bash mkdir -p /workspace/evidence/iot/<target>/firmware cp /tmp/flash_dump.bin /workspace/evidence/iot/<target>/firmware/flash_full.bin sha256sum /workspace/evidence/iot/<target>/firmware/flash_full.bin \ > /workspace/evidence/iot/<target>/firmware/flash_full.bin.sha256 # Log acquisition method and hardware used echo "Acquired via: CH341A + SOIC-8 clip; flashrom 1.4.0; chip: MX25L12835F" \ > /workspace/evidence/iot/<target>/firmware/acquisition.log ``` ## OPSEC Notes - In-circuit clips can corrupt firmware if contact is intermittent — always compare two reads before treating the image as canonical. - OTA MITM is logged server-side; only perform on isolated test-lab networks unless RoE explicitly permits production intercept. - JTAG debug may trigger internal tamper fuses on hardened targets (e.g., Qualcomm secure boot with JTAG-disable eFuse). Read the SoC TRM before probing. - eMMC RPMB partition requires authentication key to read — skip on initial triage; flag for key extraction if bootloader secrets are needed. ## References - flashrom supported hardware: `https://flashrom.org/Supported_hardware` - CH341A pinout + SOIC clip wiring: `references/ch341a-soic-wiring.md` - U-Boot command reference: `https://u-boot.readthedocs.io/en/latest/usage/index.html` - OpenOCD target configs: `/usr/share/openocd/scripts/target/`
在 GitHub 查看