《锁王创造营》 第三关:釜底抽薪 – 作者:TC111金牛座

前言

0.png

15日,美国商务部公告升级了对华为的芯片管制,即便芯片本身不是由美国来开发设计,但是只要外国公司使用了美国芯片的制造设备,就必须获得美国政府的许可,才能向华为或其附属公司提供芯片。华为想要继续获取某些芯片或使用某些美国软件或技术相关的半导体设计,也必须获得美国的许可。

芯片是科技发展的基础,一个企业甚至国家的核心竞争力,一直以来,国人都在想方设法摆脱在芯片领域被“卡脖子”的状态,例如龙芯、飞腾、兆芯,但全球芯片生态和技术迭代的时机又一次次表明这注定是一个“路漫漫其修远兮”的艰苦过程,不过也正像上图华为回应的那样“回头看,崎岖坎坷;向前看,永不言弃。”破釜沉舟、背水一战,才是唯一出路。

智能门锁安全研究自然离不开芯片层面的攻防,数智安全研究院深耕芯片安全多年,在这一块也有所积累,接下来通过一些具体案例介绍一下智能锁中的芯片安全。

智能锁芯片安全

芯片调试

预留接口调试

如果PCB上保留了厂商在研发过程中预留的 SWD 接口,可直接通过飞线的方式,连上对应的引脚进行调试。

2.png

2.png

连接 gdb 进行调试。

3.png

直连芯片 JTAG 引脚调试

大部分厂商在生产环节会去掉外部引出的 JTAG 接口,因为多数量产芯片的封装格式,直接飞线难度较大,因此可以采用探针台直连芯片引脚进行调试。在研究的某款智能锁,拆解发现采用的是 MSP432G2553 作为主控,下图红框位置。

4.png

该款智能锁利用手机 app 产生开锁音频信号,进过外部 AD 转换后传输至芯片中进行解密开锁处理,厂商在生产过程中比较注重安全意识,PC 上的没有保留调试接口,进一步分析的话,需要对芯片进行固件提取和在线调试。

查TI官方手册,MSP432G2553 芯片引脚定义如下,其支持四线 JTAG 和两线 SBW 的调试接口,随采用两线制 SBW 接口作为调试方式,其 16 引脚为 SBWTDIO 口,17脚为 SBWTCK 脚。

5.jpg

连接引脚

两线制 SBW 对应 MSP430 仿真器上的14线排针接口,分别为 16 脚 SBWTDIO 口连仿真器第一脚 TDO,17脚 SBWTCK 连第7脚 TCK,最后需要连接 GND 脚,即芯片的第 20 脚连仿真器第9口,两线制 SBW 同时需要外部电源供电,仿真器接口定义如下图。

6.jpg

按照引脚说明,开始在探针台上连接引脚,需要注意 JTAG 和 SBW 调试,对连线的长度有严格要求,超过 20 厘米信号会大幅衰减,造成无法调试,因此在探针上利用夹子和铜导线缩小接线距离。

7.png

8.png

在线调试连接上仿真器,启动 msp430-gdbproxy。msp430-gdb 远程连接 target remote 192.168.1.196:2000

9.jpg

接下来可以结合固件分析,协议分析等进一步研究此款锁的安全性。

芯片读取

jtag提取固件

拆焊芯片首先用热风*拆下智能锁主控芯片,该单片机型号为 :Stm32F103R6。

10.png

烧录座连接Jlink芯片第一脚对齐烧录座第一脚,然后把 Jlink 插入烧录座引出的 JTAG 接口。

11.png

读取固件电脑上安装好 Jlink 驱动,打开 J-Flash 客户端,设置好参数,主要在配置栏选择正确的芯片型号,然后点击连接,在点击 Target->Read Back->Entire trip 即可读写固件。

12.jpg

绕过读保护读取固件

拆开智能锁,找到PCB电路板中芯片的位置,可以直接看出芯片型号为nRF51802 。

13.png

通过查阅芯片手册,找到电路板上的芯片SWD调试接口,通过JLINK连接,发现芯片设置了读保护。由UICR(用户信息配置寄存器)中的RBPCONF(0x10001004)寄存器处理,如果设置为0xFFFF00FF,则启用读出保护,默认值为0xFFFFFFFF。通过调试端口查看:mdw 0x10001004读取z

14.png

可知智能锁有读保护。

查阅资料发现可以通过修改寄存器中的值为我们期望的内存地址,并传递给加载指令可以绕过读保护提取出固件。

15.png

毛刺攻击绕过读保护

除了使用软件漏洞,通过电压、电磁等毛刺攻击也可以绕过读保护 。

16.jpg

17.jpg

(毛刺攻击 stm32 芯片 来源:chip.fail)

物理攻击

通过电磁注入芯片,产生重置信号,实现开锁。

开锁视频

某款共享单车电路设计和机械构造存在问题,可以从外部截断输入锁体的电源线,再用一个高电压的脉冲电压作为输入电源,即可开锁。其原因在于电路设计和电机控制芯片选型存在缺陷,没有做充分的过载保护和断路保护,使控制锁柱运动的电机异常工作。

18.jpg以上为我们本期《锁王创造营》所分享的关于智能锁芯片安全的具体案例,希望能让您对智能锁具芯片安全的认知有所帮助。

在上一期《锁王创造营》中,我们成功解锁了第二关“Sydney”,今天我们将继续破解第三关——“Hanoi”。

第三关:Hanoi

18.png

首先我们浏览一下手册,看该版本更新了哪些内容。

OVERVIEW

  • This lock is attached the the LockIT Pro HSM-1.

  • We have updated the lock firmware to connect with the hardwaresecurity module.

DETAILS

LockIT Pro Hardware Security Module 1 stores the login password, ensuring users can not access the password through other means. The LockIT Pro can send the LockIT Pro HSM-1 a password, and the HSM will return if the password is correct by setting a flag in memory.

这里说该锁连接了 HSM-1(硬件安全模块),也就是说密码在的HSM中存储,LockIT Pro可以向HSM-1发送密码,再由HSM返回结果,而我们无法直接访问它。

接下来,我们查看反汇编窗口,看看它到底做了什么,首先是main函数,main中除了调用login函数外,并无其他功能。

4438 <main>
4438: b012 2045     call   #0x4520 <login>
443c: 0f43           clr   r15

查看login函数,其中调用了一些函数,put函数、getsn函数请求用户输入、test_password_valid函数根据函数名知道其作用是测试密码有效性。

4520 <login>
4520: c243 1024     mov.b   #0x0, &0x2410
4524: 3f40 7e44     mov   #0x447e "Enter the password to continue.", r15
4528: b012 de45     call   #0x45de <puts>
452c: 3f40 9e44     mov   #0x449e "Remember: passwords are between 8 and 16 characters.", r15
4530: b012 de45     call   #0x45de <puts>
4534: 3e40 1c00     mov   #0x1c, r14
4538: 3f40 0024     mov   #0x2400, r15
453c: b012 ce45     call   #0x45ce <getsn>
4540: 3f40 0024     mov   #0x2400, r15
4544: b012 5444     call   #0x4454 <test_password_valid>
4548: 0f93           tst   r15
454a: 0324           jz   $+0x8
454c: f240 f100 1024 mov.b   #0xf1, &0x2410
4552: 3f40 d344     mov   #0x44d3 "Testing if password is valid.", r15
4556: b012 de45     call   #0x45de <puts>
455a: f290 c600 1024 cmp.b   #0xc6, &0x2410
4560: 0720           jne   #0x4570 <login+0x50>
4562: 3f40 f144     mov   #0x44f1 "Access granted.", r15
4566: b012 de45     call   #0x45de <puts>
456a: b012 4844     call   #0x4448 <unlock_door>
456e: 3041           ret
4570: 3f40 0145     mov   #0x4501 "That password is not correct.", r15
4574: b012 de45     call   #0x45de <puts>
4578: 3041           ret

通过开头的手册提示,我们知道密码在HSM中,我们看看test_password_valid函数做了哪些操作。

4454 <test_password_valid>
4454: 0412           push   r4
4456: 0441           mov   sp, r4
4458: 2453           incd   r4
445a: 2183           decd   sp
445c: c443 fcff     mov.b   #0x0, -0x4(r4)
4460: 3e40 fcff     mov   #0xfffc, r14
4464: 0e54           add   r4, r14
4466: 0e12           push   r14
4468: 0f12           push   r15
446a: 3012 7d00     push   #0x7d
446e: b012 7a45     call   #0x457a <INT>
4472: 5f44 fcff     mov.b   -0x4(r4), r15
4476: 8f11           sxt   r15
4478: 3152           add   #0x8, sp
447a: 3441           pop   r4
447c: 3041           ret

通过简单分析可以看到,地址0x446e调用了INT函数,根据LockIT Pro用户手册第7页,可以看到INT函数的作用是将中断号压入栈中,然后调用系统中断,在call #0x457a <INT>上方正是将“0x7d”压入栈中,所以这是调用INT 0x7d中断。

640?wx_fmt.png

在LockIT Pro用户手册第9页中说明,调用INT 0x7d中断后,若是密码正确,将会在某一位置上覆盖标志。

20.png

我们回到login函数中,使用break 4548命令,将断点设置在调用test_password_valid后下一条指令位置,然后c运行,运行过程中调用请求输入函数getns,根据调用前参数,我们不知道正确的密码,依旧填“test”。在IO交互界面提示,密码在8~16字符之间。

21.png

getns有两个参数,请求输入密码的内存缓冲区地址(0x2400),以及接收的最大字节数(0x1c),所以尽管上面提示密码在8~16字符之间,我们还是可以输入28(0x1c)个字符。

4534: 3e40 1c00     mov   #0x1c, r14
4538: 3f40 0024     mov   #0x2400, r15
453c: b012 ce45     call   #0x45ce <getsn>

待在0x4548断下以后,我们单步分析。在不知道密码的情况下,寄存器r15(r15存放test_password_valid函数的返回值)的值为0是必然的,所以执行jz $+0x8,跳过mov.b #0xf1, &0x2410,随机打印提示测试密码是否有效字符串。

4544: b012 5444     call   #0x4454 <test_password_valid>
4548: 0f93           tst   r15
454a: 0324           jz   $+0x8
454c: f240 f100 1024 mov.b   #0xf1, &0x2410
4552: 3f40 d344     mov   #0x44d3 "Testing if password is valid.", r15
4556: b012 de45     call   #0x45de <puts>

随即cmp.b比较源操作数0xc6与地址0x2410的内容,其中目的操作数是绝对寻址模式。下一条指令jne,若是不相等则跳过unlock_door函数,ret返回。所以这是解锁的关键代码,猜测之前调用INT 0x7d时,若密码正确覆盖的正是这一地址。

455a: f290 c600 1024 cmp.b   #0xc6, &0x2410
4560: 0720           jne   #0x4570 <login+0x50>
4562: 3f40 f144     mov   #0x44f1 "Access granted.", r15
4566: b012 de45     call   #0x45de <puts>
456a: b012 4844     call   #0x4448 <unlock_door>
456e: 3041           ret
4570: 3f40 0145     mov   #0x4501 "That password is not correct.", r15
4574: b012 de45     call   #0x45de <puts>
4578: 3041           ret

关于寻址模式,在msp430手册中介绍,针对源操作数的七个寻址模式和针对目的操作数的四个寻址模可在完整地址空间寻址。

22.png

还记得之我们输入的密码在内存的位置吗?密码在地址0x2400起始的缓冲区中,和0x2410只相差0x10字节,而我们可以输入0x1c个字符,此时我们可以通过“溢出”0x10字符的范围,覆盖到地址0x2410中。

23.png

解锁

我们已经确定了解决方案,下面开始解锁。

填充0x10字节数据,在其末尾加上0xc6即可。

以16进制编码输入:41414141414141414141414141414141c6。

24.png

成功解锁!

25.png

以上就是本期《锁王创造营》的全部内容,对闯关以及其他问题感兴趣的小伙伴可以加一下我们的技术交流群哦!

26.jpg

参考

  1. MSP430 用户指南 http://www.ti.com.cn/cn/lit/ug/zhcu032i/zhcu032i.pdf

  2. 智能锁具攻防一:初探 https://yaseng.org/intelligent-lock-attack-and-defense-1.html

  3. 智能锁行业安全分析报告 https://yaseng.org/intelligent-lock-industry-safety-report.html

  4. 物联网安全百科 https://iot-security.wiki

  5. nrf51822 绕过读保护 https://www.pentestpartners.com/security-blog/nrf51822-code-readout-protection-bypass-a-how-to/

  6. 错误注入绕过大多数现代化的芯片读保护 https://chip.fail/


28.png

来源:freebuf.com 2020-05-26 16:27:39 by: TC111金牛座

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论