此篇文章发布距今已超过355天,您需要注意文章的内容或图片是否可用!
车联网安全的门槛这么高,如果有一个汽车可以直接装在自己电脑上该多好啊?你是否想过这个问题呢?没错,我们做到了。本次议题介绍我们深入研究汽车虚拟化技术的过程,在这个过程中,可以看到我们突破了技术难点,基于主机与CAN网络的虚拟化,规划了较为合理的虚拟汽车架构,形成了非常真实的虚拟汽车系统。在这个系统下,我们对虚拟汽车进行了攻击、固件仿真、产品测试等多个场景。同时,本次议题还将介绍我们在实物研究方面的经验,与虚拟化一起,介绍虚实结合的一些关键点。下面就让我们来回顾看雪·第七届安全开发者峰会(2023 SDC)上《虚虚实实——深入研究汽车虚拟化技术》的精彩内容。
上海市车联网协会特聘专家,研究方向为物联网与车联网安全攻防、创新产品孵化及落地。在第五届“强网”拟态防御国际精英挑战赛、2021智能网联汽车安全测评技能大赛等多个车联网安全大赛中荣获第一名、一等奖等成绩。
以下为速记全文:
大家好,我是绿盟科技的张克雷。今天的议题是汽车的虚拟化技术,他能降低大家的研究成本,我们愿意分享出来,希望能助力整个车联网安全行业蓬勃发展。核心内容有6大块,因为虚拟化这东西比较玄,所以尽可能的说大白话,让大家都能理解。第一个就是说它难在哪,这个问题等我讲完所有内容以后,大家心里才有底。第二就是说我们怎么做虚拟化的技术验证,会花费将近2/3的篇幅来给大家公开这个技术。第三就是如何基于这一套虚拟化技术,形成一个比较合理的或非常合理的虚拟化的汽车系统。第四,我们对这一套虚拟化的汽车系统进行攻击,基于它做一些仿真,然后再去做一些产品测试,最后它的效果怎么样。第五个就是还有一些虚实结合的东西,我们说一说自己的理解。第六,有没有另外的玩法,就把它玩起来可能会更让大家的研究会更有趣一点。这里有些名词,比如说电气架构,它就是一个汽车行业的名词,他说的是啥?就是汽车各个零部件应该怎么连的问题,怎么连能降低大家成本,这是一个方面。架构有两种,一种是功能域分布型,另外一种叫中央计算型。像右边这个图就是一个功能域,它有很多功能域,左下角域控制器网络。这个叫CAN总线,它设计之初就是为了把车所有的单片机类的设备连起来,因为90年代那个时候大部分控制器都是单片机的,很少有Linux的,现在不一样了,现在那些T-box、车机、下面ADAS也是Linux,还有很多零件,包括车身,整车有的它也会是Linux,面对这么多操作系统,零部件,仿真这么庞大的一个汽车系统,我们怎么实现它的虚拟化呢?刚才我们说一辆车分很多功能域,是我们在网上看到的或学到的。但是在真车上不见得是这么用的,实际车里网络会更复杂一些。总结一下三点,第一点就是级别越低,它可能越简单,然后反之越复杂,这个复杂就体现在一个种类,还有数量的多和全。第二我们应用时会有取舍,比如说甚至整个域都会没了,把两个域连在一起,作为一条域。从车身域打进去,甚至都可能控制整车的动力。第三,实车零部件的集成情况不一,比如说中央网关T-box,还有车身,还有VCU这种,它可能会集中在一个零部件上。以上会为车辆安全带来一些成本上的压力,成本不光是钱,还有我们自身的学习和理解上,所以说按照我们以往的想法,买一辆车确实可以解决有无,买多辆车确实可以凑齐电气架构,但是无论对于我们个人还是企业来说,它都是成本非常巨大的,这个时候我们就会想有没有一个汽车直接装在我们电脑上,我们就可以很低成本地开始研究了。为了解决这个问题,我们按照这4个思路往下去讲,第一个就是说我们要想一想我们需要的到底是什么,真的是一整辆车吗?右边那个图是整车所有的零部件,保时捷的,我们真的需要一整辆车在路上跑着我们测吗?其实是有一些关键零部件就好了,一堆运行着的零部件足够解决我们的环境问题。第二,高端的车100多个零部件,我们都把它买回来吗?如果说买全新的可能比整车的成本都要高了。这个时候我们会想有一个网关,再就是几个关键域控和下面的响应设备。比如说车门车锁,我们把它买回来。如果是想研究车门车锁,甚至防盗,这一套就够了。第三,精简后的架构是不是跟我们高端车架构不一样?这块零件都买回来了,想怎么连就怎么连了。比如说研究a车系的,就按a车系来连,研究b车去就按照b车去连,到这里很多人都能解决这个问题,但是再缩小成本缩不下去,原因就是虚拟化解决不了。接下来我主要给大家解决两个问题,一个就是建一个小型的CAN网络,第二个就是说以安卓和Linux主机的形式,把它接到CAN网络里面去,重点的内容就是怎么做的虚拟化技术验证。两个目标,一个是构建一个虚拟化的CAN网络,第二个就是基于安卓和Linux这种虚拟主机,实现CAN网络的互通,立一个小目标,做3个域,1个信息域,1个是ADAS,1个是动力域,4个零部件,分别是T-box、车机、ADAS,还有整车控制器。T-box是干嘛的?我们以前3G时代笔记本电脑上不了网,我们有时候会在运营商买一个USB的上网卡,有流量的,他电脑上能上网,卡是给电脑上网用的, T-box跟那个是一样的,就是给车上网用的。我们对每一个目标梳理一下现状,可能就解决问题了,然后解决不了的我们突破未知。先构建一个虚拟化的网络。提一个问题,我们的主机刚买回来,他没有办法进行CAN通信,我相信大家买主机的时候没有一个销售说我们这个支持CAN网络对吧?那需要怎么解决呢?一般的解决方式就是把我们主机已有的接口换成CAN网络,这种叫转换器,以往叫协议转换器,有的也叫CAN分析仪。比如说第一个是把CAN网络转成USB口,插电脑上就可以了。第二个把它转成网口,对于电脑上来说它就是一个网络适配器。第三个,它也是个USB,好处是它支持SocketCAN。那对第一个而言,我们进程a或者是软件a用了那个设备以后,软件b就打不开了,不能并发,SocketCAN就是把它并发掉,许多进程都可以同时用它收发,这是一个好处,所以我们研究SocketCAN。我们怎么去创建一个SocketCAN网络?有这么三步,加载虚拟的CAN驱动,创建CAN接口,然后把它启起来,这样一个网络就生成了。这就是一个SocketCAN接口,我们创建三条,下边三条就有了。那问题是他们仨怎么互联,上面那一条命令cannelloni,是开源的,大家可以编译自己装上,装完了以后可以把vcan0接口上所有的数据从本地的local port转发到远程主机的一个remote port。相当于我在两个主机之间进行通信。通信的啥内容?是利用的udp协议转发的CAN总线数据。网关内、这个方式是可以的,比如说我们把remote ip跟local ip全都整成127.0.0.1,然后在主机内转发可以做到网关内的CAN域数据转发,但是零部件之间转发不行,因为真车里面不是这么做的。两个零部件的IP不会暴露这样的端口去传CAN数据,因为它就是实线连起来的,我们怎么把它给虚拟化出来呢?先停一停,现在我们已经做好了网关。我们依靠现有的技术以及现成的资源就把它做好了。接下来我们去虚拟化ECU。ECU有两类,一个是Linux,一个是安卓,对于每一类,我们都梳理现状、突破未知。虚拟化软件我们怎么挑的?Qemu,很基础的一个软件,大家都会用,它支持arm的32或64位的CPU,我们利用它去启动一些操作系统,就可以实现跟实车一样,比如实车是arm的,我们也是arm的。安卓官网说支持Android for cars,这个时候我们用安卓Emulator,这个是安卓官方的一个虚拟化软件,大家编译完以后自己运行emulator,它就会出来一个虚拟的界面,虚拟化一个安卓的设备。先说 Linux,实物主机可以接PCICAN卡实现CAN总线的通信。我们想一想,我们现在主机换成了虚拟主机了,我们的卡是不是也要变成虚拟的?10年前有一个大佬,实现了这件事。他就把 PCI的卡给虚拟化了,给qemu来用,怎么用呢?左上角那3行,这个是啥意思呢?比如说我用qemu起一个Linux虚拟机对吧?第一个是我给他加CAN接口。第二我在这CAN接口上用接什么设备,用kvaser_pci这个虚拟化的设备来连接接口。前两行命令是什么意思?就相当于我们买了一个PCI的CAN卡插到我们主机上,就相当于干了这个事儿,那问题来了,插在主机上,它怎么跟外面通信,怎么跟外面连。第三个,如果说我的主机也有一条SocketCAN接口,比如我们刚才vcan0,我们把 if=can0改成if=vcan0,就可以把刚才虚拟的主机Linux通过CAN总线连到我们的主机上来。起ARM虚拟机的时候,比如下面这条命令,用qemu-system-arm来起一个Linux虚拟机机,把三个参数加上,就相当于完成了这一个连接,按理来说我们的主机跟虚拟机之间就可以进行CAN的通信了。我们选择一些很基础的素材,比如说BUSYBOX,然后随便选了个内核4.19.104,因为他那个年代是2013年的,所以我们随便选了一个2020年,大于2013应该就可以,下面选一个2019年的交叉编译器,我们把BUSYBOX、内核、文件系统用交叉编译器编译出来,然后利用编译器的配套的一个文件系统,构建一个我们自己的文件系统,生成了这么一个Linux把它跑起来了,这个很简单,按照之前的命令来跑就得了。但是有个问题,我们自己在一台主机上创建一个虚拟的CAN,它会出来一CAN接口对吧?
vcan0、vcan1、vcan2这种。但是我们发现虚拟linux中没有,这个时候就会出现一些疑问。我明明已经把三个参数加进去了,但是它没有出现。然后我们在里面lspci,看下面有没有PCI设备的时候,发现它出现了。PCI设备插入了,说明内核不认识这个设备,我们内核不支持,解决思路有两个,我们找一个支持的,或者说我们自己编一个把驱动加进去。我们选择第二种,内核的编译过程就是先make menuconfig参数来去定制它内核的一些参数,比如说我去加载一些驱动进去,然后再make生成内核文件。驱动2013年度已经实现了,肯定在内核里面,找就完了。这些框全打勾就可以了。我们启动完了以后,can0就出现了。虽然很简单就实现了,但是不要高兴太早,因为它起arm虚拟机的时候用的主板只支持arm32位的,它不支持64位的处理器。大部分处理器都是64位的,怎么让它支持64位呢?最终我们测试发现,它有一个标准的虚拟化的主板叫VIRT,我们测试了一下,用virt-2.x是可以的,但是virt-3/4/5/6/7启动后没有can0,这个问题留给大家去解决。肯定是可以解决的,我没有深究。用qemu-system-aarch64把它启起来以后,它就是64位架构的,起起来以后它有一个can0说明是支持的,当然它不支持virt-3/4/5/6/7没关系,因为尽管如此,依旧很好。基于此,我们做好了Linux ECU的一个底座。我们需要编一下内核,然后根据VCU、T-box ADAS仪表网关这种零件类型,我们去给他定制文件系统。定制一些应用在里面,实现CAN的数据交互,这样能做好我们自己的零部件了。暂且放下,我们先去看看安卓系统是怎么使能CAN总线的。对于安卓而言,源码中说它包含一个Android for Cars。我们把安卓的代码下载下来,然后按照编官网的方式来把它编译,编译完了以后运行 emulator,确实可以启动一个安卓的操作系统,启动安卓的操作系统它没有任何参数,只有一个emulator。之前我们启动Linux的时候用了三个参数,使虚拟化的Linux支持CAN总线通信。按理来说,我们让安卓具备CAN总线通信功能的话,我们也得把这个参数加进去,我们查了官网,emulator 有个-qemu选项,把三个参数摆上去,就相当于做了之前的插入CAN虚拟网卡的操作。那我们用这三个参数启动Android。但是,得到的效果跟之前一样,它还是lspci下面有设备,但是ip addr中没有 SocketCAN那个接口,怎么办?我们就按照之前的解决方式来了一遍,我们找了一下官网内核怎么来编译,按理来说我们可以编译、定制内核。我们看下官网的流程,它会有一个build.sh一个脚本,按它脚本构建下来,一个标准的安卓内核就生成了,因为我们要定制它,所以我们还得找menuconfig,于是,我们在它的源码的目录下面翻到一个config.sh,直接运行,不加任何参数,就是menu configure,运行后menuconfig的界面就出来了,这就是我们想要的,我们需要这样一个界面去定制它的内核,把相应的接口SJ1000就是 kvser它的一个驱动,本质上的一个驱动,把它们都打开,打开完了以后我们再去编译安卓内核。但发现安卓依旧启动失败了。我们起安卓操作系统起了200秒还没有起来,内核里面报了一些错误。往上翻,找到一个很关键的,它识别了我插入的kviser PCI的卡,这说明什么?说明我内核编译对了,问题出现在我们不懂这个内核如何给我们自己编译的安卓来用。安卓内核编译完了以后生成的两个东西,一个是bzImage,另外一个是dist,一个是文件,一个是目录。有一个网站说得把这两个产物,给编译环境来用,让你的编译环境用这两个东西来编译安卓系统。具体怎么做?就是在目录下编译一个文件,把我这两个文件还有目录给它指定了,再编译生成一个它就起来了。这样的安卓,它的内核是可以识别到CAN卡的,他启动完了以后跟我们一样也有一个can0接口。我们对can0做一些设置,比如设置他波特率是1000kbps,然后他把它起起来,在安卓里面用candump去抓包,我们在宿主就给他发包,宿主机发1233455667788,他就能收到。到此为止,我们安卓就具备了CAN通信的能力。总结一下,安卓多了一步,它不光要定制内核,还要把我们编完那些安卓内核的素材,重新给安卓的编译环境来用,重新编译完才能把它跑起来,否则内核和安卓的文件系统是不成一体的。我们再说CAN互联,Linux、安卓都能进行CAN通信了,宿主机一条命令也可以生成一条vcan网卡,这个时候我们怎么把这三个东西接进来,我们设计了一个结构,车机是安卓,adas控制器就是自动驾驶控制器,我们设置为Linux,T-box我们也设置为Linux,它分别具备CAN通信能力。每个里面都有can0。以下宿主机给他分配了3条卡,分别是接这三个虚拟化的设备。下面用emulator去启动车机,然后用qemu去启动ADAS和T-box,因为这俩都是Linux。以太网我们怎么做的呢?我们使用的桥接。任何一个虚拟化软件都是支持桥接的,我们构建了一个桥接网卡,三个主机桥接后,跟主机在一个网段,对于ADAS而言,我们在ubuntu去抓包,我们在ADAS shell中发包,我们发什么宿主机就能收到什么。下面也是,左边是T-box,右边是车机,最下面是宿主机,我们在T-box里面发,在车机里面抓包,在宿主机里面抓包,同样没有任何数据收发。到此为止,基于Linux和安卓节点互联的小型虚拟电气架构就做好了,基于它怎么形成一个虚拟的比较合理的汽车系统?既然是虚拟的汽车,还得有车。右边就是汽车的样子,它可以开车门开车灯,怎么才能支持开关车门的操作呢?我现在只有左下角所示可以发CAN报文的虚拟零部件。我们给它加了一个显卡,上面走unity3D把汽车的模子和路做好,现在只剩下了汽车怎么来控制。按理来说我们车是谁来控制?是汽车的虚拟化零部件来控制的。所以说我们给它加上方向盘和脚踏板,USB直接接电脑上就能使用的那种,但是我们不能直接用USB的数据,因为真实环境下汽车的动力控制也不是走的USB。所以说需要USB接进来了以后把它转成CAN通信,把CAN转到虚拟化零部件里面去。零部件发给前端的Unity3D,控制汽车的动力以及转向,比如说能开车门,踩油门控制它驾驶。整车的这么一个内部环境构造好了以后,我们一个整车的虚拟化环境也就做完了。车外的还有远程控制系统,APP小程序、安全云平台是绿盟的,具体就不给大家再做介绍了,大家自己实现一个ok就完了。还有个关键的地方,是方向盘的编码我们怎么做的。我们没有纠结方向盘的控制,到底是使用Python脚本,还是说是Linux C语言,其实本质上都是一样的,我们暂且用Python来去实现。宿主机上有一个can0网卡,我们把方向盘和脚踏板通过USB然后读出来,使用一个Python脚本,读完以后发到CAN总线上去。是发给谁?发给Linux的VCU,也就是整车控制器,他有控制转向和动力的能力。先用一个脚本将方向盘数据放到CAN数据报文中,比如设置其帧ID为0x123,数据字段包含8个字节,足以将方向盘和脚踏板的数据承载。最后我们设置PCU将CAN报文翻译为汽车的控制信号,比如方向、速度、刹车等等给到Unity3D的前端。到此为止,我们做好了方向盘,基本一辆车就可以驾驶了。小程序和云服务这些也很简单。大家梳理清楚相关业务以后自己做就可以。需要突破的难点,到此为止,基本上都解决了。我们看看它的攻击、仿真以及测试的效果.这个是个攻击的,右上角有一个攻击者,控制你的汽车,驾驶员利用方向盘驾驶。方向盘连接到宿主机上以后,通过刚才给大家介绍的网络去控制整辆汽车,它的数据流是方向盘的数据到了CAN1上,然后到了VCU上,最后就到了3D车路上,车就动起来了。而攻击者是利用一个路由器接进去了,路由器仿真的是一辆汽车的热点。因为里面都是做桥接的,所以每一个零部件的IP,攻击者都可以扫描到,这个是跟真车基本一致,有的可能会有一些网络层级,不在一个网段,但热点始终是在最底层,往上扫都是能扫到的,我们直接做桥接,不影响攻击效果。对于T-box、VCU和车机而言,攻击者如果是一个非常熟悉车联网安全的人,他会直接打VCU,因为VCU可以控车,这个时候他打进去以后会怎么做呢?他可以扫描主机,比如说我们用nmap在里面扫,可以扫描到一些IP存活。第二个是可以对每个IP进行端口扫描,扫描以后发现开了23端口,是telnet。然后还有另外一个主机,比如说91.190,我们扫到了4个5端口,5555端口就是安卓的APP服务.然后我们连接adb,运行adb root,就能获取root权限,这是一个标准的安卓的车机。下边密码爆破的是telnet。我设置的密码是root:111111。确实爆破到了弱口令。我们用现有的攻击工具像打一台主机一样打这个汽车零部件,真车也是怎么做的,我们这个虚拟化就怎么设计。所以说获取完权限以后,你基本上在里面都能控车了,比如下面那车机空调你通过APP拿到权限以后,你可以控制应用任何的显示,甚至是操作,你可以远程控制它点屏幕,都没有问题。第二就是固件的仿真,我们现在有一个实测的应用叫mv_app。我们想把它放到我们的虚拟汽车里面去运行,可不可以?可以,它原先监听两个端口,我们运行完了以后,它也会监听两个端口,怎么做的?就是把整个文件系统丢进去,运行chroot后运行应用就可以了。也就是我在我的汽车环境下切成了对方的汽车环境去运行它,就不会存在很多问题。它还会用到SocketCAN通信,这跟我们是一样的,我们给ADAS零部件插入多张虚拟网卡,mv_app会设置can1并启动can1接口收发报文,比如设置它波特率是500k,能接收到CAN数据包,证明把其他汽车的CAN应用业务也跑起来了。比较有趣的是什么呢?我们把can0和can1接起来,这个时候我们在车机里面抓包,能抓到他的发的包,mv_app发的包是010c报文,可见,确实能实现模拟汽车的业务。绿盟是做安全厂商的,会有一些车载的产品,比如车载的IDPS,我们也把它放上去做了一些测试。比如说,检测攻击它有一套规则去检测,我们提前写好了攻击手段相应的规则,然后让IDPS去应用规则后,我们攻击零部件,后来他就识别到了我的几条命令注入的攻击行为,最后在云平台上也能看到这两个攻击的记录。虚实结合,怎么来做?刚才其实我们已经虚实结合了,我们方向盘是实的,但我们整车是虚的,我们方向盘如果不做实的,我们就拿键盘,这样看起来更虚一点,但是方向盘体验会更好,这也不是很重要。基于现实还有超越现实这两方面都可以去做虚实结合,比如基于现实,我们虚拟化一辆现在的车辆,虚拟化解决不了的业务问题,我们接实物,比如说一条总线一条总线地把它连起来,这样可以解决现阶段汽车很复杂的业务上的虚拟化。对于现阶段不成熟的技术而言,比如说自动驾驶和车路协同,现在没有一家厂商敢说我车可以完美支持自动驾驶,在这样的背景下,如果一定要基于实车做前沿技术研究,显然会受限于行业发展。但是你可以在里面做一些虚实结合,提前做一些实验,比如说提前做攻防,提前做研究,提前发论文都可以。车路协同必然会落地,因为它涉及到国家的交通建设,现在没有做,只不过是基础设施不完全,还有技术不成熟。在这种情况下我们怎么去研究它的安全?车路协同有一些开源项目,比如openv2x,也可以接到里面去,都是没有问题的,大家可以去关注一下。如果说大家想做一个非常全面的汽车靶场,甚至车联网靶场,虚实结合必然是其中的特点之一,否则肯定是业务不全的。然后怎么来连,很简单,80块钱的一个USBCAN卡,把它接上去,就可以把其中一个功能域进行虚实互联。多功能域之间如果隔离的话,你就分着连这样会很简单。现在虚的我们也能搞,那实的也能搞,问题就是说我们实什么虚什么,研究员或者企业把这个问题想清楚以后,才能说虚实结合应该怎么来做。这个问题留给大家,每个人目的不一样,每人实现的方法也不一样,比较灵活。那有没有另外的玩法?刚才我们把方向盘放到CAN总线上去了,现在我们把它接到游戏上去。就这个事能解决什么问题?刚才3D的车路UI是绿盟做的,就管它叫绿盟号,绿盟号的车比如说我叫张克雷,我在绿盟,我能用而大家不能用,怎么办呢?我用极品飞车就好了,对不对?我把方向盘的数据放CAN总线上,数据再返回到Windows下,模拟一个方向盘出来,大不了再把它的按键映射回来就可以了。这样实现的是什么呢?我方向盘的信号既可以在CAN总线上发,它又可以接入现在的游戏,相对来说就比较自由了,大家不必局限于这个绿盟的3D界面怎么没开源之类的,我觉得接一个游戏会更自由一点,甚至接到steam里面开飞机也是可以的。飞机坦克也是按键控制,你炸星球都可以,这个想象空间可能会比较大,因为我们做的东西会比较基础,所以说较好的兼容性相对来说会有利于大家去做一些定制。最后谈一些感受。关于虚拟化,我们不是做的最好的一个,可能会有更合适更便捷的方式,欢迎大家分享。如果安卓想支持的话,谷歌直接启用默认的驱动就完了,它在编译内核的时候,把选项默认打开不就完了吗?很简单。本次议题更想帮助那些想了解想学习车联网安全,但是局限于没有一个环境的人,建立一个很低成本的环境,然后去学习,希望帮助高校去建立车联网专业,然后做一些车联网安全的课程。汽车它是一个支柱产业,现在汽车量应该是达到亿级别了,我们深信车联网安全绝对不只是我们现在能看到的这些,我一直认为车辆安全现在最多只是花苞阶段。我们希望越来越多的人都懂一些车联网安全的知识,甚至拿自己的车练练手。现在做车联网安全的黑客加起来可能不到100个,但是2023年网络安全相关专业的毕业人数规模就在3.2万左右,想象一下这些人都去做车联网安全,整个车联网安全行业会怎么发展,这个是很难估量的。本次演讲就给大家分享这些。如果大家认为汽车虚拟化实现起来没那么难,就弄一下内核、搞一下文件系统、再编译一下,那说明我的演讲就成功了。谢谢大家。*峰会议题PPT及回放视频已上传至【看雪课程】https://www.kanxue.com/book-leaflet-171.htm
PPT及回放视频对【未购票者收费】;
【已购票的参会人员免费】:我方已通过短信将“兑换码”发至手机,按提示兑换即可~
《看雪2023 SDC》
看雪安全开发者峰会(Security Development Conference,简称SDC)由拥有23年悠久历史的顶尖安全技术综合网站——看雪主办,面向开发者、安全人员及高端技术从业人员,是国内开发者与安全人才的年度盛事。自2017年七月份开始举办第一届峰会以来,SDC始终秉持“技术与干货”的原则,致力于建立一个多领域、多维度的高端安全交流平台,推动互联网安全行业的快速成长。
推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……
宙飒天下网
还没有评论,来说两句吧...