mcpField
A
analyzing-firmware-images

analyzing-firmware-images

github.com/trilwu安全17755 次安装12 周前更新
代码仓库

关于 analyzing-firmware-images

这是一项固件安全分析技能,用于检查更新镜像以及嵌入式设备的文件系统、服务和二进制文件,面向评估 IoT、路由器等嵌入式系统的安全研究人员。内容涵盖从提取分析到模拟运行和密码学审查。

主要功能

  1. 01识别镜像格式与熵值
  2. 02提取嵌入式文件系统
  3. 03搜索凭据和机密
  4. 04审查 Web 界面与服务
  5. 05分析跨架构二进制文件
  6. 06评估更新签名与密码学

适用场景

  1. 01根据固件镜像评估 IoT 设备
  2. 02搜索固件中的内嵌凭据或密钥
  3. 03评估设备更新验证机制
  4. 04检查嵌入式 Web 界面和网络服务

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/trilwu/secskills --skill analyzing-firmware-images

安装后在 Claude Code 中输入/analyzing-firmware-images确认已加载。

详细介绍

分析固件镜像

固件是冻结的 Linux(或 RTOS)镜像,其安全性也随之冻结。硬编码凭据、CGI 脚本中的命令注入、未签名的更新包,以及仍启用的调试接口都不是个例——而是常态。工作内容包括提取、了解镜像结构,然后像分析任何系统一样提出相同的问题,同时要知道这个系统自发布以来就再也没有打过补丁。

适用场景

  • 提取和分析固件更新文件(.bin、.img、.chk、.trx)
  • 根据固件镜像审查 IoT 设备的安全状况
  • 在设备固件中查找硬编码凭据、密钥或机密
  • 评估嵌入式设备或路由器的攻击面
  • 评估更新机制和签名验证
  • 分析微控制器上的裸机或 RTOS 镜像

不适用场景

  • 标准 x86/x64 二进制逆向工程——使用 analyzing-binaries
  • 恶意软件样本分析——使用 analyzing-malware
  • 有源代码可用——使用 auditing-code-for-vulnerabilities

固件获取

分析之前需要先获取固件。获取方式决定了你能得到什么。

方式获取内容备注
厂商下载更新包,通常经过压缩或加密查看支持门户、FTP 服务器和 FCC 文件
OTA 抓包传输中的更新载荷在设备的更新通道上使用 mitmproxy 或 tcpdump;许多设备使用纯 HTTP
UART/串口控制台Shell 访问权限、引导加载程序交互需要三根线(TX、RX、GND);使用万用表或逻辑分析仪识别
JTAG/SWD完整内存读取、调试访问权限需要识别引脚;使用 JTAGulator、OpenOCD
芯片脱焊原始闪存内容(NAND/NOR)拆下闪存芯片;使用编程器(CH341A、FlashcatUSB)读取;最后手段
引导加载程序提取通过 U-Boot md 或 sf read 命令转储如果可以通过 UART 访问引导加载程序 Shell

要拦截 OTA 更新,请将设备配置为通过 mitmproxy 代理。许多设备会忽略代理设置——可能需要 ARP 欺骗或透明网桥。如果更新通过 HTTPS 传输,请检查设备是否会验证证书;有相当多的设备并不会验证。

初步分析

提取之前,先识别格式并分析熵。

file firmware.bin
binwalk firmware.bin              # identify embedded filesystems and compression
binwalk -E firmware.bin           # entropy analysis -- high entropy = compressed or encrypted
hexdump -C firmware.bin | head -64   # header bytes reveal container format
strings -n 10 firmware.bin | head -100  # quick orientation

熵图说明:

  • 整个镜像的熵都很高且平坦(接近 1.0)——镜像整体经过加密或压缩。你需要先获取解密密钥或解压方法才能继续。
  • 高熵区域之间由低熵头部隔开——压缩的文件系统分区之间包含元数据。这很正常;提取这些分区即可。
  • 整体熵较低——未压缩的文件系统或原始闪存。应该可以直接提取。

常见容器格式:

头部魔数格式
hsqs / sqshSquashFS
UBI#UBI/UBIFS
0x1985JFFS2
0x28cd3d45cramfs
HDR0TRX(Broadcom 路由器)
\x27\x05\x19\x56uImage(U-Boot)

提取

根据文件系统选择合适的工具。通用提取会遗漏元数据和权限。

# General recursive extraction -- good starting point
binwalk -Me firmware.bin

# SquashFS -- the most common embedded filesystem
unsquashfs -d rootfs squashfs-root.img
# Non-standard SquashFS (vendor-modified): use sasquatch
sasquatch -d rootfs squashfs-root.img

# JFFS2
jefferson firmware.jffs2 -d rootfs

# UBI/UBIFS
ubireader_extract_images firmware.ubi
ubireader_extract_files firmware.ubi

# cramfs
cramfsck -x rootfs cramfs.img

# Raw NAND dumps may need OOB data stripped first
nandextract firmware.nand

如果 binwalk 没有发现任何内容,且熵很高,那么镜像很可能经过加密。寻找包含解密例程的引导加载程序或较早版本的固件。有些厂商会将解密密钥放在引导加载程序或配套分区中。

文件系统分析

提取完成后,将根文件系统视为一个你首次审计的 Linux 系统。

凭据和机密
# Password files
cat rootfs/etc/passwd
cat rootfs/etc/shadow
# Hardcoded credentials -- these are endemic
rg -rn 'password|passwd|admin|root|default' rootfs/etc/ --include='*.conf'
rg -rn 'BEGIN (RSA|EC|OPENSSH|DSA) PRIVATE KEY' rootfs/
rg -rn 'api[_-]?key|secret[_-]?key|token' -i rootfs/

# Certificates and keys
find rootfs -name '*.pem' -o -name '*.key' -o -name '*.crt' -o -name '*.p12'
# WiFi and VPN credentials
find rootfs -name 'wpa_supplicant*' -o -name '*.ovpn' -o -name 'ipsec.*'

/etc/shadow 中的默认凭据是最常见的固件发现。检查 root 是否有密码哈希,以及该哈希是否能被破解——通常可以。哈希处理请参阅 cracking-passwords。

配置和服务
# Startup scripts reveal what runs and how
ls rootfs/etc/init.d/ rootfs/etc/rc.d/
cat rootfs/etc/inittab
# Systemd units if present
find rootfs -name '*.service' -path '*/systemd/*'

# Installed packages and versions
cat rootfs/etc/opkg/status 2>/dev/null    # OpenWrt-based
ls rootfs/usr/lib/ipkg/info/ 2>/dev/null  # older ipkg

# Network configuration
cat rootfs/etc/network/interfaces 2>/dev/null
rg -rn 'iptables|ip6tables|nftables' rootfs/etc/
Web 界面

可被利用的漏洞通常藏在 Web 界面中。嵌入式 Web 服务器通常是 BusyBox httpd、lighttpd、uhttpd 或 GoAhead,负责提供以 shell、Lua 或 C 编写的 CGI 脚本。

# Find the web root
find rootfs -name 'httpd*' -o -name 'lighttpd*' -o -name 'uhttpd*'
ls rootfs/www/ rootfs/usr/www/ rootfs/usr/share/www/ 2>/dev/null

# CGI scripts -- these are the attack surface
find rootfs -name '*.cgi' -o -name '*.sh' -path '*/cgi-bin/*'
find rootfs -name '*.lua' -path '*/luci/*' -o -name '*.lua' -path '*/www/*'

# Command injection patterns in CGI
rg -rn 'system\(|popen\(|exec\(|os\.execute|io\.popen|\`.*\$' rootfs/www/
rg -rn '\$QUERY_STRING|\$REQUEST_URI|\$HTTP_' rootfs/www/

通过 CGI 参数进行命令注入,在嵌入式 Web 界面中十分常见。 常见模式是 CGI 脚本从查询参数中获取用户输入,并在未进行净化的情况下将其传递给 shell 命令。检查每个 CGI 脚本是否存在这种模式——使用 system()、popen()、反引号执行、os.execute() 和 io.popen(),且输入受用户控制。

还要检查:

  • 身份验证绕过(无需登录即可访问页面)
  • 诊断页面中的跨站脚本攻击(ping、traceroute、DNS 查询)
  • 文件处理程序中的路径遍历
  • 硬编码的会话令牌或可预测的会话生成方式

二进制分析

固件二进制文件面向非 x86 架构。反汇编前先确定架构。

# Identify architecture from ELF headers
file rootfs/usr/sbin/*
readelf -h rootfs/usr/sbin/httpd    # Machine field: ARM, MIPS, PowerPC

# Common architectures in firmware
# ARM (little-endian)  -- modern IoT, cameras, some routers
# MIPS (big-endian)    -- routers (Broadcom, Atheros, MediaTek)
# MIPS (little-endian) -- some Realtek-based devices
# PowerPC              -- older enterprise networking gear
跨架构反汇编

Ghidra 原生支持所有常见的固件架构。加载二进制文件,选择正确的处理器和字节序,然后进行自动分析。

# Ghidra headless analysis
analyzeHeadless /proj FirmwareProj -import rootfs/usr/sbin/httpd \
  -processor ARM:LE:32:v7 -postScript DecompileAll.java

# radare2 with architecture specification
r2 -a arm -b 32 rootfs/usr/sbin/httpd
# For MIPS big-endian:
r2 -a mips -b 32 -e cfg.bigendian=true rootfs/usr/bin/target

重点反汇编分析:

  • Web 服务器和 CGI 处理程序二进制文件
  • 自定义守护进程(任何非 BusyBox 或标准软件包提供的程序)
  • 实现设备特定功能的共享库
  • 以 root 身份运行且接受网络输入的二进制文件
使用 QEMU 进行仿真
# User-mode emulation for individual binaries
qemu-arm -L rootfs/ rootfs/usr/sbin/httpd
qemu-mipsel -L rootfs/ rootfs/usr/bin/target
# Use -strace to trace syscalls
qemu-arm -strace -L rootfs/ rootfs/usr/sbin/httpd

# If the binary needs specific /dev nodes or /proc, use chroot
sudo chroot rootfs/ /usr/sbin/httpd
# Or mount necessary filesystems
sudo mount -t proc proc rootfs/proc
sudo mount -t sysfs sysfs rootfs/sys

网络服务

通过读取 init 脚本和二进制配置文件,枚举设备在网络上提供的服务,而不要扫描在线设备。

# Services started at boot
rg -rn 'start\(\)|start_service' rootfs/etc/init.d/
# Listening ports from configuration
rg -rn 'listen|bind|port' rootfs/etc/ --include='*.conf'

# Common embedded services to look for
find rootfs -name 'telnetd' -o -name 'dropbear' -o -name 'sshd'
find rootfs -name 'upnpd' -o -name 'miniupnpd' -o -name 'minissdpd'
find rootfs -name 'mosquitto*' -o -name 'mqtt*'
find rootfs -name 'snmpd' -o -name 'snmp.conf'

常见发现:

  • 启用了 Telnet,且使用默认凭据或没有凭据
  • UPnP/SSDP 将内部服务描述暴露给 WAN
  • MQTT 代理未启用身份验证
  • SNMP 使用默认团体字符串(public、private)
  • 非标准端口上的自定义管理协议未启用身份验证
  • TR-069(CWMP)接口暴露在 ISP 管理 VLAN 之外
  • 调试端口(GDB 服务、网络串口)在生产环境中仍处于启用状态

全系统仿真

当单个二进制文件仿真无法满足需求时,可仿真整个固件。

# FirmAE -- automated full-system emulation
sudo python3 firmae.py -r <brand> firmware.bin

# EMBA -- comprehensive firmware analysis framework
sudo ./emba -f firmware.bin -l ./logs

# firmwalker -- static analysis without emulation
./firmwalker.sh rootfs/

FirmAE 和 EMBA 会处理难点:推断正确的 QEMU 机器类型、设置网络,以及修补 /dev/ 节点。如果它们无法运行,手动进行 QEMU 系统仿真则需要为目标平台构建正确的设备树和内核。

整个系统运行后,就像测试任何联网服务一样进行测试:使用 nmap 扫描、测试 Web 界面、对自定义协议进行模糊测试。不同之处在于,你可以访问文件系统,并在测试时阅读代码。

密码学分析

固件映像中经常包含密码学材料,并实现自定义密码方案。

# Find encryption keys and certificates
find rootfs -name '*.pem' -o -name '*.der' -o -name '*.key' -o -name '*.pub'
rg -rn 'AES|DES|RSA|SHA256|MD5|encrypt|decrypt' rootfs/usr/lib/ --include='*.so'

# Check update signature verification
# Look for signature checks in the update handler
rg -rn 'verify|signature|sign|openssl|gpg' rootfs/usr/sbin/ rootfs/etc/init.d/

检查内容:

  • 未签名的固件更新——如果更新机制不验证密码学签名,处于网络路径上的攻击者就能推送任意固件。这是严重问题。
  • 仅使用对称密钥签名更新——如果固件中嵌入了共享密钥,那么任何拿到固件的人都能签名更新。提取密钥并进行验证。
  • 硬编码的 TLS 证书和私钥——每台设备都使用相同的密钥对。提取密钥,并证明一台设备的密钥可以解密另一台设备的流量。
  • 弱加密或自定义加密——对配置文件进行 XOR“加密”、使用硬编码密钥“加密”密码,以及实际上并非加密的自定义混淆例程。
  • 熵源——嵌入式设备在启动时通常熵不足。检查 /dev/urandom 是否正确播种、随机数生成器是否在生成密钥前初始化,以及设备是否配备了实际在使用的硬件随机数生成器。

有关详细的密码学审查方法,请参阅 reviewing-cryptography。

防御审查清单

完成分析后,请依据以下控制措施进行评估。缺少任何一项都属于发现的问题。

控制措施检查项常见问题
更新包签名更新包是否使用非对称密钥进行了加密签名?刷写前是否验证签名?完全没有签名,或仅使用对称密钥
安全启动引导加载程序是否验证内核和 rootfs 的完整性?U-Boot 未进行签名验证
无默认凭据设备是否强制用户首次使用时更改密码?root:root、admin:admin 或空密码
服务精简是否只启用了必要的服务?默认启用 Telnet、UPnP、SNMP
调试接口生产环境中是否禁用或锁定了 UART、JTAG 和 SSH?UART Shell 可获取 root 权限,且无身份验证
存储加密凭据和密钥是否以静态加密方式存储?配置文件中存储明文密码
全面使用 TLS所有网络服务是否都使用带有效证书的 TLS?Web 管理界面使用纯 HTTP,MQTT 未加密
输入验证CGI 和 API 处理程序是否验证并清理输入?通过 Web 参数直接注入 Shell 命令
最小权限服务是否尽可能以非 root 身份运行?所有程序都以 root 身份运行
日志记录与审计是否记录了安全事件?没有日志,或日志仅存储在易失性内存中

应当驳斥的借口

  • “它在隔离网络上。” 嵌入式设备仍会暴露在外——通过 UPnP、配置错误的防火墙,或会向外部发起连接的云管理门户。应假定设备可被访问。
  • “固件已加密,所以我们无法分析。” 解密密钥位于引导加载程序中,或存在于先前的未加密版本中。没有安全启动的加密只是混淆,不是保护。
  • “这只是消费级设备。” 消费级设备也会组成僵尸网络。这里同样适用这些漏洞类型。
  • “我们无法修补,所以为什么还要报告?” 应记录问题,以便了解风险并采取补偿性控制措施。
  • “供应商说它是安全的。” 供应商的声明不是证据。文件系统才是证据。
  • “这是定制 RTOS,不是 Linux,所以标准工具无法使用。” 架构层面的工具(Ghidra、QEMU、binwalk 熵分析)适用于任何二进制文件。应调整方法,而不是跳过分析。
  • “没人会费心攻击这台设备。” Mirai 曾扫描整个 IPv4 地址空间,寻找默认凭据。所谓“费心”的门槛,不过是运行一个脚本。

参考资料

  • analyzing-binaries -- 反汇编和逆向工程方法
  • auditing-code-for-vulnerabilities -- 有源代码时进行源码级审查
  • enumerating-network-services -- 服务发现与评估
  • reviewing-cryptography -- 密码学实现审查

评论

支持 Markdown