news 2026/7/10 23:22:33

OBD-II/UDS 渗透测试(一):协议基础 — CAN 总线与 ISO-TP

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OBD-II/UDS 渗透测试(一):协议基础 — CAN 总线与 ISO-TP

OBD-II/UDS 渗透测试(一):协议基础 — CAN 总线与 ISO-TP

    • 第 1 章 车载诊断的"为什么"和"是什么"
      • 1.1 一句话起源
      • 1.2 OBD-II 是什么、UDS 是什么、它们的关系
        • 1.2.1 SID(UDS)vs Mode(OBD-II)—— 容易混淆的概念
      • 1.3 为什么诊断协议是"攻击金矿"
    • 第 2 章 CAN 总线层基础
      • 2.1 帧结构(11-bit 标准帧)
      • 2.2 11-bit 还是 29-bit?
      • 2.3 OBD-II 11-bit 寻址规则(关键!)
      • 2.4 实战采样:一帧完整 CAN
    • 第 3 章 ISO-TP 传输层
      • 3.1 为什么需要 ISO-TP
      • 3.2 四种 PCI(Protocol Control Information)帧
      • 3.3 PCI 字节详解
      • 3.4 多帧重组的完整交互(实战)
      • 3.5 多帧重组的关键代码

[AI 整理声明]本文内容来源于作者在汽车网络安全实战项目中积累的测试笔记,由 AI(Claude)整理归纳输出;行文措辞、内容组织和格式均由 AI 完成,原始测试发现与知识积累来自作者本人。

本文是「OBD-II/UDS 汽车网络安全实战手记」系列第一篇,内容基于真实渗透测试项目。每个知识点配有实际采集到的总线报文作佐证,由浅入深,从"什么是 CAN 总线"一路到"如何识别 ISO-TP 多帧"。文中 F-XXX 为测试发现编号。

系列文章(一)协议基础 — CAN 总线与 ISO-TP(本文) · (二)UDS 服务字典 · (三)安全机制 — NRC + Session + SecAccess · (四)实战攻防与方法论


第 1 章 车载诊断的"为什么"和"是什么"

1.1 一句话起源

20 世纪 80 年代,加州空气委员会(CARB)要求所有上路汽车都必须能被一台外部设备读出排放相关故障——这就是 OBD(On-Board Diagnostics)。1996 年起 OBD-II 在美国成为法规要求,欧洲叫 EOBD(2001 年起),中国是 GB18352 系列法规(2007 年起强制)。

OBD-II 的最初目的非常窄:让维修工和环保部门读"我的发动机控制器排放有没有故障"。当年没人想过攻击者会用同一个接口去刷固件、关闭电池保护、抹掉攻击痕迹。

1.2 OBD-II 是什么、UDS 是什么、它们的关系

OBD-II法规层面的最小诊断协议。物理上规定了一个 16 针的方梯形插座(J1962 接口),逻辑上规定了 10 个 Mode(0x01-0x0A)的命令:

Mode名称含义
0x01Show current data读实时排放参数(车速、转速、O₂ 浓度、冷却液温度等)
0x02Show freeze frame读冻结帧(DTC 触发瞬间的现场快照)
0x03Show stored DTCs读已存储的排放相关 DTC
0x04Clear DTCs清除 DTC 和相关排放数据
0x05Test results, O₂ sensor氧传感器测试结果(仅非 CAN 总线用)
0x06Test results, other其他排放部件/系统测试结果
0x07Show pending DTCs读 pending DTC
0x08Control on-board component控制排放相关部件(EVAP 系统泄漏测试等)
0x09Request vehicle info读车辆信息(VIN、校准 ID、CVN 等)
0x0APermanent DTCs读永久 DTC(不能被 Mode 0x04 清掉

OBD-II 只关心"排放相关",连"开/锁车门"都没有。Mode 0x0A PermanentDTC 是排放反取证的法规防线——见第 8 章。

UDS(Unified Diagnostic Services,ISO 14229)OEM 自定义诊断的统一标准。它定义了一套服务标识 SID(0x10-0x3E + 0x83-0xBF),覆盖整车所有 ECU 的所有诊断需求——读写 ECU 参数、刷固件、控制执行器、读故障码、控制安全访问……

UDS 的服务可以复用OBD-II 已有的功能(比如 UDS 0x19 ReadDTC 几乎涵盖了 OBD-II Mode 0x03)。所以现代车上 ECU 通常同时支持 OBD-II 和 UDS:OBD-II 接口用最少功能合规,UDS 是真正干活的接口。

1.2.1 SID(UDS)vs Mode(OBD-II)—— 容易混淆的概念

两者都是 CAN data 第一字节后面的"命令码"。区别如下:

对比项OBD-II ModeUDS SID
取值范围0x01-0x0A(固定 10 个)0x10-0x3E+0x83-0xBF(~30 个)
关心的事只关心排放相关ECU全部诊断功能
请求 ID通常用0x7DF广播或0x7E0-0x7E7OEM 自定义
正响应规则Mode + 0x40(0x01 → 0x41SID + 0x40(0x10 → 0x50
负响应格式7F + Mode + NRC7F + SID + NRC(完全一样)

关键:两者取值范围不重叠(0x01-0x0A vs 0x10+),所以一个 ECU 收到0x03就知道这是 OBD(读排放 DTC),收到0x19就知道这是 UDS(也是读 DTC,但功能丰富得多)。两套命令复用同一条 CAN 总线

部分服务功能等价:

OBD-II Mode 0x03 读 DTC ≈ UDS SID 0x19 ReadDTC(UDS 多 20+ sub-function) OBD-II Mode 0x04 清 DTC ≈ UDS SID 0x14 ClearDTC OBD-II Mode 0x09 读 VIN ≈ UDS SID 0x22 DID 0xF190 OBD-II Mode 0x0A 永久 DTC ≈ UDS SID 0x19 sub 0x15

协议栈关系:

┌──────────────────┐ │ CAN 总线物理层 │ (ISO 11898) └──────────────────┘ │ ┌──────────────────┐ │ ISO-TP 传输层 │ (ISO 15765-2, 解决 > 8 字节的多帧重组) └──────────────────┘ │ ┌──────────┴──────────┐ │ │ ┌───────────────┐ ┌───────────────┐ │ OBD-II │ │ UDS │ │ (ISO 15031) │ │ (ISO 14229) │ │ 10 个 Mode │ │ ~30 个 SID │ └───────────────┘ └───────────────┘

1.3 为什么诊断协议是"攻击金矿"

从渗透角度看,诊断协议有三个让人馋的属性:

  1. 诊断协议直接命中 ECU 内部状态机——绕过应用层,直接和 ECU 固件对话
  2. 接口物理可达——OBD-II 插座就在驾驶位下方,任何人都能插
  3. 协议明文 + 无加密——除非 OEM 主动加密(极少数高端车有),所有报文裸跑在 CAN 上

OBD-II 设计时假设"接到诊断口的是维修工/合规检测设备",完全没有威胁模型。直到 2010 年 Karl Koscher、Stefan Savage 等人发表的《Experimental Security Analysis of a Modern Automobile》、2015 年 Charlie Miller 与 Chris Valasek 远程刷写 Jeep 才把这个洞撕开。


第 2 章 CAN 总线层基础

2.1 帧结构(11-bit 标准帧)

CAN 是个广播总线——一帧报文,全总线所有节点都能听到。一帧标准 CAN 数据帧(500 kbit/s 是车上 OBD 常见波特率)的关键字段:

SOF | ID(11) | RTR | IDE | r0 | DLC(4) | Data(0-8 bytes) | CRC(15) | ACK | EOF 1bit | 11 bits | 1 | 1 | 1 | 4 bits | 0-64 bits | 15 bits | 2 | 7

我们最关心的就两件事:

  • ID:11 bit,决定总线优先级(数值越小优先级越高)和目标(OBD-II 用 ID 来路由请求/响应)
  • Data:最多 8 字节负载

2.2 11-bit 还是 29-bit?

CAN 帧的 IDE 位决定是 11-bit (Classic) 还是 29-bit (Extended)。OBD-II 法规允许两种:

  • 11-bit:诊断请求广播0x7DF,响应来自各 ECU0x7E8-0x7EF
  • 29-bit:诊断请求广播0x18DB33F1,响应0x18DA F1 xx

商用车(重卡)多用 29-bit(J1939 协议族要求);乘用车多用 11-bit。具体到诊断侧,11-bit 在 OBD 中更常见,本文示例均以 11-bit 为基础。

2.3 OBD-II 11-bit 寻址规则(关键!)

OBD-II 规范的请求/响应 ID 有配对规则,标准 OBD-II 响应 ID = 请求 ID + 8:

请求 (tester → ECU) 响应 (ECU → tester) 广播 0x7DF 各 ECU 用自己的 phy ID phy 0x7E0 0x7E8 ← 标准 OBD ECU 用 0x7E0-0x7E7 / 0x7E8-0x7EF phy 0x7E1 0x7E9 ... phy 0x7E7 0x7EF

2.4 实战采样:一帧完整 CAN

最常见的诊断请求是0x10 0x03(进 extended session)。完整 CAN 帧:

CAN ID = 0x777 DLC = 8 Data = 02 10 03 00 00 00 00 00 │ │ │ └──────────────────► padding (5 字节 0x00) │ │ └──► UDS sub-function = 0x03 (extendedDiagnostic) │ └──► UDS SID = 0x10 (DiagnosticSessionControl) └──► ISO-TP PCI byte = 0x02 (SingleFrame, length=2)

这是后面所有协议层的基础——CAN 帧只是个容器,真正的诊断信息在 Data 区里,Data 的第 1 字节是 ISO-TP 的 PCI 头。


第 3 章 ISO-TP 传输层

3.1 为什么需要 ISO-TP

CAN 一帧最多 8 字节。但 UDS 读个 VIN 就 17 字节,读个 SupportedDTC 列表可能几百字节。怎么办?

答案是ISO-TP(ISO 15765-2)——在 CAN 之上加了一层分段重组协议,类似 IP 之上的 TCP(但简单得多)。

3.2 四种 PCI(Protocol Control Information)帧

ISO-TP 用 Data 的第 1 字节高 4 位区分帧类型:

高 4 位名称含义
0SF (SingleFrame)数据 ≤7 字节,一帧打完
1FF (FirstFrame)多帧的第一帧
2CF (ConsecutiveFrame)多帧的后续帧
3FC (FlowControl)接收方控制发送速率

3.3 PCI 字节详解

SingleFrame (SF)

PCI = 0x0L, L = 数据长度 (1-7) 后 7 字节 = 实际数据 (不足补 padding)

FirstFrame (FF)

PCI = 0x1L LL, LL...L = 12-bit 总数据长度 (1-4095) 后 6 字节 = 数据的前 6 字节

ConsecutiveFrame (CF)

PCI = 0x2N, N = 序号 (0-F, 循环) 后 7 字节 = 后续数据

FlowControl (FC):接收方发回,告诉发送方"我准备好了,继续发"

PCI byte 0 = 0x3F, F = Flag (0=continue, 1=wait, 2=overflow) byte 1 = BS (Block Size, 0=一次性收完, N=每 N 个 CF 后再 FC 一次) byte 2 = STmin (相邻 CF 间隔最小毫秒)

3.4 多帧重组的完整交互(实战)

在读 0x759 的 SupportedDTC 列表时收到了 173 字节响应。完整流程:

方向 CAN ID Data 说明 ────── ────── ──────────────────────────────── ──────────────────────── T → E 0x751 03 19 0A 00 00 00 00 00 请求: SID 19 sub 0A param 00 │ │ │ │ │ └──► sub-function 0x0A (SupportedDTC) │ └──► SID 0x19 (ReadDTC) └──► PCI: SF, length=3 E → T 0x759 10 AD 59 0A 09 D1 00 00 FF: 总长 0x0AD = 173 字节 │ │ │ │ └──────────────────► 数据前 5 字节 │ │ └──► SID + 0x40 = 0x59 (正响应) + sub byte │ └──► 总长低 8 位 = 0xAD └──► PCI 高 4 位 = 1 (FF), 低 4 位 = 总长高 4 位 = 0 T → E 0x751 30 00 00 00 00 00 00 00 FC: 0x30 = continue, │ │ │ BS=0 (一次发完), STmin=0 │ │ └──► STmin (相邻 CF 间隔) │ └──► BS (块大小) └──► PCI = 0x30 (FC, flag=continue) E → T 0x759 21 D1 01 00 91 01 00 91 CF #1 (序号=1) │ └──────────────────────────► 后续 7 字节数据 └──► PCI: hi=2 (CF), lo=1 (seq=1) E → T 0x759 22 02 00 91 03 00 91 04 CF #2 (序号=2) ...继续直到收到 173 字节

收齐 173 字节后,重组的完整 UDS 响应是:

59 0A 09 D1 00 00 D1 01 00 91 01 00 91 02 ... (171 字节 DTC 列表)

3.5 多帧重组的关键代码

// 简化版多帧接收while(true){TCANFD f=receive_can_frame();if(f.FIdentifier!=expected_resp_id)continue;u8 pci=f.FData[0];u8 hi=pci>>4;// PCI 高 4 位决定帧类型if(hi==0){// SingleFrames32 len=pci&0x0F;memcpy(out,&f.FData[1],len);returnDONE;}if(hi==1){// FirstFrametotal_len=((pci&0x0F)<<8)|f.FData[1];// 12-bit 长度memcpy(out,&f.FData[2],6);// 前 6 字节collected=6;send_flow_control(req_id);// 关键!必须发 FCexpected_seq=1;}if(hi==2){// ConsecutiveFrameu8 seq=pci&0x0F;if(seq!=expected_seq)continue;// 序号不对就丢expected_seq=(expected_seq+1)&0x0F;// 0-F 循环memcpy(out+collected,&f.FData[1],7);collected+=7;if(collected>=total_len)returnDONE;}}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/10 23:22:22

VMware安装CentOS7教程:从下载镜像到网络设置_一步不落_新手零失败

如果你正在搜索 centos7下载安装教程&#xff0c;或者需要一个靠谱的 centos镜像文件iso下载 渠道——恭喜你&#xff0c;来对地方了。 今天这篇 centos安装教程&#xff0c;我会用 安装centos7步骤 全图解的方式&#xff0c;从 centos7镜像文件下载 开始&#xff0c;手把手带…

作者头像 李华
网站建设 2026/7/10 23:21:19

机器人行业面试全攻略:从0到1拿下心仪Offer,看这一篇就够了

导读: 2026年,机器人行业迎来新一轮爆发期。从人形机器人到协作机械臂,从仓储物流到手术机器人,赛道火热的背后,是无数工程师和从业者渴望入局的迫切心情。但面试这道关,到底考什么?怎么准备?过来人有哪些血泪教训?今天这篇文章,一次性讲透。 一、2026年的机器人行业…

作者头像 李华
网站建设 2026/7/10 23:20:49

医用远程会诊系统:同屏会诊模块的设计与实现

1. 引言 在医疗资源分布不均、优质专家稀缺的背景下,远程会诊系统已成为提升诊疗效率、实现医疗公平的重要工具。其中,同屏会诊模块作为系统的核心交互界面,承担着多端音视频同步、医疗影像协同标注、电子病历实时共享等关键任务。它不仅是医生之间沟通的桥梁,更是确保会诊…

作者头像 李华
网站建设 2026/7/10 23:19:50

自定义图表:选用Highcharts能否支持动态定制图表

Highcharts能否支持动态定制图表&#xff1f; 答&#xff1a;Highcharts图表库以简约、优雅和配色在商业项目中获得全球青睐&#xff0c;且图表在任何分辨率下都能清晰渲染&#xff0c; 并通过 JavaScript 或 CSS 的简单选项结构轻松设计样式。 当然&#xff0c;Highcharts 图…

作者头像 李华
网站建设 2026/7/10 23:19:34

抖音批量下载助手:三步轻松收藏心仪视频内容

抖音批量下载助手&#xff1a;三步轻松收藏心仪视频内容 【免费下载链接】douyinhelper 抖音批量下载助手 项目地址: https://gitcode.com/gh_mirrors/do/douyinhelper 还在为手动保存喜欢的抖音视频而烦恼吗&#xff1f;想要批量收藏某个创作者的所有作品却无从下手&am…

作者头像 李华