VSEC 车联网安全 CTF 挑战
Getting Started
Can you find the interface?
输入 ifconfig,根据 CAN 接口的命名规则(canX、vcanX、slcanX)判断 vcan0 是对应的 can 接口
flag:vcan0
Arbitration
利用 candump
命令可捕获到 CAN
总线传输的数据流,其中,内容分别为:sniffer device | arbitration ID |
size of the CAN packet | CAN data itself
1 | b9c80e7d115e:~$ candump vcan0 |
CAN 数据流通过 Arbitration ID 标记每一条消息
这里周期性消息的 Arbitration ID 是 59E
flag:59E
Data Field 1
数据流中 Arbitration ID 后面跟的就是 CAN 数据包的大小(size of the CAN packet):[2]
flag:2
Data Field 2
CAN 数据包大小后面跟着的即为传输的 CAN 数据,按照题目格式 Format: XXYY
flag:9E10
Message Frequency
通过 candump
的-l
命令行选项可创建日志文件,日志文件内容为:timestamp,
bus, arbitration ID, data ( #
符号分割 arbitration ID 和
data )
1 | b9c80e7d115e:~$ candump -L vcan0 |
根据dump出来两次数据的时间差的倒数,得到频率 \[ Δt = \frac{\sum_{i=1}^{n} (t_{i+1} -t_{i} )}{n} ≈ 1 \] f = 1/Δt = 1
flag:1
VSEC Garage: UDS Challenge
Simulation VIN
涉及到 ISO-TP 的原理,有一个 单帧通信(Single-frame communication) 转变到 多帧通信(Multi-frame communication) 的过程
题目要求读取 VIN 码,发送一个 单帧(Single Frame, SF) 从 ECU 请求到这个数据即可
一个的 UDS 请求帧的示例如下图:
CAN ID | 协议控制信息(PCI) | UDS服务标识符(SID)| 子功能字节 | 请求数据
通过 ifconfig
命令得到 CAN 总线接口名称
为 vcan0
然后选择使用的 CAN ID ,通常是按照下表成对的(发送与接收):
每个 ECU 都对应一个 CAN ID,一般情况下CAN
ID:0x7E0
为发动机控制模块(ECM);0x7E1
为变速箱控制模块(TCM),0x7E2
为刹车/ABS
控制模块;0x7E3
到
0x7E7
用于其他模块或预留。(未知 ECU 可通过
cansend 0x7fd
,然后看哪个 ECU 回应去逆推)这里我们使用
0x7E0
和 0x7E8
单帧的 PCI 高 4 位固定为 0x0
,低 4
位为数据长度,对应是SID和DID字节数之和0x3
(如果清楚数据的长度,超过7字节就可以直接按多帧)
然后我们需要用到 服务标识符号(SID) 是
0x22
(读取数据标识符)
,用来实现数据读取。前面示例图中我们通过UDS单帧通信读取数据,那
SID 固定就是 0x22
按照单帧通信的规则,我们还需要 DID
作为参数标识符,明确我们要读取的是什么数据,题目要求读取VIN码,那对应下表即为:
0xF190
最后我们要实现这个单帧通信的请求,需要遵守 ISO-TP 传输协议,我们用
isotpsend
和 isotprecv
工具
先在tmux新建窗口接收
1 | isotprecv -s 7E0 -d 7E8 vcan0 | xxd -r -p |
发送请求
1 | echo "22 F1 90" | isotpsend -s 7E0 -d 7E8 vcan0 |
得到flag:flag{v1n_BHmach3}
但是如果通过 cansend
命令就会发现,第一次send之后是拿不到完整VIN码的,这个时候涉及到
单帧通信(Single-frame communication) 到 多帧通信(Multi-frame
communication) 的转变
ISO-TP协议的多帧通信消息格式如下:
由于 cansend vcan0 7df#0322f190
请求之后得到响应的8字节消息中大小是0x14
,说明我们得到的VIN码并不完整,此时我们按
Flow Control
格式请求剩余帧即可:cansend vcan0 7e0#300000000000000000
flag:flag{v1n_BHmach3}
Startup Message
提示 HINT: How can you get an ECU to restart?
对应 ECU Reset 的 SID 为 0x11
其中 0x11 SID 的子函数(Sub Function Byte)如下:

我们 cansend 7df#021101
硬重置 ECU 得到 flag
1 | (1735679058.851364) vcan0 7DF#076730477265336E |
解码得到flag:g0Gre3n
flag:g0Gre3n
Engine Trouble?
读取 diagnostic code 的 SID 为 0x19:

子功能字节如下:
接下来设置 Status Mask:
Acronym | Description |
---|---|
UDS status bit 0 | testFailed bit of the UDS status byte. Indicates the result of the most recently performed test. |
UDS status bit 1 | testFailedThisOperationCycle bit of the UDS status byte. Indicates whether or not a diagnostic test has reported a testFailed result at any time during the current operation cycle. |
UDS status bit 2 | pendingDTC bit of the UDS status byte. Indicates whether or not a diagnostic test has reported a testFailed result at any time during the current or last completed operation cycle. |
UDS status bit 3 | confirmedDTC bit of the UDS status byte. Indicates whether a malfunction was detected enough times to warrant that the DTC is desired to be stored in long-term memory. |
UDS status bit 4 | testNotCompletedSinceLastClear bit of the UDS status byte. Indicates whether a DTC test has ever run and completed since the last time a call was made to ClearDiagnosticInformation. |
UDS status bit 5 | testFailedSinceLastClear bit of the UDS status byte. Indicates whether a DTC test has completed with a failed result since the last time a call was made to ClearDiagnosticInformation. |
UDS status bit 6 | testNotCompletedThisOperationCycle bit of the UDS status byte. Indicates whether a DTC test has ever run and completed during the current operation cycle. |
UDS status bit 7 | warningIndicatorRequested bit of the UDS status byte. Report the status of any warning indicators associated with a particular DTC. |