一、固件安全基础:从认识固件开始
大家好,我是老周。做二进制安全这些年,我见过太多人一上来就拿着工具瞎扫,结果连固件是什么都没搞清楚。今天咱们先把地基打牢。
说白了,固件就是「嵌入在硬件里的软件」。它不像 Windows 或 Linux 那样装在硬盘上,而是直接烧录在 ROM、Flash 这类非易失性存储器里。你家里的路由器、智能门锁、汽车 ECU,甚至你桌上的键盘——里面都跑着固件。
1.1 什么是固件?
固件(Firmware)这个词,最早是 1967 年由 Ascher Opler 提出的。它处于硬件和软件之间,负责直接操控硬件寄存器、初始化外设、提供运行时服务。
我习惯把固件理解成「硬件的灵魂」。没有它,芯片就是一块死硅片。
核心定义:固件是存储在只读或非易失性存储器中的、与硬件紧密耦合的系统级软件。它通常包含引导加载程序、操作系统内核、文件系统、设备驱动和应用程序。
举个例子,你按下路由器电源键,最先执行的就是 BootROM 里的固件代码。它初始化 CPU、检测内存、加载第二阶段引导程序,最后启动完整的操作系统。整个过程,用户是看不见的。
1.2 固件与软件的区别
很多新手问我:「固件不就是软件吗?」嗯,从代码层面看确实都是二进制指令。但从工程角度看,区别大了去了。我整理了一张对比表:
| 对比维度 | 固件 | 普通软件 |
|---|---|---|
| 存储介质 | ROM、Flash、EEPROM | 硬盘、SSD、光盘 |
| 更新方式 | 烧录、OTA 升级(有风险) | 安装包、覆盖安装 |
| 与硬件关系 | 直接操作寄存器、中断向量 | 通过操作系统 API 间接访问 |
| 调试难度 | 需要 JTAG/SWD、逻辑分析仪 | IDE 断点、日志即可 |
| 崩溃后果 | 设备变砖,可能无法恢复 | 程序崩溃,重启即可 |
| 生命周期 | 通常与硬件同寿命(5-10年) | 随版本迭代频繁更新 |
你想想看,普通软件崩溃了,最多弹个错误框。固件要是写崩了——我曾经遇到过一台工业 PLC 因为固件升级掉电,整个产线停了三天。这就是为什么固件安全比普通软件安全更致命。
1.3 固件安全的重要性
为什么我们要专门研究固件漏洞?三个字:控制权。
固件是设备里权限最高的代码。它运行在最高特权级(比如 ARM 的 EL3 或 x86 的 SMM),可以访问所有内存和外设。一旦固件被攻破,攻击者就能获得对设备的完全控制——而且这种控制是持久化的,你重装操作系统都没用。
我记得 2017 年有个经典案例:某品牌企业级防火墙被爆出固件后门。攻击者通过修改固件中的 SSH 认证逻辑,可以凭任意密码登录设备。更可怕的是,这个后门在固件升级后依然存在——因为它藏在 BootROM 里,普通升级根本覆盖不到。
⚠️ 注意:固件漏洞的修复成本极高。很多 IoT 设备出厂后就不再有固件更新,或者更新流程本身就有漏洞。这意味着一个固件漏洞可能伴随设备终身。
从攻击面来看,固件安全涉及整个供应链:
- 芯片设计阶段:硬件安全模块(HSM)设计缺陷
- 固件开发阶段:编码漏洞、调试接口未关闭
- 生产烧录阶段:密钥泄露、固件被篡改
- 用户使用阶段:OTA 升级被中间人攻击
说白了,固件安全就是设备安全的最后一道防线。破了这道防线,下面全是裸奔。
1.4 常见固件漏洞类型
做固件分析这些年,我遇到的漏洞类型五花八门。但归纳起来,无非这么几类:
1.4.1 缓冲区溢出
这是固件里最常见的漏洞。嵌入式系统资源有限,开发者经常手动管理内存,一不小心就写越界了。我曾经逆向过一个路由器固件,它的 HTTP 解析函数里有个 strcpy()——嗯,你没看错,2020 年的产品还在用 strcpy。攻击者发送超长 POST 数据就能触发栈溢出,直接拿到 root shell。
// 真实案例:某路由器固件中的漏洞代码
void handle_request(char *input) {
char buffer[256];
strcpy(buffer, input); // 没有长度检查!
// ... 处理请求
}
1.4.2 硬编码凭据
这个我见得最多。很多厂商为了方便调试,在固件里留了后门账号。更离谱的是,有些产品出厂时 debug 账号密码是固定的,而且文档里写得明明白白。
💡 小技巧:用 binwalk 解包固件后,直接 grep 搜索 "password"、"secret"、"key" 等关键词,经常有惊喜。
1.4.3 不安全的 OTA 升级
固件升级过程如果没有做签名验证,攻击者就能伪造升级包。我参与过一个智能门锁的渗透测试,它的 OTA 升级包连基本的哈希校验都没有——直接明文传输,任何人都能篡改。
1.4.4 调试接口未关闭
JTAG、SWD、UART 这些调试接口,在产品量产时应该被物理熔断或禁用。但很多厂商为了售后方便,把这些接口留到了用户设备上。攻击者只要焊几根线,就能直接读取 Flash 内容、单步调试固件。
1.4.5 逻辑漏洞
这类漏洞比较隐蔽。比如固件中的访问控制逻辑有缺陷,低权限用户能调用高权限接口。我遇到过一台打印机,它的固件里有个「维护模式」——通过发送特定 SNMP 命令就能进入,然后可以任意读写 NVRAM。
1.5 固件安全知识体系
下面这张图是我自己梳理的固件安全知识框架。你跟着这个体系学,不会走偏。
1.6 本章小结
这一章我们聊了固件的定义、它与普通软件的区别、为什么固件安全如此重要,以及最常见的几类漏洞。你可能觉得内容有点基础——但相信我,后面章节里那些花哨的漏洞利用技术,全都建立在这些基础概念之上。
我曾经带过一个新人,他上来就问「怎么用 Ghidra 找 0day」。我说你先告诉我固件里哪段代码是 Bootloader,哪段是内核,哪段是文件系统——他答不上来。嗯,这就是为什么我们要从最基础的东西开始。