2023 SDC 议题回顾 | 虚虚实实——深入研究汽车虚拟化技术
2023-12-4 18:0:37 Author: mp.weixin.qq.com(查看原文) 阅读量:10 收藏

02

演讲内容

以下为速记全文:

大家好,我是绿盟科技的张克雷。今天的议题是汽车的虚拟化技术,他能降低大家的研究成本,我们愿意分享出来,希望能助力整个车联网安全行业蓬勃发展。
核心内容有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始终秉持“技术与干货”的原则,致力于建立一个多领域、多维度的高端安全交流平台,推动互联网安全行业的快速成长。
钻石合作伙伴
黄金合作伙伴

球分享

球点赞

球在看

点击阅读原文查看更多


文章来源: https://mp.weixin.qq.com/s?__biz=MjM5NTc2MDYxMw==&mid=2458530163&idx=1&sn=17145f8cf9a17271c2b749fd74f8a5ac&chksm=b18d01f986fa88ef96fd0f93a45000fe68f83475c8c4b2d49a17014a0425c7312c9ec8c2dcf9&scene=58&subscene=0#rd
如有侵权请联系:admin#unsafe.sh