对nRF52840片上系统的硬件调试与漏洞研究(part1)

  • A+
所属分类:安全文章

在受保护 platform上激活JTAG / SWD调试接口一直是嵌入式安全研究中的敏感话题。

本次漏洞研究提出了一种绕过受保护的nRF52840上的APPROTECT的方法,以便重新激活串行线调试接口(SWD),从而在目标上提供完整的调试功能(对Flash / RAM /寄存器的R / W访问,Code Exec和重新编程)。所有nRF52版本均受到影响。

由于其固有特性,如果不重新设计硅芯片,则无法修补此漏洞,从而导致永远存在无数易受攻击的设备。

0x01 nRF52系列SoC

整个nRF52系列包含六个不同的nRF52 platform,所有platform均围绕ARM Cortex-M4F CPU构建。

image.png

整个nRF52系列SoC

这里提供了不同 platform之间的比较表。

 https://infocenter.nordicsemi.com/index.jsp?topic=%2Fstruct_nrf52%2Fstruct%2Fnrf52.html

本次分析的目标是家庭旗舰产品nRF52840。

0x02 nRF52840 的基本信息

nRF52840片上系统(SoC)是nRF52系列SoC系列中最先进的成员。它是基于64 MHz Cortex-M4F CPU构建的高级蓝牙,线程和Zigbee多协议SoC。它带有1MB的闪存和256Kb的RAM,两者均已完全集成。

在安全性方面,ARM TrustZone CryptoCell加密单元集成了加密引擎。该框图给出了nRF52840的功能详情:

image.png

nRF52840的框图

0x03 代码读取保护

如今,大多数半导体供应商都在其MCU / SoC内部实现了一种称为代码读取保护的安全功能,从而防止了具有物理访问权限的攻击者转储并修改了集成闪存中存储的代码/数据。

根据芯片供应商(CRP,RDP,PCROP…),此安全功能可以具有不同的名称。

通常,一旦攻击者获得了固件的副本,他就可以进行逆向获取一些敏感数据(例如密钥和密码)。

nRF51代码读取保护(RBPCONF)

在2015年,Include Security在nRF51代码读取保护功能(称为RBPCONF)的设计中发现了一个漏洞,攻击者可以使用SWD调试提取整个固件。

在nRF51上,一旦启用RBPCONF保护,则使用调试器直接访问Flash或RAM只会返回零。但是,仍然可以控制代码的执行以及对寄存器(甚至程序计数器)的读写。因此,在受保护的内存中找到一个“gadget”,例如一条简单的加载字指令,即从某个寄存器中的地址读取内存到另一个寄存器,就足以提取整个固件。因此,可以物理访问基于nRF51的设备的攻击者可以利用此设计漏洞来转储Flash。

因此,nRF51代码读取保护(RBPCONF)被认为是破坏性的安全机制,不能防止固件提取。

访问端口保护(APPROTECT)

漏洞爆出后,NordicSemiconductor决定设计nRF52并采用更加严格的安全性机制,以防止内存读取。此安全功能称为访问端口保护(APPROTECT),在nRF52数据表中非常简单地做了描述:

image.png

nRF52概述

通常,外部调试器通过调试访问端口(DAP)访问ARM CPU。然后,有两个不同的端口可用:

–  CTRL-AP。这是主调试端口,它不依赖于APPROTECT。

–  AHB-AP。这是真正的调试端口,用于通过SWD访问内存并控制CPU。

NordicSemiconductor不提供有关APPROTECT机制的任何信息。我建议阅读 Cortex-M的ARM参考文档。

用户信息配置寄存器(UICR)

用户信息配置寄存器(UICR)是用于配置用户特定设置的非易失性存储器(NVM)寄存器。它们被映射为0x10001000。

APPROTECT属于UICR。必须在地址0x10001208上写入0xFFFFFF00以启用访问端口保护,如下所示:

image.png

适当的配置寄存器

然后需要上电复位以应用UICR中存在的新设置。

根据Nordic的说法,必须先擦除所有RAM和内存闪存,才能禁用APPROTECT安全性。

0x04 环境配置

nRF52840开发套件

nRF52840-DK开发套件可用于试验。

 https://www.nordicsemi.com/Software-and-tools/Development-Kits/nRF52840-DK

image.png

nRF52840开发套件。

用户手册和原理图可在制造商的网站上找到。nRF52840是QFN73版本,尺寸为7x7mm,位于右侧。该套件具有嵌入式Segger J-Link调试器(最大的带有白色标签的芯片)。

该SDK是nRF5_SDK_16.0.0_98a08e2现在可用的最新版本。

Nrfjprog v10.6.0和JLink v6.64用作命令行工具。

作为快速入门,我只是编译并从SDK刷新做了一个示例,以检查我的环境是否正常。一切运行顺利,我可以专注于APPROTECT安全功能。

启用APPROTECT

方法1(通过OpenOCD):

 $ openocd -s /usr/local/share/openocd/scripts -f ./interface/jlink.cfg -c "transport select swd" -f ./target/nrf52.cfg
 #Telnet
 $ telnet localhost 4444
 > flash fillw 0x10001208 0xFFFFFF00 0x01
 > reset

方法2(通过nrfjprog):

 $ nrfjprog --memwr 0x10001208 -- val 0xFFFFFF00

之后,任何尝试连接CPU的尝试都会失败,并显示“ 错误:找不到MEM-AP来控制内核”:

image.png

由于激活了APPROTECT,SWD被禁用。

尝试附加GDB都会显示错误:

 Error: attempted 'gdb' connection rejected

禁用APPROTECT

方法1(通过OpenOCD):

 # Read APPROTECTSTATUS 
 # (0x0 Access port protection enabled - 0x1 APP disabled) 
 > nrf52.dap apreg 1 0x0c 0x00000000
 # Write ERASEALL register
 > nrf52.dap apreg 1 0x04 0x01
 > reset

方法2(通过nrfjprog):

 $ nrfjprog -f NRF52 --recover

在此过程中,所有闪存和RAM都将被擦除,复位后,可以再次对nRF52进行编程。

0x05 攻击策略

逆向

由于nRF52840不包含bootROM代码(因此,没有嵌入式Boot-loader例程,也没有用于逆向的IAP / ISP例程),因此引导过程相对简单。

入口是0x000002B4,位于闪存中:

image.png

我使用了Ghidra 进行逆向,所有模块,如NVMC,存储器,Debug Acces Port…都完全在硬件中被初始化。

重启

可能会触发重启,下表总结了所有造成重启的原因及其目标:

image.png

最后一行很有趣,上电复位将复位整个SoC,包括调试端口。

攻击方法

目标是重新启用对AHB-AP调试的访问。

上电复位后,AHB-AP必须根据存储在UICR(专用闪存分区)中的APPROTECT值进行初始化。

在引导过程中,内存控制器(NVMC)必须与CPU(或直接与AHB-AP模块)通信以提供存储在闪存中的APPROTECT值,然后相应地设置其保护状态。

由于缺少BootROM,这是通过纯硬件实现的,必须在早期启动过程中完成,然后才开始从Flash加载CPU并执行代码。

我的目标是确定此“纯硬件过程”,然后尝试修改AHB-AP调试初始化。如果成功,调试功能将被重新激活,直到下一次上电复位为止。

故障注入是此处的唯一方法。

0x06 目标配置

电源配置

该系统包含两个不同的调节器级,REG0和REG1。每个稳压器级都有两个不同的可配置选项,它们基于低压差稳压器(LDO)和降压稳压器(DC / DC)。

image.png

nRF52840的正常电压模式,仅启用LDO

上面的示意图中仅提及DEC4。

我对连接外部去耦电容器的DEC引脚(DEC1,DEC2到DEC6)特别感兴趣。NordicSemiconductor没有提供有关nRF52电源网络的任何详细信息。

经过快速探索之后,我决定重点关注DEC4(1.2V-1.3V)和DEC1(0.8V-0.9V):

· DEC4是REG1级之后的电源线。因此,它可能会提供整个数字系统(CPU和内存)

· DEC1是CPU电源线。

PCB 修改

要分析芯片内部的活动,有必要稍微修改一下PCB:

image.png

PCB原理图,一些电容器已被删除。

相应的去耦电容器C5,C15,C16和C11被移除。

故障注入

我的低成本电压钳是一个自制的硬件电子系统,专用于以适当的方式执行故障注入。该电子板的总成本不到5美元,这证明了故障注入是一种非常低成本的技术。

我的低成本电压毛刺系统的输出将使用先前安装的SMA连接器连接到DEC1。

焊接

红线焊接到DEC4,细线焊接到DEC1:

image.png

在双目镜下,将DEC1(CPU电源)和DEC4(系统电源)上的焊锡丝连接起来。

注意:我在C5位置重新焊接了一个100nF电容器,以在启动过程中获得更多的CPU电源“稳定性”。

我将两条线连接到SMA连接器,并使用GND点作为公共接地:

image.png

image.png

微型USB电缆用于为整个电路板供电。已连接USB转串行电缆以显示来自应用程序的UART消息(115200、8N1)。

配置范围

示波器已连接到目标:

· 通道1(CH1)= TxD(引脚P0.06)

· CHANNEL2(CH2)=通过DEC1的芯片功耗

· CHANNEL3(CH3)=毛刺脉冲指令

· CHANNEL4(CH4)=通过DEC4(示波器触发)的芯片功耗

0x07 攻击结果

黑盒逆向

目的是确定功耗的特定模式,这可以验证我先前的假设。

为此,同时监视DEC1上的CPU功耗(CH2)和DEC4上的系统功耗(CH4)。

首先,Flash Memory Activity可以清楚地区分(在触发T标志处),并与Flash的后续读取操作相对应:

image.png

示波器截图,监视nRF52840上电。CH1 = UART,CH2 = CPU电源,CH3 =毛刺命令(未激活),CH4 =系统电源。

在下一个截图中,Arm CPU开始执行(在触发标记后的19us处),在CH2(CPU功耗)上有区别:

image.png

CPU开始执行。CH1 = UART,CH2 = CPU电源,CH3 =毛刺命令(未激活),CH4 =系统电源。

然后,我决定通过比较两个电源信号DEC4和DEC1来集中分析NVMC活动:

image.png

NVMC初始化。CH1 = UART,CH2 = CPU电源,CH3 =毛刺命令(未激活),CH4 =系统电源。

这种模式(红色框)对应于将UICR值传输到内核(或直接传输到AHB-AP块)的内存控制器(NVMC),以配置调试端口(AHB-AP,CTRL-AP)并将APPROTECT设置为最终禁用调试接口。

绕过nRF52840上的APPROTECT

python脚本负责布防示波器,设置不同的故障参数并重置电路板。

毛刺注入开始,在DEC1电源线上产生非常短的脉冲,专门针对先前确定的模式。

下一个示波器截图显示了成功的故障注入尝试:

image.png

NVMC初始化。CH1 = UART,CH2 = CPU电源,CH3 =闪光命令(未激活),CH4 =系统电源。

请注意故障注入后如何修改系统的功耗,这是我们想要获得的结果。

每次尝试故障后,脚本都会播放以下OpenOcd命令,以转储整个Flash存储器(仅在成功连接到AHB-AP Debug接口的情况下才会发生此情况):

 $ openocd -s /usr/local/share/openocd/scripts -f ./interface/jlink.cfg -c "transport select swd" -f ./target/nrf52.cfg -c "init;dump_image nrf52_dumped.bin 0x0 0x100000"

通过故障效应,AHB-AP调试端口已成功解锁。外部调试器现在可以连接到nRF52840 CPU(cortex-M4F)来转储闪存:

image.png

尽管激活了APPROTECT,调试器仍连接到目标nRF52840。

然后附加Arm GDB会话。即使APPROTECT值显示nRF52840受保护(0xFFFFFF00),也可以调试目标,例如通过读取固件0x00000000:

image.png

尽管已激活APPROTECT,但GDB会话仍连接到目标nRF52840。

PoC:获得调试权限

你可能猜到了也可以完全控制设备(因为重新激活了调试接口)。

在我的实验过程中,故障后,CPU陷入了0x61C4的无限循环中。因此,下面的截图显示了如何将程序计数器(PC)设置为执行第一条指令(在0x2b4处),然后以PoC的方式进入代码:

image.png

在受保护的nRF52840上执行代码。

下面是对寄存器的R / W访问(SRAM和Flash R / W操作也可用):

image.png

全面的调试功能,使将来的逆向变得更加容易 !

该PoC证明了流执行的控制以及对存储器和寄存器的R / W访问。

进入FICR

信息配置寄存器(FICR)在工厂已预先编程,不能被用户擦除。这些寄存器包含特定于芯片的信息(设备ID,密钥,设备地址等),位于0x10000000:

image.png

出厂信息配置寄存器已转储

为漏洞利用增加稳定性

最后,目标是永久重新激活被测设备上的全部调试功能。该方案如下:

· 将闪存转储到0x00000000

· 将UICR转储到0x10001000

· 擦除设备:nrfjprog -f NRF52 –恢复

· 再次重新刷新nRF52,以写入闪存内容和UICR(当然,正确的APPROTECT值补丁会设置为0xFFFFFFFF)。

此后,将启用通过SWD接口的调试,并且不需要进行小故障攻击。

为了证明应用此漏洞利用有多容易,该攻击已在真实产品Logitech Pro G Mouse上进行了复制。

 https://twitter.com/LimitedResults/status/1250489319250448388

这将是对nRF52 SoC 进行研究的第二部分。在第二部分中,我还将演示该漏洞当前如何影响从nRF52810到nRF52840的所有nRF52 SoC。

0x08 研究总结

接入端口保护APPROTECT是NordicSemiconductor设计的最新安全功能,可防止固件读取和逆向。因此,整个nRF52 SoC系列都具有此APPROTECT功能。

在此文中,已成功在nRF52840上实现了低成本的故障攻击。它允许具有物理访问权限的攻击者绕过APPROTECT来永久重新激活SWD调试接口(对存储器和寄存器的R / W访问,控制CPU代码执行,转储闪存,FICR和UICR…)

由于其复杂性低,对nRF52840的这种攻击可以在现场轻松再现。我毫不怀疑任何有经验的精通黑客都可以在不到一天的时间内用少于500美元的设备重现这种攻击。

该漏洞位于Silicon中。没有硬件补丁,就无法修补。此漏洞正在影响大量基于nRF52 platform的产品。

本文翻译自:https://limitedresults.com/2020/06/nrf52-debug-resurrection-approtect-bypass/如若转载,请注明原文地址:

本文来源于互联网

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: