UDS小结
UDS 本身用处:
汽车诊断技术是指在不拆卸车辆的情况下,通过读取车辆在运行过程中所记录的数据或故障码来查明故障原因,并确定故障部位的汽车应用技术。我们可以通过该技术,快速检测到汽车故障来提高汽车安全性和维修效率。USD 协议诊断主要采用“问 - 答”模式,即诊断仪像车辆指定的 ECU 发送请求 (Request),指定的 ECU 会做出相对应的响应 (Response),并将响应返回给诊断仪。从而可以依据定义好的诊断描述文件,就可以将相对应的数据转化为相对应的问题和描述。
UDS 诊断包括 6 大类,26 种服务,每种服务都有自己独立的 ID,即 SID(Service Identifier)


基本的形式是分析/提取安全访问算法 + 用种子计算密钥 + 通过验证获取权限/flag
服务组 功能描述 典型服务ID
会话管理 控制诊断会话模式 0x10(会话控制)
0x11(ECU重置)
数据传输 读取/写入ECU数据 0x22(读数据)
0x2E(写数据)
诊断故障码 管理故障信息 0x19(读DTC)
0x14(清除DTC)
安全访问 限制高风险操作 0x27(安全访问)
远程控制 执行ECU内部功能 0x31(例程控制)
- 会话类型
- 默认会话(0 x 01):正常运行模式,仅基本诊断功能可用
- 编程会话(0 x 02):允许 Flash 操作,用于刷写程序
- 扩展诊断会话(0 x 03):高级诊断功能,如参数调整
- 安全系统会话(0 x 04):安全相关功能,如密钥管理
会话切换
上位机 → ECU: [10 03] // 请求进入扩展诊断会话
ECU → 上位机: [50 03] // 确认会话变更
注意
会话超时:会话是可能超时,即你在申请开启一个服务后,ECU 会在一段时间无通信后自动返回默认会话,有些时候返回默认对话的时间很短,可能几秒,手速不够很可能还没请求开启的会话已经返回,所以可以使用脚本来访问容器获取 seed,计算 key 并且传入!
对于权限的高低,查询了一下 ai
- 10 01(默认会话):权限最低,仅支持基础诊断服务(如 `22` 读数据、`19` 读故障码)。
- 10 03(扩展会话):中等权限,解锁大部分诊断服务(如 `27` 安全访问、`2E` 写数据、`31` 例程控制)。
- 10 02(编程会话):最高权限,专门用于固件刷写,解锁 `34`(请求下载)、`36`(数据传输)、`37`(退出传输)等核心编程服务。
一般题目如果你没进入更高级的会话,你就会默认保持在 1001 中。这样权限很低,基本上查不到什么东西,所以引出了 UDS 的核心做法就是提权。
一道简单题:

解法很简单,利用给出的 seed ,直接计算出 key,输入 key 即可获得 flag

脚本如下
def calculate_key(seed):
key = seed ^ 0xA5A5A5A5
key = ((key << 3) | (key >> 29)) & 0xFFFFFFFF
key = (key + 0x12345678) & 0xFFFFFFFF
return key
print(hex(calculate_key(0x4CAD989D)))
非常简单就是将计算过程照搬然后带入 key 即可
进阶

由于不知道为什么账号被 ban 了,暂且无法拿出复现图片,只能给出一点思路(感谢奶龙)
题干里说了 level 1 的算法与上一道题一样,但是由于它的会话给的时间很短,所以 1003 后在 2001 一般很难直接获取 seed,所以最好是使用脚本自动传入,可以得出 key,有了这个 key 就可以进入 1002,权限提高。
接下来使用 22 f1 90 拿到一个 key,使用 2705 得 seed,接下来去分析给的 pcapng 文件从里面解出来一个刷入的固件,然后逆向固件按照固件的方法生成 key。传入以后即可再次提高权限,提高权限后调用一下 routine 得到神秘字符,解密即可。
详细 wp 见:
扩展各个服务下的子服务
0 x 10 诊断会话控制
- 0 x 01 默认会话
- 0 x 02 编程会话
- 0 x 03 扩展会话
- 0 x 04 系统会话
- 0 x 05 无复位默认会话
0 x 11 ECU 复位
- 0 x 01 硬复位
- 0 x 02 钥匙开关复位
- 0 x 03 软复位
- 0 x 04 快速断电
0 x 14 清除诊断信息
- 0 x 00 清除所有故障码相关信息
- 0 x 01 按状态清除 DTC
- 0 x 02 按状态与存储区域清除 DTC
0 x 19 读取故障码信息
- 0 x 01 按状态报告 DTC
- 0 x 02 按 DTC 状态报告
- 0 x 03 报告镜像存储区 DTC
- 0 x 04 按严重程度报告 DTC
0 x 22 按标识符读取数据
- 无固定子功能,后跟 2 字节 DID
0 x 23 按地址读取内存数据
- 无固定子功能,后跟内存地址与长度
0 x 24 按标识符读取缩放数据
- 无固定子功能,后跟 2 字节 DID
0 x 27 安全访问
- 0 x 01 请求种子 (等级 1)
- 0 x 02 发送密钥 (等级 1)
- 0 x 03 请求种子 (等级 2)
- 0 x 04 发送密钥 (等级 2)
- 0 x 05 请求种子 (等级 3)
- 0 x 06 发送密钥 (等级 3)
0 x 28 通信控制
- 0 x 00 开启收发
- 0 x 01 禁止发送
- 0 x 02 禁止接收
- 0 x 03 禁止收发
0 x 2 A 按周期标识符读取数据
- 0 x 01 启动周期发送
- 0 x 02 停止周期发送
- 0 x 03 清除配置
0 x 2 C 动态定义标识符
- 0 x 01 定义 DID
- 0 x 02 读取 DID 配置
- 0 x 03 停止使用
0 x 2 E 按标识符写入数据
- 无固定子功能,后跟 DID 与待写入数据
0 x 2 F 输入输出控制
- 0 x 01 激活
- 0 x 02 去激活
- 0 x 03 读取当前状态
0 x 31 例程控制
- 0 x 01 启动例程
- 0 x 02 停止例程
- 0 x 03 请求例程结果
0 x 34 请求下载
- 无固定子功能,后跟地址、长度等参数
0 x 35 请求上传
- 无固定子功能,后跟地址、长度等参数
0 x 36 数据传输
- 无固定子功能,后跟块序号与数据
0 x 37 请求退出传输
- 0 x 01 退出数据传输
0 x 38 文件传输
- 0 x 01 启动
- 0 x 02 暂停
- 0 x 03 恢复
- 0 x 04 中止
- 0 x 05 删除
0 x 3 D 按地址写入内存
- 无固定子功能,后跟地址与待写入数据
0 x 3 E 测试器在线
- 0 x 00 测试器存在 (心跳)
0 x 83 访问时间参数
- 0 x 01 读取服务器 S 3 时间
- 0 x 02 读取客户端 S 3 时间
- 0 x 03 设置服务器 S 3 时间
- 0 x 04 设置客户端 S 3 时间
0 x 84 安全数据传输
- 0 x 01 请求控制
- 0 x 02 数据传输
- 0 x 03 退出传输
0 x 85 控制 DTC 设置
- 0 x 00 开启 DTC 记录
- 0 x 01 关闭 DTC 记录
- 0 x 02 获取 DTC 数量
- 0 x 03 DTC 快照控制
0 x 86 事件响应
- 0 x 01 事件触发启动例程
- 0 x 02 事件触发停止例程
- 0 x 03 事件模式控制
0 x 87 链路控制
-
0 x 01 校验 Boot 校验和
-
0 x 02 内存交换
-
0 x 03 禁用 ECU 复位
-
SID 22, 23, 2 E, 3 D, 84:这几个服务没有固定的子功能字节(Sub-function = 00),它们的第二字节直接是 DID 或 地址。
-
SID 31 (例程):01/02/03 是最核心的三个子功能!

-
SID 27 (安全访问):子功能是奇偶配对的(01 请求 / 02 发送,03 请求 / 04 发送)
再来讲讲题目中说的 22 服务
肯定响应:



CU 针对 22 服务具体的响应行为如下:
-
先检查诊断请求的长度是否满足最短和最长长度要求,不满足支持反馈否定响应 7 F 22 13;
-
检查请求中第一个的 DID 在当前诊断会话下是否支持 22 服务,支持则继续,不支持则检查是否还有其他 DID;
-
检查读取该 DID 需要的安全访问是否已解锁,未解锁回复 NRC 33,已解锁或不需要解锁则继续;
-
检查读取该 DID 的环境条件是否满足,不满足则回复 NRC 22,满足则继续;
-
请求中如有多个 DID,则循环②③④步逐个 DID 检查,直到检查完全部 DID;
-
如果请求的全部 DID 在当前诊断会话下都不支持 22 服务,则回复 NRC 31;
-
如果 ECU 需要响应的数据长度超出 ECU 自己限制,则回复 NRC 14;
-
以上检查均无问题时,ECU 反馈肯定响应,发送要读取的 DID 的具体数值。
关于这道题的详细 wp 见 UDS诊断初探 & PolarisCTF中ez_uds_plus的wp - 吾爱破解 - 52pojie.cn

浙公网安备 33010602011771号