2、固件基础:固件类型(BIOS/UEFI/嵌入式)、固件存储介质与启动流程概述
固件是介于硬件与操作系统之间的关键软件层,它直接控制硬件初始化、资源抽象与系统引导。在反逆向工程与安全启动实现课程中,理解固件的类型、存储介质和启动流程是后续分析漏洞、提取固件、绕过签名校验或植入持久化后门的基础。不同固件类型(BIOS、UEFI、嵌入式固件)在存储布局、执行环境和安全模型上存在显著差异,而启动流程则决定了攻击面暴露的时序与可利用的信任边界。本章将系统梳理这三部分核心知识,并建立固件安全分析的全局视图。
上图从宏观层面展示了三类固件的核心特征、存储介质和启动路径。BIOS作为传统方案已逐渐被UEFI取代,但在某些嵌入式或工业场景中仍在使用;UEFI引入了模块化驱动和Secure Boot机制,是现代PC和服务器的主流;嵌入式固件则因硬件资源受限,通常采用更精简的Bootloader+内核架构。存储介质的选择直接影响固件提取难度和更新策略,而启动流程的差异则决定了安全验证的插入点。下面逐一深入分析。
2.1 固件类型深度解析
2.1.1 BIOS(Legacy BIOS)
BIOS(Basic Input/Output System)诞生于1981年,最初为IBM PC设计。它运行在16位实模式下,代码量通常为512KB到2MB,存储在SPI NOR Flash中。BIOS的核心职责包括:上电自检(POST)、初始化中断向量表、提供基本I/O服务(通过INT 13h磁盘访问、INT 10h显示输出等)、加载主引导记录(MBR)并跳转执行。
从逆向工程角度看,BIOS固件具有以下特征:
- 代码结构:由厂商特定的初始化模块、ACPI表、VGA BIOS Option ROM、PCI Option ROM组成,通常以压缩或非压缩形式存在。
- 入口点:复位向量位于4GB地址空间的顶部(0xFFFFFFF0),该地址映射到Flash的末尾偏移处。
- 安全弱点:BIOS本身不验证MBR的签名,攻击者可通过修改MBR实现Bootkit持久化(如TDL4、Mebromi)。
- 分析工具:使用IDA Pro加载BIOS ROM,配合Phoenix/Award/AMI的模块解析脚本;硬件编程器(如CH341A)用于读取Flash内容。
2.1.2 UEFI(统一可扩展固件接口)
UEFI取代BIOS成为现代固件标准,它运行在32位或64位保护模式下,支持网络栈、图形界面和大容量存储。UEFI固件体积通常在2MB到32MB之间,存储在SPI NOR Flash中,并包含NVRAM用于保存启动变量。其核心组件包括:
- SEC(安全验证):负责CPU初始化、Cache作为RAM(CAR)设置、以及验证PEI阶段的签名。
- PEI(EFI预初始化):初始化内存控制器、发现内存、提供PEI模块(PEIM)服务。
- DXE(驱动执行环境):加载大部分设备驱动,创建EFI系统表、句柄数据库和协议接口。
- BDS(启动设备选择):根据BootOrder变量选择启动项,加载OS Loader(如bootmgfw.efi)。
- Runtime(运行时):在OS启动后仍驻留内存,提供GetVariable/SetVariable等运行时服务。
UEFI的安全启动(Secure Boot)机制通过PK(平台密钥)、KEK(密钥交换密钥)和db(签名数据库)验证每个加载的EFI驱动和OS Loader的签名。逆向UEFI固件时,使用UEFITool提取FFS(固件文件系统)中的模块,再通过IDA Pro分析DXE驱动。关键攻击面包括:
- NVRAM变量注入(如通过CVE-2016-7255修改BootOrder)
- DXE驱动中的内存破坏漏洞(如SmmCallout)
- Secure Boot绕过(如CVE-2019-14584,利用签名数据库解析缺陷)
2.1.3 嵌入式固件
嵌入式固件覆盖路由器、IoT设备、工业控制器、汽车ECU等。其存储介质多样,包括SPI NOR、NAND Flash、eMMC、SD卡等。嵌入式固件通常分为Bootloader(如U-Boot、Coreboot、ARM Trusted Firmware)、操作系统内核(Linux/RTOS)和根文件系统。启动流程一般为:芯片内部ROM(BootROM)→ Bootloader Stage1 → Bootloader Stage2 → Kernel → Init进程。
嵌入式固件的逆向特点:
- 固件打包格式:常见为TRX(TP-Link)、CHK(D-Link)、BIN(各种厂商自定义),头部包含魔数、版本、校验和。
- 文件系统:SquashFS、JFFS2、UBIFS、CramFS,需使用binwalk或jefferson解包。
- 架构多样性:ARM、MIPS、RISC-V、Xtensa,需使用Ghidra或IDA的对应处理器模块。
- 安全机制:部分设备启用Secure Boot(如苹果T2、高通骁龙),使用OTP熔丝存储根密钥,BootROM校验Bootloader签名。
2.2 固件存储介质与提取方法
固件存储介质决定了提取难度和更新方式。下表对比了常见介质的特性:
| 介质类型 | 容量范围 | 接口 | 读取方式 | 典型应用 | 提取难度 |
|---|---|---|---|---|---|
| SPI NOR Flash | 1MB - 64MB | SPI (1-1-4) | 编程器/芯片飞线 | BIOS/UEFI/路由器 | 中(需拆焊或夹子) |
| NAND Flash | 128MB - 8GB | 并行/ONFI | 编程器+坏块管理 | 嵌入式Linux | 高(需处理ECC) |
| eMMC/UFS | 4GB - 256GB | MMC/UFS协议 | 读卡器/板级调试 | 手机/平板 | 中(需BGA焊接) |
| NVRAM | 64KB - 1MB | I2C/SPI | UEFI Shell命令 | UEFI变量 | 低(软件读取) |
| OTP/efuse | 1KB - 16KB | 内部总线 | 专用工具/JTAG | 密钥/信任根 | 极高(物理不可复制) |
提取固件的标准流程包括:
- 硬件识别:查看PCB丝印,确认Flash芯片型号(如Winbond W25Q128、Micron MT29F2G08)。
- 接口连接:使用SOIC-8测试夹或热风枪拆焊,连接编程器(如RT809H、TL866II)。
- 读取与校验:读取全片数据,与芯片ID核对;多次读取并比对哈希,确保数据完整性。
- 固件解析:使用binwalk扫描文件系统、压缩段和头部信息;对于NAND,需先处理OOB区域和坏块表。
2.3 启动流程与信任链分析
启动流程是安全启动实现的核心。不同固件类型的信任链构建方式如下:
2.3.1 BIOS启动流程
BIOS启动流程相对简单:CPU复位后从0xFFFFFFF0执行第一条指令(跳转到BIOS入口),BIOS完成POST后,根据CMOS设置中的启动顺序,读取第一个可引导设备的MBR(0扇区)到0x7C00,检查0x55AA魔数后跳转执行。MBR中的引导代码再读取活动分区的VBR(卷引导记录),最终加载OS内核。
该流程的信任链薄弱点在于:
- MBR和VBR均无签名验证,攻击者可通过修改磁盘引导扇区实现持久化。
- BIOS固件自身更新通常不验证签名(老设备),可通过SMM或Flash写入漏洞植入恶意代码。
2.3.2 UEFI安全启动流程
UEFI Secure Boot的信任链从平台密钥(PK)开始。启动时,SEC阶段验证PEI阶段(通过Firmware Volume中的签名),DXE阶段加载驱动时,由安全架构协议(Security Architecture Protocol)检查驱动签名是否在db数据库中。OS Loader(如shim.efi或bootmgfw.efi)也必须签名。整个验证过程涉及:
PK (平台密钥) → KEK (密钥交换密钥) → db (允许签名数据库) / dbx (禁止签名数据库)
验证流程:
1. 固件读取PK公钥,验证KEK签名
2. 使用KEK验证db/dbx更新
3. 加载驱动/OS Loader时,计算其哈希或验证签名
4. 若签名在db中且不在dbx中,则允许执行;否则拒绝
逆向分析UEFI启动流程时,可关注以下关键点:
- 使用Chipsec工具检测SMM(系统管理模式)代码是否可被篡改。
- 分析NVRAM中的BootOrder和BootXXXX变量,了解启动项配置。
- 在QEMU中模拟UEFI固件,使用GDB调试DXE驱动。
2.3.3 嵌入式启动流程(以ARM为例)
ARM嵌入式设备的典型启动链为:BootROM(固化在芯片内)→ 加载Bootloader到SRAM → Bootloader初始化DDR → 加载内核到DDR → 启动内核。安全启动实现通常包括:
- BootROM:验证Bootloader(如U-Boot SPL)的签名,使用OTP中的公钥哈希。
- ATF(ARM Trusted Firmware):在EL3特权级别运行,验证BL33(U-Boot或内核)的签名。
- 内核验证:使用dm-verity或IMA(完整性度量架构)验证根文件系统。
背景与目标:该路由器使用联发科MT7621A方案,固件版本为3.14.1,需提取固件以分析后门漏洞。
初始现象:通过Web管理界面无法直接下载固件,且UART接口未焊接排针。
关键输入:设备拆解后,发现SPI Flash型号为Winbond W25Q128(16MB),VCC为3.3V。
分析过程:使用CH341A编程器配合测试夹,在断电状态下读取Flash全片。读取两次并比对MD5一致后,使用binwalk扫描固件,发现偏移0x20000处有TRX头部,0x2A0000处为SquashFS文件系统。
操作步骤:① 使用binwalk -e firmware.bin解包;② 使用unsquashfs提取根文件系统;③ 在/etc/passwd中发现硬编码密码哈希;④ 在/usr/sbin/lighttpd中搜索字符串,发现隐藏的调试接口。
结果对比:成功获取root shell,确认存在CVE-2020-XXXX(命令注入漏洞)。
风险与代价:拆焊Flash可能导致焊盘损坏,测试夹接触不良可能读取错误数据。建议先使用软件方式(如通过UART进入U-Boot,使用md命令读取内存)尝试提取。
复盘经验:对于SPI Flash,优先使用测试夹而非拆焊;读取后务必校验哈希;解包时注意文件系统偏移,避免遗漏。
2.4 常见误区与总结复盘
在固件分析与安全启动实现中,初学者常犯以下错误:
- 误区一:混淆BIOS与UEFI的存储布局。BIOS的Option ROM位于C0000h-EFFFFh地址空间,而UEFI的固件卷(FV)位于Flash的特定偏移,两者解析方式完全不同。
- 误区二:忽略NAND的坏块管理。直接读取NAND原始数据会导致ECC错误和坏块干扰,必须使用NAND控制器或软件模拟坏块表。
- 误区三:认为Secure Boot安全。Secure Boot只验证启动链,不保护运行时内存。SMM漏洞(如CVE-2021-20226)可绕过Secure Boot。
- 误区四:忽视启动流程中的时间窗口。在SEC到PEI切换期间,Cache作为RAM(CAR)的使用可能导致数据残留,攻击者可利用该窗口注入恶意代码。
总结复盘:固件类型决定了分析工具和攻击面,存储介质影响提取策略,启动流程则定义了信任边界。在实际项目中,建议按以下顺序推进:
- 识别固件类型(通过字符串、头部魔数、硬件平台)
- 选择合适的提取方法(硬件编程器/软件读取/网络升级包捕获)
- 解析固件结构(binwalk、UEFITool、自定义脚本)
- 分析启动流程中的验证点(签名检查、哈希比对、信任根)
- 针对薄弱环节实施逆向或加固
下一阶段的学习将聚焦于固件逆向的具体技术,包括指令集识别、压缩算法还原和动态调试环境搭建。掌握本章基础后,你将能够准确判断目标固件的分析路径,并为后续的漏洞挖掘和防护加固奠定坚实基础。