腾讯聂森+刘令:特拉斯网关的逆向揭秘

聂森:大家好,刚才已经帮我做了前面的背景介绍,今年9月份我们实现了无物理接触的远程控制方法去控制特斯拉。

实际上这是一个非常复杂的攻击连,涉及到多个漏洞,从前面的逻辑漏洞,内核相关,包括一些单片级ECU的安全,这是一个非常复杂的过程,我们认为50分钟是不可能讲完的。

而且我们现在的漏洞还在和特斯拉沟通进行修复,他们已经做了一个快速的修复,可能后续还有一些安全加强,所以我们今天重点介绍的是其中非常关键的一个环节,就是特斯拉撤电网络中非常重要的一个,叫做汽车网关的Review。

我们先做一些简单的自我介绍,我是聂森,是Keen Team的一位安全研究员,我没有很多年的安全经验,在我加入Keen Team的前两年,在学校的时候我主要是做程序相关的,主要是把一些理论和实际应用于挖掘,例如Windows内核,Linux内核以及手机的安全内核。

刘令:大家好,我是刘令,现在做车联网相关的漏洞研究工作,在此之前我做过一时间虚拟化的漏洞研究。

聂森:今天首先给大家介绍一下什么是汽车网关,讲一下特斯拉汽车网关和传统的汽车网关的异同,硬件的特性,这里我们要说的就是,在汽车安全研究领域,大家一个普遍的认识,就是很多研究工作是用在前期的一些工作。

因为现在有一些单片机,我们普通的是没有办法做到的,不太像是Windows和Linux下面的一些应用态和应用程序,所以我们要做大量的前期工作来帮助后面分析。这里面还涉及到一个操作,这个东西我们做一个快速的介绍。

然后就是由我的同事刘令真正的介绍一部分,就是特斯拉网关独有的,可能是一些攻击面或者是一些神秘的细节,以及我们最终实现整个攻击链重要的接口。

什么是汽车网关?汽车网关也是一个单片机,它的作用就是在不同的CAN上面,它要处理以太网的数据和CANBus是怎么交付的,这个工作是由汽车网关完成的。

这里除了通信之外,因为我们把这各连入英特网或者是以太网的方面数据是不可信的,CANBus我们理解为一个可信区域的话,这中间肯定有一些必然的过滤。

这里还要介绍一些常用的汽车网关,第一个就是在我们之前,他们设计了一个单片机,就是NEC V850,这个市场量非常大,利用特斯拉Freescale MPC的单片机去研究。

另外一个是我们在国内看到的一个单片机,汽车网关是NEC的78K0R。我当时做了一个简单的调研,我觉得它只是在国内的厂商应用比较多,因为它的成本还是比较低的。

但是非常巧,我没记错的话,7月底,10月初的一个国外的会议上,硬件安全相关的会议上,有一个演讲者也介绍了类似的问题,同时他也提到了对于特斯拉的一些猜测,认为我们是怎么做的。我觉得作为同行,看来大家对这个问题的理解还是比较相似的。

这是特斯拉汽车网关的一个架构,在我们的研究之前,其实大家知道,在2015年有国外的研究员已经把特斯拉称为是物理接触的,先把车拆了,做一些实验,然后就可以做到一些不涉及的一些控制项目。

当时他也给出了一个架构图,主要是偏向于我这个图里面绿色的部分,他不重点去介绍汽车网关,主要是介绍一些复杂性的架构,这个也很复杂,我们花了很多时间研究,在那张图里面,汽车网关就是一个没有重视的节点。

这个硬件架构刚才也介绍了,是Freescale MPC5668G的芯片,在上面跑了一个系统,因为它要实现CANBus和以太网的连接,所以必然要以上面一个任务的形式实习协议站和CAN模块。

在这之上还有一些任务,专门用于跟以太网通信的一些Task,用来收发消息的一些Task,包括一些调试用的Task。

红色的部分是高危组件,跟CANBus有关的,CANBus分为高速、低速不同的频道,包括开个空调,开个灯或者是车门,PT就比较重要了,包括车速和速度。

在这里展开介绍一下对于硬件方面我们是怎么获取信息的。背景就是我们只有2014年款的特斯拉,这是我们唯一一辆。大家知道,在中国想买特斯拉汽车配件是不可能的,这个盒子拆到这个地步我们就不敢拆了。

但是我们相信,Gateway应该是在图中这个白颜色的下面放着,因为其他地方确实没有看到这个Gateway的芯片。非常走运的是,我们在TMC国外专门讨论特斯拉的论坛上看到一位仁兄给出来一个非常关键的信息,在其中一个芯片上,我们上面也给出的链接,如果大家感兴趣的话可以看一下具体是什么东西。

这个信息我们应该是不敢相信的,因为我们没有看到真实的东西,大家知道黑客没有看到的话是不太相信的,我们后期还是用了很多辅助的方法确认了这些信息。

说完硬件就是固件,做单片机分析的话没有固件是很麻烦的,而这个固件提取我认为还是相对来说比较容易的。有几种方法,我相信现在特斯拉都已经把它给补掉了。

其中一个就是我的同事在两年前的时候通过拆机就可以看到有固件包,我们也是在这里提取的。后来同事刘令发现通过网络接口是可以下载到这个包的,通过它的OTA机制。

现在好像更新完之后不再有这个包了,会直接通过某种机制删掉,而网络可能下载一些方法也变了。因为这个东西把它存在SD盘里面,后续可以刷机。我们在研究过程中,也把整个机刷装过几次,拆卸非常麻烦,每次大约一个小时。

后来我这个同事,专门做硬件安全的一个小伙子,我们经过了商量之后,就在这个上面开了一个口子,就算是丢失保修了,但是我们也没准备保修。解开之后就很简单了,简单来说就是一个压缩包,我第一眼就看到了gtw.hex,其他的都不是今天要讲的重点,但是那是未来研究的特点,各有各的特色。

介绍完硬件介绍一下对于芯片的一些分析,首先是内存布局,内存布局有几块,介绍一下特斯拉特殊的东西。

虽然有一个区域叫做Flash,其实这个地方放的东西也可以出来,我们称为Flash的区域这个部分,刷写的时候为了实现更新,没有那么简单的,他把数据放在了后面,在每次执行的时候会把一部分数据再拷贝到内存里面,这样就具有了堆写能力,这一部分我们要模拟一下,后面我会介绍,否则的话分析难度会比较大。

关键集成分析,大家要忘记过去的分析方法,因为现在没有字符串可以参考,简单的程序大家看字符串就可以出来了,现在的思路就是关心什么模块就看什么模块相关的信息。我们也是前期做了大量的工作,写了一些脚本,用来进行分析。

对于前面说的论坛里面一位国外的仁兄提到的这个FreeRTOS,我们通过这个细节就确定应该是有这个信息,这里有一个字符串,应该是一个时钟相关服务的字符串,我们在源码和二进制里面找到了,而且有非常完美的对应关系,就是创建一个Task,来创建相关的代码。

两个操作系统都有介绍,一个是任务,一个是队列,这里的队列是一个数据通信的方法,Windows下可能有基于内存文件的映射,还有其他的一些相关的各种各样的通信方式。

这张图是任务的管理,生存周期,这个也很常用,不展开了。重点是创建任务,这个任务是怎么创建出来的,基于这个信息我们要提取出来有多少个任务,每个任务都是在做什么。

队列的话,就是RTOS通信的方法,在内存里面写入一些数据,这些数据是通过队列的一些封装进行传递。这个东西在特斯拉领域的作用就是消息是通过这种来传递的,一个任务接收,通过另外一个任务去发送。

基于之前介绍的这几页PPT,最终的结果就是这样,我们把那些函数都已经识别出来了,也把它标记到这个当中,这也是我们前期工作的一个部分。

还有就是非标准Task里面的协议站,具体代码我们是把标准接口列出来,最终是实现远程控制。对于一些接口文件,我们都已经逆向出来了,后期要做的工作就是说,如果深入的逆向的话,这两个模块到底是什么?

对于TCP/IP我只能说猜测,应该是非常知名的项目,叫做IOWIP这个项目实现的一个嵌入式协议站,文件系统的话,现在看不出来什么特征,如果确实是一个FS,具体怎么实现的,大家也可以猜测。另外有一个细节,这个里面是比较通用的,就是说可能明天我换一款车,还是要出这些细节。

在面对这种特殊的架构,这种特殊的格式的话,这个识别是有问题的。而这个芯片是32位的,所以肉眼去找看一下,是四字节对齐的,要写脚本把这些东西处理一下,这里给出来的就是比较典型的,有附加1个0,3个0和4个0的情况,这一部分处理的比较完美。

含多函数的IDA没有办法识别,可能没有一个明显的应用。这个时候怎么办呢?就要把一些通用的函数识别出来,脚本自动化出来。很关键的信息,这不是一个明显的调用,这种情况下看着不起眼,反而是最关键的内容所在。

刚才提到一部分,因为Flash2这个区域是只读的,是更新的,把数据放在最后,再放到内存里面,可以实现读写。如果这一部分不标记出来的话,后面的逆向难度比较大。

大家也看出来,这是相当于为后面的逆向奠定了一个很好的基础,而且都需要做类似的工作。后面这一部分由我的同事刘令给大家介绍一些特斯拉独有的攻击面,也可能是一些细节,可能是一些端口的信息。

刘令:大家好,接下来我向大家介绍一些内部的细节,包括所具有的功能,以及向外面提供的一些接口。前面聂森已经介绍了,在特斯拉上,Gateway是一个同一个网关的,当我们拿到权限的时候,和Gateway处于同一个网关,我们要关注的是上面所关注的端口。

根据空间的立项以及实际的测试,我们发现下面某一个端口是Gateway提供的,TCP23端口,是一个Shell Port,1050的端口是file Transfer Port。UDP的3500端口,CID可以通过这个端口告诉Gateway发生了什么样的数据。

38001端口是UDS协议有关的端口,在某些情况下可能会参与车身上ECU更新的过程。由于前三个端口和Gateway内部的联系更为紧密,所以今天就以这三个端口作为切入点,讲解一下在Gateway内部是如何工作的。

TCP 23端口是Shell的端口,这个任务是在Gateway起用时就创建起来的。但是当我们在CID端用NCE去尝试连接Gateway的23端口的时候,是没有办法连接的。

解决这个问题的办法在去年的GeekPwn已经有人指出了,只要到3500端口就可以成功连接,就可以收到Gateway发来的一个问号,这个时候我们并不知道Gateway的意图是什么,所以我们就去看固件。发现Gateway在发出信号以后,会再接收一段数据,将这个数据与一个静态的字符串进行比较,如果内容是相同的话,才会继续处理Shell的功能。

实际上这个字符串就是Shell的一个密码,输入完密码以后,我们就可以成功的连入到Gateway提供的Shell,就可以看到Gateway提供的一些版本信息。

Gateway还提供了很多其他的命令,其中有一个是Tegra命令,当执行完这个命令以后,我们就神奇的看到了终端登录,实际上在背后,CID的串口是连到了Gateway上面。

借助于这个串口,我们可以看到CID在启动时在串口上输入的一些信息。另外一个比较有趣的命令是Status命令,这个命令会显示车身上的CAN总线复杂的情况,通过逆向,在逆向时跟踪这个函数的代码,可以帮助我们去确定与CAN总线有关的数据结构以及在固件当中的位置,以及大致确定他们的定义是怎样的。

另外一个是Stackinfo这个命令,这个命令会显示在Gateway上所运行的每一个Task占的空间在内存当中所占的区域。这些信息对于内存破坏类漏洞的利用是比较有帮助的。

第二个端口是1050,是文件传输端口,负责这个端口的是xfeTask任务,是在Gateway启动时就创建的。CID想要发送文件到Gateway上的时候,更多使用的是gwxfer的Perl脚本,一个是源地址,一个是目的地址,指定到目录,信息或者内容按照一定的协议格式进行包装,并填好ID,发送给Gateway。

在Gateway端有许多的处理过程,根据填好的ID来选择相应的处理过程,它已经提供了7个目录,而Xfer脚本里面只使用了其中三个,还有获得文件大小的功能。

除此之外,还有其他的如创建文件夹,删除文件和重命名文件,这些就需要在CID端,只要按照一定的格式就可以去调用这些目录。

在进行文件传输的时候,有一个比较特殊的情况就是Gateway端根目录下的这个文件,如果传输到根目录下,实际上在Gateway的SD卡上面是并不会创建这样一个文件的,而从Gateway上去下载这样一个文件的时候,确确实实是可以下载到这样一个文件。

实际上这个文件的内容并不是存到Gateway的SD卡上面,而是存在了Gateway的Flash上面。firmware.rc是存到0X18000上,所存放的内容是CID、Gateway以及车身上其他ECU的一些版本信息。

与其类似的还有一个是Nternal.dat这个文件,是0X1C000,存放的是ECU的设置信息。

之所以内容并没有存放到SD卡上,是因为他们改写了fopen这个函数,对这两个文件做了特别的处理。下一个是诊断端口,负责维护这个端口的是一个名为diagTask的任务,CID选择调用Gateway所提供的功能的时候,需要按照一定的格式去放入数据,第一个字节是功能ID,后面是这个Command所需要的参数。

Gateway会根据功能ID来选择,后面跟着的是处理的结果。在我们看到的固件当中,Gateway已经提供了有31个功能ID。

下面介绍几个功能,CID只需要发送00这样一个字节到Gateway上面,Gateway就会自己重启。前面我已经介绍了,Gateway上面有一个位于2000,负责实现Gateway正常功能的,是APP代码。

另外一个是从0开始的,Bootloader代码,在新的版本上,这个反馈值是-1。

下面是0X8 Reboot for Update,会先将一个文件传输到Gateway上面,然后将这个文件作为调用的参数发给Gateway,Gateway再处理的时候,会将这个文件重命名,然后让Gateway去重启。

Gateway重启以后,会发现有这个文件,会将这个文件反应到内存,再从这个文件去执行后续的更新的过程。

0x9号功能是Reset Tegra,刚CID Sends发生0900的时候,会通知CID重启,当CID发生0901的时候,会设置为1,CID又会重启到另外一种模式。

当CID发生一个固定的字符串到Gateway上面的时候,Gateway就会去着手清理Log,首先Gateway会将这些数据放到一个队列当中,Gateway的另外一个Task会从这个队列里面取值,当取到这个0x9的时候,就会删除下面的Log文件,将Gateway重启。

0X12号功能是Enable Shell,到1201端口的时候会开启一个Shell,只有30秒。

这是因为Gateway接收到1201的时候,会放到一个全局变量里面,正常处理这个Shell请求的时候,会看当前的时间是否在30秒之内,如果是的话才会去处理用户的Shell请求。04号功能由聂森给大家来介绍。

聂森:这个部分很关键,大家看名字就可以看出来,是有希望通过以太网去注入CAN消息到CANBus上面。
这个逆向看起来非常复杂,中间我们也遇到了一些坑,是很多团队协作的工作。从两个方向进行突破,一开始是我自己犯了一个错误,我说为什么Shell里面有一个Reset BMS,好像是一个固定参数。

从另外一个方面,确实有同一个函数使用变量,因为很难想像一个东西既从Shell进来,又从另一个接口出来。

有一个小伙伴看到了队列通信的机制,看完告诉我说,这个函数是用来发CAN消息的,当时就恍然大悟了,防止有恶意数据,所以封装了一个固定的CAN消息的包。而诊断端口本身就是发任意消息的,当然有一些后面我们会介绍。

后面从两方面终于确定诊断0X04这个接口进来,最终会发一些我们用户可控的,最后就是逆向,第一个字段是0X04一个功能号,后面是这个消息的消息ID,后面是对应的内容,就把数据一共享,感觉哪些是高危的,下面给了一个Demo。

在CID里面发给Gateway,就是这么一个命令。

但是特斯拉还是做了很多,这个东西车一旦动起来是没有办法发送的,如果你想发送,就需要把一些命令绕过。

终于我们做到了这一点,我们实现了Patch,这个Patch也是由N个漏洞组成的,他既然把这个放在身上就加了很多保护,但是最终我们确实是做到的。

这里只给一个证据,我们把它Patch之后加了一个字符串,我们其实做到了,这部分信息我们等90天之后会公开。

这里有一个简单的视频,是基于我们之前的研究,可以给大家播放一下。这个Demo结合了我们如何开后备厢的,这里面有一条CAN消息,我们其实有很多条,我们加进去,远程发送,而且Patch了Gateway,我们实际测速30公里/小时没有问题,但是我们没敢测。

大家注意一个细节,很多人认为,包括网上讨论我们这个是有作弊的嫌疑的人,很多人认为我们只是控制了这个Linux的车机,车机上有一个按钮,可以打开后备厢的。

其实他们可能是买不起特斯拉,如果他们买得起的话,真正开起来你就会发现,当车动起来之后,你要是和车机都是没有办法按这个按钮的,只有去Patch了Gateway才有可能去实现。

刚才也介绍了,我们这一部分的内容很多,介绍完之后,其实不是我们整个研究,我们整个研究有将近8个人参与,持续了三个月,还有很多跟CAN总线相关的,包括浏览器内核的集群,这些东西我们是希望90天的这个时间过完之后会公开,肯定会公开,而且会发论文。

如果大家感兴趣的话可以联系我,最后再次公布两个信息。

一个就是我们科恩实验室会持续关注车联网的研究,除了特斯拉之外,我们目前也在其他的设备上有一些可能危害人身安全的,或者可能达到高危情况的研究成果,我们会陆续公开,所以大家不要认为这是一个乐趣,我们有特斯拉,我们会持续关注于这个领域。

第二个信息就是持续关注我们需要招聘一些新的安全研究人员,大家感兴趣的话可以联系我,谢谢大家!

上一篇:Pwn2Own王宇:针对黑客比赛当中安全漏洞分析

下一篇:腾讯周斌:数据安全业务上的对抗