一、车联网下的CAN总线
汽车车内CAN总线网络安全分析及防御措施智能化和信息化的发展,汽车电气系统变得日益复杂,当前汽车普遍拥有数十个电子控制单元(ECU),一辆高级轿车运行代码接近1亿行,而这些车载信息是通过车内总线实现互联。近年来汽车信息安全事件的频发大多是基于车内总线的物理访问或者远程攻击,攻击者可以通过车载ECU自身漏洞,实现对关键节点的输入控制,如汽车节气门、转向器、制动器等。在汽车总线中,控制器局域网(CAN)因其高性能和可靠性被大量应用。为保护汽车总线免受网络攻击,基于CAN网络分析的相关技术解决方案逐渐引起行业的关注和重视,同时在考虑成本和应用等方面,企业已将开始着手现有汽车零部件产品的安全升级。
二、汽车CAN网络安全综述
CAN网络是由以研发和生产汽车电子产品著称的德国BOSCH公司开发的,并最终成为国际标准(ISO 11898),是国际上应用最广泛的现场总线之一。CAN总线协议目前已经成为汽车计算机控制系统和嵌入式工业控制局域网的标准总线,同时也是车载ECU之间通信的主要总线。当前市场上的汽车至少拥有一个CAN网络,作为嵌入式系统之间互联的主干网进行车内信息的交互和共享。
CAN总线的短帧数据结构、非破坏性总线仲裁技术、灵活的通讯方式等特点能够满足汽车实时性和可靠性的要求,但同时也带来了系列安全隐患,如广播消息易被监听,基于优先级的仲裁机制易遭受攻击,无源地址域和无认证域无法区分消息来源等问题。特别是在汽车网联化大力发展的背景下,车内网络攻击更是成为汽车信息安全问题发生的源头,CAN总线网络安全分析逐渐成为行业安全专家聚焦点。如2013年9月DEF CON黑客大会上,黑客演示了从OBD-II控制福特翼虎、丰田普锐斯两款车型实现方向盘转向、刹车制动、油门加速、仪表盘显示等动作。汽车车内CAN网络安全问题当前主要通过安全漏洞的分析和各种攻击手段进行挖掘,因为汽车车内网络安全的脆弱性和威胁模型的分析尤为关键。
三、如何去逆向CAN总线协议
如何去逆向工程CAN总线?首先能够读CAN数据包,然后区分数据包是控制什么的,这就是说我们不需要访问标准的诊断CAN数据包,因为这些是仅仅只读的数据,我们感兴趣的访问其他所有的在CAN总线数据包。其他的非诊断数据包才是被用来执行相关动作的。
我们花了很长时间,抓取这些数据包中的信息,这些信息是关键的帮助我们理解汽车的行为。
注意:如果汽车关闭,CAN总线通常是静默状态,但是如果插入车钥匙,打开车门,这些操作会唤醒汽车,同信号产生。
四、工欲善其事,必先利其器
首先,需要知道总线通信的类型,我们经常想要去识别某些信号或者某些组件的通信方式。例如:汽车怎么解锁,动力系统是怎么样工作的。为了做这些,定位这些目标组件使用的总线,为了识别这些目的,逆向总线中的这些数据包。
为了监听总线活动,需要一个设备能监听并且能发送CAN数据包。市场上有成吨的这样设备。最便宜的OBD2设备,只需要几十块钱,但是这些设备嗅探速度很慢,还经常丢失数据。最好的方式尽可能拥有一个开源的设备,因为它们能兼容大部分的软件工具,所以开源硬件和软件是一个理想的选择。我们会使用candump,来自can-utils工具套件
4.1、工具套件介绍:
canutils 工具包内含 5 个独立的程序:canconfig、candump、canecho、cansend、cansequence。这几个程序的功能简述如下:
4.1.1、canconfig:用于配置 CAN 总线接口的参数,主要是波特率和模式。
4.1.2、candump:从 CAN 总线接口接收数据并以十六进制形式打印到标准输出,也可以输出到指定文件。
4.1.3、canecho:把从 CAN 总线接口接收到的所有数据重新发送到 CAN 总线接口。
4.1.4、cansend:往指定的 CAN 总线接口发送指定的数据。
4.1.5、cansequence:往指定的 CAN 总线接口自动重复递增数字,也可以指定接收模式并校验检查接收的递增数字。
4.2、工具使用
canutils 源码可以从以下地址下载,源码的编译依赖 libsocketcan 库,所以同时需要下载该库的源码。
https://public.pengutronix.de/software/socket-can/canutils/
http://public.pengutronix.de/software/libsocketcan/
以下以 57x 平台编译为例,具体的路径以实际情况修改。
4.2.1、加载编译环境:
# source ~/57x/ti-processor-sdk-linux-rt-am57xx-evm-04.03.00.05/linux-devkit/environment-setup
4.2.2、编译 libsocketcan 库
# tar xf libsocketcan-0.0.11.tar.bz2 # cd libsocketcan-0.0.11/ # mkdir build # ./configure --prefix=/home/jack/57x/demo/can/libsocketcan-0.0.11/build --host=arm-linux-gnueabihf # make && make install
4.2.3、编译 canutils
# tar xf canutils-4.0.6.tar.bz2 # cd canutils-4.0.6/ # make build # ./configure --prefix=/home/jack/57x/demo/can/canutils-4.0.6/build/ --host=arm-linux-gnueabihf libsocketcan_LIBS=-lsocketcan libsocketcan_LDFLAGS="/home/jack/57x/demo/can/libsocketcan-0.0.11/build/lib" libsocketcan_CFLAGS="/home/jack/57x/demo/can/libsocketcan-0.0.11/build/include" # make && make install
生成的可执行程序在当前 build 目录下。
4.2.4、canconfig
先设置模式为停止,然后设置波特率,再启动。一般系统起来后都需要先配置 CAN,后续几个程序才能正常使用。
TARGET# canconfig can0 stop TARGET# canconfig can0 bitrate 125000 TARGET# canconfig can0 start
4.2.5、candump
指定 CAN 接口即可开始接收。这里与 cansend 程序的结合使用,板卡上的 CAN0 和 CAN1 使用连接线进行了对接。
TARGET# candump can1
candump can1 &
'1' cansend can1
下图中 send 发出一个 ‘1’,dump 收到了两个,第一个是 send 到 can1 时第一次直接 dump 了出来,第二个是 ‘1’通过外部连接线发送到了 can0,被 echo 接收然后往 can0 发出去,通过连接线发送到了 can1,此时再次被 dump 出来。
4.2.6、cansend
往指定接口发送数据。这里与 candump 程序的结合使用。
'1' cansend can0
4.2.7、cansequence
以下演示向一个接口发送递增序列,从另一个接口接收并校验。当波特率 125000 时,可以看到有误码情况,降低波特率后就正常了。
基于该工具的源码进行对 CAN 的学习,尤其是学习 Linux 下的 socket CAN 编程,是一个不错的办法。主要是 6 个文件,5 个程序对应 5 个 C 源码文件,以及一个 libsocketcan 库的源码文件。
4.2.8、记录和回放
使用记录和回放,下一步是记录核和回放数据包,便于分析。我们使用canutils工具。
Canutils工具使用一个简单ASCII格式,用text编辑器显示,例如:我们能记录使用candump,使用canplayer回放记录。
五、实验
5.1、发现车门解锁控制
CAN总线中有很多的噪声,就是使用一个好的嗅探工具,发现单一bit的改变还是很困难的。但是有一些通用的方法识别单一的数据包。
5.1.1、 点击记录
5.1.2、执行物理动作,比如关车门
5.1.3、停止记录
5.1.4、点击回放
5.1.5、看是否这个动作重复。例如:车门是否解锁了。
如果按下回放,车门没有解锁,这时候可能发生了几个错误。在记录的时候有可能错过了,在尝试一次记录和执行动作,如果还不能发现这个动作,这个消息很可能硬线连接到了物理的锁按钮,通常是驾驶门,尝试解锁乘客那边的车门。开门的报文可能是在其他的CAN总线上,我们需要去发现其他的CAN总线网络。
使用candump记录和使用canplayer回放日志。直到你发现了一个数据包,然后使用cansend验证哪一个字节或者bit控制目标操作。例如:
slcan0 300 [8]00 00 84 00 00 0F 00 00
现在的工作就是编辑每一个字节核回访这个命令,直到你解锁车门。
我们可以验证我们的发现用 cansend:
#00008400000F0000 cansend slcan0300
如果发送这个命令之后,车门打开了,代表着我们成功了。
本文来源于互联网:汽车计算机控制系统-CAN总线的秘密