When to use / when not to use
- Use: when you already have unpacked artifacts / filesystem images and need to find boot entry points, configuration, keys, hardcoded credentials
- Use: when you need to locate programs and architecture inside the firmware (cross binaries)
- Don't use: when you don't have any unpacked artifacts yet (first [[re-fw-extract]])
- Don't use: when you need to run firmware programs to observe behavior (go to [[re-fw-emulate]])
- Don't use: when you need a physical board (go to [[re-hardware-io]])
Tool preparation
Verify all tools before use. This skill is purely static analysis and can skip the sandbox ([[re-analyze/platform-tips]] highest principle); when the extracted programs need to be run, switch to [[re-fw-emulate]].
Unpacking tools (unblob / binwalk artifacts preferred)
- If already installed, directly use the unpacked artifacts from [[re-fw-extract]]; if not installed, install according to that skill's "Tool preparation"
- Verify:
unblob --version/binwalk --version
7-Zip (7z) — general-purpose container fallback
- Linux:
apt install p7zip-full/dnf install p7zip-plugins/pacman -S 7zip - macOS:
brew install p7zip - Windows:
choco install 7zip(or the official installer from 7-zip.org) - Verify:
7z i | head -5(display version)
squashfs-tools(unsquashfs)
- Linux:
apt install squashfs-tools/dnf install squashfs-tools/pacman -S squashfs-tools - macOS:
brew install squashfs - Windows/WSL: Linux version inside WSL
- Verify:
unsquashfs -version
cramfs unpacking (cramfsck)
- Linux:
apt install cramfsprogs(Debian/Ubuntu); other distributions have no official package → use unblob to unpack cramfs as a fallback - macOS/Windows: unblob fallback
- Verify:
cramfsck -V
grep / ripgrep — configuration and key search
- Linux:
apt install ripgrep/dnf install ripgrep/pacman -S ripgrep(grep comes with the distribution) - macOS:
brew install ripgrep - Windows:
choco install ripgrep(or WSL) - Verify:
rg --version/grep --version
Cross binutils (readelf / objdump across architectures)
- Linux:
apt install binutils-arm-linux-gnueabi binutils-arm-linux-gnueabihf binutils-mipsel-linux-gnu binutils-mips-linux-gnu(Debian/Ubuntu;Fedora:dnf install binutils-arm-linux-gnu binutils-mips-linux-gnu) - macOS:
brew install binutils(greadelf) orbrew install llvm(llvm-readelf) - WSL: Linux version works directly
- Verify:
arm-linux-gnueabi-readelf --version; the native readelf can also read cross ELF headers (readelf -h), for attribute-level information use the cross versionreadelf -A
Procedure
Execute in order, record the result of each step.
-
Mount/unpack the filesystem:
# squashfs(最常见) unsquashfs rootfs.squashfs -d rootfs_out # cpio initramfs mkdir rootfs_out && cd rootfs_out && cpio -idmv < ../initramfs.cpio # 通用兜底 7z x rootfs.img # cramfs(Debian 系) cramfsck -x rootfs_out rootfs.cramfs # ext 类镜像(需 root,只读挂载) mkdir mnt && mount -o loop,ro rootfs.img mntIf already unpacked with [[re-fw-extract]], proceed directly to the next step and skip this step.
-
Find the program entry point from boot scripts:
ls etc/init.d/ etc/rc.d/ 2>/dev/null cat etc/inittab 2>/dev/null cat etc/init.d/rcS 2>/dev/null # 常见主启动脚本Read the boot sequence: record the services started first and the firmware main program (httpd / server main process), and start analysis from it; rcS / rc scripts often contain version, vendor information and debug switches.
-
Dig keys/credentials out of configuration files:
rg -i "password|passwd|secret|token|key|login|admin" rootfs_out -l cat etc/passwd etc/shadow 2>/dev/nullKey directories: /etc, /usr/share, web interface directories (firmware web configuration often stores credentials in plaintext), wpa_supplicant.conf, SSH private keys (
find rootfs_out \( -name "*id_rsa*" -o -name "*.pem" \))。 -
Locate cross-compiled binaries:
find rootfs_out -type f -exec file {} \; 2>/dev/null | grep ELF # 大镜像改用: find rootfs_out -type f -print0 | xargs -0 file | grep ELF arm-linux-gnueabi-readelf -h rootfs_out/usr/sbin/httpd # Machine + Data 字段确认架构/字节序 arm-linux-gnueabi-readelf -A rootfs_out/usr/sbin/httpd # 交叉工具链细节(EABI 等)Key directories: /bin, /usr/bin, /usr/sbin, /usr/lib; busybox is a set of symlinks (
ls -la bin/check the link target to confirm the applet). -
Search for weak credentials/backdoor accounts:
cat etc/passwd rg -i "admin|root|debug|backdoor|telnet" rootfs_out/etc -lCommon ones: root with empty/weak password, telnetd resident, default admin/admin, debug accounts (debug/backdoor); after discovering backdoors and suspicious programs, switch to [[re-malware]] for evaluation.
Cross-domain combination
- [[re-firmware]]: step 3 of the workflow always calls this skill
- Deep dive into ELF inside firmware → [[re-binary-core]] ([[re-format-elf]] / [[re-ghidra]])
- Need to run firmware → [[re-fw-emulate]]; discover backdoor/malicious sample → [[re-malware]]; discover communication → [[re-protocol]]
- This skill is invoked by the triage "analyze firmware / IoT device" path of [[re-analyze]]
Common pitfalls and traps
- Hardcoded keys/passwords in configuration are common: Symptom—SSH private keys, WiFi passwords, and cloud platform API keys lie directly in the firmware; Cause—IoT vendors hardcode them to save cost; Countermeasure—systematically
rgscan all configuration directories and web directories, don't just look at /etc (step 3) - Startup scripts determine the analysis order: Symptom—dozens of executables, no idea where to start; Cause—not reading the startup scripts first, starting from a random binary; Countermeasure—first read rcS / inittab / init.d, locate the main program according to the startup order (step 2)
- Cross-architecture binaries require the corresponding toolchain: Symptom—local readelf gives incomplete information / objdump disassembly fails; Cause—missing binutils for the corresponding architecture, or the architecture/endianness was identified incorrectly; Countermeasure—install cross binutils,
readelf -Aconfirm the architecture and EABI (step 4), and after confirmation choose the emulation/decompilation tool - busybox is a collection of symlinks: Symptom—bin/ is full of symlinks with the same name,
fileall pointing to the same ELF; Cause—busybox is a single binary with multiple applets; Countermeasure—the symlink name is the applet function (ls/cat/httpd, etc.), and analyzing that single ELF covers all commands