智能汽车网络安全权威指南(下册)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

11.4 汽车网络安全架构视角下的攻击手法

汽车网络安全架构分为云、管、端三部分,从黑客视角来看,分别对应远程攻击、中程攻击、近程攻击。

11.4.1 远程之云端控车攻击

现代智能汽车通常具有云端控车的功能,即通过手机向云端发送指令,再由云端向车辆发送指令来实现远程控制,例如解锁车门或开关空调等。

针对云端的攻击对汽车产生的影响极大。可以想象,云端可以控制所有同款车辆,一旦被攻破,其后果将不堪设想。本节知识点如图11-30所示。

图11-30 远程之云端控车攻击知识点

1.云端控车越权漏洞

云端控车的漏洞大多是越权问题,比如利用某个用户的token越权访问其他用户、登录验证存在缺陷等。我们接下来将借助两个公开的漏洞案例进行讲解。

(1)案例一

为了攻击云端控车,首先要做的就是了解手机和云端是怎么通信的。对此,抓包是第一步。而攻击者要抓取控车的数据包,则要先获取服务器的token,如图11-31所示。

图11-31 获取服务器的token

该token是一个JWT token,用来鉴权控车指令,获取token的请求参数只有customerId和VIN码。众所周知,汽车的VIN码是不保密的,甚至就在车的挡风玻璃前。

该案例中的攻击者经过一些尝试后发现,将customerId改为如图11-32所示的格式就可以通过验证。

图11-32 修改customerId实现越权

有了此token后,攻击者就可以“为所欲为”了。

(2)案例二

利用同样的手段来抓取手机控车的数据包,查看身份校验,如下所示。

上述代码是通过VIN码和邮箱进行验证的,同时会加上当前登录的token,也就是说服务器会判断token所登录的邮箱以及该邮箱所绑定的VIN码是否正确。这种验证方式看起来似乎是没有问题的,因为攻击者既无法登录受害者的邮箱,也拿不到受害者的token。

但是在该案例中,聪明的攻击者绕过了该检查。因为攻击者发现在注册新用户时并不需要验证邮箱,因此他用了一个特殊的邮箱,即受害者邮箱加一个换行符,即%0d。

注册成功后,攻击者利用此账号竟然成功绕过了前面控车的身份校验,可以“为所欲为”了。

2.云服务平台管理员弱口令漏洞

车联网云服务一般会提供登录界面,并且有些登录界面可能开在公网。对登录的数据包进行抓包分析。如果系统没有有效的验证码并且系统的密码是明文传输或者只用md5等脆弱的算法进行加密,则可以利用工具或者脚本对登录数据包重放,进而对账户或者密码进行暴力破解。如果云平台的管理员账户存在弱口令,则可以利用弱口令登录云平台。

如图11-33所示是访问TSP云服务平台的登录界面。

如图11-34所示,对登录请求进行抓包后,使用工具对管理员账户进行密码爆破。

图11-33 TSP云服务平台登录界面

图11-34 爆破TSP云服务平台的登录密码

利用爆破出来的账号密码登录TSP云服务平台测试环境。登录车联网云服务系统后,获得管理员账户权限,通过扫描或者对系统进行漏洞挖掘,利用相应的漏洞对云服务系统进行进一步的安全测试。

3.云服务平台SQL注入漏洞

在云服务平台利用SQL注入进行安全测试,能获取数据库中的表信息。图11-35展示了一个存在SQL注入漏洞的接口。

图11-35 TSP云服务平台测试环境的某接口存在SQL注入漏洞

4.云服务平台SSRF漏洞

在云服务平台利用SSRF漏洞进行安全测试,对测试内网环境的系统进行横向安全测试,可能导致内网系统拒绝服务,或者可以获取内网其他系统的权限。

图11-36显示的是利用SSRF漏洞访问内网其他系统。

图11-36 TSP云服务平台通过SSRF漏洞攻击内网系统

5.云服务平台硬编码漏洞

云服务平台的开发人员可能不慎将隐藏的后门程序或其他内部开发的安全控件发布到生产环境中。比如开发人员可能在一个混合应用程序中无意地包含了一个作为注释的密码,测试人员在对源码进行审计后,发现可以持续利用这个硬编码的账户密码登录云服务平台。

如下所示,实现登录逻辑的代码中硬编码了账户密码,利用该账户和密码就可以登录云服务平台。

6.云服务平台任意文件上传漏洞

云服务平台上有一些文件上传的功能,如果文件存在可以解析的目录,并且代码层面没有对上传的文件后缀做限制,安全测试人员就可以上传webshell,并利用该上传的webshell获取服务器权限,可以在拖代码后进行代码审计,连接数据库。

如图11-37所示,先利用任意文件上传漏洞上传一个webshell,再利用工具连接这个webshell,就可以获取服务器权限。

图11-37 利用任意文件上传漏洞上传webshell

攻击者利用工具连接webshell地址,就可以对服务器进行攻击。

7.云服务平台命令注入漏洞

TSP云服务平台由于涉及车控,甚至可能介入OTA升级,所以代码中难免会调用一些系统命令的函数,这就给攻击者提供了利用命令注入漏洞的攻击条件。攻击者由此获取服务器权限后,可以在拖代码后进行代码审计,连接数据库。

如图11-38所示,利用命令注入漏洞,就可以在云服务器上执行任意命令。

图11-38 通过命令注入获得云服务器权限

8.云服务平台敏感接口未授权漏洞

很多情况下,攻击者找到云服务的管理平台后,却发现管理员没有弱口令,或者其登录功能不在当前站点上。此时攻击者会通过爬取页面上的.js文件等来收集接口列表信息,然后利用收集到的接口构造请求包进行测试。如果相关的接口存在未授权访问的漏洞,则攻击者可以利用接口进行未授权的攻击。

9.云服务器基础漏洞

部分传统的车联网云服务由于服务时间较长,将应用直接部署在云服务器上,然后挂一个公网IP就开放到公网了。因此云服务器存在漏洞,导致云服务被攻击。

(1)数据库弱口令

对测试环境的云服务器进行端口扫描,发现数据库服务开放在公网。再对其进行爆破攻击,发现存在弱口令。利用弱口令连接数据库后,查看里面的表信息,查找管理员账户密码。对密码进行解密后,利用获取的账户密码登录云服务系统并进行攻击。

(2)服务器SSH服务弱口令

对云服务器进行测试,如果云服务器把SSH服务开放在公网,就对其进行爆破攻击。如果发现其弱口令,则可以利用弱口令登录服务器,并对服务器进行进一步的安全测试。

10.云供应商漏洞

一些云供应商在一些场景下没有对鉴权进行隔离,导致攻击者可以通过替换请求中的VIN码或者用户ID的方式对部分接口进行越权攻击。比如可以通过供应商的某个接口替换VIN码来获取车主的电子钥匙信息。具体来说,抓包获得用户甲的请求信息后,将请求中的VIN码改为用户乙的VIN码,然后该请求返回了用户乙的车辆的电子钥匙信息。

11.4.2 远程之车机应用攻击

对于车辆来说,远程攻击的主要攻击面是云端。攻击者如果想进行远程攻击,也往往集中在云端,例如对于手机远程控车功能,攻击者会关注云端是否存在越权的可能性。另外一些车载应用程序的云端也可能存在远程攻击的风险,例如应用市场App等。

然而,并非所有远程攻击面都与云端有关。例如,浏览器就是一个天然的远程攻击面,因为它可以访问任意网站,包括攻击者的网站。除了浏览器,还有一些应用程序也可能存在远程攻击的可能性。例如社交软件,攻击者可以通过社交软件发送恶意文件或消息,并在社交软件中解析这些文件和消息时利用漏洞进行攻击。此外,邮箱软件、文档软件、多媒体播放软件等应用程序也可能被攻击者用来进行远程攻击。如果这些应用程序在解析文件时存在漏洞,则存在被远程攻击利用的可能性。本节知识点如图11-39所示。

图11-39 远程之车机应用攻击知识点

1.车机浏览器内核及WebView攻击

本节不涉及浏览器内核的攻击细节,因为这是一个专门的安全研究领域。无论从攻击还是防御的角度来看,浏览器内核攻击都是最具挑战性的项目之一。很多安全研究者多年致力于研究浏览器安全。

本节的主要目的是讲解如何找到车内浏览器的攻击面。由于浏览器的功能在使用上过于自由,因此许多汽车制造商都已将浏览器删除。这可能会让人误以为车辆上不存在浏览器攻击问题。实际上,Android平台中有一个名为WebView的特殊组件,它背后就是一个浏览器引擎(HTML+JavaScript),只是没有呈现浏览器的外观。因此,许多车辆仍然无法逃避浏览器的攻击面。

我们需要找出所有使用WebView的应用程序。为了实现这个目的,我们可以采用一些简单而有效的方法。首先需要对APK进行反编译,如下所示。

接下来需要对反编译后的内容进行搜索,查看是否存在与WebView相关的内容。

接着需要看WebView是如何被使用的,这些内容能否被攻击者控制。对此,通常有以下几种方式可以利用。

1)程序没有限制WebView加载的URL,即用户可以直接控制WebView要访问的URL。如下代码所示,程序会引入第三方可控的URL。

攻击者可以使用如下代码控制URL。

2)程序对WebView的URL校验不严格,校验机制可以被绕过,比如如下代码存在校验被绕过的风险,其中只检查了URL的Host,但没有检查URL scheme头部。

可以通过如下几种URL进行绕过。

❑javascript://legitimate.com/%0aalert(1)

❑file://legitimate.com/sdcard/exploit.html

❑content://legitimate.com/

3)如下所示的代码是一个看似安全的检查,但是其URI是通过getIntent().getData()获取的,而android.net.Uri是一个抽象类,它的子类HierarchicalUri是可实例化的,因此我们可以通过反射来创建HierarchicalUri对象,从而绕过上述检查。

4)如下所示,该程序使用了不安全的endsWith字符串函数,这样攻击者可以通过修改Host为xxx.test.com绕过该检查函数。对此,需要更改成更严格的校验方法。

5)程序中的WebView存在XSS漏洞,如以下代码所示。

6)存在JavaScript注入漏洞,如以下代码所示。

可以利用URL的参数注入JavaScript代码,如下所示。

7)有些应用程序可能会覆盖WebView的原始URL处理逻辑,此时需要使用WebViewClient.shouldOverrideUrlLoading(...)方法进行特殊处理。然而,这种做法往往会导致安全问题的发生,例如XSS攻击等。如以下代码所示。

可以使用https://www.example.com/search?q=<script>alert('XSS')</script>来进行XSS攻击。

8)WebView如果没有对HTTPS证书校验失败进行适当处理,就容易遭受中间人攻击。攻击者通过DNS劫持或ARP劫持等方式伪造一个服务器,向WebView返回恶意的响应,从而在WebView中注入攻击者的代码。例如下面的代码存在漏洞,开发者忽略了HTTPS请求中的TLS错误,使得访问可以继续进行。

一旦我们能够加载任意的URL或者执行自己的JavaScript代码,就可以通过JavaScript进行以下攻击。

1)访问JavaScript接口。如果程序向WebView添加了JavaScript接口,那么攻击者可以访问这些接口,如下所示。

攻击者可以使用如下代码调用接口。

2)利用XHR盗取文件。如果程序开启了允许file URL的功能,攻击者就可以指定任意URL,从而可以在WebView中使用XMLHttpRequest(XHR)对象来发送恶意请求,以此来盗取用户的本地文件。例如,攻击者可以通过XHR读取存储在用户手机上的敏感文件,比如Cookie等。

攻击者可以用以下代码盗取文件。

3)访问Cookie。有时WebView使用Cookie进行授权,而不是使用像Authorization这样的头字段,如下所示,应用为攻击者可控的URL设置了鉴权Cookie。

此时访问URL,攻击者就可以获取Cookie,从而获取用户凭证。

4)攻击Content Provider。默认情况下,WebView打开了访问content://的权限,这意味着WebView可以访问用户设备上任意的内容提供程序。例如,下面代码中的Content Provider将自己内部的数据导出到了SD卡中。

攻击者可以使用content://provider.authority/debug作为WebView的URL,从而触发此Content Provider。

5)攻击浏览器内核本身。对浏览器本身的攻击超出了本书的内容范畴,感兴趣的读者可以自己通过网络资源学习。

2.车机社交软件及媒体库攻击

社交软件,如微信、钉钉和邮箱等,提供了消息、文件和语音等功能,这也为攻击者打开了远程攻击的大门。如果社交软件没有得到很好的保护,攻击者就可以趁机发送病毒、恶意网站等内容,一旦受害者打开这些内容就会遭受攻击。

下面以公开的社交软件漏洞为例,讲解常见漏洞和攻击方式。

安全行业中的读者肯定听说过Project Zero团队针对iMessage的在野漏洞利用分析。这被认为是史上最复杂的漏洞利用过程之一。iMessage没有将.gif文件后缀放在沙箱内解析运行,而ImageIO库可以解析20多种格式的文件。因此,攻击者利用ImageIO中解析PDF的漏洞达到攻击目的。具体来说,PDF中的JBIG2编码存在缓冲区溢出漏洞,可让攻击者使用任意多的JBIG2段命令。然而,最让人惊讶的是,攻击者使用了70000多个JBIG2段命令,定义了一个具有寄存器、全64位加法器和比较器等功能的小型计算机体系结构,用于搜索内存和执行算术运算,并在此小型计算机的模拟环境下完成了漏洞利用。有关该漏洞的更多描述,请参考https://googleprojectzero.blogspot.com/2021/12/a-deep-dive-into-nso-zero-click.html。

11.4.3 远程之车载蜂窝网络攻击

现代智能汽车之所以能够上网,是通过车载蜂窝网络来实现的,该网络技术与我们的手机上网类似。然而,对于攻击者而言,车载蜂窝网络也存在劫持、伪造、重放、篡改、注入等一系列通信攻击的可能性。但因为在蜂窝网络通道上确实很难找到入口来进行攻击,所以许多整车渗透测试人员可能会认为蜂窝网络是安全的,不会进行相关测试。本节知识点如图11-40所示。

图11-40 远程之车载蜂窝网络攻击知识点

现代智能汽车大多使用4G网络,基于LTE标准。这个标准在设计时考虑了安全性,公开资料显示它不易受到中间人攻击,除非攻击者更换车上的SIM卡(前文已介绍过如何使用白卡进行安全测试),或者干扰2G网络。因此,我们的关注点只能放在如下两个层面上。

首先,我们需要关注车载蜂窝网络协议栈底层的安全性(即基带安全)。基带安全是一个专门领域的研究,攻击者需要深入了解协议栈的底层原理,熟悉协议标准,再通过Fuzz或逆向等手段检查基带芯片的固件是否存在代码漏洞,通常是一些内存漏洞。考虑到这属于一个专门的研究领域,本节不涉及这方面的安全性分析。

其次,我们需要考虑攻击者能否从应用层入手,加入车载蜂窝网络中进行攻击。

下面将介绍两种可能的应用层攻击方式。

1.蜂窝网络IP攻击

在车辆接入蜂窝网络后,会获得一个由供应商分配的内网IP地址。有时供应商会犯配置错误,导致多辆车在接入同一个蜂窝网络后可以相互进行IP通信。这样一来,攻击者就可以通过IP攻击进入车辆网络。

这时,攻击的方式类似于Wi-Fi攻击,攻击者可以攻击车辆开放的端口。例如,端口5555可以通过ADB进行访问,端口23可以通过Telnet进行攻击。

攻击者可以扫描蜂窝网络网段的IP地址,以查找具有开放端口的车辆,再通过T-BOX读取rmnet网卡的IP地址来获取该网段地址。

2.蜂窝网络SMS攻击

短信是蜂窝网络中的另一种通信方式,它是基于SIM卡号来收发消息的。在汽车中,有些业务功能是通过SMS实现的,这就给攻击者提供了攻击的可能性。

由于短信并不会像IP那样进行隔离,攻击者只需知道目标车辆的SIM卡号,就可以通过手机发送短信进行SMS通信。如果车端在处理短信时存在漏洞,攻击者就能利用这些漏洞。如图11-41所示,解析短信内容的代码中存在命令注入漏洞。

图11-41 命令注入漏洞

如何获取车辆的电话号码呢?我们需要知道SIM卡本身并不存储电话号码,而只保存序列号、IMSI等信息。电话号码是运营商存储的虚拟号码,当SIM卡激活后,运营商会建立起电话号码之间的关联关系。因此,有以下几种方式获得车辆的电话号码。

❑利用社交工程学手段询问运营商或汽车厂商售后人员。

❑利用钓鱼手段让车主通过汽车发送短信或拨打电话。

❑在具备伪基站的情况下直接给车辆发送短信。

❑在车辆上使用AT命令(即AT+CNUM)来获取号码。

11.4.4 中程之BLE钥匙攻击

根据一些公开资料的统计,在车联网安全事件中,基于蓝牙数字钥匙的安全问题所产生的事件数量位列前三。可以看出,这是一个影响范围很大的攻击面。主要原因是蓝牙数字钥匙涉及手机、云端、车端三者之间的复杂交互,并且可以用来远程解锁车辆,因此它具有很高的攻击价值。大多数安全研究人员都以此为入口进行车辆攻击研究。

本节知识点如图11-42所示。

图11-42 中程之BLE钥匙攻击知识点

蓝牙数字钥匙本质上是一个密钥分发系统。云端会给手机和车端分发密钥,而手机和车端则通过蓝牙通信相互校验密钥是否正确,如图11-43所示。

图11-43 蓝牙数字钥匙密钥分发系统

蓝牙数字钥匙还有一个重要特性,即支持离线解锁。这意味着在没有云端参与,且车辆和手机都无法上网的情况下,手机也能通过蓝牙解锁车辆。此外,蓝牙数字钥匙还具备被动进入功能。这意味着车主只要靠近车辆,车辆就能自动解锁,车主在手机上无须进行任何操作。蓝牙钥匙具有如此众多的高级功能,因此成了攻击者的重点关注对象。

1.BLE钥匙工作原理

上面介绍了BLE钥匙具有众多高级功能,那么它到底是如何工作的呢?我们通常将其工作过程分为以下4个步骤。

1)车辆实时广播:车辆会不断发出广播包,其中包含车辆的标识,例如UUID、NAME、VIN等信息。

2)手机App识别车辆:手机App会通过车辆的广播包识别出哪一辆是对应的汽车。这主要是依据车辆广播的身份标识信息,包括UUID、NAME、VIN等信息。

3)手机和车辆进行身份认证:这一步是整个蓝牙钥匙工作中最重要的一步,各个厂商所实现的方式都有所不同。其目的就是防止攻击者进行伪造、窃取、重放、篡改等一系列攻击。下面我将介绍一些常见的认证方式。

❑思路一:核心在于身份认证的全程由云端参与,以保证数字钥匙的安全性。具体流程是:当手机接收到车辆的身份标识后,会向云端请求数字钥匙,该数字钥匙是一堆加密的数据;然后该数据被发送给车端,车端再向云端请求验证该数据的合法性,如果合法则通过身份认证;使用之后,该数字钥匙失效,需要重新申请。

❑思路二:利用手机和云端各有一对公私钥的特点进行身份验证。具体流程是:云端事先下发一串数据给车端,该数据中包含了手机公钥,并且用云端的私钥加签,无法被篡改;然后,在进行BLE通信时,车端会利用手机的公钥来验证手机的合法性。比如,车端生成一个随机数给手机,手机通过私钥加密返回,车端利用公钥解密来判断手机私钥是否正确。如果成功,则代表该手机通过了身份认证。

❑思路三:利用手机和车端各有一个证书的特点进行身份验证,类似于TLS双向认证的过程。具体流程是:手机和车端互换证书,校验其证书链是否合法,并判断双方证书私钥是否正确;接下来,手机要验证车端证书中的VIN码是否正确。如果正确,手机将云端派发给它的数字钥匙发送给车端,该数字钥匙中包含了手机证书的信息、VIN码信息等,并经过云端签名无法篡改。车端会验证数字钥匙中的VIN码是否正确,以及手机证书是否正确。如果都没问题,则代表认证通过。

4)手机发送控车指令:到了这一阶段,就可以发送各种控车指令了,包括开门解锁等。

以上4个阶段是笔者根据自身的经验总结的简要过程,实际的蓝牙数字钥匙协议比以上过程要复杂得多,因为需要考虑功能的扩展性和响应速度等方面。因此,即使最初的设计是合理的,但在实现复杂功能的过程中,仍然有可能在某个环节出错,导致最终失败。

2.BLE钥匙安全风险

通过上一节蓝牙数字钥匙的工作原理,我们可以发现蓝牙数字钥匙的重要通信渠道有3个:车与手机、手机与云和车与云。在实际环境中,车与云的通信通常是通过APN私有网络完成的,攻击者很难进行劫持、重放、篡改等攻击。因此,攻击者更有可能利用车与手机、手机与云之间的通信漏洞进行攻击。

首先是手机与云,这与传统的App渗透测试类似,但需要更多关注数字钥匙相关的API。这类漏洞常见的是云端的越权漏洞,比如非车主账户是否能申请到数字钥匙,车主是否能越权影响其他车主,能否越权从云端向车辆下发恶意数据等。

其次是手机和车,这涉及BLE。BLE的协议栈自带配对机制,但目前很多车辆并未使用,而是采用自己实现的配对和认证机制,即Just Works模式。这可能是基于性能和易用性的考虑,但私有的配对协议往往没有经过大规模验证,经常会出现问题。以下是一些常见的私有协议问题。

1)重放攻击:这种问题是指蓝牙通信的协议中没有引入随机数、时间戳、滚码等变化的数据。即使通信过程都被加密,攻击者也可以对数据包进行重放,从而导致一系列看似安全的加解密操作变得毫无意义。

2)中间人攻击:在讨论中间人攻击时,我们很容易将其与中继攻击混淆,需要先明确两者之间的区别。中继攻击是一种通道转发攻击,主要用于扩大蓝牙通信的距离。它要求手机和车辆处于实时在线状态,中继设备只是“传话筒”,即如果手机和车辆中的任何一方不工作,就无法进行攻击。中间人攻击是一种可以劫持、代理的攻击,比中继攻击更具危害性。因为它是一种可以离线执行的攻击,即可以单向与手机或车辆交互。

那么中间人攻击是如何产生的呢?它的攻击场景是什么呢?

首先,中间人攻击多数会利用身份伪造,即车端和手机在通信过程中对彼此的身份验证存在缺陷,比如数据未加密、加密数据可重放、证书未校验、加密Key不变等。这使得攻击者通过其中一方获取某些信息后,可以与另一方进行通信,然后通过另一方获取更多的信息,最终攻击者在两方收集足够的信息后,可以直接与车端通信并通过身份验证。

3.BLE钥匙抓包分析

(1)抓取广播包

BLE具有广播包,它公开在所有蓝牙频段中,任何人都能接收到。广播包具有规定好的格式,其中包含一系列AD结构,每个结构具有一个AD Type,该Type指示AD Data的内容,例如设备名称、UUID、服务ID等。图11-44展示了广播数据包的结构。

有非常多的工具可以抓取广播包,比如可以直接通过Android App来抓取,如nRF Connect for Mobile这一应用,如图11-45所示。

图11-44 蓝牙广播包结构

图11-45 nRF Connect for Mobile

此外,对于Linux电脑,可以使用hcitool软件,部分代码如下。

抓取广播包的目的是了解目标蓝牙设备的基本信息,包括其设备名等。接下来我们就可以有针对性地进行完整抓包分析了。

(2)Android主动交互抓包

如果可以使用Android手机作为BLE钥匙与车端通信,就可以很方便地抓取蓝牙数据包,即通过Android原生自带的hcidump功能实现。

首先,开启Android开发者模式:打开“关于手机”,点击版本号,一直点到提示“开发者模式”,如图11-46所示。

然后,打开HCI日志:点击“设置”,打开开发者模式,开启蓝牙HCI日志,如图11-47所示。

图11-46 开启开发者模式

图11-47 开启蓝牙HCI日志收集

接下来,与车辆进行正常的通信,比如开启车辆操作,HCI日志被保存在/sdcard/btsnoop_hci.log中,通过ADB将该日志拷贝出来,如下所示。

在Wireshark查看HCI日志,就能看到蓝牙的数据包,如图11-48所示。

(3)Linux主动交互抓包

如果可以使用Linux PC作为BLE钥匙与车端通信,就可以具备和手机一样的抓包能力,具体如下。

图11-48 HCI日志

1)安装bluez-hcidump,代码如下。

2)使用hcidump抓包,将结果保存在/tmp/hci.log。

3)使用蓝牙钥匙开门,hcidump就会把蓝牙通信数据记录下来。

4)在Wireshark中查看hci.log,同Android一样。

关于hcidump的更多使用,可以查看https://linux.die.net/man/8/hcidump。

(4)被动嗅探抓包

BLE协议设计了一些防止被动嗅探的功能,但并非面对所有情况都能有效应对,这主要取决于不同的配对方式。例如Just Works和Passkey Entry配对方式无法有效防止被动嗅探抓包。

另一个存在被动嗅探风险的方面是BLE的跳频功能。BLE拥有40个频段,其中3个频段用于广播包,37个频段用于数据包。在蓝牙交互过程中,每个数据包都会在不同频段中变化。这虽然增加了被动嗅探的难度,但并不能完全避免嗅探。而对此各种嗅探工具都有着自己的解决方案,通常有两种方式:全频段抓包;抓取初始包,然后跟踪初始包的跳频。具体的被动抓包方法已在上一章中介绍过,本节不再赘述。

(5)主动与被动

主动抓包和被动嗅探的原理不同,各有优缺点。

主动抓包使用的功能是hcidump,它记录了蓝牙协议栈中Host和Controller之间交换的数据包。这些数据包由HCI命令格式组成,而不是原始的蓝牙数据。hcidump只能看到Host接收的数据包,无法看到链路层数据。如果链路层数据经过加解密,则Host看到的是被解密后的数据。因此,主动抓包的优势在于抓到的数据包是可靠的、不会丢失,并且即使有链路层加密也能看到明文。

被动嗅探完全不接触交互双方设备,通过空中抓包获取原始的信号数据,因此包含了所有的信息。被动嗅探的优势在于无须访问交互设备,并且可以观察链路层数据,查看是否有链路层加解密。如果被动嗅探可以获取泄露的敏感信息,那么这就是一个非常直接的攻击场景。

4.BLE钥匙重放攻击

前面已经对蓝牙协议进行了深入介绍,蓝牙协议栈如图11-49所示。由于蓝牙采用配对、跳频等机制,很难像433MHz那样直接从无线信号层面进行重放攻击。因此,本节重点关注建立连接后(即配对完成后)针对业务层数据包的重放攻击,即对协议栈中GATT层数据包的重放攻击。更多关于蓝牙协议栈的介绍请参考上册第3章。本章将继续讲解重放攻击的具体操作。

(1)抓取控车指令数据包

首先,我们需要一个具有正常控车权限的手机App和账号,然后按照之前讲解的方法通过Android抓取HCI日志的工具,并进行操作,抓取完整的控车过程。

例如,如果想要重放开窗操作,我们需要详细分析哪个write characteristic command数据包触发了车辆的开窗操作。为此,我们需要在Wireshark中过滤出所有的ATT(Attribute protocol)。可以在过滤栏中输入btatt,这样所有的characteristic操作都会被包含在ATT中,如图11-50所示。

(2)重放指令

重放其实有两种方式,一种是对HCI日志进行全部重放,另一种是经过分析后仅重放所需要的那几条指令。

1)全部重放。对hcidump的全部重放非常简单,甚至不需要用Wireshark分析,直接用开源的工具BLE-Replay重放即可,地址是https://github.com/nccgroup/BLE-Replay。

图11-49 BLE协议栈

图11-50 ATT数据包

2)精准重放。全部重放是非常粗暴的操作,很有可能无法成功。因此如果我们能把重放的精度提高,就可以提高成功概率。接下来我们需要分析出哪个指令或哪几个指令是用来控制车的,如图11-51所示,可以参考第1章的方法来对蓝牙协议进行逆向分析。

假设,我们已经分析出了对0x23的characteristic进行操作就可以控制车窗,那么接下来我们可以使用常见的工具,比如gatttool,无须编写代码即可进行重放操作。gatttool是一个gatt client命令行工具,可以连接蓝牙设备并与其交互,每一步操作都可以手动定制。而相比之下,BLE-Replay是一个一键式工具,自由度较低。

下面是使用gatttool进行重放的具体步骤。

图11-51 分析控车指令

5.BLE钥匙控车协议逆向分析

抓包之后,需要对整个通信过程协议进行具体分析。在逆向分析BLE钥匙协议时,主要操作集中在characteristic上。因为其他部分都符合BLE协议标准,Wireshark可以自动解析。而characteristic是真正实现业务逻辑的部分,是由使用者自定义的。

通常,对BLE钥匙协议的逆向分析会从手机App入手,因为相比于车端的ECU,对App进行逆向容易得多。

下面介绍一些逆向分析手机App中BLE钥匙的小技巧。

(1)定位蓝牙开发相关的API

首先需要了解蓝牙开发的流程,并定位流程中涉及的关键API,以找到蓝牙处理的相关代码。以下是蓝牙开发流程中的关键步骤和代码示例。

1)声明BLE相关权限:为了使用BLE功能,需要在应用的AndroidManifest.xml文件或代码中声明相关权限。

2)判断系统是否支持BLE:在操作蓝牙之前,需要判断系统是否支持BLE。

3)获取本机的蓝牙适配器:通过BluetoothManager获取BluetoothAdapter。

4)开始扫描外围设备:使用startScan方法扫描外围设备,并用BluetoothAdapter.LeScanCallback方法接收扫描结果。

5)连接外围设备:使用connectGatt方法对设备进行连接,并通过BluetoothGattCallback对象交付操作结果给客户端。如果连接成功,将返回BluetoothGatt实例,该实例是进行蓝牙控制的基础。

6)读写attribute:成功建立连接后,可以对attribute(属性,参考前面的BLE协议栈)进行读写。通过getService和getCharacteristics方法获取外围设备的service和characteristic,并对其中支持写操作的characteristic写入相应的数据,以实现对外围设备的控制。

了解BLE App开发流程后,在进行逆向分析时思路会更加清晰。首先,可以通过调用startLeScan和实现LeScanCallback等方法定位到扫描BLE外围设备的相关代码段;然后,通过调用connectGatt、实现BluetoothGattCallback等API来定位设备连接的相关函数,并找到指令交互部分;最后梳理出整个控制流程,包括写入特征值的调用位置,如下所示。

(2)Frida挂钩定位法

使用Frida挂钩Android Framework提供的BLE API来打印出调用栈,快速定位处理协议的代码块,具体步骤如下。

1)安装Frida,并在手机中安装Frida Server。

2)通过Frida的Python API编写Frida脚本,在脚本中挂钩android.bluetooth.Bluetooth-Gatt对象的方法,并在方法调用时打印出调用栈信息。

3)在手机中启动目标App,并让目标App与蓝牙设备建立连接。

4)在PC端使用Frida命令行工具运行脚本,并等待输出调用栈信息。

示例代码如下。

执行以上脚本后,Frida将在目标App与蓝牙设备建立连接并写入特征值时,打印出调用栈信息。可以根据输出的调用栈信息快速定位处理协议的代码块。

Frida使用教程可参考https://frida.re/docs/home/。

(3)数据包Magic Number定位法

数据包Magic Number定位法是一种抓包分析方法,可以搜索关键的Magic Number,并用这些数字来定位蓝牙控制命令ID或者自定义的数据包类型ID。使用Wireshark等工具来分析数据包,我们可以找到一些特定的魔法数字。例如,在捕获的蓝牙数据包中,如果每个数据包都以E1C8开头,那么E1C8就是一个Magic Number,如图11-52所示。接着,我们可以在APK中搜索该Magic Number,从而找到对应的蓝牙代码,如图11-53所示。

6.BLE钥匙中间人攻击

(1)厘清中间人攻击的概念

正如前文所述,本节所讲的中间人攻击并非中继攻击,这是一个比较狭义的中间人攻击概念,跟网络上所描述的中间人攻击的概念有所区别,我们暂且称之为广义中间人攻击和狭义中间人攻击吧。对此,笔者具体讲解一下两者区别。

图11-52 数据包中的Magic Number

图11-53 通过Magic Number定位蓝牙相关代码

1)广义中间人攻击:在网络上,有很多开源的BLE蓝牙中间人工具,例如非常著名的GATTacker和BtleJuice,它们自称为Bluetooth Smart(LE)Man-in-the-Middle Framework,我们将这些工具称为广义中间人工具。这种攻击方式的原理类似于以太网中间人攻击,相当于在通信链路中插入了一个代理节点。在此过程中,客户端、代理节点和服务器三者实时在线通信。通常情况下,我们将这种攻击方式称为中继攻击。

2)狭义中间人攻击:本节所描述的中间人攻击更多是从漏洞的角度出发,通过伪造车端和伪造手机端与双方进行通信,从而获取一些关键凭证,最终实现单边离线的车辆解锁攻击。与广义中间人攻击不同,这种攻击方式没有中间代理节点,而是直接伪造客户端或服务器,使得双方认为它们在直接通信。这种攻击方式在特斯拉公开的案例——TesMla项目中得到了广泛的应用。

(2)分析BLE钥匙通信协议原理

为了进行狭义中间人攻击,我们需要从具体的BLE钥匙协议出发。结合BLE嗅探攻击的内容,通过抓包逆向的方式,分析手机和车辆之间的通信协议。这里以特斯拉为例,参考TesMla项目。以下是特斯拉车主使用智能手机自动解锁他们的汽车的过程描述,该攻击是在手机和车辆已经完成首次配对之后进行的。

1)如果手机和车辆已经配对,则手机中具有车辆的公钥和车辆的BLE MAC地址,车辆中也具有手机的公钥。

2)车辆会不断广播自己的设备名称和BLE MAC地址。

3)当手机接近车辆时,它会接收车辆的广播。手机根据自己保存的车辆MAC地址发送连接请求给车辆。

4)建立连接后,车辆会通知手机验证身份。

5)手机此时可以选择向车辆发送请求,获取车辆的一些状态信息。

6)接着,手机会通过ECDH密钥协商算法生成一个共享密钥,我们称之为Secret。ECDH使用了车辆的公钥和手机的私钥。

7)接下来,手机需要发送一段使用AES-GCM加密的数据给车辆,其中共享密钥作为AES的Key,计数器count作为AES的IV。加密后将数据和count发送给车辆。

8)车辆此时具有手机的公钥,它同样使用ECDH算法生成共享密钥Secret,该密钥与手机所生成的一样,这也是ECDH密钥协商算法所保证的。接下来,使用共享密钥和手机发来的count解密数据。

9)如果解密成功,车端会生成一个token(G),返回给手机。

10)手机接下来会继续发送一段由AES-GCM加密的消息,并将token作为AES-GCM的附加身份验证数据一并参与运算。

11)车辆在收到第二段由手机加密的数据并验证通过后,则认为手机身份没有问题,返回确认身份无误。

手机蓝牙解锁汽车的过程图如图11-54所示。

(3)发现协议中存在的缺陷

当分析清楚手机和车辆之间的通信协议后,我们就要扮演攻击者的角色,尝试通过伪造的手机来控制车辆。为了实现这个目标,我们需要思考伪造的手机与车辆通信会经过哪些步骤。

1)与车辆建立连接。由于特斯拉汽车并没有使用蓝牙的任何配对机制(即Just Works模式),所以建立连接这一步是没有障碍的,只需依赖上层的算法来保证安全。

2)需要发送一个由共享密钥加密的数据。而伪造手机无法获取共享密钥,所以需要伪装成车辆与车主手机通信,以获取加密后的数据。

3)获取第一段加密数据。伪造车辆,广播BLE MAC地址,让车主手机主动连接伪造的车辆,以获取加密数据。

4)如果上一步成功,接下来需要获取车辆返回的token,然后再次使用手机利用共享密钥发送加密数据。此时,参考第二步,伪造车辆与手机通信以获取该加密数据。

5)获取第二段加密数据,此时参考获取第一段加密数据的伪造车辆操作。

6)如果第二段加密数据也可以成功获取,则此时伪造手机所需的所有信息都已经齐备了,可以尝试进行最终的控车攻击。

通过手机蓝牙进行中间人攻击的过程图如图11-55所示。

图11-54 手机蓝牙解锁汽车过程

(4)伪造蓝牙设备之车端

通过上面的分析,我们知道攻击者需要伪造车辆来获取手机的加密数据。在这里,我们以Android为例,简要介绍如何编写伪造车辆的代码。具体步骤如下。

❑启动BLE,并模拟车辆启动蓝牙广播,让手机能够发现伪造的车辆。

❑模拟车辆添加BLE Service,等待手机连接并访问该Service。

❑根据具体的车辆协议,回复手机请求,以获取加密数据。

需要注意的是,具体实现的细节会根据不同的车辆厂商和车型而有所不同。因此,在编写伪造车辆代码之前,需要仔细研究目标车辆的通信协议,并且对Android开发有一定的了解,代码示例如下。

图11-55 手机蓝牙中间人攻击过程

(5)伪造中心设备之手机端

最终攻击者的场景是实现一个伪造的车主手机,直接可以解锁车辆,本节以Android为例讲解如何编写伪造手机端的代码,主要包括模拟手机扫描车辆蓝牙,与车辆蓝牙建立连接,连接后发送确认数据,进行蓝牙钥匙协议的通信。

11.4.5 中程之Wi-Fi攻击

Wi-Fi攻击是一个经久不衰的话题。路由器、手机、智能电视和智能音箱等各种物联网设备都离不开Wi-Fi。因此,Wi-Fi也是攻击者长期关注的目标之一。本节内容不涉及Wi-Fi协议本身,因为围绕它的话题属于通用领域,有许多公开资料,比如如何绕过无线Wi-Fi认证、破解Wi-Fi加密、蜜罐攻击和热点攻击等。这些攻击大多与Wi-Fi配置相关,因为Wi-Fi有许多版本,一些历史版本可能存在缺陷。

本节的主要探讨是通过Wi-Fi这个通信渠道,车辆可能面临哪些风险以及攻击者如何进行攻击。车辆上的Wi-Fi攻击方式有两种:一种是连接车辆的热点(AP模式)进行攻击;另一种是让车辆连接攻击者的热点(STA模式)进行攻击。本节知识点如图11-56所示。

图11-56 中程之Wi-Fi攻击知识点

(1)连接车辆热点的安全风险

连接车辆热点后,攻击者可以通过DHCP获得一个IP地址。通常,这个功能是由车内的T-BOX组件完成的。攻击者的目标是通过该IP地址寻找所有可以访问的车辆资源。

对于车辆来说,连接热点具有哪些风险呢?以下是笔者基于自己的经验列举的几项。

❑T-BOX对外部IP访问自身服务端口的隔离不足,导致攻击者可以访问T-BOX的一些网络服务端口,对T-BOX进行攻击。

❑T-BOX对外部IP的路由转发策略隔离不足,导致攻击者可以访问车辆内部其他ECU的IP地址,进而攻击车内其他ECU的网络服务。

以上两项就是通过连接车辆热点所能进行的攻击手段。往往,攻击者会从端口扫描、IP扫描等方面入手。

(2)车辆连接攻击者热点的安全风险

车辆连接攻击者热点后,攻击者会通过DHCP分配一个IP给车辆。通常该功能也是由T-BOX完成的。根据笔者的经验,从这条攻击通道来看,车辆存在以下风险。

❑类似于连接车辆热点,T-BOX对外部IP访问自身服务端口的隔离不足,导致攻击者可以访问T-BOX的一些网络服务端口,对T-BOX进行攻击。

❑类似于连接车辆热点,T-BOX对外部IP的路由转发策略隔离不足,导致攻击者可以访问车辆内部其他ECU的IP地址,进而攻击车内其他ECU的网络服务。

❑由于T-BOX的IP是由攻击者的DHCP分配的,因此T-BOX的IP可以由攻击者控制。如果T-BOX在执行某些操作或者防火墙策略时以该IP为判断依据,那么攻击者可以通过修改DHCP来进行绕过。

❑当车辆连接攻击者热点后,车辆的公网访问流量会从攻击者的热点通过。此时攻击者相当于路由器。劫持、嗅探、篡改、中间人等一系列攻击手段就都可以用上了。

以上4项就是针对车辆连接攻击者热点的攻击手段。攻击者通常会打开抓包软件,从嗅探网络流量开始入手。

1.Wi-Fi内外网隔离绕过攻击

以下介绍的绕过网络隔离的攻击方法,同时适用于连接车辆热点(AP模式)和车辆连接攻击者热点(STA模式)两种场景。但是在STA模式下,攻击者需要添加强制路由,让访问车内的流量从T-BOX通过,否则默认是转发到外网的。添加路由命令如下。

网络隔离是很重要的减小攻击面的手段,它能够保护车辆内部ECU不受外部攻击者的直接攻击。车内被保护的ECU开发者自认为不会受到外部的攻击,所以保护机制会相对薄弱一些,如果攻击者能够绕过网络隔离的限制,直接访问车辆内网,那么就等于打开了新世界的大门。接下来笔者介绍一些通过Wi-Fi绕过网络隔离的方法。

(1)内网探秘之抓包分析

网络隔离意味着内部和外部网络是分离的。如果想要绕过它,首先需要了解当前车辆的内部和外部网络是什么样子,网络结构是怎样的,有多少个网段和网络节点,内部IP地址是多少,外部IP地址是多少,路由设置如何,以及防火墙如何设置。了解得越多,就越有助于绕过它。

攻击者有许多方法可以获得这些信息,例如固件逆向工程、抓包分析、进入ECU系统进行查看、查找设计资料等。本文将介绍一种通用、并不太困难及耗时的方法——抓包分析。在真实的攻击场景中,攻击者会结合各种方法,不限于某一种方式,尽可能多地获取信息。

本文介绍的抓包分析不需要进行ECU固件逆向工程,具有较好的通用性,不会受到ECU固件逆向工程难度的影响。在本节,我们将涉及车载以太网的知识,并将在第11.4.11节中进行详细介绍。我们假设读者已经了解车载以太网的基本知识。

首先,我们需要找到T-BOX和网关设备。T-BOX是我们直接连接Wi-Fi的设备,如果想要访问内部网络,所有流量都需要通过它。而网关是车内流量的中转站,所有流量都需要通过它,包括T-BOX到车内其他ECU的流量。如果不清楚这些设备的位置,可以咨询车辆维修员,他们通常会非常清楚。

然后,将我们的以太网嗅探设备接入T-BOX或VGM的车载以太网接口上。该嗅探设备没有现成的,需要自己制作。具体的制作方式将在关于车载以太网的内容中介绍。连接好设备后,让车辆正常运行,即可开始抓取车内的以太网流量。

1)在收集到足够的车内以太网流量后,我们将其扔到Wireshark中或tshark做进一步分析。

2)获取所有流量的MAC信息。

3)获取所有流量的VLAN信息。

4)获取所有流量的IP信息。

5)获取所有流量的端口信息。

如图11-57所示,我们获取了车内以太网流量的基本信息。

图11-57 车内以太网流量的基本信息

以上是我们需要收集的信息,除非车内设置了链路层或网络层的安全传输机制,否则这些信息都是明文的。有了这些信息,我们就可以进行一些绕过网络隔离的尝试了。

(2)TCP/UDP层连接尝试

有了上述信息收集,我们可以逐层实验,尝试访问目标。首先是TCP/UDP层,这一层的重点是端口访问。保护策略通常是对端口设置白名单或黑名单。对于这一层的尝试动作比较简单,只需对目标进行端口扫描。

我们可以从以太网上层协议到底层协议,一步一步地实验。首先,对Wi-Fi网关(即T-BOX)进行端口扫描。如果PC获取的Wi-Fi的IP地址为192.168.123.123,那么T-BOX的IP地址通常为192.168.123.1。可以使用nmap对其进行端口扫描,命令如下。

接下来是车内网络的端口扫描。如果我们之前获取的内网IP地址为195.35.38.22,那么可以使用nmap扫描端口,命令如下。

需要注意的是,以上nmap命令所扫描的都是TCP端口。如果是UDP端口,通过nmap扫描是不准确的。因为UDP是不建立连接的,如果发送的数据没有得到返回结果,就无法知道目标是否接收到了数据包。因此,对于UDP,需要尽可能发送一些有针对性的数据包,让目标有所响应,才能判断是否可以访问。

(3)IP层隔离绕过

如果在TCP/UDP层的尝试失败了,说明车辆已经实施了隔离措施。首先,我们假设它在IP层面实现了某些隔离措施。既然是IP层面的隔离,那么该隔离策略必然与IP地址相关,例如限制源地址或目标地址的范围。因此,对于攻击者来说,只能修改自身的IP地址。需要注意的是,修改IP地址只能在车辆连接攻击者热点的情况下进行;如果是连接车辆热点,则无法随意修改IP地址。以Ubuntu 20为例,可以使用nm-connection-editor的方法开启热点,这是一个用户界面程序,非常方便。

通常,我们会尝试将自己的IP地址修改为内网网段的地址。可以通过修改热点DHCP server的配置,将热点的地址配置为内网网段。以Ubuntu 20为例,操作过程如下。

修改文件“/etc/NetworkManager/system-connections/你的热点”,内容如下。

通过上述修改,我们热点的IP地址就和车内网络IP地址在同一个网段了。接着,可以再次使用前面提到的TCP/UDP的方式,尝试访问车辆内部网络,从而绕过隔离策略。

(4)利用IPv6绕过IP层策略

有些车辆支持IPv6,尤其是T-BOX。车辆在连接热点后,会自动分配IPv6地址。然而,很多T-BOX的开发者在设置防火墙或路由策略时会遗忘IPv6,这就导致攻击者在IPv4无法成功访问时,可以利用IPv6来解决问题。下面介绍一些IPv6攻击的步骤。

首先检查自己的IPv6地址。

然后检查目标的IPv6地址。由于IPv6没有ARP,我们采用广播Ping包的方式获取该地址。

再以IPv6为访问目标。

(5)VLAN层隔离绕过

如果经过了上述几种尝试都无济于事,那么就需要考虑车辆是否在更底层做了某些防护措施。对于车内网络而言,设计者通常会考虑使用VLAN将不同功能的网络进行隔离,因此极有可能是VLAN的限制导致我们无法访问。

假设VLAN阻碍了我们的通信,那么我们就需要给数据包加上VLAN标签。VLAN是通过在MAC层中加入一个VLAN Tag字段来实现的,该字段中包含VLAN ID,具有相同ID的流量则属于同一个VLAN,从而对同一个局域网内的流量进行划分。VLAN数据包如图11-58所示。

图11-58 VLAN数据包

接下来,我们将介绍如何给自己的数据包加上VLAN标签。首先,我们需要知道车辆内网的VLAN ID是如何划分的,可以通过车内抓包分析的结果来查看。例如,内网的VLAN ID有1/2/3/4/5。然后,我们为电脑网卡添加VLAN。这里以Ubuntu 20为例,操作如下。

在eth1网卡上添加一个虚拟网卡eth1.10,并且VLAN ID是10,这样通过eth1.10的流量都会携带VLAN ID 10的标签。

配置完成后,我们需要配置路由,使流量通过VLAN的网卡出去,具体操作如下。

然后,我们可以依照上述TCP/UDP和IP的方式尝试发包,看能否绕过网络隔离的限制。

(6)MAC层隔离绕过

如果TCP/UDP、IP、VLAN的方式都失败了,那么就只剩下最后一种方式了,即通过MAC层绕过隔离策略。隔离策略可能限制了MAC地址的取值,因此我们需要修改自己电脑网卡的MAC地址。

首先,通过车内抓包分析的结果来查看车内网络MAC地址。然后,尝试将自己的MAC地址修改为车内已存在的MAC地址。例如,车内某个MAC地址是02:42:80:63:2e:54,这里以Ubuntu 20为例,进行如下操作。

配置完成后,再依照前面提到的几种方法(TCP/UDP、IP、VLAN)进行发包尝试,看能否绕过网络隔离。如果到这一步仍然无法访问车内网络,说明车辆设置了非常好的隔离措施,仅仅通过外围的尝试是很难突破隔离措施的,需要进一步研究其具体的隔离方案。例如,可以采用车内系统分析或逆向固件分析等方法。

2.Wi-Fi暴露端口攻击

经过上述端口扫描的尝试,我们应该已经能访问车辆的一些端口了,接下来看如何通过这些端口拿到目标的权限。

(1)通用端口

通用端口指的是一些众所周知的端口,例如SSH的22端口、Telnet的23端口等。通常情况下,只要不是特意修改,这些通用端口所代表的功能是确定的,我们不需要进行固件逆向分析就能了解它们的功能。然而,这些通用端口常常被攻击者用来发起攻击。以下是一些常见的通用端口,它们可能会被攻击者用来发起攻击,如表11-1所示。

表11-1 常见的通用端口

对于以上这些端口常用来调试、测试的端口,我们可以在网上搜到如何使用,笔者在这里不再介绍。

(2)私有端口

私有端口是指开发者自行监听的网络端口,通常用于实现业务需求。在渗透测试中,这类端口是需要重点研究的,因为它们涉及业务上的自主开发,往往比通用端口更容易存在漏洞。

攻击这类端口需要结合逆向、调试、抓包分析等手段,研究清楚此端口的通信协议和所具备的功能。在此基础上,可以利用常见的漏洞挖掘手段,如逆向审计、Fuzz等方式,检查目标是否存在漏洞。根据笔者的经验,这类私有端口通常都存在问题。保护措施弱一些的端口可能会存在命令注入漏洞,而保护措施强一些的端口可能会存在栈溢出或堆溢出的内存问题。此外,根据业务不同,私有端口还可能存在一些业务逻辑的问题,如鉴权绕过、文件目录穿越、任意文件读写、环境变量注入、SQL注入等。因此,攻击者需要具有耐心地慢慢探索,以便发现潜在的漏洞。

3.Wi-Fi中间人攻击

中间人攻击是网络通信中常见的攻击手段。在车辆Wi-Fi场景下,主要是指当车辆连接攻击者热点时,攻击者可以伪装路由器,并拦截车辆所有对外访问的流量。因此,该场景存在着中间人攻击的风险。

(1)开发中间人攻击探测工具

关于中间人攻击的工具,网上有很多开源产品,例如mitmproxy,但这类工具的目的是防御中间人攻击,而非探测漏洞。通常情况下,这些工具只能支持HTTPS这类协议,无法通用于所有TLS协议。实际上,仅仅探测哪些流量可以进行中间人攻击,是很容易实现的。在这里,笔者将以Ubuntu 20为例,向大家介绍如何自己实现一个中间人攻击探测工具。

首先,让车辆连接到攻击者电脑上的热点。然后我们需要配置一条iptables规则,将所有的TCP流量都重定向到我们自定义的一个端口上。具体实现步骤如下。

1)执行命令sysctl-w net.ipv4.ip_forward=1,开启IP转发功能。

2)执行命令iptables -A PREROUTING -s 10.42.0.94/32 -i wlp0s20f3 -p tcp -j REDIRECT--to-ports 8888,将所有TCP流量引导到端口8888上。其中,10.42.0.94/32是指车辆的IP地址,wlp0s20f3是指网卡接口名称。

接下来,我们需要编写自己的端口代理程序。笔者采用Python编写,代码如下。

接下来,所有向外流出的车辆流量都会被转发到我们的代理程序上。如果有某些连接请求能够与车辆建立正常的连接,那么就表明该流量可以被中间人攻击。根据协议类型的不同,我们可以将可被中间人攻击的流量分为3种类型。

❑未进行服务端证书校验的TLS流量:车辆虽然使用了TLS协议,但未进行服务端证书校验,因此攻击者可以伪造服务端对车端进行攻击。

❑HTTP协议流量:车辆采用明文协议,没有任何保护。

❑未使用TLS保护的私有协议流量:车辆使用了自己实现的TCP协议,由于没有使用TLS进行保护,因此存在被中间人攻击的风险。

对于以上3种类型的流量,用我们的工具进行测试,运行结果可能会有以下几种。

1)无法进行中间人攻击:车辆对服务端证书做了校验,代理与车辆连接失败。

2)可以进行中间人攻击:车辆使用了TLS协议,但是未对服务端证书做校验。

3)可以进行中间人攻击:车辆使用了HTTP,未使用HTTPS。

4)可以进行中间人攻击:车辆使用了私有的TCP协议,未使用TLS。

(2)中间人攻击手法

通过上述的探测方法,我们可以发现车上存在可以被中间人攻击的流量,接下来需要考虑的就是如何利用了。开发者可能并不会关注此类问题,会认为服务端是可信的,因此往往并不考虑安全性的问题,从而导致对这一攻击面的保护是比较脆弱的。利用这类漏洞的方法就是伪造服务端,针对车端的请求返回伪造的恶意数据。对于这类场景,笔者无法阐述一个通用、标准化的方法,读者需要根据目标协议,自己构造恶意的服务端返回数据。例如,2022 Pwn2Own上通过Wi-Fi破解特斯拉汽车的案例,就是利用了特斯拉汽车上ConnMan程序的可被中间人攻击的漏洞(CVE-2022-32293),成功获取了车机权限。关于此案例的更多细节,可以参考https://www.synacktiv.com/sites/default/files/2022-10/tesla_hexacon.pdf。

如何实现一个中间人攻击工具,可以参考以下代码。

11.4.6 中程之NFC钥匙攻击

现在许多汽车使用NFC钥匙进行车门解锁。然而,NFC M1卡已经被公认为不安全。在上册中,我们已经介绍了针对M1卡的攻击方式,所以本节将重点介绍CPU卡的一些攻击方法,不涉及M1卡。本节知识点如图11-59所示。

图11-59 中程之NFC钥匙攻击知识点

现在汽车所使用的NFC钥匙基本都是CPU卡。与M1卡相比,CPU卡在卡内安装了一个芯片,开发者可以为卡片编写代码来确保卡的安全性。由于每种卡片的协议都可能不同,因此本节将重点介绍如何嗅探它们的通信数据,以便进行自定义的数据篡改和收发。

1.NFC钥匙嗅探分析

NFC是一种无线通信技术,虽然通信距离比较短,但仍然需要掌握抓包的能力。在本节中,我们将使用非常著名的开源NFC嗅探和模拟工具Proxmark 3来抓包。使用Proxmark 3抓包非常方便,几乎只需一键操作。

首先,我们将Proxmark 3放在车辆和卡片钥匙之间,如图11-60所示。接着,输入hf 14a sniff命令开始嗅探工作。完成后,可以使用hf 14a list命令列出刚才嗅探到的数据,如图11-61所示。

图11-60 使用Proxmark 3嗅探NFC通信数据

2.NFC自定义数据包收发

由于CPU卡公开的漏洞很少,本节主要介绍攻击CPU NFC卡必备的技巧。在进行任何通信攻击之前,都需要与目标进行收发包的交互,这样才能尝试发送一些畸形的数据,从而查看是否能够使目标出现问题。

NFC与蓝牙、Wi-Fi不同,缺乏方便的库可以使用。因此,我们仍然需要使用Proxmark 3,但是Proxmark 3没有编程接口,需要直接修改其固件。本节将主要参考Proxmark 3源码中的Standalone这一例子的实现,该实现的地址为https://github.com/RfidResearchGroup/proxmark3/blob/master/armsrc/Standalone/hf_reblay.c。

首先初始化一张14443卡。

图11-61 NFC数据包嗅探

然后,读取车发来的数据,receivedCmd中存放着接收的数据。

接着处理数据,根据不同的命令来处理。

最后返回数据给汽车,记得通过AddCrc14A函数添加CRC字节。

11.4.7 近程之UDS/OBD攻击

UDS(Unified Diagnostic Services)是车辆中一个重要的协议,该协议的标准为ISO 14229。UDS服务在车辆售后、维修以及与控制器软件相关的操作中扮演着关键的角色,是工程师与车辆控制器软件之间最重要的沟通渠道。由于UDS服务有一个重要的外部通信入口(OBD),因此攻击者对其很感兴趣。此外,UDS服务并非只针对某个控制器,而适用于车辆中大多数控制器,这使得攻击者可以通过它与任意控制器进行通信。这是在蓝牙、Wi-Fi等攻击场景下无法实现的。UDS是一种上层应用协议,可以置于各种网络传输层之上,如CAN总线、FlexRay总线和以太网。接下来笔者将带读者进入UDS攻击的奇妙之旅。本节知识点如图11-62所示。

图11-62 近程之UDS/OBD攻击知识点

首先我们需要将电脑连接到OBD的接口上,这在上一章中已经讲解过。接下来我们进行各种UDS攻击。

1.UDS拒绝服务攻击

在针对车辆这种特殊目标的情况下,DoS攻击的危害显著增加。UDS具有许多DoS攻击点,例如没有对EcuReset(0x11)服务进行限制,该服务用于重启ECU,如果没有任何条件限制,就会导致目标ECU的DoS攻击。例如,当车辆正在行驶时,如果有人恶意地重启了动力ECU或制动ECU,就会导致车辆发生严重故障。我们使用基于以太网的UDS通信协议来执行此次攻击,并使用以下代码对0x2B01号ECU不断进行重启攻击。

2.UDS未鉴权服务攻击

UDS提供了许多读、写和控制服务,其中大多数服务需要通过安全访问(0x27)服务才能使用。但是,具体某个DID或服务是否需要通过安全访问,则是由ECU设计和编码所定义的。如果由于设计不周或编码不严谨,某些敏感操作不需要通过安全访问就可以执行,那么攻击者就会有可乘之机。我们使用基于以太网的UDS通信协议来完成此次攻击。由于0x2B01号ECU的0x1234号DID可以读取私钥,但该DID被设计为不需要通过0x27安全校验,攻击者可以直接获取该密钥。下面是攻击代码。

3.UDS安全访问攻击

最后谈到的是安全访问(0x27)服务的缺陷。在安全访问的过程中,我们已经介绍了如何通过seed和Secret计算Key。然而,这个过程中的每个环节都可能存在风险。

(1)seed

seed必须是一个不可预测的随机数,但实际上许多车辆没有实现这一点。最严重的缺陷是seed被设置为一个固定的数,其次是seed生成算法存在缺陷,导致它很容易被预测。例如,基于时间的伪随机数,控制ECU重启(0x11)服务,使seed在特定时间发送,这样每次返回的seed都是相同的。如果seed可以被控制为相同的值,则意味着最终的Key也将是相同的,这样攻击者就可以直接破解Key,而无须关心密钥。

(2)Secret

Secret是一种密钥,只有厂商知道,用于售后诊断。然而,在现实中,许多车辆的密钥已经被破解了,主要原因如下。

❑密钥存储在ECU的非安全存储器中,攻击者可以通过逆向的方式读取Flash或MCU内存来获取该密钥。

❑厂商的诊断设备或软件泄露,导致攻击者可以通过逆向分析该软件来获取密钥。

❑密钥长度不足。通常,密钥长度应大于4个字节,但一些车辆只有3个字节的密钥长度。因此,攻击者可以通过穷举的方式来暴力破解该密钥。

❑密钥没有实现一机一码。一机一码意味着每辆车的每个ECU都应该有一个唯一的密钥。如果没有实现这一点,攻击者在破解了某一辆车的某个ECU后,就可以将攻击范围扩大到其他车辆或其他ECU上。

(3)算法

防御这类攻击的最佳的方式是采用公认安全的非对称加密算法,这样即使ECU中的公钥被提取,攻击者也无法对其进行破解。然而,现实中很多厂商的UDS安全访问算法是自定义的,并没有经过大规模测试和认证,所以这类算法很容易出现问题。以下是常见的算法问题。

❑密钥可逆:算法存在被逆向算出密钥的缺陷,当攻击者获取到seed和Key时,可以通过逆算法来得到密钥。

❑降低爆破复杂度:由于算法的缺陷,密钥中的一些位没有参与到Key的运算中,或者参与了但没有给Key增加熵值。这样即使密钥长度满足要求,攻击者只要爆破其中一部分位就足以计算出Key。

❑碰撞攻击:算法存在被碰撞的风险,即seed相同,不同的密钥可以产生相同的Key。攻击者可以通过碰撞来产生Key。

❑后门攻击:某些算法中存在后门,即存在不公开的简便方法来通过安全访问。攻击者可以通过逆向ECU固件来发现后门,从而不需要对抗算法本身。

(4)Key

如果Key的长度不足,那么攻击者可以通过固定seed来穷举暴力破解Key,我们用伪代码来解释一下攻击过程,如下所示。

11.4.8 近程之USB攻击

USB是车机上很常见的接口之一,通常用于插入U盘,可以播放U盘上的媒体文件。此外,它还有像carplay、车机升级等其他的功能。本节知识点如图11-63所示。

图11-63 近程之USB攻击知识点

USB协议将连接的两个设备分为Host端和Peripheral端。以U盘为例,Host端指的是电脑端,Peripheral指的是U盘端。而在汽车中,不同的场景下可以转换这两种身份。例如插上U盘,车就变成了Host端;插上电脑,车就变成了Peripheral端。下面我们将分别讲解在这两个不同的角度下,如何攻击汽车USB接口。

1.车为主机端(Host)攻击

所谓的Host攻击是指将车辆视为Host端,攻击者则是外设。首先,我们需要知道当前车辆支持哪种USB设备。通常,Host端是通过外设的VendorID、ProductID、Class、SubClass和Protocol来识别该外设是不是自己需要的设备。对于常见的通用外设来说,上述参数通常是固定的,因此我们可以遍历这些通用的常量来检查车辆是否支持它们。

首先,我们需要一个连接到车辆的USB设备,例如上册中提到的FaceDancer或Beaglebone Black。然后,我们可以使用上册提到的umap 2工具来检查车辆支持哪些类型的设备。该工具支持以下设备。

上述是针对通用设备的扫描方法。然而,车辆也可能使用自己实现的USB外设,这时我们就需要进行固件逆向分析。下面是一个在Android中自定义USB外设的代码示例。这段代码是一个Android应用程序的Manifest文件中的部分内容,用于声明该应用程序需要使用USB Host功能,并处理USB设备的连接和断开事件。

首先,在Manifest文件中使用<uses-feature>元素声明了应用程序需要使用android.hardware.usb.host功能。这意味着该应用程序作为USB Host设备,能够连接和管理其他USB设备。

然后,在<application>元素内部定义了一个<activity>元素,并在其中添加了一个<intent-filter>元素。这个<intent-filter>元素用于捕获当一个USB设备连接到Android设备上时发出的android.hardware.usb.action.USB_DEVICE_ATTACHED广播事件。

接下来,使用<meta-data>元素声明了当上述广播事件发生时需要使用一个XML文件来筛选和识别连接的USB设备。在本例中,该XML文件的资源ID是@xml/device_filter。

在资源文件里定义要过滤的USB设备。

然后与USB外设通信。

针对这种自定义的USB设备,我们可以使用umap 2工具进行模拟。umap 2官方并没有提供关于如何编写自定义设备的文档,因此我们可以通过阅读源代码来自己编写,可以参考https://github.com/nccgroup/umap2/blob/master/umap2/dev/vendor_specific.py中的vendor_specific.py文件。在该文件中,我们可以看到编写自定义设备的示例代码。通过参考这些示例代码,我们可以编写自定义设备代码,并使用umap 2工具进行模拟测试。

2.U盘业务层攻击

业务层攻击是一种将车辆视为Host、攻击者视为USB设备的攻击方式。但在这种攻击中,我们并不直接攻击USB协议栈本身,而是查看车辆在上层应用中如何使用该USB设备,其中是否存在漏洞。其中,最常见的攻击方式是USB升级攻击。有些车辆为了方便支持通过U盘来升级系统。攻击者可以利用这一点,研究升级过程中是否存在签名校验问题或内存漏洞等。此外,攻击者还可以利用U盘中的特殊文件来启用某些特殊功能。例如,将特定目录文件存放在U盘中,该文件包含密钥。当检测到该文件时,车机会验证密钥是否正确,从而开启相关特殊功能。攻击者可以探查在这个过程中是否存在获取该密钥或绕过检查的可能性。

以下是一个公开案例。当USB设备插入车机后,车机的Linux系统会使用udev脚本进行检查。此脚本通常存放在/etc/udev/scripts目录中。

这里面的shell文件都是可以研究的,其中mount.sh有以下代码。

虽然该代码似乎已经实现了比较严格的命令注入检查,但它却没有防止目录穿越的机制。攻击者可以控制mountdir参数为../../some,然后将U盘挂载到任意位置。接下来,mount.sh将调用logger,这是一个位于/usr/bin/logger的可执行文件。攻击者可以将U盘的文件系统标签改为../../usr/bin/,这样U盘就会挂载到/usr/bin目录下。攻击者随后可以创建一个名为logger的文件,此时mount.sh将调用攻击者自己创建的logger文件,从而实现命令执行的目的。

另一个例子是利用在Black Hat上公开的一个USB漏洞。在USB升级车机系统的过程中,它执行了USB中的sh文件,但没有检查该文件的合法性。如图11-64所示,它执行了U盘中的swdl-pre-extra-exec.sh文件。

图11-64 执行U盘中的.sh文件

3.车为设备端(Peripheral)攻击

Peripheral攻击是一种将车辆视为外设、攻击者视为Host端的攻击方式。在这种情况下,车辆通常会提供调试的接口给Host端。下面,笔者将介绍如何识别这种情况。

首先,需要判断USB外设的地址。

用Wireshark抓取该外设的所有流量。

如图11-65所示,分析流量,查看USB设备的description,找到设备类型,可以看出是ADB设备。

图11-65 USB流量分析

通过分析出的设备类型,找到相对应客户端程序ADB,并进行访问。

11.4.9 近程之CAN总线攻击

谈到汽车攻击,不得不提CAN网络。CAN是汽车内部网络中广泛使用的通信总线,为各个ECU之间提供了可靠的传输通道。本节将介绍如何研究CAN网络,从原理到实践,带领读者进入CAN世界。需要注意的是,本节不涵盖CAN总线工具的基本使用方法,如需了解请参考上册中的详细介绍。本节知识点如图11-66所示。

图11-66 近程之CAN总线攻击知识点

1.CAN总线数据包嗅探

CAN数据包通常是未加密的,因此攻击者可以通过抓取数据包来获取明文数据。如果CAN报文中包含敏感信息,就可能造成信息泄露。

CAN的嗅探相对容易,常用的工具包括CANoe、Komodo CAN Duo Interface、周立功CAN收发器和带CAN收发器的单片机等。在本例中,我们将使用周立功设备进行抓包。首先安装CANTest软件,然后将CANTest对应的通道与待研究设备的CANH和CANL正确连接。运行软件并点击“启动”,即可开始抓取CAN报文,如图11-67所示。

图11-67 嗅探CAN流量

以下代码使用了CANoe编程实现嗅探。

2.CAN总线假冒节点攻击

CAN通信采用广播方式发送,即网络中的所有CAN节点都可以接收所有的CAN报文。每个节点控制器中都有过滤器,通过CAN ID来筛选实际所需的报文。但是,由于CAN节点无法判断是谁发送了消息,攻击者可以冒充节点并向总线上的任意ECU发送CAN报文,从而使目标ECU出现不符合预期的行为。

例如,在车辆夜间行驶时,攻击者可以冒充车身控制模块的ECU向车灯控制器发送关闭车灯的CAN报文。这将导致车灯关闭,给驾驶者带来危险。我们可以在CANTest中输入要冒充的报文并发送,如图11-68所示。

图11-68 CAN假冒节点攻击

以下是通过CANoe实现的假冒节点攻击的代码。

3.CAN总线DoS攻击

CAN总线的DoS攻击方式有许多种,下面逐一讲解。

(1)过载DoS攻击

在总线上发送大量随机数据包造成总线过载,以进行过载DoS攻击。这种攻击方式可以采用CANTest进行测试,如图11-69所示。

图11-69 通过CAN数据过载进行DoS攻击

以下是通过CANoe实现过载DoS攻击的代码。

(2)优先级抢占DoS攻击

根据CAN总线仲裁机制,消息ID越小的消息优先级越高,越被优先处理。攻击者可以利用这一特性,构造并发送大量高优先级ID的消息到总线上,导致总线阻塞,从而实现DoS攻击,如图11-70所示。为了测试CAN总线系统的安全性,可以使用CANTest工具。

图11-70 CAN高优先级消息阻塞

以下是通过CANoe实现优先级抢占DoS攻击的代码。

(3)远程帧DoS攻击

对单个目标ECU发送大量远程请求帧,使得目标ECU无法处理正常消息,从而实施DoS攻击。对此,同样采用CANTest进行测试,如图11-71所示。

图11-71 CAN远程帧泛洪测试

(4)错误帧DoS攻击

攻击者可以通过利用CAN总线错误帧机制,精心构造一些可以导致总线错误的报文,如位错误、格式错误、ACK错误、CRC错误等,并发送出去。当错误报文帧达到一定次数后,总线将进入busoff状态,关闭并拒绝服务。攻击者可以持续发送错误报文,使节点一直处于busoff状态。

下面是一个具体的例子。攻击者使用CANoe VH6501干扰仪,干扰目标ID为0x100,干扰对象是报文中的ACK界定符位,将ACK界定符位从默认的隐性1(Recessive)干扰成显性0(Dominant),从而监测到Form Error格式错误,并发送错误帧。这样可以引发总线的错误状态,造成DoS攻击,如图11-72所示。

图11-72 CAN错误帧DoS攻击

4.CAN总线恶意消息注入攻击

CAN总线通信缺乏认证及消息校验机制,因此不能对攻击者伪造、篡改的异常消息进行识别和预警。攻击者可以发送一些精心构造的恶意消息到总线上进行攻击,比如修改里程、车速等报文。

举例来说,如图11-73所示,结合逆向分析和重放攻击,攻击者确定发送报文09 2F 79 55 2B 21 6A 95可以导致某品牌电动汽车在行驶途中突然断电,失去动力。这是因为这条报文中包含了能够触发断电的指令。攻击者发送这条指令后,ECU会执行该指令,使得汽车失去动力。

以下是通过CANoe实现的恶意消息注入攻击的代码。

图11-73 CAN恶意消息注入

11.4.10 近程之FlexRay总线攻击

FlexRay总线是车内的一种总线网络,其基本原理和工具使用方法在上册中已经介绍过,本节不再重复讲解FlexRay总线工具的基本使用方法。如果读者需要了解更多关于FlexRay总线工具的使用方法,可以参考上册中的详细介绍。本节知识点如图11-74所示。

图11-74 近程之FlexRay总线攻击知识点

1.FlexRay总线数据包嗅探

我们此处使用Vector的CANoe 8914的FlexRay模块创建工程。在配置完FlexRay通道正确的接线后,可以抓取如图11-75所示报文。

图11-75 FlexRay总线嗅探

2.FlexRay总线DoS攻击

攻击者根据FlexRay静态帧传输机制,恶意占用正常时隙,使ECU无法定期发送报文,因此造成拒绝服务,如图11-76所示,用CANoe发送DoS攻击。

以下是通过CANoe编程实现FlexRay DoS攻击的代码。

图11-76 FlexRay总线恶意占用时隙攻击

3.FlexRay总线恶意消息注入攻击

FlexRay总线通信缺乏认证及消息校验机制,因此不能对攻击者伪造、篡改的异常消息进行识别和预警。攻击者可以发送一些精心构造的恶意消息到总线上进行攻击,比如修改里程、车速等报文。

举例来说,如图11-77所示,攻击者可以通过抓包重放分析确定FlexRay报文帧中的其中一字节代表某品牌电动汽车的车内香氛余量。当该数值为0时,车辆中控屏幕将持续发出警告提示:香氛耗尽。

图11-77 FlexRay总线恶意消息注入

11.4.11 近程之车载以太网攻击

以太网在互联网产业的应用非常广泛,它有着众多的优势,如速度快、成本低、全双工、协议成熟。而汽车领域随着电子电气架构的不断发展,也逐渐引入了以太网,主要用于需要联网的数据、大数据的传输。本节知识点如图11-78所示。

图11-78 近程之车载以太网攻击知识点

车载以太网和传统PC以太网的主要区别在于物理层。如图11-79所示,车载以太网协议栈中上层的链路层、网络层、传输层大多使用我们熟悉的MAC、IP、TCP/UDP等协议。此外,还有一组AVB(Audio Video Bridging)协议簇,现在更名为TSN(Time-Sensitive Networking)协议簇。这些传输协议代表了对实时性的高要求,主要用于实时音视频、实时控制流等通信场景。

由于TSN目前还在发展阶段,使用并不广泛,本节主要介绍传统TCP/IP协议簇在车载环境下的使用方法和安全风险。在IP协议簇下,车载以太网主要在应用层的协议使用上与传统PC以太网稍有不同。为了方便车内多个控制器之间的沟通协作,车载以太网采用了诸如SOME/IP、DDS的一系列中间件协议。本节主要从以太网的链路层和应用层两个方面介绍车载以太网所面临的安全风险。

图11-79 车载以太网协议栈

车载以太网作为一种车内通信方式,同样面临着CAN、Flexray等车内总线的安全风险,包括重放攻击、信息泄露、假冒节点攻击、DoS攻击、恶意消息注入等。

幸运的是,以太网对防范这些攻击都有成熟的解决方案。从MAC层到IP层,再到TCP/UDP层,每一层都有可用的安全协议,例如MAC层的MACSec、IP层的IPSec、TCP层的TLS和UDP层的DTLS等。

使用这些安全协议后,之前提到的安全风险问题可以得到解决。即使如此,攻击者仍可能在获得一个合法节点的权限后,利用车内网络进行横向渗透。因此,对于业务层应用,尤其是一些敏感业务,需要严格校验数据来源的身份,将一切来源视为不可信的,判断数据的合法性,避免出现本地执行恶意代码或敏感操作等漏洞。

1.车载以太网嗅探

车载以太网抓包可以分为两种方式:在系统上抓包和在链路上抓包。其中,在系统上抓包是最方便的方法,但需要攻击者具有车载系统的权限,并在系统上执行抓包命令。具体命令如下。

如果攻击者没有车载系统权限,或目标系统没有抓包的命令(如实时操作系统),则可以通过在链路上加装硬件设备来抓包。以下是自制该工具的过程。

1)准备一个镜像交换机,用于流量嗅探。如图11-80、图11-81所示,1号端口可抓取其他端口的流量。将电脑连接到1号端口,并使用Wireshark抓取该接口的流量。

图11-80 镜像交换机

图11-81 1号口嗅探流量

2)准备两个车载网口转PC网口的转换器,由于车载以太网用的是T1接口(如图11-82所示),与PC使用的RJ45接口不一样(如图11-83所示),需要做接口转换。

图11-82 车载以太网100BASE-T1接口

图11-83 PC以太网RJ45接口

3)将以上设备连接到车内需要嗅探的控制器上。先将控制器的以太网线拔掉,通过接口转换器将该线接到交换机上,然后将交换机另一头通过转换器再接到控制器上,相当于在中间加了一个交换机设备。如图11-84所示,这样即可抓取该控制器的所有以太网流量了。

图11-84 车载以太网流量

最终车载以太网嗅探设备全貌如图11-85所示。

2.车载以太网链路层攻击

车载以太网是一个局域网,因此适合于链路层的攻击,即MAC层攻击。这和传统PC局域网是相同的。以下是一些常见的攻击方法。

(1)ARP欺骗攻击

ARP欺骗可以实现流量的劫持。攻击者发送恶意的ARP包给目标,污染目标的ARP缓存表,让它将流量发送到攻击者的地址。例如,如果我们想要劫持自动驾驶模块的流量,攻击者的IP和MAC地址应为192.168.6.88(50:e5:49:eb:46:8d),网关的IP和MAC地址应为192.168.6.1(14:e6:e4:ac:fb:20),自动驾驶系统的IP和MAC地址应为192.168.6.101(0:19:21:3f:c3:e5)。

图11-85 车载以太网嗅探设备全貌

首先,我们需要欺骗自动驾驶系统,让其认为我们是网关。攻击者可以执行以下代码,向自动驾驶系统发送ARP欺骗包,告诉它网关的MAC地址是攻击者的MAC地址。

接下来,我们还需要欺骗网关,让网关认为我们是自动驾驶模块。攻击者可以执行以下代码,向网关发送ARP欺骗包,告诉它自动驾驶模块的MAC地址是攻击者的MAC地址。

经过上述操作后,自动驾驶的所有流量都发送给攻击者,网关发送给自动驾驶的流量也会发送给攻击者。

(2)MAC泛洪攻击

MAC泛洪攻击是指将网关的MAC表填充满,这样网关会会进入广播模式,攻击者就可以嗅探到网络上的所有流量。使用如下代码进行攻击。

3.车载以太网网络层攻击

网络层即IP层,在该层有个很出名的协议ICMP,它也是被攻击的重点对象。常见的攻击方式如下。

(1)Ping of Death

Ping of Death是指攻击者向目标主机发送一个过大的ICMP Echo请求,使目标主机崩溃。可以使用如下代码进行攻击,其中$1是要攻击的IP地址。

(2)Smurf Attack

Smurf Attack是指攻击者向网络中广播一个ICMP Echo请求,并设置源IP地址为目标主机的地址,使网络中的主机都向目标主机发送ICMP回应,从而使目标主机负载过重。可以用如下代码来进行攻击。

(3)Land Attack

Land Attack是指攻击者向目标主机发送一个源IP地址和目的IP地址都为目标主机的ICMP Echo请求,从而使目标主机崩溃。可以用如下代码进行攻击。

4.车载以太网传输层攻击

以太网传输层主要是TCP/UDP协议,关于它们的常见攻击方式如下。

(1)TCP SYN泛洪攻击

该攻击方式通过发送大量的SYN数据包来占用目标资源。可以使用以下代码进行攻击。

(2)UDP泛洪攻击

该攻击方式通过发送大量的UDP数据包来占用目标资源。可以使用以下代码进行攻击。

5.车载以太网应用层攻击

接下来我们进入应用层,讨论车载应用协议的攻击原理。在上册第1篇中,我们已经介绍了SOME/IP和MQTT这两种常用的车载应用协议。因此,本节的重点是讲解如何对这些协议进行攻击。

(1)SOME/IP应用协议攻击

SOME/IP是车载以太网中常用的中间件协议。一方面,对于SOME/IP协议本身的攻击,主要是查找中间件协议栈实现中是否存在二进制漏洞,这不在本节的讲解范围内。另一方面,由于它是一种中间件协议,因此在车辆上,依赖它的服务端和客户端很多,这些是我们需要重点关注的目标。尽管目前还没有公开的SomeIP漏洞案例,但本节将重点介绍攻击SomeIP的一些必要操作手法,攻击过程中我们将使用scapy库。

首先,我们发送SOME/IP数据包。下面的代码功能是调用服务地址为192.168.0.10的0x1234服务的0x421方法。

然后,发送SomeIP-SD包,下面代码用于广播自己发布了服务0x1234。

有了收发包的技能后,可以开始尝试进行攻击了,比如中间人攻击。如图11-86所示,攻击者劫持了ECU A和ECU B之间的服务通信,强制通过ECU C进行通信。正常情况下,ECU A发送服务发现提供消息,提供S1服务。这些消息以组播方式发送,因此ECU C也会接收到它们。为了执行攻击,对于接收到的每个Offer S1消息,ECU C需要做两件事:首先通过向ECU A发送SUBSCRIBE S1消息来订阅服务,然后向ECU B发送欺骗的Offer S1消息。

ECU B同时接收原始的S1分组和欺骗分组,但它只订阅后一个分组,因为它恰好在前一个分组之后到达。通过这种方式,启动了两个连接——ECU A到ECU C,以及ECU C到ECU B。

然后,ECU C在ECU A和ECU B之间转发消息。例如,如果ECU A向其客户端ECU C发送通知,它会立即将其内容转发到ECU B。在整个攻击过程中,服务订阅和消息中继都会重复执行。

对手从执行这样的攻击中获得了两种能力。第一种是窃听ECU A和ECU B之间的通信的能力。如果没有攻击,这种通信对ECU C是不可见的,因为交换机只向每个交换机端口转发相关的数据包。第二种是控制和欺骗ECU之间的通信的能力。通过执行此攻击,对手能够向客户端发送虚假通知,调用服务器上的远程函数,更改消息数据或丢弃关键消息。所有这些操作都不会在服务器或客户端上造成任何可检测到的通信错误。

图11-86 SOME/IP中间人攻击

(2)MQTT应用协议攻击

①分析MQTT安全风险

在上册中,我们了解了MQTT的工作原理。接下来,我们将从攻击者的角度来了解MQTT可能存在的安全风险。MQTT的安全风险关键在于节点身份的验证,如果攻击者可以订阅敏感主题并接收敏感消息,或者可以发布消息到敏感主题,那么MQTT网络就会面临攻击风险。接下来描述一些常见的攻击场景。

❑利用重复的客户端ID进行DoS攻击:当新客户端连接到服务器并提供已被当前连接到服务器的另一个客户端使用的客户端ID时,服务器会断开当前连接并让新客户端连接。这种行为有时有合理的理由,因此它不被视为错误。然而,攻击者可以利用这个漏洞在MQTT网络中发起DoS攻击。

❑使用客户端ID进行身份验证/访问控制:有时客户端ID被用于验证客户端身份和访问敏感主题。在这种情况下,攻击者可以利用伪造客户端ID的技术绕过客户端身份验证,访问MQTT网络并操作敏感数据。

❑克隆客户端:根据服务器是否实施了身份验证,以及攻击者是否能够获得身份凭证,攻击者可以伪造合法客户端并操纵数据。

❑通过恶意输入攻击应用程序:应用程序开发人员通常信任来自服务器的数据。这意味着,如果攻击者可以制作恶意有效负载,则可以利用应用程序。例如,当前的路况信息通过MQTT定期发送给车辆应用程序并显示在车机上。假设攻击者可以访问MQTT网络并且可以将恶意消息发布到相同的主题上,而恶意消息没有被应用程序过滤,就可能会造成严重后果。

②进行信息收集

MQTT攻击的入手点是MQTT Broker。第一步是进行信息收集,以了解MQTT网络的详细信息。以下是信息收集的步骤。

1)确定是否可以未经授权进行连接。有些MQTT连接不需要进行身份验证,即用户名和密码为空。因此,我们可以尝试直接连接,使用MQTT客户端进行测试。例如,我们可以使用https://github.com/bapowell/python-mqtt-client-shell这个MQTT客户端。如果连接成功,则表明该MQTT Broker连接不需要身份验证。

2)当订阅了所有主题时会发生什么。当建立了连接后,我们可以尝试订阅所有的主题,比如#、$SYS/#主题。我们使用如下的一个简单脚本来实现。

订阅之后,我们可以查看订阅的所有消息都是什么,确认其中有没有敏感信息,或者我们感兴趣的内容。比如下面的结果暴露了地理位置信息。

3)有哪些很重要的MQTT主题。我们尝试订阅所有主题后,可以通过名称判断它们是不是一些重要的MQTT主题。如图11-87所示,我们订阅了#主题后,通过抓包看到了所有正在发布的主题。

图11-87 获取MQTT发布的消息

4)ClientID是如何生成的,以及ClientID是否存在规律。首先通过抓包,查看MQTT的ClientID是否有规律,然后通过逆向分析MQTT客户端,查看ClientID是如何生成的。在如下所示函数中,我们只需在代码中找调用mosquitto_new的地方,对应的id就是ClientID。

5)是否使用了TLS。MQTT是基于TCP的协议,在不使用TLS时是明文传输的。如图11-88所示,可以通过抓包获取MQTT的账号密码。

图11-88 MQTT连接请求包含明文的账号密码

6)设备发送的数据在服务端如何使用。此时需要逆向分析服务端处理MQTT数据的代码,通常逆向的代码形式如下。处理MQTT数据的代码通常都在回调函数mosquitto_message_callback_set里。

7)逆向固件或移动应用程序发现敏感信息。其中一些需要重点关注的信息如下。

❑ClientID:在连接MQTT Broken的时候,每个客户端都会有一个ClientID,该ID在代码中是在调用mosquitto_new时传入的,我们可以通过找到该函数的调用来找到ClientID是否存在规律。如下所示,ClientID取自PID。

❑凭证:在连接MQTT Broken时可以设置用户名密码,用于身份校验。使用mosquitto_username_pw_set函数,检查用户名密码是不是硬编码的。如下所示,该代码硬编码了用户名和密码。

❑证书和密钥:MQTT支持TLS传输,因此需要设置客户端的证书和私钥。在代码中使用mosquitto_tls_set函数来进行设置。因此我们可以找到该函数来检查证书和密钥的来源是否安全。如下所示,我们可以找到私钥文件。

❑使用的主题:MQTT的重点就是主题订阅和发布。在代码中mosquitto_publish和mosquitto_subscribe函数就用于此。我们可以找到该函数,检查客户端到底使用了哪些主题。如下所示,客户端订阅了control/all主题,发布了/triangulation/master/masterlist/主题。

❑在特定主题上的通信数据以及这些数据如何影响组件的行为:这就需要继续查看该节点在收到消息后会做什么了。可以使用上述mosquitto_message_callback_set来了解程序的具体业务。更多关于lbmosquitto库的函数和使用,可以参考https://mosquitto.org/api/files/mosquitto-h.html。

③进行攻击

一旦我们收集了有关MQTT实现的基本信息,我们就可以利用它来对生态系统发动不同的攻击。所谓生态系统即MQTT基础设施的所有组件,包括设备、网关、云代理和应用程序、移动应用程序等。

下面我们将列出一些想法来让你的黑客细胞工作。

1)密码爆破。如果Broker需要身份验证,我们可以发起密码暴力破解或基于字典的攻击。

我们可以使用exploit_framework工具来爆破,该工具的下载地址为https://gitlab.com/expliot_framework/expliot,操作如下所示。

首先准备一个password-list。

然后进行爆破。

2)发布主题攻击。当发现一个能造成危害的主题后,如果我们有权限发布它,则会造成严重的后果。比如有一个开车门的主题不需要身份验证即可发布,那么我们可以直接发布该主题实现远程开门,代码如下。

3)克隆客户端攻击。当我们通过逆向拿到客户端的凭证后,就可以以该客户端的身份进行访问。操作如下所示。

4)利用重复客户端ID进行DoS攻击。正如前面所说,我们利用重复的客户端ID可以将现有的连接断开,并且如果服务端使用该ID做身份验证,那我们还能做一些敏感操作,如下所示。

5)恶意消息注入攻击。这主要是发布一些精心构造的主题消息。通过逆向手段我们可以找到节点在处理某些主题数据时存在的漏洞,比如内存漏洞,此时我们可以构造一个主题来触发漏洞,如下所示。

11.4.12 近程之车载系统攻击

本节将带领大家进入车载系统的世界,探索车载系统的安全研究。系统安全是一个经久不衰的话题。无论对桌面主流操作系统Windows、移动操作系统Android/iOS,还是对服务器操作系统Linux,都有许多安全研究人员拥有丰富而深厚的研究经验。

然而,有关车载系统安全研究的公开资料寥寥无几,各大车企也不像操作系统厂商那样公开发布漏洞公告。因此,我们只能从一些安全会议和论文中寻找一些线索。在本节中,笔者将根据自己的经验为大家揭开车载系统的神秘面纱。

本节知识点如图11-89所示。

图11-89 近程之车载系统攻击知识点

首先,车辆中有许多ECU,每个ECU都是一个PCB板,上面有它的主控芯片,有的是MCU,有的是SOC。这些芯片承载的系统软件被称为车载系统。正如前文所述,车辆上的系统分为成熟操作系统和嵌入式的Bare Metal系统。在本节中,笔者将更进一步介绍汽车上这两类系统的具体实现。

1.车载系统常见实现方式

(1)车载系统之AUTOSAR系统

说起车载系统,就不得不谈起AUTOSAR(AUTomotive Open System ARchitecture,汽车开放系统架构)系统。由于一辆汽车包含非常多的ECU,整车制造商不可能对每个ECU都自己研发制造。因此,在汽车行业,每辆汽车都是由各个一级供应商、二级供应商和整车厂共同研发生产出来的,每家供应商负责不同的ECU模块。

基于这样复杂的合作关系,如果在ECU软件层面没有一个统一的标准,制造商就很难把控产品的质量、可移植性、安全性、研发周期等。因此,为了提高各个厂商之间的合作便捷性、提高ECU软件质量、减少开发时间和成本,一级汽车供应商、半导体制造商、软件供应商、工具供应商和其他供应商于2003年共同创建了AUTOSAR联盟。

AUTOSAR将车载应用软件和基本车辆功能之间的接口标准化。并且随着进化,AUTOSAR分为AUTOSAR CP和AUTOSAR AP两类标准。

①AUTOSAR CP(AUTOSAR经典平台)

AUTOSAR CP是一种经典平台的形式。它是用C语言实现的一个小型系统,是一个基于Bare Metal的操作系统。与Linux等富操作系统不同,它的架构主要分为3个层次,如图11-90所示。

首先,基础软件层进一步分为3个部分。

❑微控制器抽象层:该层主要包含MCU的标准驱动程序。

❑ECU抽象层/复杂设备驱动程序:该层主要包含ECU上其他外设的驱动程序。虽然它与MCU是分离的,但是与ECU上其他硬件有关系。

❑服务层:服务层是进一步的封装抽象,为应用程序层、运行时环境以及基础软件模块提供最基本的服务,它将上层软件和其他硬件进行了分离。

其次,应用程序层中最小的单元是SWC(software component)。一个功能通常包含多个SWC,有些SWC负责与外部交互,有些SWC负责数据的处理。

最后,运行时环境的主要作用是协调多个SWC之间的工作,包括SWC之间的通信和调度。

图11-90 AUTOSAR CP架构

②AUTOSAR AP(AUTOSAR自适应平台)

随着汽车电子行业和芯片技术的发展,更强大的SOC出现了,这也带来了更强大的汽车功能,例如自动驾驶和智能座舱等。经典平台已经无法满足这些需求,因此自适应平台应运而生。它的目标是在富操作系统上建立一套标准的车载系统体系结构,如图11-91所示。从本质上来说,自适应平台并不是操作系统,而是一种中间件。该中间件可以运行在各种成熟操作系统之上,为应用程序提供标准的API接口。而这些API封装了各式各样的车辆ECU所需的基础功能。因此,应用程序只需要关注业务逻辑即可。

(2)车载系统之其他成熟操作系统

所谓成熟操作系统是指类似于个人电脑上的成熟系统,具备清晰的内核态、用户态、进程、内存等一系列功能。目前汽车上使用的操作系统的组件通常为T-BOX、IVI、ADAS。这3个组件是智能汽车与传统汽车的标志性差异点,它们赋予智能汽车互联的特色和智能化的能力。当然,这3个组件的功能也非常复杂,不仅涉及车内操作,还涉及车外交互,因此它们需要成熟操作系统的支持。目前在汽车上最常用的成熟系统是Linux、Android、QNX等。而上述的AUTOSAR AP是建立在这类操作系统之上的中间件。

图11-91 AUTOSAR CP架构

通过上述介绍,我们大致了解了常见车载系统的实现方式。从宏观的形态上来看,车载系统正如前文所讲,分为Bare Metal系统和成熟操作系统。因此,在实际的攻击研究方法上,这两种系统也是不同的。接下来笔者将讲解这两种系统的攻击研究方法。

2.成熟操作系统攻击

这里我们暂时不介绍某一种具体的操作系统,而是根据操作系统的共性问题进行研究思路和方法的探讨。一个完整的操作系统需要包括引导加载程序、内核、驱动、子系统、框架和应用,更复杂的操作系统还可能包括Hypervisor和TEE(Trusted Execution Environment,可信执行环境)等。每一个部分都包含着复杂而庞大的代码。在攻击者眼中,它们都是潜在的攻击目标。如果你非常熟悉操作系统,尤其是参与过以上这些部分的开发工作,那么你完全可以驾轻就熟地直奔你感兴趣的目标,以攻击的视角重新审视该目标,相信你会有很大的收获。如果你是操作系统小白,那么该如何入手呢?笔者在这里总结一些通用的方法以供参考。

1)学习使用:无论是Linux、Android还是其他操作系统,学会使用它是第一步。例如你是否可以在操作系统上面开发一个自己的应用,或者开发一个自己的驱动等。

2)分析原理:当学会开发一个简单的应用后,我们需要研究应用背后到底发生了什么。例如系统是如何启动起来的,当我调用一个API时,这个API的背后有哪些代码被执行;系统自带的应用和服务的功能是什么,实现的原理是什么。

3)抽象分析:上述分析原理是一个非常费时和复杂的过程。尤其对一个闭源的系统来说,一个API的调用可能涉及很多模块,复杂的调用关系和逻辑会让人眼花缭乱。在早期的分析阶段,你如果陷入其中,就可能会走入死胡同。因此,在第一次做分析原理时,一定要做抽象。这样你往往只需要分析出一个调用关系、一个数据流图或者一个猜测假设即可。

4)攻击面分析:通过上述初步分析,你应该已经了解了该系统的整体架构,至少知道系统分为哪些模块,每个模块负责做什么,它们之间有什么关联。接下来,你需要根据自己的需求选择合适的攻击面。例如,如果你想研究远程攻击,那么就从可能与外部进行交互的功能入手;如果想要研究本地提权,就要从一些高权限的进程或者内核入手;如果想要研究协议栈,那么可以从使用该协议的应用程序入手。

5)编写测试代码:确定好你想要研究的攻击目标后,建议从编写测试代码开始着手,这将成为你攻击代码的基础。测试代码需要根据与目标进行交互的方式来确定,这通常需要确定一个攻击场景。例如,如果你要进行远程攻击,那么你的测试程序应该在系统外部运行,与目标进行交互;如果你想研究本地提权,那么你的测试代码就是一个低权限的程序,可以与高权限目标进行交互;如果要研究协议栈,那么可能需要编写一个客户端和一个服务端,并且一个在系统外部、一个在系统内部,让它们进行通信,触发协议栈的代码。

6)调试、分析、发现:有了测试代码,接下来就是艰苦的“持久战”,需要通过调试、逆向、代码审计等一系列手段来分析目标的工作原理。在分析过程中,你需要以攻击者的视角去观察目标,看它是否存在漏洞。

在后续关于汽车功能应用的视角中,我们会介绍对车载系统层面的攻击。对于复杂的操作系统,由于它具有复杂的资源管理和权限控制机制,我们将重点介绍其提权攻击思路。

3.Bare Metal系统攻击

针对Bare Metal系统,它不像操作系统那样有许多模块和代码,它没有内核态和用户态的区分,也没有子系统、进程或服务等概念。它是一个非常明确的程序,旨在完成特定的功能,既是系统本身,也是应用本身。

虽然在开发过程中,Bare Metal系统会被分层,例如分为用于处理外设、中断、协议栈、内存管理和任务调度等的模块。但最终,这些模块都会被编译成一个大的二进制文件。

在没有源代码的情况下研究Bare Metal系统存在许多障碍,举例如下。

❑逆向障碍:Bare Metal系统编译出来的二进制文件是原始的bin文件,不包含任何类似ELF的结构。因此,使用逆向工具会遇到许多障碍,例如确认基地址、函数边界和引用关系等。这意味着在许多情况下需要人工分析逆向结果的正确性,帮助逆向工具修复错误。

❑功能定位:Bare Metal系统将所有功能都集成到一个二进制文件中,代码量很大,因此我们在逆向过程中很容易迷失,难以定位到关键代码。

❑非常规指令集:Bare Metal系统的MCU芯片具有不同的指令集。对于一些非常规的指令集,现有的逆向工具的支持不够完善,这会使逆向分析更加困难。

❑调试:Bare Metal系统通常没有交互式shell,也没有类似GDB的调试工具,因此动态分析非常困难。通常只能借助JTAG这种硬件调试或模拟器进行调试。

由于极简的设计,Bare Metal系统相对于操作系统,产生的漏洞确实较少。但是,针对这种系统的攻击也是存在的,攻击者主要从外部入侵来实现攻击目的。下面结合汽车特性,列出一些可能的攻击思路。

❑通过片外的有线通道:指的是车内各个ECU之间的有线通信方式,比如CAN、FlexRay、Lin、Ethernet等。攻击者需要从二进制代码中定位到处理这些通信的代码,这些通信协议通常是分层的,攻击者需要识别链路层、传输层和应用层的代码,并进行对应攻击。

❑通过片外的无线通道:指的是具有无线通信能力的PCB板的攻击渠道,比如蓝牙、Wi-Fi、433等。通常MCU并不直接进行无线信号的收发,而是通过片内总线与专门无线信号收发器或无线信号芯片进行收发数据的交互。攻击者需要识别出MCU中处理这些无线数据的代码段,然后从这里进行攻击。

❑通过片内的通道:指的是在ECU上具有多个计算芯片的情况,比如同时具有MCU和SOC。攻击者如果已经攻破SOC,那么需要通过片内的通道来攻破MCU。攻击者需要识别出在MCU和SOC之间的通信方式,通常是SPI/I2C/UART等,然后从这里进行攻击。

Bare Metal系统并不具备复杂的资源管理、权限控制等功能,因此它的功能相对较为简单。然而,这也导致了漏洞利用变得更加复杂,因为攻击者需要利用系统中的漏洞来获取权限。在这里,我们将介绍一个公开的案例,该案例源自2022年Black Hat Asia会议的Backdooring of Real Time Automotive OS Devices报告。该报告利用了一个在RH850芯片中的实时操作系统漏洞。该漏洞是指,在处理CAN-FD协议时,若目标Buffer小于CAN-FD帧的长度,则会导致内存越界写入。接下来,我们将介绍该漏洞的利用方法。

该漏洞存在于中断上下文中,因此可以通过该漏洞实现“一次任意地址写32个字节的任意内容”的原语(Primitive)。有了该原语,攻击者可以直接覆盖栈上的返回地址来控制PC寄存器。因为MCU的程序没有进行地址随机化,所有的代码段、数据库、栈都是固定地址。基于此,攻击者可以实施以下行动。

首先,尝试使MCU的AES私钥泄露。方法是跳转到CAN_Send函数,该函数可将CAN数据发送出来。然后把该函数的参数(发送数据的缓冲区地址)地址改为AES Key的地址,以达到泄露的目的。通过漏洞构造的栈结构如图11-92所示。

尽管这种方法可以泄露AES Key,但是无法执行任意代码。此外,每个ECU的Key也不同,因此该方法的作用不是很明显。

然后,攻击者尝试执行shellcode。执行的方法很简单,只需将栈的返回地址覆盖为SHELLCODE的地址即可,如图11-93所示。

图11-92 调用CAN_Send栈结构

图11-93 执行shellcode的栈结构

然而,这种方法所能执行的shellcode的长度很有限。

接着,攻击者需要尝试执行更大长度的shellcode。思路是将上一步中的shellcode构造为AAW(Any Address Write,任意地址写),并且不让程序崩溃。这样可以通过多次调用来上传大量shellcode。此过程需要禁用MCU的多个保护措施,比如硬件看门狗(Hardware Watchdog)和内存保护(MPU)。

最后,需要触发执行这大量的shellcode。此步骤通过修改代码里条件跳转的Flag来实现。

通过以上步骤,就可以对MCU植入shellcode后门。如需了解更多细节,请参考完整的会议资料,链接为https://i.blackhat.com/Asia-22/Friday-Materials/AS-22-Delarea-Backdooring-of-real-time-automotive-os-devices.pdf。

11.4.13 近程之芯片攻击

本节主要介绍芯片攻击,即硬件攻击。该攻击主要是为了获取芯片级的调试接口,获取芯片固件等。本节中所使用的工具在上一章中已经讲解,因此不会详细介绍工具如何使用,主要讲解使用这些工具怎么达到我们的目的。本节知识点如图11-94所示。

图11-94 近程之芯片攻击知识点

1.JTAG/SWD攻击

经过对ECU芯片的分析之后,如果想要深入了解ECU内部的工作细节,就需要通过调试接口来实现。这个接口可以直接与MCU通信,获取固件并调试芯片等。而MCU芯片最常用的调试接口是JTAG/SWD,该接口在开发过程中用于下载、调试固件源代码、恢复被锁定的硬件以及执行边界扫描。

(1)JTAG/SWD攻击分类

攻击者可以通过访问硬件上的JTAG/SWD接口,侵入设备并发现许多攻击的可能性。以下是可能的攻击场景。

❑攻击者可以访问控制器的内部存储器,从而操纵寄存器的值。操作内部寄存器可能会产生不同的效果。例如,在某些情况下,即使实现了控制器读保护,攻击者也可以操纵寄存器的值,并且存在绕过保护的可能性。同样,攻击者还可以更改设置并绕过与引导加载程序和其他关键寄存器相关的保护。开发人员可能已经为安全而锁定了这些寄存器。

❑访问带有JTAG/SWD接口的硬件使攻击者有可能调试系统。这可能有助于攻击者挖掘更多漏洞并对设备进行攻击。

❑从攻击者的角度来看,对JTAG/SWD调试接口的访问增大了从设备提取固件、修补固件,并将修改后的易受攻击/恶意固件重新刷新回设备的可能性。因此,访问固件为攻击者捕获和利用其他漏洞提供了巨大的机会。

(2)JTAG/SWD攻击之侦测

我们首先需要确定硬件上的各个端口引脚,以便通过JTAG/SWD端口与设备交互。图11-95和图11-96显示了硬件上的大多数JTAG端口测试点/引脚布局的样子。

图11-95 JTAG端口/引脚样式(1)

图11-96 JTAG端口/引脚样式(2)

如上所述,对于JTAG,我们需要识别4个信号引脚(TCK、TDI、TDO、TMS)和VCC、GND引脚。对于SWD,我们需要两个信号引脚(SWDIO、SWCLK)和VCC、GND引脚,这些引脚的含义在上册中讲解过。

下面将介绍识别设备上这些接口引脚的几种方法。

①手动识别

识别设备中使用的微控制器,取出其数据表。并识别微控制器的JTAG/SWD引脚,如图11-97所示。

图11-97 STM32开发板示例

在PCB上微控制器使用的是STM32F411x。我们可以搜索它的DataSheet,发现它具有JTAG/SWD接口引脚。图11-98显示了数据手册的这一部分。

图11-98 STM32F411x芯片引脚之SWD

我们识别控制器上的JTAG端口引脚。首先设置万用表连通模式,然后我们将一个探头放在控制器上的JTAG端口引脚上,将另一个探头放在怀疑是JTAG端口引脚的电路板上的测试点/插头引脚上。重复此测试,直到识别出引脚为止。

②自动识别

许多工具可以帮助我们扫描和识别硬件上的JTAG/SWD针脚。

❑EXPLIoT Bus Auditor:它支持JTAG、SWD、I2C、UART。

❑JTAGEnum:这是一个基于Arduino的开源项目。它不支持UART,也没有可调电压。

❑JTAGulator:它支持JTAG、UART、SWD。它有一个可调的目标电压。

将JTAGulator连接到板子的引脚上,会自动识别出其中是否有JTAG接口,如图11-99所示。

(3)JTAG/SWD攻击之交互

为了与设备上的JTAG/SWD接口通信,我们需要一个协议适配器和一个软件。该软件可以通过适配器与设备的JTAG/SWD接口进行通信,它可以通过主机从用户那里获取指令,并通过协议适配器向各自的JTAG/SWD接口发送相应的低级指令,反之亦然。

在通过上述方法识别JTAG引脚后,将JTAG引脚TCK、TMS、TDI、TDO与适配器上相应的JTAG引脚连接,如图11-100所示。

图11-99 JTAGulator使用示意图

图11-100 JTAG适配器引脚飞线

然后使用OpenOCD。它是一款开源的片上调试器调试软件,提供片上编程和调试功能这是通过JTAG/SWD接口和TAP支持的分层架构实现的。它支持多种目标调试,如ARM、MIPS等,并且支持单步执行、断点/观察点等调试方法。同时,它支持各种芯片、接口和目标,并可以打开GDB和Telnet服务器,用户可以在硬件上执行GDB调试,也可以通过telnet命令与OpenOCD进行通信。为了与不同的芯片和接口通信,我们需要提供正确的芯片和接口配置文件。

在使用OpenOCD之前,需要先启动它。我们可以通过命令openocd-f stm32f4x.cfg来启动它,并将相应的配置文件传递给OpenOCD,让它了解所使用的目标微控制器和调试适配器。对于不同的微控制器和适配器,我们需要选择相应的配置文件。

对于OpenOCD配置文件的更多信息,请访问http://openocd.org/doc/html/Config-File-Guidelines.html。

现在,在另一个终端中,我们将打开Telnet并通过JTAG接口执行不同的操作,包括存储器读取、写入、转储等。例如,为了提取固件,使用命令dump_image/tmp/flash_dump.bin<address><flash memory length>,如下所示。

因此,各种OpenOCD的命令可以用来执行各种操作,包括操作寄存器值、修补固件等。对于SWD接口也是采用类似的方法。我们只需要连接相应的SWD引脚,并且在配置文件中提到相应的SWD传输。一旦我们成功地与JTAG/SWD端口进行对接和通信,就有可能出现上述各种攻击场景。

2.UART攻击

除了JTAG,UART也常常成为攻击者的目标。UART是一种异步串行通信接口,MCU使用UART接口与外围设备进行通信,如调制解调器、Wi-Fi芯片、蓝牙模块、GPS模块、路由器、相机和其他许多应用。对于没有键盘或监视器等接口进行调试的嵌入式设备,UART也可以作为替代调试接口。

(1)UART攻击分类

从硬件安全的角度来看,UART端口是一个很有趣的方面。因为它通常会连接设备的嵌入式操作系统的调试shell或控制台,如果没有得到正确保护,它就会为攻击者提供通过访问root shell来侵入设备的机。

通过访问设备root shell,攻击者可以进行如下操作。

❑搜索文件系统,寻找一些易受攻击的二进制文件或正在运行的服务,这些文件或服务很容易被攻击者利用。有时,访问与调试或网络相关的二进制文件可能会启用远程访问,从而危及设备安全。

❑对正在运行的系统执行修改。

❑篡改设备上的补丁固件。

❑浏览文件系统以查找一些敏感和硬编码的值,如加密密钥、配置、凭据等。通过访问这些敏感信息,攻击者可以更容易地执行进一步的攻击。

除了访问root shell外,攻击者还可以通过UART串口监听外围设备和控制器之间的通信。此外,如果设备控制台输出到UART,它会在控制台上提供大量与调试和系统日志相关的信息。这对进行逆向工程以及了解系统的行为非常有用。

(2)UART攻击之侦测

要通过UART端口攻击设备,我们首先需要识别硬件上的UART引脚Rx、Tx。图11-101和图11-102显示了硬件上大多数UART端口测试点/引脚的外观。

图11-101 UART端口

图11-102 UART引脚

UART端口通常有4个引脚:Rx、Tx、VCC和GND。如果我们找到一组4针,那这可能是一个UART端口。下面将介绍几种手动识别设备上的UART端口引脚的方法。

①万用表电导识别

怎么使用万用表在上册已经详细介绍过,这里我们使用它识别微控制器的UART引脚。首先,我们可以在DataSheet中找到关于具有UART端口引脚的信息,同前文提到的查看JTAG的方法一致。然后,我们将万用表模式设置为连通模式,将一个探头放在控制器上的UART端口引脚上,将另一个探头放在怀疑是UART端口引脚的PCB的测试点/插头引脚上。重复此测试操作,直到识别出引脚为止。对于VCC和接地引脚,也可以用类似方式来识别。

②万用表电压测量识别

即使我们没有设备使用的控制器的数据表,我们也可以通过测量可疑引脚/测试点上的电压来识别UART端口引脚。

❑找可疑引脚:打开设备后,我们查找可能的UART端口引脚/测试点组。通常,它们是组中的4个或更多引脚。标记所有此类可疑的UART端口引脚组,并测试所有被标记的引脚组。

❑识别接地引脚:从识别接地引脚开始,将万用表设置为连通模式。将万用表的红色探头放在可疑的接地引脚上,将另一个探头放在设备输入电源的接地引脚上或设备的任何金属屏蔽物上。如果万用表发出蜂鸣音,即设备上的疑似接地引脚和实际接地引脚之间存在连续性,则表示可用于UART端口连接的是接地引脚。如果没有,则继续对疑似UART端口引脚组中的其他引脚进行重复操作。

❑识别VCC:VCC通常不用于连接UART接口,但识别它会缩小我们的搜索范围,以方便找到另外两个引脚Rx和Tx。打开设备电源,将万用表旋转到类似V(20)的直流电压(考虑设备在20V范围内),将黑色探头放在设备的接地引脚上,将红色探头放在疑似的VCC引脚上。如果万用表上的电压读数显示为恒定的3.3V或5V(取决于设备电压),则为VCC引脚。如果不是,则对疑似UART端口引脚组中的其他引脚重复此操作。

❑识别Tx:要识别Tx引脚,需要先打开设备电源,将万用表设置为前面提到的直流电压范围。然后将黑色探头放在设备的接地引脚上,将红色探头放在疑似的引脚上。若万用表上的读数显示电压变化,则意味着它是Tx引脚。这是因为设备一直在Tx引脚上进行传输。

❑识别Rx:通常,如果我们成功识别3个引脚——Tx、GND、VCC,则识别第4个引脚Rx变得更容易。正如我们在上一步中所做的那样,在测量电压时,万用表有时会在不同的情况下显示不同的结果,有时表现为恒定的低电压或高电压,有时甚至表现为变化的电压。

(3)UART攻击之交互

在大多数设备中,UART都用作调试接口。它连接设备的串行控制台,可以访问root shell,并记录消息。要通过UART端口访问设备的控制台,我们需要一个支持UART接口的适配器,比如Expliot nano、Bus Pirate、Shikra、CH341A、USB转URAT控制器(CP2102)。

选择工具后,根据引脚定义进行正确的连接,如图11-103所示。

设备的Rx连接到适配器的Tx,并且设备的Tx连接到适配器的Rx,此时两个设备的接地均已连接。现在,可以使用Minicom、Picocom、PuTTY和Teraterm等串口终端访问设备的串口控制台了。在连接之前,我们需要知道波特率。在手动情况下,我们需要利用常见的波特率进行命中试验。试验失败则需要使用示波器采集串口的信号样本,才能计算出波特率。一旦检测到波特率,就将转换器通过串口连接到主机,以访问设备的串口控制台。如图11-104所示如果在设备中没有身份验证,则攻击者可以在获得root shell的访问权限后直接进入设备。

图11-103 UART引脚接线

图11-104 使用UART接口获取root shell

3.SPI攻击

SPI是一种同步串口通信接口,它主要用于同一ECU上的组件之间的通信(板内通信)。

(1)SPI攻击分类

在嵌入式设备中,SPI协议用于与设备上的各种组件进行通信。这些组件可能是传感器、控制设备、LCD、SD卡、EEPROM、闪存等。对于SPI,通常有以下几种攻击方式。

❑嗅探传感器、控制设备、存储芯片等SPI设备与控制器/处理器之间的通信。这可能会导致攻击者窃取敏感信息。例如,在一些嵌入式设备中,SPI EEPROM用于存储敏感信息,如密钥、日志等。如果攻击者嗅探EEPROM和控制器/处理器之间的SPI通信,则这些敏感信息可能会泄露。如果硬件供应商在生产的所有硬件中都使用了相同的敏感信息(如相同的密钥),则攻击者可能会以多种方式进行破坏,甚至可能造成大规模破坏。

❑从SPI内存芯片中提取固件/敏感信息。一些嵌入式设备使用SPI闪存作为内部存储器存储固件。一些工具和方法可用于读取NAND/NOR SPI/并行闪存。攻击者可以读取闪存并从中提取固件,还可以对固件进行逆向工程,并对其进行分析以发现潜在的漏洞。如果固件不受保护,则很容易被窃取信息。如果固件包含配置信息或其他敏感数据,攻击者对此进行提取和分析时可能会发现新的漏洞。攻击者还可以为SPI闪存芯片中的固件打补丁。在这种情况下,如果固件没有在设备上实现安全管理,攻击者就可以用后门修补固件,并用恶意固件重新编程SPI闪存。

(2)SPI攻击之侦测

为了攻击SPI,首先我们需要检测PCB上是否存在SPI。这需要检查PCB电路板上的每个芯片、测试点。

首先识别设备上使用的SPI芯片,然后根据DataSheet识别所给出的引脚图,并在PCB电路板上找到这些引脚,检查控制器的SPI引脚和电路板上的测试点之间的连续性。例如我们发现其中一个芯片是SPI EEPROM 25LC256,如图11-105所示。

接着确定芯片的SPI引脚(MISO、MOSI、SCK、CS)是否连接到印刷电路板上的某些点。我们通过DataSheet为芯片的各个引脚进行标识,如图11-106所示。

图11-105 SPI EEPROM 25LC256芯片

图11-106 SPI芯片引脚定义

再使用万用表检查这些SPI引脚与PCB电路板上其他引脚的连接性,发现J5接头上的引脚连接到这些SPI引脚上。

(3)SPI攻击之嗅探

一旦硬件上的SPI引脚被成功识别,我们就可以继续嗅探SPI芯片和控制器之间的通信了。可以使用像逻辑分析仪这样的工具来嗅探SPI总线上的通信,如图11-107所示。

图11-107 用逻辑分析仪嗅探SPI信号

逻辑分析仪显示了全部4个SPI引脚上的信号,即MISO、MOSI、CLK、CS。根据协议时序图对这些信号进行解码。Saleae Logic Analyzer、PulseView等软件具有检测这些协议的功能,可以直接显示解码后的数据和信号。如果数据传输是纯文本的,我们就可以嗅探并获取它。

(4)SPI攻击之提取固件

为了使用SPI协议与嵌入式设备中的芯片进行通信,我们需要支持SPI协议的适配器工具。这些工具使得在没有主机的情况下进行通信变得可行。有时候,我们还需要将闪存芯片从硬件上取下来,将其焊接到Perf板上,或将其放入合适的TSOP插座中,并将需要的引脚连接到适配器上。

有许多工具可以用于从内存芯片中提取数据,例如EXPLIoT Nano、Bus Pirate、Shikra、CH341A、EXPLIoT Framework、Flashrom、pyspiflash、pyftdi、RaspberryPi和Beaglebone。

假设我们在嵌入式设备的PCB上发现了一个SPI闪存,并且我们想要从芯片中提取固件。我们的方法如下。

首先,获取SPI闪存的DataSheet,确定所需的引脚和电压。

然后,选择适用的适配器工具,并将SPI闪存的引脚连接到适配器上,如图11-108所示。

图11-108 SPI芯片连接适配器示意图

接着,在主机上安装适配器所支持的框架,例如EXPLIoT Nano。对此,可以使用命令run spi.generic.readflash-w dump.bin从闪存中提取固件,如下所示。也可以使用合适的其他工具和框架来转储来自SPI存储芯片的固件。

(5)SPI攻击之无现成工具提取

如果找不到任何SPI内存芯片工具,那么硬件设置步骤与上面相同。需要先取得任何基于FTDI232H的适配器,再匹配SPI芯片和适配器的电压电平,然后按照适配器和芯片的用户手册/数据手册进行连接。在这种情况下,需要自己编写工具,甚至可以将当前不支持的闪存芯片添加到所选择的任何开源工具中。

因此,首先需要仔细阅读SPI内存芯片的DataSheet。该DataSheet包含编写从内存芯片读取数据到向内存芯片写入数据的脚本所需的所有详细信息。例如,读取SPI闪存W25Q256JV的DataSheet,它提供了读取、写入和执行其他操作所需的详细指令及命令。如图11-109所示,这是SPI读取指令(03H)的通信格式。

图11-109 SPI芯片读取命令格式

因此,按照SPI内存芯片数据手册的说明,用户既可以编写脚本来转储或编程芯片。

4.I2C攻击

I2C也是一种同步串行通信接口,它主要用于短距离板内通信。它是由飞利浦半导体(现在的恩智浦半导体)开发的。它提供半双工通信模式,即发送方和接收方可以一次发送/接收一个数据,而不是同时发送/接收数据。主从式架构,支持多主多从。它是一个二线制的串行接口。

(1)I2C攻击分类

I2C和SPI类似,也是用于与设备上的各种外设进行通信,因此对它的攻击方式和SPI也很类似。

1)嗅探传感器、控制设备、存储芯片、ADC、DAC等I2C设备与控制器/处理器之间的通信。这可能导致攻击者窃取敏感信息。例如,在一些嵌入式设备中,I2C EEPROM用于存储一些敏感信息,如密钥、日志等。如果攻击者嗅探EEPROM与控制器/处理器之间的通信,这些敏感信息可能会泄露。获得此敏感信息后,如果硬件供应商在生产的所有硬件中都使用了相同的敏感信息,攻击者可能会进行影响更大的破坏。

2)提取或修改基于I2C的存储芯片、传感器或任何受控设备中的数据。在这种情况下,如果设备上的数据没有得到安全管理,攻击者可以对其进行操纵。这可能会导致设备出现故障。根据应用程序的不同,攻击者操纵传感器数据可能会对系统造成重大损害。

(2)I2C攻击之侦测

为了攻击I2C,我们需要检测PCB上是否存在I2C。这就需要检查PCB电路板上的每个芯片、测试点。

如果成功识别了设备上使用的I2C芯片,根据DataSheet所给出的引脚图,在PCB电路板上追踪这些引脚。再使用万用表检测I2C引脚和PCB电路板上的测试点之间的连续性。如图11-110所示,发现其中一个芯片是I2C EEPROM 24LC256。

找到芯片后,下一项任务是确定芯片的I2C引脚(SDA、SCL)是否连接到PCB上的某些点。然后去网上找到它的DataSheet,确定各引脚含义,如图11-111所示。

图11-110 I2C EEPROM 24LC256芯片

图11-111 I2C芯片引脚定义

检查这些I2C引脚与PCB电路板上其他引脚的连接性。我们发现J5接口上的引脚连接到这些I2C引脚。

(3)I2C攻击之提取固件

与SPI一样,选择符合要求的工具和框架后,检查工具的电压电平和芯片。如果适配器工具和I2C芯片的电压电平不匹配,则使用电平移位器。如果有合适的工具,就可以进行以下操作了。

首先,通过I2C芯片的DataSheet确定所需的引脚和电压。相应地,选择可以使用的适配器工具。例如EXPLIoT Nano,将芯片的引脚连接到合适的协议适配器,如图11-112所示。

图11-112 I2C芯片连接适配器示意图

然后在主机上安装已使用的适配器工具,例如EXPLIoT Nano。使用命令i2c.generic.Readeeprom-c <chipname>-w<filename>从闪存中提取固件,如下所示。

EXPLIoT还支持对I2C内存芯片的Patch操作,对此需运行i2c.generic.writeeeprom-c<chipname>-r<patched_filename>命令。同样,其他工具也可以转储/修改来自I2C存储芯片的数据。