3. 固件静态分析:Binwalk、字符串与后门排查

静态分析,说白了就是不动手运行固件,直接拆开看。我做了这么多年逆向,发现很多新手一上来就急着调试、跑模拟器,结果连固件里藏着什么都不知道。其实,静态分析能解决 70% 的安全问题——硬编码密码、后门账号、明文密钥,这些都在文件里躺着等你发现。

这一章,我带你走一遍我的标准流程:从拆固件、搜字符串,到揪出那些不该存在的东西。

3.1 Binwalk:固件拆解第一刀

拿到一个固件,我第一件事就是跑 binwalk。它就像一把瑞士军刀,能识别文件类型、提取文件系统、甚至帮你分析熵值。

3.1.1 基本扫描与提取

先来个快速扫描:

binwalk firmware.bin

输出会告诉你固件里嵌了哪些东西——比如 U-Boot、LZMA 压缩段、SquashFS 文件系统。我个人习惯加个 -Me 参数,一步到位:

binwalk -Me firmware.bin

这个命令会递归提取所有已知类型的文件。嗯,这里要注意:提取出来的文件会按偏移量命名,比如 12345.squashfs。你最好建个目录专门放这些碎片。

我的小技巧: 如果 binwalk 识别不出文件系统,试试 binwalk -E firmware.bin 看熵值图。高熵区域通常代表压缩或加密数据。我曾经遇到一个固件,厂商把文件系统藏在了高熵段后面,靠熵值图才找到。

3.1.2 手动识别与常见陷阱

Binwalk 不是万能的。有些固件会故意混淆头部,或者用非标准偏移。这时候你得手动看十六进制:

hexdump -C firmware.bin | head -100

常见的文件系统魔数你得记住几个:

文件系统 魔数(十六进制) 说明
SquashFS hsqs (0x68737173) 最常见,只读压缩
CramFS 0x28cd3d45 老设备还在用
JFFS2 0x19851985 带日志,适合 NAND
UBIFS 0x31181006 新设备常见
避坑指南: 我曾经遇到一个固件,binwalk 提取出来的文件系统是空的。后来发现厂商在固件末尾附加了一个 XOR 校验字节,导致 binwalk 误判了偏移量。解决办法:先 dd 去掉最后 1 字节,再跑 binwalk。

3.2 字符串分析:从垃圾堆里找金子

提取出文件系统后,下一步就是翻字符串。你想想看,一个固件里少说几万个字符串,但真正有价值的就那么几个——密码、路径、调试信息。

3.2.1 基础字符串提取

我通常这样干:

strings extracted_rootfs/* | grep -iE '(password|passwd|pwd|secret|key|token|admin|root|debug)' | sort -u

这个命令会从所有提取出的文件里搜关键词。但要注意,strings 默认只抓长度 >= 4 的 ASCII 字符串。如果固件用了 UTF-16 或短字符串,你得加参数:

strings -e l extracted_rootfs/bin/busybox   # 小端 UTF-16
strings -n 3 extracted_rootfs/etc/passwd     # 长度 >= 3

3.2.2 硬编码凭据的典型藏身地

根据我的经验,硬编码凭据最爱藏在以下几个地方:

  • /etc/shadow 或 /etc/passwd:直接看哈希值,如果哈希是空的或者常见弱密码(比如 admin:admin),那就是漏洞。
  • Web 配置文件:比如 lighttpd.conf、httpd.conf,里面可能有 Basic Auth 的明文密码。
  • 二进制文件中的字符串:比如 /bin/login、/sbin/init,用 strings 搜 pass 或 login。
  • 脚本文件:.sh、.lua、.py 里经常有写死的 API Key 或数据库密码。
真实案例: 我分析过一个 IP 摄像头固件,在 /usr/bin/rtsp_server 里搜到了字符串 admin:888888。这不是配置文件,是编译进二进制里的硬编码。厂商后来承认这是调试账号,忘了删。

3.3 后门查找:那些不该存在的入口

后门分两种:一种是厂商故意留的(比如调试接口),另一种是攻击者植入的。静态分析能帮你找到前者,后者通常需要动态分析配合。

3.3.1 常见后门模式

我总结了几种高频出现的后门:

后门类型 特征 查找方法
Telnet/SSH 后门 非标准端口、硬编码密码 搜 telnetd、sshd、dropbear
Web Shell cmd.php、shell.asp 搜 exec、system、popen
调试接口 UART 控制台、JTAG 搜 debug、console、serial
隐藏账号 /etc/passwd 中 UID=0 检查 UID 0 的非 root 账号

3.3.2 实战:用 grep 和 binwalk 联合排查

我常用的一个组合拳:

# 1. 提取固件
binwalk -Me firmware.bin

# 2. 进入文件系统
cd _firmware.bin.extracted/squashfs-root

# 3. 搜所有可执行文件中的可疑字符串
find . -type f -executable -exec strings {} \; | grep -iE '(backdoor|shell|cmd|exec|system\(|popen|eval)' | sort -u

# 4. 检查所有配置文件中的 IP 和端口
grep -rE '([0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]+' etc/ usr/etc/ 2>/dev/null

# 5. 找所有 SUID 文件(提权后门常见)
find . -perm -4000 -type f
我曾经踩过的坑: 有一次我搜 backdoor 什么都没找到,后来发现后门是通过 LD_PRELOAD 环境变量注入的,静态分析根本看不到。所以记住:静态分析不是万能的,它只能找「静态存在」的东西。动态行为分析是下一章的事。

3.4 知识体系:静态分析全景图

下面这张图是我自己梳理的静态分析流程,你照着走基本不会漏东西:

固件静态分析流程 固件静态分析核心流程 1. 固件获取 2. Binwalk 拆解与提取 3. 文件系统分析 字符串分析 grep / strings 硬编码凭据 密码 / 密钥 / Token 后门排查 SUID / 隐藏账号 漏洞清单输出 注意:静态分析无法检测运行时行为

3.5 自动化脚本:批量扫描硬编码凭据

手动翻太累?我写了个小脚本,能自动扫描常见凭据:

#!/bin/bash
# scan_creds.sh - 批量扫描固件中的硬编码凭据
# 用法: ./scan_creds.sh /path/to/extracted/rootfs

ROOTFS="$1"
if [ -z "$ROOTFS" ]; then
    echo "用法: $0 <rootfs目录>"
    exit 1
fi

echo "[*] 扫描硬编码凭据..."
echo "=============================="

# 1. 检查 /etc/passwd 和 /etc/shadow
if [ -f "$ROOTFS/etc/passwd" ]; then
    echo "[+] /etc/passwd 内容:"
    grep -v '^#' "$ROOTFS/etc/passwd" | grep -v '^$'
fi

# 2. 搜索常见密码模式
echo "[+] 搜索密码字符串..."
find "$ROOTFS" -type f -exec strings {} \; | grep -iE '(password|passwd|pwd)=' | sort -u

# 3. 搜索硬编码 IP 和端口
echo "[+] 搜索硬编码 IP:端口..."
grep -rE '([0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]+' "$ROOTFS" 2>/dev/null | head -20

# 4. 搜索 SUID 文件
echo "[+] SUID 文件列表:"
find "$ROOTFS" -perm -4000 -type f 2>/dev/null

echo "=============================="
echo "[*] 扫描完成。"
进阶技巧: 你可以把这个脚本集成到 CI/CD 里。每次固件编译完自动跑一遍,如果发现新的硬编码凭据就报警。我帮客户搭建过这样的流水线,效果很好。

3.6 本章小结

静态分析是固件安全的第一道防线。Binwalk 帮你拆开固件,字符串分析帮你找到线索,后门排查帮你揪出隐患。记住:不要只依赖工具,你得理解文件系统结构、常见藏匿手法,以及——嗯,保持怀疑。厂商说「没有后门」的时候,我通常先跑一遍 strings 再说。