使用ChipWhisperer对微控制器的硬件攻击及其防护方法


硬件攻击会威胁到所有带有微控制器(以下简称MK)的设备,因为它们可以绕过各种安全机制。 使用软件或硬件很难抵御这种攻击。 例如,您可以阅读意法半导体的文章 ,内容涉及各种类型的硬件攻击和保护MK的方法。
Raccoon安全团队对这个主题很感兴趣,因为我们公司活动的领域之一是嵌入式设备的开发,包括那些包含信息保护机制的设备。 在大多数情况下,我们对毛刺攻击感兴趣,因为它们使您可以跳过可执行的MK指令。 这是对MK中包含的机密信息的严重威胁,这种攻击最危险的后果是绕过MK开发人员提供的安全机制读取封闭的固件。


在海牙举行的Hardwear.io 2018和纽伦堡的EmbeddedWorld 2019上,NewAE展示了ChipWhisperer设备,该设备可以实现非侵入式硬件攻击的这一部分,不需要深入了解纳米电子学知识和特定设备的可用性。 使用此设备,我们研究了嵌入式设备的安全性,并弄清了如何最大程度地减少此类攻击的结果。 根据削减-我们做了什么。


花栗鼠


ChipWhisperer套件是一个开源工具套件,用于分析最流行的MK(STM,Xmega,Intel D2000,SAM,LPC,MSP,78K等)和FPGA的安全性。 该项目于2015年2月27日在Kickstarter启动 。 目前,有不同版本的ChipWhisperer(所有选项都可以在目录中找到)。 它们具有不同的工具集,但通常针对以下类型的硬件攻击:


•旁道攻击(SCA);


•小故障攻击。


为了进一步分析,我们选择了ChipWhisperer-Pro(CW1200),它是目前最古老的ChipWhisperer型号,具有广泛的功能和大型的包装:



ChipWhisperer套件(CW1200)


板载CW1200带有一个示波器,该示波器包括一个可调放大器和一个ADC,采样率为105 MSPS。 这套工具可让您以百分之一毫伏的方式记录信号电平,并获得良好的时基。 同样在CW1200中,还有用于组织CLK毛刺和Vcc毛刺的端口,这些GPIO端口可以分配为用于跟踪事件起源(密码输入请求,下载状态等)的输入触发器。 CW1200通过USB连接到PC,并具有两种与MK的通信协议:UART和SPI。


要使用ChipWhisperer,您必须安装驱动程序,从GitHub下载Python库和可用示例或在Linux上下载虚拟机​​的预备映像,其中已预安装了所有库和可用示例。 这些开放库包含:


•与ChipWhisperer的通信协议;


•用于处理对流行加密方法的攻击的数学算法;


•与流行的MK的引导程序进行通信的协议;


•准备的固件,用于在套件中随附的带有MK的板上进行培训。


我们决定浏览旧的 NewAE 网站上的所有教程。 现在正在开发另一个资源 ,其中提供了更多相关信息,并且有一个论坛


在本文中,我们将仅提供一些ChipWhisperer开发人员指南的示例,并且不在STM32F103RBT6上(包括MK的板上)实现它们:



板STM32F103RBT6


我们还编写了与编写的示例相同的代码,但使用的是从CubeMX生成的HAL库。 需要采取所有这些措施,以确认使用ChipWhisperer进行的攻击可以在任何随机设备上实施,而不仅仅是在套件中的主板上实施。


接下来,我们简要概述了SCA攻击和故障攻击。


SCA分析


SCA攻击的基础是在开发各种指令期间跟踪MC状态的外部因素(MC的电流消耗,温度,电磁场)的变化。 ChipWhisperer实现了使用ADC监视功率和使用天线监视电磁场的通道。


SCA分析可有效检测密码,加密密钥等。 NewAE网站具有许多不同的功能
查找加密密钥SCA 攻击的 有用 指南 ,但是我们仅举一个SCA分析示例,因为小故障攻击是我们最感兴趣的。


SCA攻击示例-功率签名分析


指南演示了一种SCA攻击类型-通过监视电源通道上的签名来跟踪每个字符的密码输入。 通过重复电源签名,可以识别MK内部各种程序指令的开发。 上面的示例通过跟踪break操作的签名演示了密码输入MK的开发。


让我们开始准备。 首先,您需要根据下图进行连接:



MC连接以进行SCA分析


该图删除了不需要连接的组件(与标准MK连接不同)。 箭头指示ChipWhisperer的连接点,签名指示其引脚。


准备固件MK。 以下函数位于while(1)主循环中:


 028 void password_check() { 029 char passwd[32]; 030 char correct_passwd[] = "Vulkan"; 031 HAL_Delay(10); 032 uart_send("WARNING: UNAUTHORIZED ACCESS WILL BE PUNISHED\n"); 033 led_off(); 034 035 //Get password 036 uart_send("Please enter password to continue: "); 037 uart_receive(passwd, 32); 038 039 uint8_t passbad = 0; 040 041 led_on(); 042 043 for(uint8_t i = 0; i < sizeof(correct_passwd); i++) 044 { 045 if (correct_passwd[i] != passwd[i]) 046 { 047 passbad = 1; 048 break; 049 } 050 } 051 052 if (passbad) 053 { 054 //Stop them fancy timing attacks 055 int wait = rand() % 100000; 056 for(volatile int i = 0; i < wait; i++) 057 { 058 ; 059 } 060 HAL_Delay(4); 061 uart_send("PASSWORD FAIL\n"); 062 } 063 else 064 { 065 uart_send("Access granted, Welcome!\n"); 066 } 067 while(1) 068 { 069 ; 070 } 071 } 

030行设置输入密码-Vulkan。 接下来,LED点亮
led_on()并发送有关密码请求的UART消息。 led_on()函数激活PA12 MK的GPIO引脚,并通知有关ChipWhisperer将开始累积波形的事件。 CW_TRIG应该连接到此引脚。 为了方便起见,所有这些都是“合成的”,但是在实际情况下,差异是微不足道的,因为您可以输入相对于CW_TRIG连接到的任何事件的CLOCK时钟周期数的时间延迟。 例如,它可以是MK下载,消息接收/传输,包括LED等的开始。


此外,MK等待输入密码,它将逐字符验证密码。 如果队列中的任何字符都不匹配(例如,三个字符正确,而第四个字符不正确),则需要使用break语句退出for循环并报告错误的密码。 在055-059行中,实现了一个随机延迟发生器。 这种设计最常用于使临时攻击的行为复杂化(即跟踪整个系统响应时间的变化)。 包含此设计是为了了解我们没有使用临时攻击方法选择密码。


Jupyter Python教程代码托管在相应的资源上 。 下图显示了一个示例,该示例使用每个正确的新符号在MK的电源波形输出中输入密码。 请注意,使用正确密码的字符输入(要输入的密码显示在图的顶部), break操作的签名移至046行(在下图中以橙色突出显示)。 这是在逐字符验证密码时,中断操作所造成的“弱点”。



密码波形图


熟悉本指南后,我们发现使用SCA分析来使用这种方法来绕过密码保护是多么容易。 注释掉该固件中第048行的break操作就足够了,通常,密码检查将同样成功,但是签名处理的跟踪将变得更加复杂。 因此,为降低此类攻击的有效性,应避免立即中断扫描周期的操作。


这种分析的复杂性在于找到必要的签名。 因此,进行此类攻击会使密码验证时引入临时rand()构造,添加其他计算或给其他组件添加噪音的情况大大复杂化。


小故障攻击


小故障攻击是根据某种影响方法,在确切的时间通过一系列短期脉冲进行的。 最受欢迎的方法是:时钟(CLK-毛刺),功率(Vcc-毛刺)和电磁场。 电磁场由MC附近的高压火花产生。 为此,NewAE使用ChipSHOUTER设备。 我们没有购买它,所以我们只进行了CLK毛刺和Vcc毛刺攻击。


通过向MK的外部CLOCK信号(来自外部石英或发生器)施加电压脉冲(对于CLK毛刺),对Vcc毛刺,施加电压脉冲来进行毛刺攻击。


通常,故障攻击使您可以绕过任何MK指令,例如,输入密码,访问请求,许可协议等。 小故障攻击更为复杂,艰苦且耗时。 另外,有必要重复重复小故障攻击,因为它的成功本质上是概率性的,并且取决于脉冲的参数。 以下是故障选项:


•scope.glitch.width-相对于CLOCK的脉冲宽度(以百分比为单位);


•scope.glitch.offset-相对于CLOCK的脉冲偏移量,以百分比为单位;


•scope.glitch.repeat-攻击脉冲的重复次数;


•scope.glitch.ext_offset-事件触发后错过的小节数。


时序图中显示了CLK毛刺和Vcc毛刺的毛刺映射:



CLK毛刺的时序图



Vcc毛刺的时序图


选择毛刺脉冲的所有参数,以便MK内核在不稳定模式下运行(由于跳过了指令)。


根据小故障攻击的结果,可以发现,如果参数scope.glitch.repeat的值太小,则不会发生指令的“滑动”。 如果设置较大的值,则不仅可以跳过必要的说明,而且可以跳过所有后续说明。 在大多数情况下,在5-25范围内查找scope.glitch.repeat就足够了。 关于其他参数,这完全取决于攻击的类型和连接条件。


CLK毛刺


通过向CLOCK MK信号添加较短持续时间的脉冲来执行CLK毛刺攻击。 因此,必须将CLOCK与MK断开连接,并已通过CLK小故障攻击将其从ChipWhisperer提供。


首先,您需要将ChipWhisperer连接到MK:



CLK毛刺连接图


参考资料中提供了所有Python代码和手册的详细说明。 然后,在STM32F103RBT6中,“填充”固件,将以下功能添加到主while(1)


 075 void glitch_password(void) 076 { 077 char inp[16]; 078 char c = 'A'; 079 unsigned char cnt = 0; 080 uart_send("Password:"); 081 082 while((c != '\n') & (cnt < 16)) 083 { 084 c = getch(); 085 inp[cnt] = c; 086 cnt++; 087 } 088 089 char passwd[] = "Vulkan"; 090 char passok = 1; 091 092 led_on(); 093 led_off(); 094 095 //Simple test - doesn't check for too-long password! 096 for(cnt = 0; cnt < 5; cnt++) 097 { 098 if (inp[cnt] != passwd[cnt]) 099 { 100 passok = 0; 101 } 102 } 103 if (!passok){ 104 uart_send("Denied\n"); 105 } 106 else 107 { 108 uart_send("Wow! Vulkan win!\n"); 109 } 110 } 

我们的目标是在输入错误密码时绕过103行的if ,并进入106行的else情况。此攻击中最重要的事情是检查103行的passok变量。为此,请选择scope.glitch.ext_offset参数。 通过将示波器连接到UART并将毛刺设置为干扰的位置,这是最容易做到的,因为毛刺会渗入整个MK:



小故障位置


攻击代码和方法摘自本手册 (“攻击循环”部分,块9-10)。 我们在代码中所做的唯一更改是启用了所有print(response)消息的输出而不进行过滤,因为重要的事件通常由于配置的过滤器而被跳过,例如:


 if need_response not in response: pass else: print ("!") 

下图显示了消息输出日志的示例,该消息输出日志在CLK小故障攻击接近成功或远未成功时出现。 当接近正确的故障参数时,MK运行中的不稳定开始出现(消息中断,MK进入重新启动状态)。 这可能是搜索时的提示。



毛刺攻击期间的消息输出,其参数远非成功(a),接近成功(b)



成功的CLK小故障攻击的结果


攻击的结果表明,取决于与Clock MK的ChipWhisperer连接的质量,CLK毛刺脉冲的参数可以“浮动”。 例如,将示波器探头设置为CLOCK引脚时,scope.glitch.offset参数对于成功进行攻击就变得不同,因为探头具有自己的电容性电感参数,可以校正高频毛刺。 因此,通过较长的非屏蔽电缆进行连接会带来很多惊喜。 否则,CLK毛刺攻击可以称为稳定攻击,例如 对于各种指令,它们的参数略有变化(如果已检查)。


防止此类攻击的方法是使用内部的CLOCK MK信号,但其温度和时间稳定性最差。 同样,一种有效的方法可能是在重要指令(检查密码,个人数据等)之前和之后引入随机的时间延迟,这可能会使CLK短时脉冲的正确命中变得复杂。


Vcc故障


Vcc毛刺与CLK毛刺一样,仅通过将MK电源接地短路即可将高频干扰引入MK的操作。 进行Vcc小故障攻击时,必须考虑成功脉冲的参数取决于许多因素,例如:


•用于MK的印刷电路板的设计特征以及各种捆扎带的存在;


•用于连接MK和ChipWhisperer的故障端口的同轴电缆的长度(电缆越长,成功攻击的可能性越小,最佳长度为10-15厘米);


•MK系列;


•要跳过的指示;


•MK编译器优化;


•MOSFET晶体管的类型(由于S参数的高频分量不同)。


因此,进行攻击时,必须确保这些参数不变。


首先,您应该将ChipWhisperer连接到MK:



Vcc小故障攻击的连接方案


接下来,我们“刷新” MK中的固件,其中在主while(1)中具有以下功能:


 115 void glitch_while() 116 { 117 volatile uint8_t infinity = 0; 118 uart_send(" Hello habr!"); 119 led_on(); 120 led_off(); 121 122 while(infinity != 2) 123 { 124 ; 125 } 126 uart_send("WOW!!! Vcc Glitch work!"); 127 while(1) 128 { 129 ; 130 } 131 } 

发送消息“ Hello habr!”后的MK进入第122行的无限循环。我们的任务是使用Vcc-glitch从此循环中删除MK。 在此循环中, volatile uint8_t infinity变量用作条件,当程序正常volatile uint8_t infinity时,该变量永远不会等于2。 如果我们用while(1)代替while(infinity != 2) ,则编译器将忽略下面的代码,包括我们宣布从无限循环中退出的消息。 由于类型为volatile的变量volatile编译器将无法执行此操作。 while(1)第127行添加了while(1)以便在WOW !!!之后 Vcc小故障工作! 我们没有再显示您好哈勃!


我们使用Python代码从本指南中控制ChipWhisperer。 这是来自MK的消息:



Vcc小故障攻击成功的结果


从图中可以看出,Vcc小故障攻击是成功的。


进行Vcc小故障攻击的困难在于选择正确的脉冲参数。 与其他攻击相比,实施此攻击花费的时间最长,因为成功实施Vcc小故障攻击取决于上述因素。


防范此类攻击的方法还可以是在重要说明之前和之后(检查密码,个人数据等)引入随机的时间延迟。 这可以在适当的时间使Vcc毛刺脉冲的精确击中复杂化。 在PCB布线过程中,电源与地之间的电容性耦合的增加也可能会有所帮助。


结论


进行的攻击使您可以规避MK中的说明。 SCA分析的例子表明,即使是最简单的此类攻击,也可能威胁到数据(密码,加密密钥)的安全性。 我们确保小故障攻击会规避设备中提供的各种说明和软件保护方法。 在所考虑的手册中,防范攻击的通用方法可以是在MC中执行重要指令时引入随机时间延迟。


我们对硬件攻击的研究并不止于此。 将来,我们计划探索使用Vcc-glitch攻击绕过MK固件的固件字节验证的可能性。 访问MK固件可以为攻击者带来巨大的机会:从克隆设备以进行转售到完全访问所有专有信息以及对MK的控制。


在我们使用Vcc-glitch进行的实验中,我们尝试绕过固件的保护,并获得了成功。 我们确保这是可能的。 我们将在下一篇文章中展示演示如何读取隐藏的MK固件的实验。



Raccoon Security是位于火山科学技术中心的特殊专家团队,负责实践信息安全,密码学,电路,逆向工程和低级软件的创建。

Source: https://habr.com/ru/post/zh-CN480500/


All Articles