4、固件文件系统分析:文件系统挂载、目录结构分析、关键文件识别
固件文件系统分析是嵌入式漏洞挖掘的基石。当我们从设备中提取出固件二进制后,面对的是经过压缩、加密或自定义格式封装的原始数据。只有成功识别并挂载其内部文件系统,才能将固件从“黑盒”变为“白盒”,进而定位配置文件、脚本和二进制程序,为后续的漏洞分析提供具体目标。本章将深入讲解固件文件系统的挂载技术、目录结构分析方法以及关键文件的识别策略,帮助读者建立一套系统化的固件分析流程。
4.1 固件文件系统识别与挂载技术
4.1.1 核心原理:从固件镜像到可读文件系统
嵌入式固件通常是一个包含引导加载程序(Bootloader)、内核(Kernel)、根文件系统(Root Filesystem)和附加数据(如校准参数、Web 页面)的复合二进制镜像。文件系统分析的第一步是确定固件中是否包含文件系统,以及包含何种类型的文件系统。常见的嵌入式文件系统包括 SquashFS(只读压缩,广泛用于路由器)、JFFS2/UBIFS(闪存日志型)、CramFS(老式只读)、ext2/ext4(较少见)以及ROMFS。识别文件系统的核心工具是 binwalk,它通过扫描固件中的魔数(Magic Bytes)来定位文件系统的起始偏移量。
- SquashFS:文件头包含 "hsqs" 魔数,通常以 4KB 对齐。
- JFFS2:文件头包含 "19 85 20 03" 魔数,常见于 NAND Flash。
- CramFS:文件头包含 "0x28cd3d45"(小端序),较老设备使用。
- UBIFS:包含 "UBI#" 节点,通常需要配合 UBI 工具处理。
4.1.2 操作流程:使用 Binwalk 与手动挂载
标准操作流程分为自动提取和手动挂载两种路径。自动提取使用 binwalk -e 命令,它会自动递归提取所有识别的文件。但自动提取有时会失败或产生错误偏移,此时需要手动挂载。
# 自动提取(推荐优先尝试)
binwalk -e firmware.bin
# 手动识别文件系统偏移
binwalk firmware.bin
# 手动挂载 SquashFS(假设偏移为 0x123456)
mkdir /mnt/fw
mount -o loop,offset=$((0x123456)) -t squashfs firmware.bin /mnt/fw
# 手动挂载 JFFS2(需要 mtdram 模块)
modprobe mtdram total_size=16384 erase_size=128
modprobe mtdblock
dd if=firmware.bin of=/dev/mtdblock0 bs=1 skip=$((0x123456))
mount -t jffs2 /dev/mtdblock0 /mnt/fw
对于使用 UBI 的固件,需要先使用 ubiformat 和 ubiattach 工具模拟 NAND 设备。对于加密固件,则需要先进行解密或寻找硬件漏洞绕过加密。
| 工具 | 适用场景 | 优点 | 局限性 |
|---|---|---|---|
| binwalk | 快速扫描与提取 | 自动化程度高,支持多种格式 | 对损坏或自定义格式可能失效 |
| mount -o loop | SquashFS/Ext 等 | 直接挂载,可读写(只读挂载更安全) | 需要 root 权限,依赖内核支持 |
| unsquashfs | SquashFS 专用 | 无需 root,可解压到目录 | 仅支持 SquashFS |
| jefferson | JFFS2 专用 | Python 实现,跨平台 | 对损坏镜像处理能力弱 |
| ubi_reader | UBIFS 专用 | 提取 UBI 镜像内容 | 需要额外安装,依赖 Python |
4.1.3 案例拆解:某品牌路由器固件的挂载实战
假设我们获取了一个 16MB 的路由器固件 router_v1.0.bin。初始 file 命令显示为 "data",无法识别。使用 binwalk 扫描后,输出显示在偏移 0x1F0000 处存在 SquashFS 文件系统。我们尝试 binwalk -e 自动提取,但提取出的文件系统不完整,部分目录缺失。此时采用手动挂载:
mkdir -p /mnt/router_fs
mount -o loop,offset=$((0x1F0000)) -t squashfs router_v1.0.bin /mnt/router_fs
ls -la /mnt/router_fs/etc/
挂载成功后,我们看到了完整的 /etc 目录,包含 passwd、shadow、init.d/ 等关键文件。通过对比自动提取与手动挂载的结果,发现 binwalk -e 在提取过程中遗漏了部分符号链接和特殊文件,这提醒我们:自动提取结果必须经过完整性校验,手动挂载是验证和补充的最佳手段。
-o ro),避免意外修改宿主机文件系统。对于未知来源的固件,建议在虚拟机或容器中操作,防止恶意固件中的脚本在宿主机上执行。
4.2 目录结构分析与关键路径定位
4.2.1 核心原理:嵌入式 Linux 目录约定
绝大多数嵌入式设备基于 Linux 内核,其目录结构遵循 FHS(Filesystem Hierarchy Standard)的简化版本。但与桌面 Linux 不同,嵌入式系统通常使用 BusyBox 提供精简的 Unix 命令集,目录结构也更为紧凑。理解目录结构有助于快速判断设备的功能模块、网络服务类型以及潜在的漏洞入口。
4.2.2 判断方法:重点目录与文件清单
分析目录时,应重点关注以下路径:
- /etc:系统配置核心。包含
passwd(用户列表)、shadow(密码哈希)、inetd.conf或xinetd.d/(网络服务监听)、init.d/或rcS(启动脚本)、web或lighttpd(Web 服务器配置)。 - /bin, /sbin, /usr/bin, /usr/sbin:二进制程序目录。重点关注
busybox(多功能命令)、telnetd、sshd、httpd、nvram(路由器参数读写工具)。 - /var:运行时数据。包含
tmp/(临时文件)、run/(进程 PID)、log/(日志)。 - /lib:共享库。查看
libc.so版本可判断系统架构和编译选项。 - /www 或 /htdocs:Web 页面文件。包含 HTML、PHP、CGI 脚本,是 Web 漏洞分析的重点。
- /nvram:非易失性存储挂载点,用于保存配置参数,常包含敏感信息。
4.2.3 实战场景:从目录结构还原设备功能
假设我们在固件中看到以下目录:
/etc/init.d/S50dropbear
/etc/init.d/S70httpd
/usr/sbin/dropbear
/usr/sbin/lighttpd
/www/cgi-bin/admin.cgi
/bin/nvram
通过分析,我们可以判断:该设备启用了 SSH 服务(dropbear)、Web 服务(lighttpd),存在 CGI 管理接口(admin.cgi),并且使用 nvram 保存配置。攻击面初步确定为:SSH 弱口令、Web 管理界面漏洞、CGI 注入、nvram 配置篡改。进一步查看 /etc/passwd 和 /etc/shadow 文件,如果发现空密码或默认密码哈希,则可以直接尝试登录。
/etc/passwd.bak、/etc/config.xml.bak 可能包含旧版本配置或未加密的密码。使用 ls -la 查看所有文件,并注意文件权限位(SUID 文件是提权漏洞的高发点)。
4.3 关键文件识别:配置文件、脚本与二进制程序
4.3.1 核心原理:三类文件的不同分析价值
关键文件识别是固件分析的核心产出。配置文件提供了系统的逻辑视图,脚本揭示了系统启动和运行时的行为逻辑,二进制程序则是漏洞挖掘的最终目标。三者相互关联:配置文件决定服务如何启动,脚本调用二进制程序,二进制程序读取配置文件。
4.3.2 识别与分析方法
配置文件分析:使用 grep 搜索敏感关键字,如 password、passwd、、secret、key。重点关注 Web 配置文件(如 lighttpd.conf)、网络服务配置(dropbear 配置)、以及应用层配置(如 mqtt.conf)。
grep -r "password" /mnt/router_fs/etc/
grep -r "admin" /mnt/router_fs/etc/
脚本分析:查看 /etc/init.d/ 下的启动脚本,理解服务的启动顺序和参数。检查是否存在 wget、curl、nc 等网络工具被脚本调用,这可能是命令注入的入口。同时,注意脚本中是否包含硬编码的 IP 地址或密钥。
二进制程序分析:使用 file 命令确认架构(ARM/MIPS/x86),使用 strings 提取可打印字符串,查找格式化字符串漏洞线索、文件路径、IP 地址等。对于网络服务程序,使用 checksec 检查安全属性(NX、PIE、RELRO、Stack Canary)。
| 文件类型 | 分析工具 | 关注点 | 漏洞示例 |
|---|---|---|---|
| 配置文件 | grep, cat, vim | 明文密码、调试开关、远程管理配置 | 硬编码后门账号 |
| 脚本文件 | cat, shellcheck | 外部输入拼接、危险命令调用 | 命令注入 (CVE-2021-xxxx) |
| 二进制程序 | strings, objdump, Ghidra | 危险函数 (system, strcpy)、网络监听端口 | 缓冲区溢出、格式化字符串 |
4.3.3 案例拆解:从配置文件到远程代码执行的完整链路
在某 IP 摄像头的固件分析中,我们通过目录结构分析定位到 /etc/init.d/S99start.sh 脚本。该脚本内容如下:
#!/bin/sh
/usr/bin/rtsp_server -c /etc/rtsp.conf &
/usr/bin/cloud_connect -s $SERVER_IP -p 8080 &
进一步查看 /etc/rtsp.conf,发现其中包含 username=admin 和 password=123456 的明文凭据。同时,cloud_connect 二进制程序通过 strings 分析发现其调用了 system() 函数,且参数中包含从网络接收的数据。通过逆向 cloud_connect,我们确认其存在命令注入漏洞:攻击者可以通过构造特定的云平台消息,在设备上执行任意命令。整个分析链路为:目录定位 → 脚本分析 → 配置提取 → 二进制逆向 → 漏洞确认。这一案例表明,固件文件系统分析不是孤立的步骤,而是为后续漏洞利用提供关键输入。
4.4 常见误区与总结复盘
4.4.1 常见误区
- 误区一:过度依赖 binwalk 自动提取。自动提取可能遗漏文件或错误识别文件系统类型,导致后续分析方向错误。务必使用
mount或unsquashfs进行验证。 - 误区二:忽略文件权限和所有权。SUID 文件、全局可写的配置文件是提权漏洞的温床。使用
find / -perm -4000查找 SUID 文件。 - 误区三:只关注二进制程序,忽视脚本和配置。许多 IoT 漏洞源于脚本中的命令注入或配置中的弱口令,而非复杂的二进制漏洞。
- 误区四:不检查文件系统完整性。提取后应检查关键文件是否存在、符号链接是否有效,避免因提取不完整而错过重要线索。
4.4.2 总结复盘
固件文件系统分析是连接固件提取与漏洞挖掘的桥梁。一个高效的分析流程应包含:识别(Identify)→ 挂载(Mount)→ 探索(Explore)→ 提取(Extract)→ 关联(Correlate)。识别阶段确定文件系统类型和偏移;挂载阶段获得可操作的目录视图;探索阶段梳理目录结构和关键路径;提取阶段将关键文件复制到分析环境;关联阶段将配置文件、脚本和二进制程序串联起来,形成完整的攻击面视图。建议分析人员建立固件分析清单,记录每个文件的哈希值、分析状态和发现的问题,确保分析过程的系统性和可追溯性。