汽车安全入门 06:SocketCAN 与 can-utils 工具链

导语:前三讲把 CAN 帧结构、UDS 诊断服务、攻击面建模都讲透了,第四讲给到硬件选型。但 Linux 上跑 CAN 才是真正的甜点——内核原生把 CAN 当成网络设备(netdev),candump、cansend 用起来和 tcpdump、ping 一样顺手。再配上 DBC(CAN 数据库)文件解读,一根 USB 转 CAN 线就能开测。下篇把工具链从 C 切到 Python。


一、SocketCAN:Linux 内核原生 CAN 协议栈

SocketCAN 是 Linux 内核从 2.6.25 开始引入的 CAN 协议栈,把 CAN 设备当作网络接口——ifconfig can0 看到的是和 eth0 平级的网卡,ip link set can0 up 拉起接口、ip -d link show can0 看详情,RTNETLINK(路由管理 netlink 套接字)配置比特率、采样点、FD 模式。

这套设计带来三个好处:

  • 复用网络栈基础设施 — iptables 可以过滤 CAN 帧(CAN-IDs 匹配),tc(流量控制)可以做带宽限流,Socket 编程直接 read/write
  • 统一命名空间 — 物理 CAN、USB 转 CAN、虚拟 CAN(vcan)都是 canX / vcanX,上层工具不用关心硬件差异
  • 零拷贝抓包 — SocketCAN 直接在内核环形缓冲区里分发,wireshark 都能直接 .pcapng 抓 CAN 帧

对比 tcpdump 的网络视角就懂了:

维度tcpdump (以太网)candump (SocketCAN)
接口eth0can0 / vcan0 / slcan0
帧单位packet (含 Ethernet II/ARP/IP)CAN frame (含 ID + 0-8 字节)
过滤语法BPF(伯克利包过滤器) host 1.2.3.4candump can0,7FF:7FF 掩码过滤
记录格式pcap / pcapng.log (文本) 或 .candump 二进制
实时分析wireshark / tsharkcansniffer / candump_decode

红队的最爽之处:不需要写内核驱动就能做 CAN 渗透。所有工具链的入口都在 userspace(用户态),一个 apt-get install can-utils 就能装齐。

SocketCAN 工具链总览

二、零硬件上手:vcan 虚拟 CAN 接口

Linux 内核自带 vcan(虚拟 CAN)驱动——不需要任何硬件,就能创建一对虚拟 CAN 接口互相收发。教学、单元测试、协议开发全靠它:

# 加载内核模块
sudo modprobe can
sudo modprobe vcan

# 创建虚拟接口并拉起
sudo ip link add dev vcan0 type vcan
sudo ip link set up vcan0

# 验证
ip -d link show vcan0
# 3: vcan0: <NOARP,UP,LOWER_UP> mtu 16 qdisc noqueue state UNKNOWN mode DEFAULT
#     link/can  promiscuity 0

接下来开两个终端互相发收:

# 终端 A:监听
candump vcan0

# 终端 B:发一帧
cansend vcan0 123#DEADBEEFCAFEBABE

终端 A 会立刻看到:

vcan0  123   [8]  DE AD BE EF CA FE BA BE

格式是 接口名 CAN-ID(hex) DLC 数据(hex)——CAN-ID 是仲裁 ID(11/29 位),DLC(Data Length Code)是数据长度(0-8 字节,CAN FD 可到 64 字节),后面是数据字节。

这套虚拟环境能让初学者 30 分钟内跑完协议栈,不花一分钱买硬件。


三、can-utils 工具链六件套

can-utils 包(Debian/Ubuntu 直接 apt install can-utils,源码 linux-can/can-utils)提供了 30+ 工具,按用途分四类。

3.1 显示与记录

  • candump — 实时显示、过滤、记录 CAN 帧到文件
    • candump vcan0 实时显示
    • candump -L vcan0 记录到 .log 文件
    • candump vcan0,123:7FF 只看 0x123 附近的 ID(掩码过滤)
    • candump -a -A vcan0 显示仲裁过程和时间戳

3.2 单帧发送

  • cansend — 发一帧就走
    • cansend vcan0 123#11.22.33.44.55.66.77.88 标准帧
    • cansend vcan0 18FF1234##011.22.33.44.55.66.77.88 扩展帧(29 位 ID)
    • cansend vcan0 123##0FF CAN FD 帧(## 表示 FD)

3.3 流量生成

  • cangen — 生成随机流量,做压力测试
    • cangen vcan0 -g 100 每 100ms 一帧随机帧
    • cangen vcan0 -i 0x100 -e 在固定 ID 上生成
  • cansequence — 按固定 ID 发递增 payload 的帧序列,用来验证总线稳定性和丢帧率
    • cansequence vcan0 -i 0x100

3.4 流量分析

  • cansniffer — 高阶分析工具,持续发送时显示 payload 哪些字节在变化(差异显示),哪些是常量(静态信号)。渗透测试里识别”哪些字节是计数器/状态位”必备
    • cansniffer vcan0 输出格式:123 [8] 00 1A 02 (00) (FF) (00) (3C) (00) 括号里是变化的字节

3.5 回放与重放

  • canplayer — 把 candump 录制的 .log 文件原速或变速重放到总线上
    • canplayer -I captured.log vcan0
    • canplayer -I captured.log -t 2.0 vcan0 2 倍速回放

攻击者最爱的组合:candump 录制 → 分析 → canplayer 回放。录一段门锁解锁时的 CAN 帧,过几小时回去 cansend 一下,车门就开了——这就是翻车现场的常客。

3.6 内核网关与 ISO-TP

  • cangw — 配置内核 CAN 网关,把一条 CAN 总线上的某些 ID 转发到另一条
    • cangw -A -s can0 -d can1 -X -f 7ff:7ff 把 can0 上 ID 范围 0x000-0x7FF 的帧全量转发到 can1
    • 实战场景:底盘 CAN 和车身 CAN 之间架桥,过滤特定 ID 做旁路监听
  • isotpsend / isotprecv — 第 03 讲提到的 ISO-TP 多帧传输(UDS 的传输层),按 0x27 安全访问发 Seed-Key 都靠它
  • isotpsniffer / isotpdump — 抓 ISO-TP 多帧会话并解码,比 cansniffer 更聚焦在诊断层

3.7 总线负载与位时序

  • canbusload — 实时算 CAN 总线利用率百分比,超过 70% 就要警惕丢帧风险
    • canbusload vcan0@1000000 指定比特率参数;超过 30% 算繁忙,超过 50% 临界
  • can-calc-bit-timing — 给定时钟频率和目标比特率,算出最优的 tq / prop-seg / phase-seg1 / phase-seg2 组合,比 ip link set 手动算省事
  • canerrsim — 在总线空闲时人为注入错误帧,用来测试 ECU 的错误处理逻辑(红队很关心这条)

四、DBC 文件解读:从原始字节到物理量

CAN 总线上跑的是裸字节(DEADBEEF 这种),但工程师写代码时关心的是物理量——车速 67.3 km/h、油门开度 23%、方向盘转角 -15.2°。DBC 文件(CAN database)就是这张映射表,由 Vector、CANalyzer、CANoe 这些工具定义。

4.1 DBC 三层结构

DBC 文件是纯文本,三层定义:

  • BO_ (Message) — 报文,定义一个 CAN 帧
    • BO_ 256 VehicleState: 8 ECU1 表示 ID=0x100、长 8 字节、来自 ECU1 的报文 VehicleState
  • SG_ (Signal) — 信号,定义报文里的一个字段
    • SG_ VehicleSpeed : 0|16@1+ (0.01,0) [0|655.35] "km/h" ECU1 — 第 0 位开始 16 位、有符号 Intel 字节序、精度 0.01、偏移 0、单位 km/h、来自 ECU1
  • VAL_ (Value Table) — 枚举值表
    • VAL_ 256 GearPosition 0 "P" 1 "R" 2 "N" 3 "D" ; 把字节值映射成档位字符串

4.2 canmatrix 工具链

直接看 DBC 文件是反人类的——用 CANmatrix(ebroecker/canmatrix):

  • 支持 .dbc / .dbf / .kcd / .arxml / .xls(x) / .yaml / .sym / .xml / .lua / .scapy 多种格式互转
  • 提供 canconvert 命令行工具:canconvert input.dbc output.kcd
  • 提供 candump_decode.py 用 DBC 文件解码 candump 输出,把字节流还原成可读的”车速 67.3 km/h”
pip install canmatrix
canconvert manufacturer.dbc my_project.kcd
python -m canmatrix.tools.candump_decode -d my_project.dbc candump.log

红队实战里 DBC 文件价值极高——拿到一份 DBC 等于拿到了车辆所有 ECU 信号的位级定义,配合 UDS 0x22 服务读 DID(数据标识符)能直接拿到当前车速、里程、电池电压等所有状态。


五、实战:拉起真实 CAN 接口

真车上 OBD-II 接口接入 CANtact、Macchina M2 这种 USB 转 CAN 适配器,驱动层是 slcan(串口线 CAN)或厂商专有驱动(gs_usb for CANtact),下面是通用流程:

# 1. 加载 CAN 内核栈
sudo modprobe can
sudo modprobe can-raw
sudo modprobe slcan    # 串口 CAN
# 或厂商驱动
sudo modprobe gs_usb   # CANtact / candleLight 固件

# 2. 接 USB 转 CAN,绑定 slcan 设备(/dev/ttyUSB0 为例)
sudo slcand -o -c -s6 -t hw -S 1000000 /dev/ttyUSB0 slcan0
sudo ip link set up slcan0

# 3. 设置 CAN 接口参数(比特率、采样点)
sudo ip link set can0 type can bitrate 500000 
        sample-point 0.875 
        tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
sudo ip link set up can0

# 4. 开抓
candump -a -A can0,7FF:7FF   # 0x000-0x7FF 全捕获,-a 显示仲裁,-A 显示 ASCII

参数含义:

  • bitrate 500000 — 500 kbps(高速 CAN,主流车厂默认)
  • sample-point 0.875 — 87.5% 采样点(CAN 经典值,容错最好)
  • prop-seg / phase-seg1 / phase-seg2 — 位时间分段,相加乘 tq 得位时间
  • sjw — 同步跳转宽度

如果接错比特率,看到的就是 CRC(循环冗余校验)错误帧满天飞。candump -e 能看到错误帧。

实际工作中常用 ip -details -statistics link show can0 看收发统计——RX packets 字段异常增长但应用层收到的帧没增加,多半是被内核环形缓冲区丢了,常见于高速 CAN + 低性能 CPU 的组合。


六、思考题

  1. vcan 接口和真实 CAN 接口在内核代码里走的是同一条路径吗?vcan 的局限是什么——它能模拟 CAN FD 吗?
  2. cansniffer 显示 123 [8] 00 1A 02 (00) (FF) (00) (3C) (00),括号里的字节变化说明什么信号类型?
  3. 没有 DBC 文件时,红队怎么从字节流反向推断物理量?给你一段 8 字节帧 payload,思路是什么?
  4. 录制了一段 60 秒的 .log 文件,里面 0x18B0 ID 每 100ms 出现一次,内容都是 8 字节——这是不是一条信号?怎么用 canplayer 回放验证它控制的是哪一项功能?

下一篇 07 讲,把工具链从 C 切到 Python——python-can、Scapy CAN 层、Caring Caribou,写出能批量 fuzz 的脚本。


七、素材出处

  • can-utils GitHub:https://github.com/linux-can/can-utils
  • SocketCAN 内核文档:https://www.kernel.org/doc/html/latest/networking/can.html
  • CANmatrix(ebroecker/canmatrix):https://github.com/ebroecker/canmatrix
  • Wikipedia SocketCAN:https://en.wikipedia.org/wiki/SocketCAN
  • awesome-vehicle-security 列表 #161 / #135 / #177

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

请登录后发表评论

    暂无评论内容