initialChris/hc08-fault-injection

GitHub: initialChris/hc08-fault-injection

一个针对NXP HC908微控制器的开源电压故障注入工具包,通过绕过监控模式身份验证实现锁定位片的固件完整提取。

Stars: 0 | Forks: 0

# HC08 故障注入 本仓库包含了在飞思卡尔/NXP MC68HC908微控制器上执行电压故障注入攻击所需的固件和硬件。 该工具允许您绕过监控模式(Monitor Mode)身份验证阶段并恢复中断向量(作为安全密码),从而实现对闪存的完整转储。

Serial Console Glitching Demo

## 目录 - [HC08 故障注入](#hc08-fault-injection) - [目录](#table-of-contents) - [前言](#preface) - [了解 HC908 监控模式](#understanding-hc908-monitor-mode) - [进入条件](#entry-conditions) - [时钟生成与波特率选择](#clock-generation-and-baud-rate-selection) - [身份验证序列](#authentication-sequence) - [监控命令](#monitor-commands) - [攻击概述](#attack-overview) - [时序攻击](#timing-attack) - [简单功耗分析 (SPA)](#simple-power-analysis-spa) - [故障注入](#fault-injection) - [硬件原理图](#hardware-schematic) - [引脚配置](#pinout-configuration) - [设计说明](#design-notes) - [MON08 驱动](#mon08-driver) - [主要特性](#key-features) - [配置](#configuration) - [小应用](#applets) - [故障注入器](#glitcher) - [转储器](#dumper) - [烧录代码](#flashing-the-code) - [环境要求](#requirements) - [构建与烧录](#build-and-flash) - [操作步骤](#operating-procedures) - [注入阶段](#glitching-phase) - [转储阶段](#dumping-phase) - [结果](#results) - [参考文献与扩展阅读](#references--further-reading) - [许可证](#license) ## 前言 在为我自己的汽车做一个项目时,我需要分析中控锁系统,该系统由各种MCU控制,其中包括一个飞思卡尔(现为NXP)的HC908微控制器。 为了能在替代原厂芯片的自定义芯片上实现新功能,我首先需要确切了解原厂固件是如何处理通信和逻辑的。 深入研究MC68HC908的数据手册后,我发现了**MON08**。监控模式是一个用于调试和编程的内置接口。然而,我立即遇到了一个重大安全障碍。要访问完整的命令集(包括内存读取),需要一个**8字节(64位)的身份验证序列**。考虑到该协议的时序限制,**暴力破解**方法在数学和实际上都是**不可能的**。 我开始研究专业的汽车编程器(如 _Multi-Prog_ 或 _ETL 908_)是如何绕过这种安全机制的。我的研究表明,这些工具通常依赖于特定制造商使用的已知密码或向量的预定义字典。不幸的是,我无法收集到更多信息,因为这些工具是严格闭源的,我也没有机会接触它们以分析其内部工作原理。 这促使我探索科学文献,寻找展示通过硬件攻击绕过芯片安全技术的手段,特别是**简单功耗分析**和**故障注入**。 为了确保拥有一个受控的环境并避免在测试过程中损坏原始MCU,我购买了一片 **MC68HC908QY4A** 作为**参考目标**来开始开发阶段。由于我可以随意对该芯片进行重新编程,因此我完全掌握其安全序列。这使我能够在转向实际目标之前,校准毛刺时序、分析功耗曲线并验证攻击成功率。 虽然HC08架构的漏洞多年来一直为人所知并遭到利用,但我发现关于该特定系列故障注入的文档非常匮乏。据我所知,这是首个有记录的在HC908上成功实施电压毛刺攻击的案例,尤其是使用非专业设备完成的。 我的实验装置包括一台基础的 _24MHz WeAct 逻辑分析仪_、一台 _Hantek DSO5102P_ 和一块 _STM32F401 Nucleo 开发板_。 ## 了解 HC908 监控模式 以下信息收集自 [MC68HC908QY4A 数据手册](https://www.nxp.com/docs/en/data-sheet/MC68HC908QY4.pdf) 的 _第15.3节_

Monitor Mode - Block Diagram

### 进入条件 要强制已编程的MCU进入监控模式,必须满足以下条件: * IRQ 引脚上的电压必须至少为 $V_{TST} = V_{DD} + 2.5V$。 * 特定的 GPIO 引脚必须根据目标芯片连接到相应的逻辑电平。对于 *QY4A*,配置为 `PTA0 = 1`、`PTA1 = 1` 和 `PTA4 = 0`。 在这些条件下上电后,芯片进入MON08模式并等待一个8字节的安全序列。如果正确,闪存将被解锁;否则,读取命令将被锁定,并且只允许进行全片擦除以允许重新编程。 **MC68HC908QY4A 进入条件:** | 模式 | $\overline{IRQ}$ (PTA2) | $\overline{RST}$ (PTA3) | 复位向量 | PTA0 | PTA1 | PTA4 | 外部时钟 | 总线频率 | 波特率 | | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | | 正常监控模式 | $V_{TST}$ | $V_{DD}$ | X | 1* | 1 | 0 | 9.8304 MHz | 2.4576 MHz | 9600 | | 强制监控模式 | $V_{DD}$ | X | \$FFFF (空白) | 1* | X | X | 9.8304 MHz | 2.4576 MHz | 9600 | | 强制监控模式 | $V_{SS}$ | X | \$FFFF (空白) | 1* | X | X | X | 3.2 MHz (微调后) | 9600 | *在监控模式下,`PTA0` 必须接有上拉电阻至 $V_{DD}$。 ### 时钟生成与波特率选择 在已编程状态下,标准MON08需要9.8304 MHz的外部时钟才能以标准的9600 bps进行通信。 为了尽量减少外部元件并保持对毛刺时序的精确控制,目标时钟直接通过STM32的定时器生成。 在故障注入阶段,时钟以相对保守的 **4 MHz** 频率生成。这产生了 **3906 bps** 的波特率。以较低的频率运行可以在调整毛刺参数时提供更宽的容错范围。 如果目标允许,在转储阶段,时钟可以以更高的频率(例如 **8 MHz**)生成。 ### 身份验证序列

Monitor Mode - Entry Conditions

During MON08 communication, every command and security byte sent to the MCU is followed by a hardware echo to confirm reception. 从上电开始经过256个总线周期后,芯片准备好接收8字节的身份验证密钥。在第8个字节回显之后,MCU会发送一个 `BREAK` 信号。 需要注意的是,这个 `BREAK` 仅仅确认身份验证阶段已经结束,而并不意味着密码是正确的。 要验证是否成功解锁(或成功注入毛刺),可以读取受保护的内存地址,例如位于 `0xFFFE-0xFFFF` 的复位向量。如果内存被锁定,MCU会主动屏蔽输出并为每个字节返回 `0xAD`。如果我们读到的不是该值,则说明安全绕过成功(因为复位向量指向以 `0xAD` 开头地址的可能性极低)。 ### 监控命令 一旦通过身份验证,MON08允许通过基本的 `READ` 和 `WRITE` 命令进行交互,以及通过 `RUN` 命令执行小型RAM小应用。为了在处理连续内存块时显著减少通信开销,监控ROM还实现了 `IREAD`(索引读取)和 `IWRITE`(索引写入)命令。 像 *CodeWarrior* 这样的官方工具严重依赖这些自定义的RAM小应用来对芯片进行编程,因为MON08本身并不支持直接的闪存编程。 目前,本仓库仅专注于**固件转储和故障注入**。然而,底层的 `mon08.c` 驱动实现了上述所有命令,允许您在需要时编写自己的刷写小应用。 如果您需要在提取安全字节后重新对芯片进行编程,强烈建议将转储出的密钥与CodeWarrior以及标准串口适配器结合使用,正如数据手册中所建议的那样(这不需要昂贵的编程器!)。

Monitor Mode Circuit

## 攻击概述 最初,评估了两种经典的侧信道攻击方法:_时序攻击_ 和 _简单功耗分析 (SPA)_。由于微控制器ROM中实施的防御措施,这些方法被证明是不切实际的。 ### 时序攻击 这种类型的攻击是最简单的攻击之一,涉及测量CPU验证密码所需的时间。通过分析响应时间的变化,理论上可以每次推断出一个字节的密钥。然而,监控ROM在执行此检查时采用恒定时间,无论数据正确与否,所消耗的时钟周期数完全相同。 ### 简单功耗分析 (SPA) 通过在电源和芯片的 $V_{DD}$ 引脚之间插入一个分流电阻,可以直观地观察CPU在密码验证阶段消耗的电流。其核心理念是,当处理不正确的字节时,错误标志的激活会导致与预期不同的电流特征。这将允许通过识别电流变化来推断正确的字节,从而将尝试次数减少到 $255 \times 8 = 2040$ 次。 即使在这种情况下,结果也不如人意。安全字节的评估很可能是使用累积逻辑执行的,仅在数据接收周期结束时才批量执行。 ROM可能的内部实现可能如下所示: ``` uint8_t input[8]; uint8_t secret[8] = {...}; uint8_t error_flag = 0; // Receive the eight authentication bytes for (uint8_t i = 0; i < 8; i++) { receive_byte(&input[i]); send_echo(input[i]); } // Check the security bytes in constant time (no branching) for (uint8_t i = 0; i < 8; i++) { // Thanks to this logic evaluation, the current footprint is almost the same for each byte error_flag |= (input[i] ^ secret[i]); } // Evaluate the error flag only if authentication is done after a power-on reset if (is_POR()) { if (error_flag != 0) disableFlash(); else enableFlash(); } send_break(); ``` 由于这种结构设计,推断被比较的字节并识别错误标志被激活的确切时钟周期将需要更为高级的 _差分功耗分析 (DPA)_ 技术,这使得 _SPA_ 显得无效。 ### 故障注入 SPA的结果对于理解身份验证过程的精确时序至关重要。通过使用[Python脚本](spa_analysis/plot_data.py)绘制在身份验证期间测量到的功耗曲线,出现了两种截然不同的行为场景:

Simple Power Analysis

这些数据使我们能够精确定位芯片评估安全序列并决定是否启用闪存的准确时刻。在上图中,时间参考点 `t = 0` 标志着MCU完成传输最终回显字节(1个起始位 + 8个数据位 + 1个停止位)的确切时刻。 安全评估在此点之后立即发生。在经过相当于2个UART位的延迟后,MCU发送 `BREAK` 信号。正是在这个可预测的狭窄时间窗口内,可以注入电压毛刺以破坏评估指令并强制解锁闪存。 该毛刺在物理上是通过触发一个MOSFET短路微控制器的 $V_{DD}$ 和 $GND$ 引脚来注入的。这会产生一个突然的电压下降,足以导致CPU流水线内执行的指令遭到破坏。 然而,HC08具有极快的内部上电复位 (POR) 电路。因此,即使在生成可能的最短毛刺时(在72 MHz下,理论上约为15 ns,但由于封装寄生电容的影响,实际会延长到几百 ns),芯片也会复位,从而阻挠攻击。 为了减轻这种影响,在主电源和芯片的 $V_{DD}$ 引脚之间放置了一个22欧姆的电阻(与用作测量分流电阻的电阻相同),并与MOSFET串联了一个100欧姆的多圈电位器。通过正确调整电位器,可以在不触发POR的情况下破坏逻辑电路。 ## 硬件原理图 ![硬件原理图](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/b704234a2a223828.png) 该原理图是简化的,是使用我作为一个离家在外的大学生手头仅有的一些元件搭建的。尽管如此,它足以成功执行毛刺注入和内存转储。 ### 引脚配置 | Nucleo 引脚 | STM32 引脚 | 信号名称 | 描述 | | :--- | :--- | :--- | :--- | | **D2** | `PA10` | `POWER_N` | 驱动NPN三极管以控制目标电源。 | | **D3** | `PB3` | `POWER_P` | 驱动PNP三极管以控制目标电源。 | | **D4** | `PB5` | `GLITCHER` | 触发MOSFET撬棍电路以进行故障注入。 | | **D5** | `PB4` | `OSC_TRIGGER` | 用于示波器同步的专用触发输出。 | | **D8** | `PA9` | `UART_MON08` | 与目标MON08接口的半双工串行通信。 | | **D10** | `PB6` | `CHARGE_PUMP` | 用于驱动高压电荷泵的PWM输出。 | | **D12** | `PA6` | `HC08_CLOCK` | 目标时钟生成。 | ### 设计说明 * **目标电源控制:** 可以使用专用的栅极驱动器或互补的MOSFET对来替代推挽晶体管级(BC337/BC327 NPN-PNP对),以实现更陡峭的开关沿,但双极型解决方案已经足够好用。 * **电压生成:** 电荷泵以10 kHz、50%占空比运行。由3.3V逻辑电源驱动时,它产生一个由齐纳二极管安全钳位至6.3V的电压,满足触发监控模式的阈值要求。更理想的方法是使用经过适当滤波的缓冲器来驱动它,以避免给STM32的GPIO输出引脚带来压力。 * **故障注入器 (撬棍电路) 布局:** 充当撬棍电路的MOSFET最好尽可能靠近目标的VDD和GND引脚放置,以最大程度地减少寄生电感。然而,由于MC68HC908QY4A对相对较宽的毛刺脉冲(大约10-20 µs)很敏感,寄生效应的影响较小。对于此目标,整个电路可以直接在标准的面包板上成功构建并运行。

Circuit on breadboard

## MON08 驱动 位于 [`mon08`](firmware/App/common/mon08) 目录中的驱动程序提供了与MC68HC908监控模式的核心接口,利用了STM32的串行外设。 ### 主要特性 * **裸机 UART ([`mon08_uart.c`](firmware/App/common/mon08/mon08_uart.h)):** 在发送和接收期间,串行总线访问直接通过控制和状态寄存器执行。这完全绕过了HAL开销,确保了在毛刺注入阶段的精确控制,因为关键时序参考与传输最终安全字节的确切时刻紧密相关。 * **动态时钟与波特率生成:** 目标时钟通过硬件定时器 (PWM) 生成。驱动程序根据生成的频率动态计算并初始化UART速度。这允许在用于毛刺注入的保守速度(例如4 MHz)和用于内存转储的更快速度(例如8 MHz)之间即时切换。如果目标由外部时钟源(例如函数发生器)驱动,也可以禁用时钟生成。 * **电源与电荷泵控制:** 处理监控模式的物理进入条件。它管理一个PWM驱动的电荷泵,以在 $\overline{IRQ}$ 引脚上产生所需的高压 ($V_{TST}$)。此外,它通过三种状态管理目标的 $V_{DD}$ 线路:`ON`、`OFF`(强制上电复位)和 `HIGH-Z`(高阻态,用于在电路中插入22欧姆的电阻以进行毛刺攻击)。 * **协议命令:** 完全实现了 `READ`、`WRITE`、`IREAD`、`IWRITE` 和 `RUN` 命令,允许用户无缝读写内存区域,以及执行小型RAM小应用。 * **故障注入模块 ([`mon08_glitcher.c`](firmware/App/common/mon08/mon08_glitcher.c)):** 负责执行故障注入攻击。它包含一个可连接到示波器的专用触发信号,用于观察毛刺发生的准确时刻。 * **日志友好:** 旨在促进全面的日志记录,允许实时监控毛刺注入进度,并提供即时反馈,以便在没有外部仪器的情况下正确调整毛刺参数。[`mon08_strings.h`](firmware/App/common/mon08/mon08_strings.h) 实用程序头文件将协议状态和配置枚举转换为人类可读的字符串,以实现清晰的遥测和控制台调试。 * **跨平台兼容性:** 旨在可移植到不同的STM32系列。目前,它仅在Nucleo F401RE上进行了开发和测试。 ### 配置 要使驱动程序适应特定的开发板,需要填充 `Mon08_Config_t` 结构体,该结构体向驱动程序提供必要的STM32外设和引脚。 该配置在不同的应用程序之间共享,位于 [`mon08_config.h`](firmware/App/config/mon08_config.h) 中。有关每个配置参数的详细说明,请参阅 [`mon08.h`](firmware/App/common/mon08/mon08.h) 头文件中提供的内联文档。 ## 小应用 固件被组织成模块化的小应用,以将硬件初始化代码(由 _STM32CubeMX_ 生成)与应用程序逻辑分开。这种架构允许添加新的小应用而无需创建冗余项目,并通过提供新的CubeMX硬件配置来便于将代码库移植到不同的STM32开发板。所需小应用的选择和编译由 [`CMakePresets.json`](CMakePresets.json) 文件中定义的CMake预设管理。 ### 故障注入器 位于 [Glitcher](firmware/App/Glitcher) 文件夹中的故障注入模块负责编排和记录电压故障注入攻击。如果毛刺注入成功且芯片解锁,该小应用会自动提取可用于转储目标内存的8字节安全密码。 ### 转储器 位于 [Dumper](firmware/App/Dumper) 文件夹中的转储器小应用旨在提取目标的内存区域,并通过串行控制台以标准的摩托罗拉S-record(`.s19`)格式输出结果。 这种格式允许用户将串行输出直接复制并粘贴到文本文件中,该文件可以导入到 _CodeWarrior_ 或逆向工程工具(如 _Ghidra_)中。 要提取的特定内存范围在 [mon08_memory_defs.h](firmware/App/config/mon08_memory_defs.h) 中定义。由于不同HC08型号的内存映射各不相同,请参阅特定微控制器的数据手册以确定要转储的正确闪存/ROM地址范围。 ## 烧录代码 ### 环境要求 要开发并与系统交互,需要以下工具: * **编辑器**:[Visual Studio Code](https://code.visualstudio.com/) * **VS Code 扩展**: * [STM32 VS Code Extension](https://marketplace.visualstudio.com/items?itemName=stmicroelectronics.stm32-vscode-extension)(用于项目管理和调试)。 * [Serial Monitor](https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-serial-monitor)(用于监控故障注入器和转储器的输出)。 * **替代方案**:代码可以作为CMake项目导入到 [STM32CubeIDE](https://www.st.com/en/development-tools/stm32cubeide.html) 中。在这种情况下,需要一个支持控制台命令的外部串口终端,例如 [PuTTY](https://www.putty.org/) 或 [minicom](https://linux.die.net/man/1/minicom)。 ### 构建与烧录 1. 使用Visual Studio Code打开仓库文件夹。 2. 当STM32扩展检测到项目时,接受配置并输入正在使用的开发板的信息。 3. 如果CMake提示,请选择位于项目根目录的 [`CMakeLists.txt`](CMakeLists.txt) 文件。 4. 选择与所需小应用对应的 **CMake 预设**(例如 `F401RE-Dumper` 或 `F401RE-Glitcher`)。 5. 将STM32开发板连接到计算机并运行 **Flash firmware** 任务。 ## 操作步骤 ### 注入阶段 故障注入攻击需要精确校准,以确定目标处理器的工作阈值。 1. **软件配置**:选择 **Glitcher** CMake预设并刷写开发板。 2. **硬件配置**:将22欧姆电阻连接在电源和芯片的 $V_{DD}$ 引脚之间。 3. **校准**:电路通电后,监控串口日志。调整多圈电位器,直到 `NO_BRK` 计数(表示触发了上电复位)开始与 `UNAUTH` 计数(表示未复位但身份验证失败)交替出现。理想的绕过点处于POR激活的阈值上;当大多数(但非全部)尝试返回 `UNAUTH` 时,说明调整正确。 4. **参数微调**:如果毛刺未能导致解锁,请凭经验调整 [`firmware/App/Glitcher/app.c`](firmware/App/Glitcher/app.c) 中的脉冲参数,因为不同芯片型号的敏感性各不相同。 ### 转储阶段 通过故障注入器恢复身份验证代码后,即可继续进行完整的数据提取。 1. **密钥配置**:将恢复的身份验证代码输入到位于 [`firmware/App/Dumper/app.c`](firmware/App/Dumper/app.c) 的转储器小应用源代码中。 2. **内存映射**:确保活动的内存映射与目标芯片的数据手册匹配。如果不存在相应的映射,请在 [mon08_memory_defs.h](firmware/App/config/mon08_memory_defs.h) 中定义所需的内存区域,并在转储器代码中选择它。 3. **固件更新**:将CMake构建预设更改为 **Dumper**,移除22欧姆电阻以恢复直接供电,并刷写开发板。 4. **导出**:等待转储过程完成。将串行输出(包含在起始和结束分隔符之间)复制到文本文件中,并保存为 `.s19` 扩展名。 5. **分析**:生成的Motorola S-record文件可以直接导入到诸如CodeWarrior等工具或如Ghidra等逆向工程套件中。 ## 结果 该项目已在以下目标上成功测试: * **MC68HC908QY4A**:通常在大约10秒内即可实现安全绕过。该攻击具有高度可重复性。 * **MC68HC908RF2**:该型号对攻击的抵抗力明显更强。经过广泛的参数调整,在数小时的尝试后终于获得了访问权限。与前一目标相比,该过程的可重复性较差,并且需要精确的脉冲宽度校准。 ## 参考文献与扩展阅读 所使用的方法和获得的结果在很大程度上受到了以下学术材料的启发。我建议参考这些资源,以更好地了解所使用的方法和攻击策略: * **Bozzato, C., Focardi, R., & Palmarini, F. (2019).** [*Shaping the Glitch: Optimizing Voltage Fault Injection Attacks.*](https://tches.iacr.org/index.php/TCHES/article/view/7390/6562) IACR Transactions on Cryptographic Hardware and Embedded Systems (TCHES), 2019(2), 199–224. * **Skorobogatov, S. (2005).** [*Semi-invasive attacks – A new approach to hardware security analysis.*](https://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-630.pdf) Technical Report UCAM-CL-TR-630, University of Cambridge, Computer Laboratory. ## 许可证 本项目基于GNU通用公共许可证v3.0进行授权 - 详情请参阅 [LICENSE](LICENSE) 文件。 本文档中包含的来自MC68HC908QY4A数据手册的屏幕截图和图表为 **NXP Semiconductors**(原飞思卡尔)的财产。此处基于 _合理使用 (Fair Use)_ 原则将其用于技术解释、文档编制和教育目的。完整的数据手册可在 [NXP官方网站](https://www.nxp.com/) 上找到。所有其他产品名称、徽标和品牌均为其各自所有者的财产。
标签:Bash脚本, CISA项目, Flash存储器读取, MC68HC08, MC68HC908, NXP微控制器, SPA, 功耗分析, 固件提取, 安全漏洞分析, 客户端加密, 密码绕过, 嵌入式安全, 微控制器安全, 旁路攻击, 汽车电子安全, 电压毛刺攻击, 硬件安全, 硬件故障注入, 硬件黑客, 逆向工具, 高性能