1. 固件安全概述
大家好,欢迎来到这门课。我是你们的讲师,一个在嵌入式安全领域摸爬滚打了十几年的老兵。
咱们开门见山。固件安全,说白了就是保护设备“脑子”里的那套程序。你想想看,从智能灯泡到心脏起搏器,从路由器到卫星,哪个设备没有固件?一旦固件被攻破,设备就不再是你的设备了。我见过太多因为固件漏洞导致整个产品线召回的例子,那损失,真金白银,触目惊心。
1.1 固件定义与分类
先聊聊固件到底是什么。很多人觉得固件就是“写在ROM里的软件”。这个说法有点过时了。我个人习惯的定义是:固件是固化在非易失性存储器中的、负责硬件初始化和底层控制的软件代码。它介于硬件和操作系统之间,是硬件灵魂的载体。
固件的分类,我一般按两个维度来看:存储介质和功能层级。
| 分类维度 | 类型 | 典型例子 | 安全关注点 |
|---|---|---|---|
| 按存储介质 | ROM固件 | 早期BIOS、微控制器掩膜ROM | 无法修改,但可能被物理探测 |
| Flash固件 | UEFI、路由器固件、IoT设备固件 | 可被篡改、注入恶意代码 | |
| OTP固件 | 安全芯片、eFuse中的BootROM | 一次性编程,抗篡改强,但设计缺陷无法修复 | |
| 按功能层级 | Bootloader | U-Boot、Coreboot、Little Kernel | 信任根建立、签名校验 |
| 操作系统固件 | Linux内核、RTOS内核 | 内核漏洞、驱动提权 | |
| 应用固件 | Web服务、协议栈、业务逻辑 | 命令注入、缓冲区溢出 |
1.2 固件安全威胁模型
搞安全,先得知道敌人是谁,他们想干嘛。固件安全的威胁模型,我习惯从攻击者的视角来画。攻击者能接触到什么?他们有什么能力?
我把它总结为三个核心维度:攻击途径、攻击目标、攻击能力。
1.2.1 攻击途径
- 物理攻击: 直接接触设备。比如JTAG/SWD调试接口、串口、SPI Flash探针、侧信道攻击(功耗分析、电磁分析)。
- 网络攻击: 通过网络接口。比如远程代码执行、协议栈漏洞、固件更新中间人攻击。
- 供应链攻击: 在固件生产或分发过程中植入后门。比如恶意SDK、被污染的编译器、不安全的更新服务器。
1.2.2 攻击目标
- 提取固件: 读取Flash内容,逆向分析,寻找漏洞。
- 篡改固件: 植入恶意代码,修改设备行为。
- 绕过安全启动: 加载未签名的固件,破坏信任链。
- 持久化控制: 在固件中植入后门,即使重启或更新也无法清除。
1.2.3 攻击能力分级
| 能力等级 | 描述 | 典型攻击手段 |
|---|---|---|
| L1 - 远程脚本小子 | 只能通过网络远程攻击,无物理接触 | 扫描默认密码、利用已知CVE、命令注入 |
| L2 - 本地攻击者 | 能物理接触设备,但无专业设备 | UART串口读取、拆解Flash芯片、短接复位 |
| L3 - 专业实验室 | 拥有示波器、逻辑分析仪、探针台 | 侧信道分析、电压故障注入、激光攻击 |
| L4 - 国家级 | 拥有半导体级逆向能力 | FIB电路修改、芯片去层、光学逆向 |
1.3 固件安全生命周期
安全不是某个阶段的补丁,而是贯穿整个产品生命周期的活动。我把它分成五个阶段,每个阶段都有对应的安全动作。
下面这张图,是我自己一直在用的固件安全生命周期模型,分享给大家。
嗯,这张图的核心思想是:安全不是终点,而是一个闭环。每个阶段都会产生反馈,影响下一个阶段。
1.3.1 安全设计阶段
这是成本最低、效果最好的阶段。在这个阶段,我们要做威胁建模,确定信任边界,选择加密算法,设计安全启动链。我建议每个项目都画一张数据流图,标出所有攻击面。
1.3.2 安全开发阶段
代码质量是安全的基础。我个人习惯在CI/CD流水线里集成静态分析工具(比如Flawfinder、Cppcheck),自动扫描危险函数(strcpy、sprintf)。另外,一定要禁用调试接口,或者在生产版本中物理熔断JTAG。
1.3.3 安全验证阶段
光靠代码审查不够。必须做模糊测试(Fuzzing),用随机数据冲击固件的协议栈和文件解析器。我记得有一次,我们用AFL对某款路由器的HTTP解析器做Fuzzing,半小时就崩了三次,挖出两个堆溢出。
1.3.4 安全部署阶段
固件分发必须签名。而且,更新机制要支持回滚保护,防止攻击者刷回有漏洞的旧版本。这里有个坑:很多设备只校验了固件头部的签名,没校验整个镜像。攻击者可以替换签名后的有效载荷。
1.3.5 安全运维阶段
设备出厂不是结束。要有远程日志和异常检测机制。一旦发现漏洞,能快速推送安全更新。设备退役时,要安全擦除敏感数据,防止被翻新或逆向。