漏洞/实验概述

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 交互流程

  1. 诊断仪发送 0x27 0x01 请求等级 1 的种子;
  2. ECU 生成并返回种子(正响应 0x67 0x01 <seed>);
  3. 诊断仪用厂商约定的算法把种子与秘密值计算出密钥;
  4. 诊断仪发送 0x27 0x02 <key>;
  5. 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 不再是秘密,而只是一个需要正确实现的校验步骤。

攻击链路分析

以下描述攻击者从接触到解锁的完整思路,省略任何具体的密钥推导代码与工具参数。

  1. 接触总线:通过 OBD-II 接口(CAN-H 为 6 脚、CAN-L 为 14 脚)、车载诊断座、网关调试口,或在具备网络访问能力时经车机/Telematics 单元转向车内网络。
  2. 发现诊断目标:被动监听或主动扫描诊断 CAN ID,识别 0x7E0–0x7E7 的请求响应关系,确认目标 ECU 与支持的会话类型。
  3. 进入扩展会话:发送 0x10 0x03,并按需周期发送 0x3E 0x80 维持会话,避免超时回到默认会话。
  4. 请求种子:发送 0x27 0x01,记录返回的种子长度与取值。
  5. 分析算法:在授权靶场中对比多轮种子与固件静态分析结果,判断算法是固定映射、线性变换还是带密钥的密码学运算。此步骤通常离线完成。
  6. 提交密钥:发送 0x27 0x02 与计算出的密钥,观察正响应或负响应,根据 NRC 调整策略。
  7. 执行敏感操作:解锁后可调用写入数据 0x2E、例程控制 0x31、请求下载 0x34、数据传输 0x36、传输退出 0x37,在编程会话下完成刷写,最后用 0x11 复位使新配置生效。
  8. 持久化与影响:修改标定参数、关闭故障监测、写入自定义数据,或替换应用分区。对整车而言,影响可能是动力、制动、座舱功能被非授权改变。

需要区分两种场景:授权靶场中上述流程用于验证防护强度;未授权实车上执行同样步骤即构成非法侵入。本文的实验与结论均限定在前者。

攻击痕迹与日志特征

总线与诊断流量特征

观察点可疑特征
会话切换非诊断工位时段出现 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 无法定性,必须结合会话上下文、来源与车辆状态形成证据链。

实验声明:本文章所有相关实验,均在本人拥有完全授权的自建隔离靶场中完成,仅用于网络安全技术学习、防御方案研究。未经授权对任何信息系统进行测试、攻击属于违法行为。