导语:从 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 |
| FlexRay | 1 – 10 Mbps | 线控驾驶(X-by-Wire)、ADAS | ⭐⭐⭐ 高端车型才有,攻破后影响转向/制动 |
| Automotive Ethernet(100BASE-T1 / 1000BASE-T1) | 100 Mbps – 1 Gbps | ADAS、自动驾驶、信息娱乐 | ⭐⭐⭐⭐ 数据量大,攻击面更复杂 |
入门阶段主要啃 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 总线的两件大事
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 注入攻击最直接的物理基础。

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 讲我们会完整复盘这条链路。
七、思考题(引下一讲)
- 你拿到一帧
0x100 08 AA BB CC DD EE FF 00,怎么判断它是车速、油门、还是其他信号? - 如果车上跑了 CAN FD(可变数据长度 0-64 byte),普通 candump 工具还能直接看吗?
- 想嗅探真实车辆总线,但 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 个模块














暂无评论内容