前言:本文严格来说不能算作渗透性测试(penetration test),毕竟有相对明确的测试用例和判断标准,威胁点也都是业界早就已知的,实际上是一个偏验证性+Fuzzing和遍历的测试思路
信息收集阶段
1. 扫描ECU
遍历所有CAN ID,发送02 10 01
/02 10 02
/02 10 03
等会话切换命令,如果有响应则说明该CAN ID指向特定ECU。Extend ID理论也可以进行扫描,不过最好能提前确定范围。
有时会存在一个CAN ID对应多个回复的情况,说明该ID为功能寻址 通常为7DF
2. 扫描服务和子服务
在第一步已经获取到所有ECU ID的基础上,遍历ECU支持的服务。由于UDS规定的SID只有一个字节,因此只需要遍历00-FF,参数部分可以适当随机一两个字节。
例如遍历 03 【00-FF】 01 01
,有+0x40的响应就说明ECU支持该服务。
获取到ECU支持的服务后,即可以开始遍历DID或子服务ID,如对于31 Routine Control、22 Read Data By DID而言,需要至少遍历两个字节,而对10 Session Control而言,遍历一个字节便足够。判断标准仍然是看是否有+0x40的响应
威胁建模阶段
1. Session切换及复位(10 11)
Session Control(10)常见威胁为:未限制切换条件、未设定复归条件
复位(11)常见威胁为:未限制响应条件
主要测试方法如下
Session切换:分别在车辆静止、车辆低速行驶、车辆高速行驶、车辆低电量、车辆远程等工况中随机发送 02 10 02
和 02 10 03
,观察车内ECU的响应情况,动作情况,在车辆行驶时不应该响应,也不能出现进入编程模式(02 10 02
)后无法恢复到普通模式(02 10 01
)的情况。
复位: 分别在车辆静止、车辆低速行驶、车辆高速行驶、车辆升级等工况中随机发送02 11 01
02 11 02
02 11 03
,观察车内ECU响应情况。进阶版还可以在上一步基础上,分别在不同的Session中发送复位命令,观察车辆状态。
2. 安全访问(27)
安全访问常见威胁为:种子随机度不足、未限制Seed尝试次数、未限制Key尝试次数、安全算法泄露等
主要测试方法如下
种子随机度及Seed尝试次数测试:切换到编程模式或扩展模式下多次发送02 27 01
,观察Seed的长度,Seed是否会更新,更新是否有规律。一般认为Seed Key在4字节以上才算基本安全
Key尝试次数测试: 以Key为4字节为例,发送02 27 01
后,遍历发送06 27 02 【AA BB CC DD】
,观察消极响应的错误码是否会发生改变。
安全算法泄露: 可以通过地下论坛、买通企业内部人员、Tier1泄露、固件逆向等找到原始的诊断Key算法。还可以通过购买通用的诊断仪如X-431,各种清DTC设备等,分析多个解锁Seed Key找出规律。
3. 服务执行(31及隐藏服务)
对于31服务,分别尝试在各Session下(10 02 /10 03)执行该服务
参数从0-3个字节开始遍历
例子:04 31 【AA AA】 01
=> 07 31 【AA AA】 01 23 34 45
4. 固件刷写 (34 36 37 )
固件刷写中主要威胁点在于34 36未做相关的限制条件。使其可以在不进行安全认证或不安全的条件下进行刷写。
测试方法:
分别尝试在普通模式、编程模式、扩展模式下发送固件刷写相关命令
以及参照 1中Session切换的条件,发送相关命令。
随着各种FOTA上线,软件DL相关的疏忽已经很少了,主要期待Tier1犯傻
5. 参数配置读写 (22 23 2D 2E)
量产项目上UDS上比较少见23和2D,一般会在开发时再专门的Calibration CAN用CCP协议对固件进行内存分析读写等。
测试方法基本同3 ,考虑到内存地址的长度,参数的遍历字节数需要更多一点
6. 其他捣乱服务(85 28)
分别在测试1中的各种条件(静止、行驶、低电压等)上发送28命令和85命令,观察车内ECU是否有响应和动作。
实际测试中某些整车发送28后,整车控制会部分失灵、仪表显示也会异常,但一般动力相关ECU仍能正常动作(也可能进入失效模式)
漏洞利用阶段
假设在威胁建模阶段发现了若干UDS漏洞,那么可以使用UDS漏洞对车辆造成如下攻击
- 静止或运行状态下使车辆黑屏、关闭发动机、进入自检模式(如喇叭蜂鸣、雨刷自己动、车窗自动上下)
- 刷写篡改ECU固件、严重可能导致车辆无法启动,功能失效
- 获取任何ECU发送CAN总线权限后,通过UDS对同网段的ECU进行攻击,使其停止响应等
美女大佬,请问为什么seedkey在4字节以上才算安全呢
如果seedkey过短的话,可能出现多次请求遍历所有key的可能
或者如果能抓成功一个challenge-response对,则请求多次总有一个能匹配上
写的不错,支持!