isecwire/canbus-sniffer

GitHub: isecwire/canbus-sniffer

这是一个基于 Linux SocketCAN 的汽车与工业总线安全审计工具,集成了多协议解码、流量统计及实时异常检测功能。

Stars: 0 | Forks: 0

# canbus-sniffer [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/07c8502ca7094739.svg)](https://github.com/isecwire/canbus-sniffer/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![C++](https://img.shields.io/badge/C%2B%2B-17-blue.svg)](https://isocpp.org/) [![Platform](https://img.shields.io/badge/platform-linux-lightgrey.svg)](https://www.kernel.org/doc/html/latest/networking/can.html) 用于汽车和工业安全评估的 CAN 总线流量捕获、多协议解码器和异常检测器。 `canbus-sniffer` 是一个基于 Linux SocketCAN 构建的命令行工具,用于捕获原始 CAN 帧,使用 DBC 信号数据库或内置协议解码器(J1939、OBD-II、UDS)对其进行解码,重新组装 ISO-TP 多帧消息,并应用实时异常检测(包括统计时序分析和熵监控)来识别对 CAN 网络的潜在攻击。它专为在汽车 ECU 网络、工业 SCADA 总线以及任何使用 CAN 2.0A/B 的系统中进行渗透测试、安全审计和事件调查而设计。 ### CLI 输出 ![CLI 截图](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/1ea0c83bd2094745.svg) ### 终端界面 (`--tui`) ![TUI 截图](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/e5275ba57f094750.svg) ## 功能特性 ### 捕获与接口 - 在任何 SocketCAN 接口(`can0`、`vcan0`、PEAK、Kvaser 等)上进行 **实时捕获** - 通过仲裁 ID 进行 **硬件级过滤**,以减少繁忙总线上的噪声 - 带有微型表达式解析器的 **软件过滤表达式**(`id=0x100-0x1FF,dlc>4`) - **重放模式** —— 离线分析之前捕获的 candump 日志文件 - **持续时间受限的捕获**,用于自动化测试脚本 ### 协议解码 - **DBC 信号解码** —— 解析标准 DBC 文件并实时显示物理信号值 - **J1939 协议支持** —— 从 29 位 ID 解码 PGN、源/目的地址、优先级;内置 PGN 数据库,支持 EEC1、CCVS、ET1、LFE、DM1、TSC1、AMB 等的 SPN 解码 - **OBD-II PID 解码器** —— 从 ID 为 0x7DF/0x7E0-0x7E7 的 CAN 帧中解码标准 OBD-II PID(发动机转速、车速、冷却液温度、节气门、燃油液位等) - **UDS(统一诊断服务)解码器** —— 解析诊断请求/响应,包括 DiagnosticSessionControl、SecurityAccess、ReadDataByIdentifier(带 DID 名称查找)、RoutineControl,以及带有 NRC 解码的否定响应 - **ISO-TP (ISO 15765-2) 重组** —— 处理多帧消息(单帧、首帧、连续帧、流控制),具有序列验证和超时处理 ### 异常检测 - **学习/检测两阶段模型**,可配置学习持续时间 - 基线期间未见过的未知仲裁 ID - 总线泛洪检测(每个 ID 可配置的消息速率阈值) - 重放攻击检测(重复的有效载荷序列) - DLC(帧长度)异常 - **统计时序异常检测** —— 跟踪每个 ID 的消息间时序分布,标记超出 3 sigma 的消息 - **Shannon 熵分析** —— 计算每个仲裁 ID 的有效载荷熵,标记异常的高/低熵有效载荷 - **序列号跟踪** —— 检测递增字节模式并标记间隙 - **伪装检测** —— 基于时序检测多个源声明相同的仲裁 ID ### 输出与导出 - 带有 ANSI 代码的 **彩色终端输出** —— 异常为红色,解码为绿色,警告为黄色 - **实时统计模式**(`--stats`)—— 刷新显示每个 ID 的帧计数、消息速率、总线负载百分比、熵 - **PCAP 导出**(`--pcap FILE`)—— 以 PCAP 格式写入捕获的帧(LINKTYPE_SOCKETCAN = 227),以便用 Wireshark 进行分析 - **多种导出格式**(`--export json|csv|candump`),可选输出文件 - 以 candump 兼容格式和结构化 JSON 进行 **日志记录** ### 终端界面(可选) - 使用 FTXUI 构建的 **交互式 TUI**(`--tui`)—— 可选择使用 `-DENABLE_TUI=ON` 进行编译 - 顶部面板:实时帧源(滚动,按类型着色) - 左侧边栏:仲裁 ID 列表,包含帧计数和速率 - 右侧面板:选定 ID 的详细信息,包含解码信号、熵、时序 - 底部栏:总帧数、总线负载 %、异常计数、运行时间 - 状态行:过滤表达式、接口名称、录制状态 - 键盘:`q` 退出,`p` 暂停/继续,`r` 重置统计,Up/Down 选择 ID ## 环境要求 - 支持 SocketCAN 的 Linux(内核 2.6.25+) - C++17 编译器(GCC 8+,Clang 7+) - CMake 3.14+ - `can-utils`(可选,用于使用 `cansend`/`candump`/`cangen` 进行测试) - FTXUI(可选,当使用 `-DENABLE_TUI=ON` 时自动获取) ## 构建说明 ### 不带 TUI(默认) ``` mkdir build && cd build cmake .. make -j$(nproc) ``` ### 带 TUI ``` mkdir build && cd build cmake .. -DENABLE_TUI=ON make -j$(nproc) ``` FTXUI 会通过 CMake FetchContent 自动下载。该工具在没有 FTXUI 的情况下也能完全编译和运行。 生成的二进制文件位于 `build/canbus-sniffer`。 ### 运行测试 ``` cd build ctest --output-on-failure ``` ## SocketCAN 设置 ### 物理 CAN 适配器 大多数 USB-CAN 适配器(PEAK PCAN-USB、Kvaser Leaf、CANable)会自动注册为 SocketCAN 接口: ``` sudo ip link set can0 up type can bitrate 500000 ``` ### 用于测试的虚拟 CAN (vcan) 创建一个虚拟 CAN 接口,以便在没有硬件的情况下进行本地开发: ``` sudo modprobe vcan sudo ip link add dev vcan0 type vcan sudo ip link set up vcan0 ``` ## 使用方法 ``` canbus-sniffer v2.1.0 [OPTIONS] Interface & capture: -i, --interface CAN interface (default: can0) -D, --duration Capture duration (0 = infinite, default: 0) -q, --quiet Suppress frame output to stdout -C, --no-color Disable ANSI colored output Protocol decoding: -d, --dbc Load DBC file for signal decoding -P, --protocol Protocol mode: raw (default), j1939, obd2, uds Filtering: -f, --filter Hardware filter by arbitration ID -F, --filter-expr Software filter expression e.g. "id=0x100-0x1FF,dlc>4" Anomaly detection: -a, --detect-anomalies Enable anomaly detection --learn Learning phase duration (default: 30) --flood-threshold Messages/sec per ID to flag as flood (default: 500) Logging & export: -l, --log Log frames to file (candump format) -j, --json Log frames to file (JSON format) --pcap Write captured frames in PCAP format --export Export format: json, csv, candump --export-file Export output file (default: stdout) Statistics & replay: -s, --stats Live statistics mode (refreshing display) --replay Replay a candump log file through the analyzer Terminal UI: --tui Launch interactive terminal UI -h, --help Show this help ``` ### 示例 在虚拟 CAN 接口上进行基本捕获: ``` ./canbus-sniffer -i vcan0 ``` J1939 重型车辆总线解码: ``` ./canbus-sniffer -i can0 -P j1939 -a --learn 10 ``` 带过滤的 OBD-II 诊断捕获: ``` ./canbus-sniffer -i can0 -P obd2 -F "id=0x7E0-0x7EF" ``` UDS 诊断会话监控: ``` ./canbus-sniffer -i can0 -P uds -j diag_session.json ``` 带 DBC 解码和 PCAP 导出的捕获: ``` ./canbus-sniffer -i can0 -d vehicle.dbc --pcap capture.pcap -l capture.log ``` 带实时统计的异常检测: ``` ./canbus-sniffer -i vcan0 -a --learn 10 -s ``` 通过 J1939 解码器重放捕获的日志: ``` ./canbus-sniffer --replay capture.log -P j1939 --export csv --export-file out.csv ``` 带异常检测的交互式终端界面: ``` ./canbus-sniffer -i vcan0 --tui -a --learn 5 ``` 用于 CI 流水线的限时捕获: ``` ./canbus-sniffer -i vcan0 -D 60 -l test_capture.log -q ``` ### 过滤表达式语法 ``` filter = condition { ',' condition } condition = field op value | 'id' '=' value '-' value (range) field = 'id' | 'dlc' | 'data[N]' op = '=' | '!=' | '<' | '<=' | '>' | '>=' value = hex (0x...) or decimal number ``` 示例: ``` id=0x100-0x1FF # ID range filter id=0x7DF,dlc>4 # Combined conditions id=0x100,data[0]=0xFF # Data byte filter dlc<=4,id!=0x000 # Multiple conditions ``` ### 使用 vcan 进行测试 在一个终端中,以 J1939 模式启动嗅探器: ``` ./canbus-sniffer -i vcan0 -P j1939 -a --learn 5 -s ``` 在另一个终端中,发送 J1939 流量: ``` # EEC1 (engine speed) cansend vcan0 18F00400#00000080003E0000 # CCVS (vehicle speed) cansend vcan0 18FEF100#0000500000000000 ``` 对于 OBD-II 测试: ``` # Request engine RPM cansend vcan0 7DF#0201010000000000 # Simulate RPM response (1726 rpm) cansend vcan0 7E8#04410C1AF8000000 ``` ## 架构 ``` src/ main.cpp Main entry point, CLI parsing, capture loop can_interface.h/cpp RAII SocketCAN wrapper frame_decoder.h/cpp DBC parser and signal extraction anomaly_detector.h/cpp Learning/detection anomaly engine logger.h/cpp Candump and JSON file logging j1939.h/cpp J1939 PGN decoder with SPN database obd2.h/cpp OBD-II Service 01 PID decoder uds.h/cpp UDS service/DID/NRC decoder isotp.h/cpp ISO-TP multi-frame reassembly engine statistics.h/cpp Statistical analysis, entropy, timing, bus load pcap_writer.h/cpp PCAP file writer (LINKTYPE_SOCKETCAN) filter_expr.h/cpp Filter expression parser and evaluator tui.h TUI controller interface (always available) tui.cpp FTXUI implementation (compiled with -DENABLE_TUI=ON) tui_stub.cpp Stub when FTXUI not available tests/ main_test.cpp Hand-rolled test framework (no external deps) test_*.cpp Unit tests for each module ``` ## DBC 文件格式 该工具解析标准的 Vector DBC 文件。最小示例: ``` BO_ 291 EngineData: 8 ECU SG_ EngineSpeed : 24|16@1+ (0.25,0) [0|16383.75] "rpm" Vector__XXX SG_ EngineTemp : 40|8@1+ (1,-40) [-40|215] "degC" Vector__XXX BO_ 1024 BrakeStatus: 2 ABS SG_ BrakePedal : 0|8@1+ (0.392157,0) [0|100] "%" Vector__XXX ``` ## 安全背景 车辆和工业系统中的 CAN 总线网络通常缺乏身份验证和加密。常见的攻击向量包括: - **欺骗** —— 注入带有伪造仲裁 ID 的帧,以冒充 ECU - **重放攻击** —— 记录并重新发送有效的帧序列 - **总线泛洪** —— 通过高优先级饱和总线来进行拒绝服务 - **模糊测试** —— 发送格式错误的帧,以触发 ECU 中的未定义行为 - **伪装攻击** —— 基于时序的冒充,攻击者替换合法的 ECU - **Bus-off 攻击** —— 强制错误状态以断开合法节点 - **诊断滥用** —— 未经授权的 UDS 会话,用于固件提取或 ECU 重编程 `canbus-sniffer` 帮助安全评估人员在实时评估期间建立流量基线并检测这些模式。它还可以作为轻量级 IDS 部署在嵌入式 Linux 网关上。 ## 常见问题 ### “解码 CAN 帧”是什么意思? CAN 总线是车辆、机器人和工业机器内部的通信网络。电子控制单元(ECU)发送包含原始字节的帧 —— 例如,ID 为 0x0C0、数据为 `0B B8` 的帧。如果不进行解码,你只能看到十六进制。经过解码(使用 DBC 文件或协议知识)后,你会看到:“Engine Speed: 3000 RPM”。 canbus-sniffer 捕获这些原始帧,并使用 J1939(卡车/重型设备)、OBD-II(汽车)或 UDS(诊断)协议解码器将其转换为人类可读的值。 ### 什么是 CAN 总线上的重放攻击? 攻击者记录合法的 CAN 帧(例如,“解锁车门”),并在稍后重放它们。车辆/机器会执行该命令,因为 CAN 没有身份验证 —— 它无法区分重放的帧和真实的帧。canbus-sniffer 通过跟踪帧序列并标记重复模式来检测重放攻击。 ### 实际中如何使用? ``` # Set up virtual CAN for testing sudo modprobe vcan && sudo ip link add dev vcan0 type vcan && sudo ip link set up vcan0 # Capture and decode J1939 traffic canbus-sniffer --interface can0 --protocol j1939 --detect-anomalies --log capture.json ``` ## 许可证 MIT -- 详见 [LICENSE](LICENSE)。 版权所有 (c) 2026 isecwire GmbH
标签:Bash脚本, C++, CAN总线, DBC文件, ECU, ISO-TP, J1939, OBD-II, SCADA, SocketCAN, UDS, 二进制发布, 协议解码, 哈希传递, 工业控制安全, 开源工具, 异常检测, 数据擦除, 汽车安全, 车载网络