ATSAM4C32

来自 RECESSIM,一个逆向工程社区

目录

绕过锁定 - Microchip/Atmel SAM4C32

Hash Salehi

简介

本文将分析 Microchip (ATMEL) SAM4C32 微控制器的漏洞,该漏洞允许攻击者获得对先前锁定的设备的未锁定 JTAG 访问权限。此攻击似乎影响 SAM 系列中的许多设备(但并非全部)。 发现 0x01 TeamSAM E70/S70/V70/V71 上执行的本质上相同的攻击在许多 SAM 处理器上都有效。本文的新颖之处在于将复位引脚识别为旁路通道

虽然使用的攻击方法是电压故障注入,但我认为 EMFI(电磁故障注入)也可能是一种绕过安全性的可行方法。EMFI 通常允许在不需要移除电源轨上的所有电容器的情况下进行攻击。这在攻击不想改变目标板的设备时很有帮助。

为什么要攻击 SAM4C32?

SAM4C32 用于此 Landis+Gyr Generation 5 智能电表。 我有很长的历史 分析这些智能电表的各个方面,之前从使用 Renesas (Mitsubishi) M30626FHPGP 处理器的Generation 4智能电表中提取了固件。 它是 M16C 架构,提取的固件证明使用诸如 Binary Ninja 和 Ghidra 之类的工具进行逆向工程具有挑战性。

ARM 架构受到更多 RE(逆向工程)工具的支持,并且 RE 社区中有更多人对其进行了分析。 因此,我决定从 SAM4C32 中提取固件,以进一步分析智能电表技术。

锁定机制

SAM4C32 使用通用非易失性存储器 (GPNVM) 位来控制锁定、启动模式和存储器平面选择,如下所示。

以下摘自 Microchip 数据表 DS60001717B。

安全位

SAM4C 具有基于特定通用 NVM 位(GPNVM 位 0)的安全位。 启用安全性后,禁止通过 SW-DP/JTAG-DP 接口或通过快速闪存编程接口访问闪存、SRAM、内核寄存器和内部外设。 这确保了闪存中编程的代码的机密性。

只能通过 EEFC 用户界面的“设置通用 NVM 位 0”命令来启用此安全位。 只能通过将 ERASE 引脚置为 1 并在执行完全闪存擦除后才能禁用安全位。 禁用安全位后,允许访问闪存、SRAM、内核寄存器、内部外设。

SAM-BA 引导

SAM-BA 引导是主处理器 (CM4P0) 的默认引导程序,它提供了一种简单的方法来就地编程片上闪存。 SAM-BA 引导助手支持通过 UART0 或 USB 端口进行串行通信,用于 SAM4C32。

SAM-BA 引导提供与 SAM-BA 图形用户界面 (GUI) 的接口。

当 GPNVM 位 1 设置为 0 时,SAM-BA 引导位于 ROM 中,并映射到闪存中的 0x0 地址。

虽然我的攻击侧重于针对安全位 GPNVM 0,但也有可能针对 GPNVM1 进入引导加载程序并以这种方式提取闪存。 在这种情况下,不需要 JTAG 编程器。 截至 2025 年 4 月 1 日,我尚未测试这是否有效。

复位 vs 电源周期

SAM 系列中的某些微控制器在复位与电源周期时,在 VDDCORE 电源轨上表现出不同的行为。 我已经验证了 SAM4C32、SAM4S2A 和 0x01 Teams 的 SAM E70/S70/V70/V71 都表现出如下所示的行为。 我的假设是,数据表中提及 GPNVM 的任何 Microchip SAM 系列处理器都容易受到此攻击。

复位捕获

这是 SAM4C32 重新启动时活动的基线。 紫色复位轨迹 (nRST) 由外部设备切换,我们可以看到芯片启动时产生的黄色 VDDCORE 活动。

VDDCORE(黄色)由于重新启动时的处理器活动而波动

电源周期捕获

以下图像逐步放大,以便您可以查看复位线的活动。 在第一张图像中,您可以看到所有三条线都从低到高,因为我们正在向处理器供电。 控制复位线的设备设置为 High-Z 状态,因此我们可以看到处理器正在做什么。

电源周期缩放捕获

我注意到的第一件事是处理器本身在启动后不久切换了复位线。 仅重置处理器时未观察到此情况。 我还注意到 VDDCORE 同时出现明显的功率波动。

电源周期中等缩放捕获

更近距离地放大,我们可以清楚地看到这落在处理器断言其复位线的时间窗口内。 0x01 Team 在其漏洞撰写中也发现了这种启动时的相同波动。

当处理器断言复位时观察到的电压波动的放大捕获

复位引脚作为旁路通道

这次攻击最有趣的部分是发现 复位引脚在您应该插入毛刺的时间窗口内变为低电平 以绕过安全性!

对于数据表中提及 GPNVM 的所有 Microchip/ATMEL SAM 芯片来说,似乎都是这种情况。 但是,我仅验证了 SAM4C32、SAM4S2A 和 E70/S70/V70/V71 表现出这种行为。

从通电到复位断言自身的时间因芯片而异。 SAM4C32 大约需要 17 毫秒,而 SAM4S2A 仅需要 600 微秒。

如下所示,SAM E70/S70/V70/V71 大约需要 1 毫秒。 蓝色 (3.3V)、红色 (VDDCORE)、绿色(复位)

由 0x01 Team 的 Waleed 提供的示波器捕获

我应该注意到,我只是在设置不同的测试以在重置处理器后尝试进行毛刺时才发现这一点。 我喜欢在执行毛刺攻击时观看示波器,看看是否会出现任何异常,这些异常可以为未来的攻击提供信息。 当我发现 0x01 Team 的研究并意识到我应该进行电源循环而不是重置时,示波器已经配置为监视 VDDCORE 和复位。 我第一次对芯片进行电源循环时,很明显复位线活动以某种方式与 VDDCORE 上的电压波动相关。

电压故障注入

下面的视频显示了接近电压波动时注入到 VDDCORE 电源中的故障。 当它落在波动顶部的正确位置时,过程停止。 它停止是因为处理器上启用了 JTAG,并且 OpenOCD 能够连接以停止毛刺脚本。

触发的轨迹跳动如此之多,因为我正在触发 VCC 3.3V 的上升沿,并且由于诸如使用的 chipwhisperer 分线板的电容和电源本身等原因,此上升沿会变化。

下图显示了使用的激进毛刺参数。 最初猜测了这个值并且有效,没有测试更窄或更宽的毛刺。

毛刺宽度约为 2 微秒

JTAG 访问

Ubuntu 中的 OpenOCD 和 ATMEL-ICE 编程器用于连接到 SAM4C32。 Windows VM 中的 Microchip Studio IDE 用于设置安全位,尽管此功能似乎在 OpenOCD 中可用,但我从未对其进行测试。

当安全位被绕过时,可以运行以下命令,并显示其关联的输出

at91sam4 info

> at91sam4 info
  CKGR_MOR: [0x400e0420] -> 0x00000008
	  MOSCXTEN:   0 [0x0000] (main xtal enabled: NO)
	  MOSCXTBY:   0 [0x0000] (main osc bypass: NO)
	  MOSCRCEN:   1 [0x0001] (onchip RC-OSC enabled: YES)
	   MOSCRCF:   0 [0x0000] (onchip RC-OSC freq: 4 MHz)
	  MOSCXTST:   0 [0x0000] (startup clks, time= 0.000000 uSecs)
	   MOSCSEL:   0 [0x0000] (mainosc source: internal RC)
	    CFDEN:   0 [0x0000] (clock failure enabled: NO)
  CKGR_MCFR: [0x400e0424] -> 0x000107a0
	  MAINFRDY:   1 [0x0001] (main ready: YES)
	    MAINF: 1952 [0x07a0] (3.998 Mhz (32.768khz slowclk)
 CKGR_PLLAR: [0x400e0428] -> 0x00003f00
	    DIVA:   0 [0x0000] 
	    MULA:   0 [0x0000] 
	PLLA Freq: (Disabled,mula = 0)
  CKGR_UCKR: [0x400e041c] -> 0x00000000
  PMC_FSMR: [0x400e0470] -> 0x00000000
  PMC_FSPR: [0x400e0474] -> 0x00000000
   PMC_IMR: [0x400e046c] -> 0x00000000
  PMC_MCKR: [0x400e0430] -> 0x00000001
	     CSS:   1 [0x0001] mainosc (3.998 Mhz)
	    PRES:   0 [0x0000] (selected clock)
		Result CPU Freq: 3.998
  PMC_PCK0: [0x400e0440] -> 0x00000000
  PMC_PCK1: [0x400e0444] -> 0x00000000
  PMC_PCK2: [0x400e0448] -> 0x00000000
  PMC_PCSR: [0x400e0418] -> 0x00000000
  PMC_SCSR: [0x400e0408] -> 0x00000003
   PMC_SR: [0x400e0468] -> 0x00030018
 CHIPID_CIDR: [0x400e0740] -> 0xa64d0ee0
	   Version:   0 [0x0000] 
	    EPROC:   7 [0x0007] Cortex-M4
	   NVPSIZE:  14 [0x000e] 2048K bytes
	  NVPSIZE2:   0 [0x0000] none
	  SRAMSIZE:  13 [0x000d] 256K Bytes
	    ARCH:  100 [0x0064] SAM4CxxC (100-pin version)
	   NVPTYP:   2 [0x0002] embedded flash memory
	    EXTID:   1 [0x0001] (exists: YES)
 CHIPID_EXID: [0x400e0744] -> 0x00000000
  rc-osc: 4.000 MHz
 mainosc: 3.998 MHz
   plla: 0.000 MHz
 cpu-freq: 3.998 MHz
mclk-freq: 3.998 MHz
 UniqueId: 0x20000c00 0x01006df3 0x010046af 0x010046b3

reg

> reg
===== arm v7m registers
(0) r0 (/32): 0x00000000
(1) r1 (/32): 0x00000000
(2) r2 (/32): 0x00000000
(3) r3 (/32): 0x00000000
(4) r4 (/32): 0x00000000
(5) r5 (/32): 0x00000000
(6) r6 (/32): 0x00000000
(7) r7 (/32): 0x00000000
(8) r8 (/32): 0x00000000
(9) r9 (/32): 0x00000000
(10) r10 (/32): 0x00000000
(11) r11 (/32): 0x00000000
(12) r12 (/32): 0x00000000
(13) sp (/32): 0xffffffd8
(14) lr (/32): 0xfffffff9
(15) pc (/32): 0xfffffffe
(16) xPSR (/32): 0x01000003
(17) msp (/32): 0xffffffd8
(18) psp (/32): 0x00000000
(20) primask (/1): 0x00
(21) basepri (/8): 0x00
(22) faultmask (/1): 0x00
(23) control (/3): 0x00
===== Cortex-M DWT registers

at91sam4 gpnvm

请注意,由于毛刺,下面的 GPNVM 位 0 表示其当前值为 0,如果重置处理器,我们将失去访问权限并且它会恢复为 1。

> at91sam4 gpnvm                   
sam4-gpnvm0: 0
sam4-gpnvm1: 1
sam4-gpnvm2: 1

其他易受攻击的设备

Microchip (ATMEL) 系列

此列表并不详尽,可能还有更多易受攻击且未显示在 Microchip 提供的设备的主要概述中的设备。 仅粗体的设备已确认,其他设备被假定为易受攻击,因为数据表指定使用 GPNVM 位进行安全性保护。

审查了以下数据表,并且__显示使用 GPNVM 位进行安全保护。 这并不意味着它们是安全的,但是可能不存在这种特定的漏洞。

结论

Microchip (ATMEL) SAM 系列中的许多设备都使用 GPNVM 位来保护对 JTAG 调试接口的访问。 可以使用电压毛刺绕过此保护,从而可以完全访问设备。 看来这是一个低级硬件错误,可能无法在现场修补。

披露

在发现时通过 YouTube 完全披露。 尽情享受吧!