“最开始看到这个议题,难以理解TPMS怎么RCE,后面了解到TSLA的TPMS使用的是BLE,尝试简单分析一下这个漏洞”
总结
SYNACKTIV团队曾多次破解特斯拉汽车,这次他们通过TPMS Sensor拿下VCSEC ECU,漏洞发现和漏洞利用都非常有意思,通过这个漏洞,在2024年温哥华Pwn2own上赢下20w刀和一辆model 3。
漏洞发现的巧妙之处,就是利用数组溢出(OOB)来完成一次地址读写,覆盖一个函数指针,利用了特斯拉的auto-learning技术触发到攻击入口,完成了从1-click到0-click。
漏洞发现
-
VCSEC ECU在负责远程控制车辆、NFC解锁和TPMS。
-
VCSEC ECU的SOC是PowerPC架构的,ST的SPC56,运行VLE模式。
-
固件更新由安全网关从车载娱乐系统中获取,固件未加密。
-
软件运行在FreeRTOS上,使用蓝牙与TPMS(胎压监测系统)通信,通信信息为protobuf。
特斯拉车上有5个Sensor传感器,用于定位TPMS
VCSEC和TPMS通过GATT service进行通信,Characteristic ID:00000211-b2d1-43f0-9b88-960cebf8b91e,传输内容为Protocol Buffer序列过的数据。
标准消息示例:
// Received:
TPData {
pressure: 101
temperature: 22
}
// Received:
TPWheelUnitInfo {
TIAppCRC: "[..]"
MLXAppCRC: "[..]"
batteryVoltage_mV: 3011
}
逆向过程
大约1MB程序3千个函数、没有符号、大量结构体、回调函数和没有太多字符串
对于以上语句,每一个字我都很害怕,搞二进制的基本都害怕,不排除有夸张的成分,如果一群人看的话,逆向难度应该还好
逆向过程发现了,当传感器注册时,VCSEC会请求TPMS的证书,仅对Type5 TPMS,因为这种TPMS已经不再生产了
这个判断很好理解,就是判读你的数据大小,512数组是否可以放下,数据起始加上数据大小可以放下。
这里startIndex是可以控制的,如果为负数,那么就是对g_cert_buffer数组向前越界,通过memcpy造成一个任意地址写。
我理解的是,因为有上面的判断,所以data_size最大是512,start_index就可以是-512,因为如果两者两加为负数,就不满足这个if条件了。
但是在他们实际逆向时发现,data_size最大128,那么意思就是最多可以向前写128个字节。
合理,在g_cert_buffer前面发现了函数指针validate_subject_name,当发送有效x509证书时会触发这个函数指针。
漏洞逆向
漏洞已经非常清晰了,整数溢出去写函数指针,然后触发它,。
是时候关心它的保护机制了,没有CFI,没有ASLR,MMU/MPU未配置,所有地址RWX。
MMU内存管理单元、MPU内存保护单元,所有地址RWX
覆盖结构体指针为可控的buffer,然后执行编写好的shellcode,他们用C写的shellcode,因为C可以直接调用固件中的函数(没太理解,调用导出函数吗?)
他们写的shellcode,是VCSEC中的一个函数向CAN上发消息的
1-0 Click
漏洞需要VCSEC更换新的传感器时触发,使用UDS可以触发,但是pwn2own不同意,然后就盯上了Tesla 自动学习机制。
自动学习这个机制是为了平衡前后轮磨损的,它触发条件如下
更换新的传感器时,新传感器广播,VCSEC会尝试建立连接
-
-
-
-
VCSEC连接TPMS(仅连接注册过的MAC地址)
这时他们想伪造一个传感器,因为除了需要验证MAC地址,没有其他安全措施。
这时构造一个假的的传感器用注册的MAC地址发送广播,VCSEC就会连接到假的传感器,并且接受假消息,如胎压和温度。但是还是没有触发漏洞所在地,TPMS的adoption phase
只要能Dos一个传感器就可以触发漏洞,在VCSEC激活传感器前连接它,通过干扰信号
在自动学习期间,断掉一个传感器,允许注册一个任意新的传感器
第一次尝试用的BlueZ(linux主要用的蓝牙栈)但是它太慢了
第一块ESP32自动连接VCSEC的BLE,速度挺高的,第二块模拟TPMS
切换TPMS到我们模拟的ESP32时,成功触发漏洞
结论
大佬说多尝试独立的ECU,其实就是没经过时间检验的ECU是软柿子,这个VCSEC是特斯拉自己实现的
对此我想说,这他妈才是黑客,而不是像我一样,IDA打开没有命令注入下班。
配合视频食用更佳
原文始发于微信公众号(安全脉脉):TESLA TPMS-RCE(0-click)