漏洞/实验概述
UDS(Unified Diagnostic Services)是 ISO 14229 系列定义的诊断协议,运行在 ISO-TP(ISO 15765-2)之上,常见载体是 CAN 总线。服务 0x27 SecurityAccess 用于在诊断仪与 ECU 之间建立“安全等级”,只有通过 Seed/Key 校验后,ECU 才允许执行写入、例程控制、刷写等敏感操作。
设计初衷是防止随意修改 ECU 参数,但 Seed/Key 的强度完全取决于主机厂实现。固定种子、弱算法、缺失尝试限制、算法可从固件中提取等问题,会让这道门槛退化为“流程性校验”。
| 项目 | 内容 |
|---|---|
| 协议 | ISO 14229-1(UDS)、ISO 15765-2(ISO-TP) |
| 服务 | 0x27 SecurityAccess |
| 典型子功能 | 0x01 请求种子,0x02 发送密钥(等级 1) |
| 常见前置 | 进入扩展会话 0x10 0x03 |
| 风险核心 | 种子可预测、算法泄露、尝试次数与延迟约束缺失 |
| 公开内容边界 | 本文只讨论机制、风险与检测防御,不提供可用的密钥计算脚本 |
漏洞成因 / 原理
服务与会话
UDS 服务按会话区分权限。默认会话 0x10 0x01 通常只允许读取类服务;扩展会话 0x10 0x03 才允许访问更多诊断功能;编程会话 0x10 0x02 用于刷写。多数 ECU 要求先进入扩展会话再请求安全访问,且会话切换或 ECU 复位后安全等级会失效,需要重新解锁。
诊断请求通常使用物理寻址 CAN ID 0x7E0–0x7E7,响应使用 0x7E8–0x7EF。功能寻址可用于广播,但安全访问一般使用物理寻址,因为需要一对一交互。
Seed/Key 交互流程
- 诊断仪发送
0x27 0x01请求等级 1 的种子; - ECU 生成并返回种子(正响应
0x67 0x01 <seed>); - 诊断仪用厂商约定的算法把种子与秘密值计算出密钥;
- 诊断仪发送
0x27 0x02 <key>; - ECU 校验通过后返回
0x67 0x02,该安全等级解锁;校验失败返回负响应0x7F 0x27 <NRC>。
如果 ECU 返回的种子长度为 0,表示当前已处于解锁状态,无需再次校验。这是规范允许的一种优化,但也可能被用于判断 ECU 当前状态。
报文示例(ISO-TP 单帧)
# 请求等级 1 的种子
02 27 01 # 数据长度 2:服务 0x27,子功能 0x01
# ECU 的肯定响应,携带 4 字节种子(示例值)
06 67 01 A1 B2 C3 D4 # 数据长度 6:0x67,0x01,4 字节 seed
# 诊断仪回送 4 字节密钥(内容省略,仅示意长度)
06 27 02 XX XX XX XX
# 校验通过
02 67 02
负响应的结构统一为 0x7F + 服务号 + NRC,例如密钥错误返回 03 7F 27 35。
子功能编号规律
| 子功能 | 方向 | 含义 |
|---|---|---|
0x01 | 请求 | 请求等级 1 的种子 |
0x02 | 发送 | 提交等级 1 的密钥 |
0x03 / 0x04 | 请求 / 发送 | 等级 2 |
0x05 / 0x06 | 请求 / 发送 | 等级 3 |
0x41 / 0x42 | 请求 / 发送 | 更高安全等级 |
0x43–0x5E | — | ISO 保留 |
0x5F–0x7E | — | 厂商自定义 |
规律是奇数子功能请求种子、相邻偶数子功能提交密钥。实际支持到哪一级、每级需要什么前置条件,由 ECU 的诊断规范定义。
常见实现弱点
| 弱点 | 表现 | 后果 |
|---|---|---|
| 固定种子 | 每次 0x27 0x01 返回相同值,常见 00 00 | 一次观察即可复用密钥,防护形同虚设 |
| 弱算法 | 简单异或、加减、线性变换 | 少量样本即可反推算法与秘密值 |
| 算法可提取 | 算法与密钥硬编码在固件中 | 拿到固件即可离线计算任意种子对应的密钥 |
| 无尝试限制 | 连续错误密钥不返回 0x36 | 可离线或在线暴力枚举 |
| 无延迟约束 | 失败后不返回 0x37,可立即重试 | 提高爆破速率,缩短攻击时间 |
| 会话约束缺失 | 默认会话也能解锁,或解锁后跨会话保持 | 降低攻击前置条件,扩大暴露面 |
| 种子可预测 | 基于计数器、时间戳或固定序列 | 可预计算下一轮种子与密钥 |
其中“算法硬编码在固件中”是车联网场景的典型问题:攻击者只要获得 ECU 固件(维修资料、OTA 包、拆片读取),就能在离线环境完成算法逆向,Seed/Key 不再是秘密,而只是一个需要正确实现的校验步骤。
攻击链路分析
以下描述攻击者从接触到解锁的完整思路,省略任何具体的密钥推导代码与工具参数。
- 接触总线:通过 OBD-II 接口(CAN-H 为 6 脚、CAN-L 为 14 脚)、车载诊断座、网关调试口,或在具备网络访问能力时经车机/Telematics 单元转向车内网络。
- 发现诊断目标:被动监听或主动扫描诊断 CAN ID,识别
0x7E0–0x7E7的请求响应关系,确认目标 ECU 与支持的会话类型。 - 进入扩展会话:发送
0x10 0x03,并按需周期发送0x3E 0x80维持会话,避免超时回到默认会话。 - 请求种子:发送
0x27 0x01,记录返回的种子长度与取值。 - 分析算法:在授权靶场中对比多轮种子与固件静态分析结果,判断算法是固定映射、线性变换还是带密钥的密码学运算。此步骤通常离线完成。
- 提交密钥:发送
0x27 0x02与计算出的密钥,观察正响应或负响应,根据 NRC 调整策略。 - 执行敏感操作:解锁后可调用写入数据
0x2E、例程控制0x31、请求下载0x34、数据传输0x36、传输退出0x37,在编程会话下完成刷写,最后用0x11复位使新配置生效。 - 持久化与影响:修改标定参数、关闭故障监测、写入自定义数据,或替换应用分区。对整车而言,影响可能是动力、制动、座舱功能被非授权改变。
需要区分两种场景:授权靶场中上述流程用于验证防护强度;未授权实车上执行同样步骤即构成非法侵入。本文的实验与结论均限定在前者。
攻击痕迹与日志特征
总线与诊断流量特征
| 观察点 | 可疑特征 |
|---|---|
| 会话切换 | 非诊断工位时段出现 0x10 0x03 或 0x10 0x02 |
| 种子请求频率 | 短时间内大量 0x27 0x01,明显高于正常诊断节拍 |
| 种子重复 | 多轮请求返回相同 seed,暴露固定种子实现 |
| 负响应聚集 | 连续出现 0x7F 0x27 0x35(密钥错误) |
| 尝试限制触发 | 出现 0x7F 0x27 0x36(尝试次数超限)或 0x37(延迟未到) |
| 刷写服务 | 出现 0x34、0x36、0x37 组合,且不在售后刷写流程内 |
| 会话维持 | 异常长时间、固定周期的 0x3E 0x80 |
| 来源异常 | 诊断请求来自非诊断仪节点、非授权网关或外部随身设备 |
网关与 ECU 侧痕迹
- 网关诊断路由日志中出现陌生源地址访问受保护 ECU;
- ECU 的安全访问尝试计数增加,或触发锁定状态;
- 编程会话进入记录、刷写计数器变化与故障码(DTC)异常清除;
- 车辆非售后场景下出现诊断会话或例程控制事件,时间与用户使用行为不符;
- 车载 T-Box 日志中出现异常诊断透传请求或远程指令。
检测逻辑示意
若 同一 ECU 在 60 秒内 0x27 0x01 次数 > 阈值
且 连续多轮 seed 相同 -> 固定种子/重放风险
若 0x7F 0x27 0x35 连续出现 >= 3 次 -> 密钥猜测行为
若 非诊断工位时段出现 0x10 0x02 或 0x34 -> 高优先级告警
若 诊断请求源不在授权设备清单内 -> 网关侧阻断并记录
检测阈值必须结合车型的正常诊断节拍标定,否则售后检测、下线检测与 OTA 流程会产生大量误报。
缓解、检测与防御方案
ECU 实现层
- 每会话随机种子:使用硬件随机数发生器生成种子,禁止固定值、计数器或时间戳推导;
- 密码学校验:采用带密钥的算法(如基于 AES-CMAC/HMAC 的挑战响应),秘密值存放在 HSM 或安全存储区,不以明文出现在固件可读区;
- 尝试限制与退避:失败累计达到阈值后返回
0x36并锁定,冷却期内返回0x37,锁定解除需要点火循环或售后设备授权; - 会话绑定:安全等级只在当前会话有效,会话切换、超时或复位后立即失效;
- 前置条件校验:仅在扩展/编程会话且车辆处于允许状态时接受
0x27,避免行驶中解锁; - 常量时间比较:密钥比较使用恒定时间实现,降低时序侧信道风险。
网关与整车层
- 诊断防火墙:网关按源节点、服务白名单过滤
0x27、0x2E、0x31、0x34等敏感服务,外部诊断设备只放行售后必要功能; - 编程会话管控:量产车辆默认关闭编程会话,需售后授权或安全解锁后才能开启;
- 安全启动与签名固件:刷写包必须验签,启动链校验应用完整性,防止绕过 Seed/Key 直接写入恶意固件;
- 入侵检测:在网关或中央计算单元部署 CAN IDS,对诊断流量做频率、序列与来源基线检测;
- 日志留存:记录安全访问失败、锁定、编程会话进入与刷写事件,支持事后追溯;
- 渗透测试与基线核查:在授权台架或仿真环境中验证种子随机性、尝试限制、会话绑定与算法强度。
排查建议
面对疑似事件,优先确认三件事:诊断请求的来源节点是否授权、发生时段是否处于售后或下线流程、ECU 的安全访问计数与刷写计数是否异常。单看某一帧 0x27 无法定性,必须结合会话上下文、来源与车辆状态形成证据链。
实验声明:本文章所有相关实验,均在本人拥有完全授权的自建隔离靶场中完成,仅用于网络安全技术学习、防御方案研究。未经授权对任何信息系统进行测试、攻击属于违法行为。