目前暂时删去侧信道攻击内容。侧信道攻击在硬件安全领域十分重要。受限于认知有些理不清,后续会更新加上。

以望闻问切的方式打开ECU硬件安全

在车内具有许许多多的零部件ECU,这些ECU通过如同脉络一般的车载网络彼此有序相联,而ECU内部又是一个个相对独立的单元,各司其职发挥作用

望诊

打开ECU的外壳,内部是一大块或者多块相连的PCB板,上面焊接着各种芯片

通过丝印找寻芯片Datasheet

芯片本质上是由计算电路与将其引出方便接线的引脚构成,但引脚那么多该如何找到对应的功能接口呢?类似于在软件中写README或者API文档,芯片也有对应的文档,详细记录了芯片的开发所需信息,叫做Datasheet

在ECU的PCB板上,能看到的芯片通常情况下是会将丝印磨去的,这正是因为丝印上往往填写由芯片的编号、封装等信息,根据这些信息能够轻易找到Datasheet,泄露接口信息

通过PCB板上焊盘找寻调试接口

如果芯片丝印被磨去了,没法通过Datasheet直接看接口信息了怎么办?很多时候在PCB板上会留下一些空焊的焊盘,有通孔的,也有贴片的。这些焊盘有的会成组排列,这样的地方就有可能是调试接口

调试接口的长相相对来说比较固定,最常见的UART大概长这样:
O O O 口
由供电、写入、读取、地线四线组成,不过也可能排列成两行两列形式。JTAG也常见四根引脚,但同时可能会有更多引脚(10、14、20)的版本。SWD可以视作JTAG的“精简版”,将收发复用在同一引脚上

存储芯片RAM/ROM与FLASH

在PCB板上除了计算用的芯片外,自然也有存储用的芯片,而芯片中存储的恰恰就是我们所关注的固件等数据

目前常见的存储芯片封装有两种,一种是BGA的,也就是引脚埋在封装的下面,另一种是SOP或者QFP这样在芯片外有短引脚的

闻诊

在初步确定完可能有哪些接口后,需要进行下一步功能嗅探

使用万用表嗅探引脚功能

一般来说,两根最粗的线排一块,连着一个两口的接线端子大概率就是供电线VCC与地线GND了,当然在ECU上的接线一般都是一大堆在一块,不过这也不是什么难事

首先先寻找GND,一般来说地线网络在整个PCB板上是面积最大的连续铺铜区域,其次是可以通过大电容标识的负极,一般也与GND相连。找到了GND,用万用表蜂鸣器档位测出与地线相连的所有引脚,做好标记,这里个人使用的方法是拍一张照片然后在照片上做标记

将ECU上电,万用表调至电压档位,测量剩下的引脚,电压一直保持不变的大概率就是供电线VCC,如果一直跳变的那基本可以判断为数据线

使用Jtagulator嗅探调试接口

找到了疑似是接口的引脚该如何确定功能呢?这时候就可以借助工具:Jtagulator

将探测到的GND与VCC对应连接到Jtagulator上,随便接一对就行。之后将其他感觉像是接口的线一股脑接上,就可以使用Jtagulator进行扫描了,可以通过h指令查看支持哪些功能

Jtagulator需要通过串口连接,通过USB连接上电脑,如果有安装好D2XX或者D3XX驱动是可以在设备管理器中看到包含serial、com这类字段名称设备的,之后就可以使用Xshell、SecureCRT之类的软件,设置端口和波特率115200进行连接

使用逻辑分析仪嗅探I2C、SPI总线数据

计算芯片与存储芯片会通过总线收发数据,如果总线上未加密,在读取固件时就能通过逻辑分析仪dump出来

不过能够抓取高速flash的逻辑分析仪超级贵,想体验弄个bus pirate v3.6或者v4就差不多了

问诊

有句话是这么说的,“代码是逻辑的载体,逻辑则是实体之间的联系,实体的属性叫做数据,数据的流向由控制流决定,当数据流入侵到控制流,漏洞就产生了”

在获取到可分析的信息后,我们需要去推敲“逻辑的实装”

多种途径的固件提取

除了通过逻辑分析仪嗅探计算芯片的读取流外,更常见的方法其实是使用调试接口或编程器提取

如果固件中跑的是某种操作系统,且正好有可连接的uart口,那就撞大运了,连上去就是shell!想要分析什么保存就好;如果有可连接的JTAG或者SWD接口,则可以尝试使用JLink、STLink等工具尝试提取

但都没有,那就得看封装,比较友好的是有外部引脚的SOP封装,这种可以非常容易的使用测试夹夹住,然后连接到编程器上,选择对应的芯片,直接就能读出来;其次是QFP,这种四面都有引脚的就不方便夹住了,但不过可以用热风枪轻松吹下来,焊到转接板上进行操作;最难搞的是焊盘在底下的BGA,在板上弄飞线要飞半天,吹下来弄焊到转接板上太吃手法

庖丁解牛固件分析

拿到dump出来的bin文件后的第一步自然就是解析了,首先先要确定固件的熵值,熵值顾名思义,就是指的数据的无序程度,在熵值高的情况下则说明固件被压缩或者加密了
可使用binwalk -E firmware.bin查看熵

之后则是判断固件用的是什么文件系统,常见的有SquashFS、JFFS2,当然也可能会有“裸奔”的固件,毕竟不会真有人往51系单片机上整什么文件系统吧,这种就可以直接拿去逆向分析了
可使用binwalk firmware.bin分析

在了解这些情况后,就可以对固件进行解包,比较轮椅一点的就是直接binwalk -Me firmware.bin递归解包,想要硬核一点可以通过十六进制编辑器找到文件系统魔数的偏移位置,使用dd提取出文件系统,然后用对应的解压软件即可,具体原理就要涉及到各种压缩解压了,这里不多赘述

最后则是对具体的程序进行逆向分析,静态分析IDA、Ghidra都行,这个大伙都比较熟悉。有些时候需要分析Bootloader,Bootloader在漏洞发掘中是较为重要的一个部分,通过中断向量表找到加载地址,然后分析Bootloader是否存在有验签机制以及相应的bypass手段。
在动态分析方面往往需要使用qemu这个强大的仿真器,当然,也有很多时候由于缺少环境等原因仿真执行跑不通,这种时候就要使用patch或者hook了

切诊

“切诊”在于触诊,探寻脉搏的跳动,定位病灶

在分析完固件后,自然对于可能存在的漏洞有了一定的了解,进行实际的验证与利用,精准定位安全问题

模拟执行进行漏洞验证

如果说在之前通过强大的静态分析能力,没有做任何的仿真就审计出了漏洞,但由于各种缺环境始终无法真正意义上把程序跑起来,这是非常痛苦的事情。别担心,这个时候就可以使用Unicorn、Qiling等模拟执行框架,直接执行有漏洞的代码,验证是否存在

比如在某个程序中发现了一个栈溢出,那么就可以通过地址模拟执行此处的函数,可以将函数的返回地址设定成某个显眼的值,然后在溢出点传入payload,在这之后再次打印返回地址,就轻易看出漏洞是否真实存在了

漏洞利用

在之前我们探讨了固件中的Bootloader和应用程序的各类分析方法,对于Bootloader,常见的漏洞在于验签机制存在但不完善,这样就可以尝试写入存在漏洞的老版本固件;应用程序则需要通过传入接口分析数据走向,就像是在已知漏洞的情况下做TARA分析,常见的漏洞在于CAN总线通讯上没有合理的校验机制,导致指令报文可重放可篡改

一个仍在爬山的人