汽车安全入门 01|汽车总线协议全景:CAN/LIN/FlexRay/以太网,红队先搞懂’它怎么说话’

导语:从 Miller 和 Valasek 在 DEFCON 23 上远程把 Jeep Cherokee 干趴下,到腾讯科恩在 Black Hat 2017 把 Tesla 从 Wi-Fi 一路打到 CAN 总线,所有车载攻击最终都要回到”总线”这条终点线。搞懂总线协议,是车安全研究的入场券。今天我们把 4 大总线一次性梳理清楚。


一、为什么先讲总线?

攻击车的链路再花哨——Wi-Fi 破解、蓝牙 fuzz、OBD-II 物理接入——目的都只有一个:在总线上塞进你自己造的 CAN 帧。只要帧能塞进去,方向盘、刹车、油门、灯光就全是你的。

所以车安全研究的第一道分水岭就是:你能不能看懂总线上跑的帧。


二、4 大总线速览

总线速率主要场景攻击价值
CAN(控制器局域网)125 kbps – 1 Mbps(CAN FD 可达 5 Mbps)动力总成、车身电子、底盘⭐⭐⭐⭐⭐ 最核心,几乎所有车型都跑 CAN
LIN(局域互联网络)19.2 kbps车门、座椅、镜面等低成本节点⭐⭐ 进不去 CAN 时横向打到 LIN
FlexRay1 – 10 Mbps线控驾驶(X-by-Wire)、ADAS⭐⭐⭐ 高端车型才有,攻破后影响转向/制动
Automotive Ethernet(100BASE-T1 / 1000BASE-T1)100 Mbps – 1 GbpsADAS、自动驾驶、信息娱乐⭐⭐⭐⭐ 数据量大,攻击面更复杂

入门阶段主要啃 CAN。剩下三个知道定位就行,遇到了再深挖。

2.1 CAN vs CAN FD

传统 CAN(Classical CAN)数据场最多 8 字节,2012 年 Bosch 推出 CAN FD(Flexible Data-Rate)把上限提到 64 字节,并且仲裁段用原速、数据段可以提速到 5 Mbps。2010s 后的新车基本都跑 CAN FD,2015 年后 CAN XL(速率 10 Mbps+)开始上车。

红队注意:candump 默认按 8 字节解析 CAN FD 帧会显示错位,看到 hexdump 长度异常就要切换工具(如 candump -L vcan0 或专用 CAN FD 监听器)。

CAN 帧结构示意图

三、CAN 总线的两件大事

3.1 帧结构(Data Frame)

标准 CAN 帧长这样(最常见的 11-bit ID 数据帧):

仲裁场(11 bit ID + RTR)| 控制场(DLC)| 数据场(0-8 byte)| CRC | ACK

具体到一帧 ID=0x123 的数据帧,hex dump 看起来像这样:

123 08 11 22 33 44 55 66 77
│  │  └─────────────────┘
│  └── DLC = 8 字节
└──── ID = 0x123

红队视角:拿到这一串 hex,能不能反推出是车速、油门、还是方向盘转角?这就要看 DBC 文件(CAN 数据库)——后面讲工具时再细聊。

3.2 仲裁机制——为什么攻击者能”插嘴”

CAN 总线是多主异步结构,没有中央仲裁器。谁的 ID 越小,谁就赢总线(线与逻辑,0 占主导)。举个例子:

  • ECU_A 发 ID=0x100(仲裁场显性位更多)
  • ECU_B 发 ID=0x200

A 发出后总线电平被拉低,B 检测到总线电平和自己发的不一致,立刻主动退让,让 A 继续。这就是为什么 ID 越小优先级越高。

攻击启示:你只要造一帧 ID 比正常 ECU 都小的帧,就能”挤掉”原车的正常通信。这是 CAN 注入攻击最直接的物理基础。

CAN 总线仲裁机制示意图

3.3 经典攻击演示

插一帧伪造的车速指令,伪代码长这样:

import can

bus = can.interface.Bus('socketcan', channel='vcan0', bitrate=500000)
msg = can.Message(
    arbitration_id=0x123,            # 比目标 ECU 的 ID 略小
    data=[0x00, 0x00, 0xFF, 0xFF, 0, 0, 0, 0],
    is_extended_id=False
)
bus.send(msg)
print("伪造车速帧已发出")

是不是很简单?前提是先嗅探到总线(用下一讲会讲的硬件)拿到一帧样本,照葫芦画瓢改几个字节。


四、在 Linux 上接入 CAN

嵌入式玩家用 SocketCAN,桌面玩家直接装 can-utils 就行:

# Ubuntu / Kali
sudo apt install can-utils

# 加载内核模块
sudo modprobe can
sudo modprobe can_raw
sudo modprobe vcan                  # 虚拟 CAN(没硬件先玩这个)

# 创建一个 vcan 接口
sudo ip link add dev vcan0 type vcan
sudo ip link set up vcan0

# 实时监听
candump vcan0

# 周期发帧
cangen vcan0 -I 123 -D 1122334455667788 -L 10

跑通这两行命令,你就有了”没硬件也能练手”的实验环境。下一讲会用真硬件(CANtact / Macchina M2)替换掉 vcan0。

更进阶的命令:

# 只看特定 ID 的帧
candump vcan0 | grep "123#"

# 高亮变化的字节位(肉眼看哪个字节在动)
cansniffer vcan0 -c

# 发送自定义帧(一帧)
cansend vcan0 123#1122334455667788

# 录制 + 回放
candump -L vcan0 > traffic.log
canplayer -I traffic.log vcan0

cansniffer 这个工具特别值得玩——它把每个字节按”是否变化”用颜色高亮,肉眼就能找到哪个字节是”油门、刹车、方向盘转角”这类活跃信号。这是后面 Python 工具链的基础。


五、防御视角:为什么必须监控总线

CAN 是 1986 年博世发明的协议,设计时根本没考虑安全:

  • 无认证:所有节点信任所有帧
  • 无加密:明文传输
  • 无速率限制:攻击者可以高频注入

后果是:车内任何一个节点被攻破(OBD-II 接入 / Wi-Fi 网关沦陷),都能往 CAN 塞恶意帧。车企的防御只能靠后置的 IDS(入侵检测系统):

  • 监测总线流量频率异常
  • 识别”从未出现过的 ID”
  • 校验信号物理特性(电压、时间间隔)

这就把我们引向第 14 讲(CAN IDS + ROAD 数据集)。


六、真实攻击链示例(Jeep 2015 简化版)

为了让你对总线在攻击里的位置有体感,列一个简化版的 Jeep 攻击链路:

远程入口:Sprint 蜂窝网络 → Uconnect 头单元(Harman OMAP 芯片)
  ↓
漏洞利用:D-Bus 服务端口 6667 未授权访问 → 重刷固件
  ↓
植入代码:通过 UART 把攻击者的 MCU 桥接到 CAN 总线
  ↓
总线操作:伪造 ID=0x006 的车身控制帧 → 改变方向盘助力、刹车、油门显示
  ↓
物理后果:Miller/Valasek 在 DEFCON 现场让 Jeep 在高速上抛锚

可以看到,真正的”杀伤性指令”全在 CAN 那一步。前面 4 步只是给攻击者一个”上车的机会”。所以做 IDS、做防御,重点监控的就是最后这段。第 8 讲我们会完整复盘这条链路。


七、思考题(引下一讲)

  1. 你拿到一帧 0x100 08 AA BB CC DD EE FF 00,怎么判断它是车速、油门、还是其他信号?
  2. 如果车上跑了 CAN FD(可变数据长度 0-64 byte),普通 candump 工具还能直接看吗?
  3. 想嗅探真实车辆总线,但 OBD-II 接口在发动机舱深处——有什么硬件方案能”贴”到 OBD-II?

八、本期素材出处

本讲涉及的 awesome-vehicle-security 资源:

  • #138 OpenXC(http://openxcplatform.com/hardware.html)—— 福特开源的车载数据接口,理解 CAN 信号 → 物理量的范例
  • #161 SocketCAN Utils(https://github.com/linux-can/can-utils)—— Linux 原生 CAN 工具集,本讲所有命令都来自这里
  • #170 Caring Caribou(https://github.com/CaringCaribou/caringcaribou/)—— 业内常说的”车安全的 nmap”,下讲会演示它的 12 个模块

© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容