2024年底,某自主品牌4S店的技术主管老张遇到了件怪事。一位车主来店里做常规保养,顺口提到:“上周我在外面一个汽修店刷了ECU程序,动力确实提上去了,但仪表盘偶尔会弹出一个黄色的故障灯。”
老张连上诊断仪一看——ECU的软件版本号不对,而且安全访问(Security Access, 0x27服务)的失败计数器是0。这说明刷机者不是暴力破解了安全访问,而是直接绕过了它。
后来厂家安全团队溯源发现,这家汽修店使用的"刷机盒子"利用了该车型ECU中UDS 0x34(请求下载)和0x36(传输数据)两个服务在安全访问状态校验上的一个逻辑漏洞——在特定时序下,即使0x27服务返回了否定响应,后续的刷写操作仍然可以继续执行。这个漏洞影响了该品牌旗下至少4款车型,涉及约15万台车。
一、UDS诊断协议:一把被低估的万能钥匙
UDS(Unified Diagnostic Services,统一诊断服务)是ISO 14229定义的车载诊断通信协议。它的设计初衷是让诊断工具能够读取ECU的故障码、查看实时数据、执行功能测试、更新固件——简单说,它是车载ECU的"统一管理后台"。
UDS定义了几十个服务ID(SID),其中的高风险服务包括:
| 服务ID | 服务名称 | 功能 | 风险等级 |
|---|---|---|---|
| 0x10 | 诊断会话控制 | 切换默认/编程/扩展会话 | 高 |
| 0x27 | 安全访问 | Seed-Key认证解锁ECU | 关键 |
| 0x2E | 通过ID写入数据 | 直接修改ECU内部数据 | 高 |
| 0x31 | 例程控制 | 触发ECU特定功能(如擦除内存) | 高 |
| 0x34 | 请求下载 | 发起固件下载请求 | 关键 |
| 0x36 | 传输数据 | 传输固件数据块 | 关键 |
| 0x37 | 请求退出传输 | 完成固件传输 | 高 |
| 0x3D | 通过地址写入内存 | 直接写ECU内存地址 | 极高 |
一个正确的安全设计逻辑是:这些高风险服务在执行前,必须先通过0x27安全访问认证。但在工程实践中,这个检查逻辑往往存在各种"裂缝"——而且这些裂缝不是在OBD口才暴露的。
二、攻击面一:0x27安全访问的算法级弱点
0x27服务的工作流程是:诊断工具发0x27 0x01请求Seed → ECU返回一个随机数(Seed)→ 诊断工具用预置的算法对Seed做运算得到Key → 发送0x27 0x02请求Key → ECU验证通过后解锁。
理论上,Seed是随机数,Key依赖保密算法,安全性应该没问题。但现实中:
问题一:Seed不是真随机。很多ECU使用软件实现的伪随机数生成器(PRNG),其种子可能来自ECU上电后的定时器值。如果攻击者能控制或预测上电时机(比如通过CAN总线发送特定报文触发ECU复位),就能大幅缩小Seed的搜索空间。
问题二:Key算法被逆向。大多数ECU的0x27 Key算法实现在应用层固件中,没有放在HSM的安全区域内。攻击者只需要通过JTAG/SWD接口提取出固件,用IDA Pro反编译,找到0x27服务的处理函数,逆向出Key的生成逻辑——整个过程在一台配置过得去的笔记本电脑上,快则半天、慢则两天就能完成。
问题三:故障注入绕过。2023年,安全研究人员在欧洲黑客大会上演示了通过电压故障注入(Voltage Fault Injection)攻击0x27服务:在ECU执行Key验证的精确时间窗口施加一个电压脉冲,导致验证逻辑跳过——无论Key对不对,ECU都返回肯定响应。这种攻击不需要任何软件漏洞,纯粹物理层面操作。
三、攻击面二:会话状态机的逻辑漏洞
UDS协议定义了三种诊断会话:默认会话(0x01)、编程会话(0x02)、扩展会话(0x03)。安全访问认证与不同会话绑定——在默认会话下通过了0x27认证,切换到编程会话后需要重新认证。
但很多ECU的实现在这里出现漏洞:
漏洞模式一:会话切换不清除认证状态。攻击者在默认会话下通过0x27认证后,发送0x10 0x02切换到编程会话,如果ECU没有清除认证标志,攻击者就直接获得了编程会话的全部权限——可以擦除内存、刷写固件。
漏洞模式二:编程会话下绕过0x27。某些ECU在编程会话下直接允许0x34(请求下载)操作,不做任何安全访问校验。原因是开发阶段为了方便调试,将编程会话设计为"信任态"——结果量产版本忘记改回来。
漏洞模式三:负响应仍然解锁。这就是开篇案例中的问题:攻击者发送错误的Key后,ECU虽然返回了否定响应码(NRC 0x35),但因为代码实现中状态机的处理顺序错误,在返回否定响应之前已经把"认证通过"标志置位了。后续的0x34请求被允许执行。
四、攻击面三:DoIP让远程诊断成为可能
传统的UDS诊断通过CAN总线 + OBD-II接口进行,攻击者需要物理接触车辆。但新一代车型大量使用DoIP(Diagnostics over IP,基于车载以太网的UDS诊断),这意味着UDS诊断服务可以通过TCP/IP网络远程访问。
DoIP的ISO 13400标准定义了车辆发现、路由激活、诊断通信等流程。标准虽然建议了安全措施(TLS加密、客户端认证),但在实际部署中:
- 部分车型的DoIP服务端口(13400)直接暴露在车载Wi-Fi子网中,没有任何网络层过滤
- TLS证书校验可能被跳过(常见于"为了方便售后诊断"的内部决定)
- 即使有TLS,某些车企使用的是自签名证书或不安全的证书链
一旦攻击者通过车载Wi-Fi或蓝牙接入车内网络,就可以直接向网关ECU发送DoIP诊断请求,从而远程执行0x27解锁、0x34固件下载、0x3D内存写入等高危操作——物理接触不再是必要条件。
五、防御方案:四层防护模型
面对UDS诊断协议的攻击面,单点防御是不够的。推荐四层纵深防护:
第一层:硬件安全隔离
0x27的安全访问Key算法、Seed生成、认证状态机,应当全部放在HSM内部的安全域中执行,而不是应用层固件里。HSM的Secure Element提供防物理攻击、防侧信道分析的能力,杜绝固件逆向和故障注入攻击。对于Key算法,使用HSM内部的真随机数生成器(TRNG)替代软件PRNG,确保Seed的不可预测性。
第二层:会话状态机加固
对诊断会话切换做严格的安全审计:每次从默认会话切换到编程/扩展会话时,强制清除认证标志;编程会话下执行0x34/0x36/0x37服务前,强制检查认证状态(不是检查是否收到过0x27请求,而是检查0x27是否返回了肯定响应)。代码层面,确保否定响应在清除认证标志之前返回。
第三层:网络层访问控制
对于DoIP,在网关ECU上实施严格的访问控制:DoIP通信端口仅对经过认证的设备开放;TLS双向认证必须启用(同时验证客户端和服务器证书);对于不需要远程诊断的车型,直接关闭DoIP服务。车载防火墙应当默认阻断所有到13400端口的非授权连接。
第四层:运行时监控
部署车载入侵检测系统(IDS),监控异常诊断流量:比如短时间内大量0x27失败尝试(暴力破解特征)、非正常时序的诊断会话切换、非工作时间段(如凌晨3点)的诊断操作。当检测到异常模式时,触发报警并临时锁定ECU的诊断功能。
六、总结
UDS诊断协议是一把双刃剑——它既是售后诊断的必需工具,也是整车安全体系中最容易被忽视的攻击入口。OBD口只是物理攻击面的冰山一角,隐藏在UDS协议实现中的逻辑漏洞、DoIP带来的远程攻击面、以及故障注入这类物理侧信道攻击,才是真正需要汽车安全工程师持续关注的领域。
对于主机厂,建议在下一轮TARA分析中,把"UDS服务的状态机安全性"单独列为威胁场景进行评估——而不仅仅是把"OBD口物理防护"列在列表里。
你们在做ECU安全测试时,有没有发现过UDS方面让你"倒吸一口凉气"的漏洞?欢迎评论区分享。