UDS小结

UDS 本身用处:

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

UDS 诊断包括 6 大类,26 种服务,每种服务都有自己独立的 ID,即 SID(Service Identifier)

image
image

基本的形式是分析/提取安全访问算法 + 用种子计算密钥 + 通过验证获取权限/flag

服务组	功能描述	        典型服务ID
会话管理	控制诊断会话模式	0x10(会话控制)
                        0x11(ECU重置)
数据传输	读取/写入ECU数据	0x22(读数据)
						0x2E(写数据)
诊断故障码	管理故障信息	0x19(读DTC)
						0x14(清除DTC)
安全访问	限制高风险操作	0x27(安全访问)
远程控制	执行ECU内部功能	0x31(例程控制)
  1. 会话类型
    • 默认会话(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 的核心做法就是提权。

一道简单题:
image

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

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 即可

进阶

image

由于不知道为什么账号被 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 是最核心的三个子功能!
    image

  • SID 27 (安全访问):子功能是奇偶配对的(01 请求 / 02 发送,03 请求 / 04 发送)

再来讲讲题目中说的 22 服务
肯定响应:
image
image
image
CU 针对 22 服务具体的响应行为如下:

  1. 先检查诊断请求的长度是否满足最短和最长长度要求,不满足支持反馈否定响应 7 F 22 13;

  2. 检查请求中第一个的 DID 在当前诊断会话下是否支持 22 服务,支持则继续,不支持则检查是否还有其他 DID;

  3. 检查读取该 DID 需要的安全访问是否已解锁,未解锁回复 NRC 33,已解锁或不需要解锁则继续;

  4. 检查读取该 DID 的环境条件是否满足,不满足则回复 NRC 22,满足则继续;

  5. 请求中如有多个 DID,则循环②③④步逐个 DID 检查,直到检查完全部 DID;

  6. 如果请求的全部 DID 在当前诊断会话下都不支持 22 服务,则回复 NRC 31;

  7. 如果 ECU 需要响应的数据长度超出 ECU 自己限制,则回复 NRC 14;

  8. 以上检查均无问题时,ECU 反馈肯定响应,发送要读取的 DID 的具体数值。

关于这道题的详细 wp 见 UDS诊断初探 & PolarisCTF中ez_uds_plus的wp - 吾爱破解 - 52pojie.cn

posted @ 2026-09-07 10:12  JIEGE328  阅读(17)  评论(0)    收藏  举报