Block Harbor 是一家专注于汽车网络安全领域的公司,Block Harbor 组织的汽车CTF挑战赛,第一季以教育和乐趣为核心,教授参与者如何嗅探CAN总线并发送控制信息。赛事迅速获得了社区的积极响应,并发展成为一个全球性的活动,吸引了来自亚洲、中东、欧洲和北美的900多名参与者。
第一季赛事结束后,Block Harbor 通过其平台VSEC公开了50个独特的汽车挑战,并提供了5000美元的奖金,激发了更广泛的参与和社区建设。 第二季赛事预计将在2024年8月24日至9月8日举行,奖金池增至10万美元(From Garage to Glory: The Rise of a $100K Automotive Capture the Flag Challenge – Block Harbor)
ICSim
Unlock my door
题目描述:Please download https://github.com/zombieCraig/ICSim and read the instructions to compile/run. Once setup, set the seed value -s 10000 for both the ./controls and ./icsim. Next Answer the following questions. Use any tool you would like in order to arrive at the answers.
What is the arbitration id for door unlocks?
NOTE: Submit in the format 0xARBID
翻译:请下载 https://github.com/zombieCraig/ICSim 并阅读编译/运行说明。设置完成后,为 ./controls 和 ./icsim 设置种子值 -s 10000。下一步回答以下问题。使用任何您想要的工具来获得答案。
门解锁的仲裁 ID 是什么?
注意:以 0xARBID 格式提交
这道题的出题方式还挺不错的,这个 ICSim 本来就支持自定义种子,种子相同的情况下仲裁 ID 是一样的,因此环境让选手自己搭建,主办方指定一个种子就好了
直接参考项目 README 搭建起来后指定种子运行
/icsim vcan0 -s 10000
./controls vcan0 -s 10000
然后开启一个窗口使用 candump -l vcan0 记录一下 CAN 信号,然后操作几次车门(在 controls 界面按键盘右边的 shift + A )结束后让 kimi 写个小脚本,统计一下不同的 CAN ID 出现的次数,例如:
# 导入所需的库
from collections import defaultdict
import re
import sys
def count_can_ids(log_file_path):
# 创建一个字典来存储CAN ID及其出现次数
can_id_count = defaultdict(int)
# 尝试打开并读取candump日志文件
try:
with open(log_file_path, 'r') as file:
for line in file:
# 使用正则表达式提取CAN ID
match = re.search(r'\(\d+\.\d+\)\s+vcan0\s+(\w+)#', line)
if match:
# 将匹配到的CAN ID添加到字典中,并增加其计数
can_id = match.group(1)
can_id_count[can_id] += 1
except FileNotFoundError:
print(f"Error: The file '{log_file_path}' does not exist.")
sys.exit(1)
except Exception as e:
print(f"An error occurred: {e}")
sys.exit(1)
# 打印统计结果
for can_id, count in sorted(can_id_count.items()):
print(f"CAN ID {can_id} appears {count} times.")
# 从命令行参数获取日志文件路径
if len(sys.argv) != 2:
print("Usage: python script.py <path_to_candump_log_file>")
sys.exit(1)
log_file_path = sys.argv[1]
count_can_ids(log_file_path)
我只操作了 5 次车门,那么这里出现 5 次的就是车门解锁的仲裁 ID:5C6 了,提交:0x5C6
Speedometer ArbId
题目描述:Please download https://github.com/zombieCraig/ICSim and read the instructions to compile/run. Once setup, set the seed value -s 10000 for both the ./controls and ./icsim. Next Answer the following questions. Use any tool you would like in order to arrive at the answers.
What is the abritration id for the speedometor display?
翻译:请下载 https://github.com/zombieCraig/ICSim 并阅读编译/运行说明。设置完成后,为 ./controls 和 ./icsim 设置种子值 -s 10000。下一步回答以下问题。使用任何您想要的工具来获得答案。
速度计显示屏的 ID 是什么?
这道题应该是想问仪表盘上显示车速的 CAN ID 是什么,可以使用 cansniffer -c vcan0 高亮显示出变化的 CAN 报文,看了一会,发现当加速到最高速时 0x779 不变了,松开加速键它的值在减少,因此 0x779 就是 flag
VSEC HarborBay
Simulation VIN
题目描述:This challenge is within the Harborbay vehicle simulator on VSEC. From the home page, enter HarborBay. Select the Mach-E UDS Challenge Simulation, then launch the terminal.
Retrieve the VIN of the simulation using UDS.
翻译:此挑战在 VSEC 上的 Harborbay 车辆模拟器中进行。从主页进入 HarborBay。选择 Mach-E UDS 挑战模拟,然后启动终端。
使用 UDS 检索模拟的 VIN。
首先使用 candump -l vcan0 & 把接收到的 CAN 消息保存到日志中,方便查看
使用 cansend vcan0 7df#0322f190发送一个诊断读取 VIN 码的消息,可以看到是 7E8 回复了一部分 VIN 码
因此再发送流控帧把剩余的内容读出来
cansend vcan0 7df#0322f190
cansend vcan0 7E0#3000000000000000
提取 VIN 码后转为 ASCII 得到 flag:flag{v1n_BHmach3}
至于为什么 ID 是 7E0,可以参考这张表,既然 ECU 回复的 ID 是 7E8,那你去请求自然要是 7E0 了
Startup Message
题目描述:This challenge is within the Harborbay vehicle simulator on VSEC. From the home page, enter HarborBay. Select the Mach-E UDS Challenge Simulation, then launch the terminal.
It seems the simulation broadcasts some diagnostic information on arbitration ID 0x7DF when booting up, what does this message say? (in ASCII)
HINT: How can you get an ECU to restart?
翻译:此挑战在 VSEC 上的 Harborbay 车辆模拟器中进行。从主页进入 HarborBay。选择 Mach-E UDS 挑战模拟,然后启动终端。
似乎模拟在启动时广播了一些有关仲裁 ID 0x7DF 的诊断信息,这条消息说了什么?(ASCII 格式)
提示:如何让 ECU 重新启动?
想要看初始的值,那就给他复位一下呗
076730477265336E 转为 ASCII:g0Gre3n
Engine Trouble?
题目描述:This challenge is within the Harborbay vehicle simulator on VSEC. From the home page, enter HarborBay. Select the Mach-E UDS Challenge Simulation, then launch the terminal.
The simulation's engine light is on, can you read the diagnostic code?
Check out our youtube walkthrough if you get stuck: https://www.youtube.com/watch?v=IaUL0dA4Z_Y
The format of the DTC is Pxxxx-xx. Example answer: P1234-01
翻译:此挑战在 VSEC 上的 Harborbay 车辆模拟器内进行。从主页进入 HarborBay。选择 Mach-E UDS 挑战模拟,然后启动终端。
模拟的发动机灯亮了,你能读出诊断代码吗?
如果你遇到困难,请查看我们的 YouTube 演示:https://www.youtube.com/watch?v=IaUL0dA4Z_Y
DTC 的格式为 Pxxxx-xx。示例答案:P1234-01
使用 UDS 的 19 服务查看 DTC,其常用子服务如下:
子功能ID | 子功能描述 |
0x00 | ISO SAE Reserved |
0x01 | Report Number Of DTC By Status Mask |
0x02 | Report DTC By Status Mask |
0x03 | Report DTC Snapshot Identification |
0x04 | Report DTC Snapshot Record By DTC Number |
0x05 | Report DTC Stored Data By Record Number |
0x06 | Report DTC External Data Record By DTC Number |
0x07 | Report Number Of DTC By Severity Mask Record |
0x08 | Report DTC By Severity Mask Record |
0x09 | Report Severity Information Of DTC |
0x0A | Report All Supported DTC |
0x0B | Report First Test Failed DTC |
0x0C | Report First Confirmed DTC |
0x0D | Report Most Recent Test Failed DTC |
0x0E | Report Most Recent Confirmed DTC |
0x0F | Report Mirror Memory DTC By Status Mask |
0x10 | Report Mirror Memory DTC Extended Data Record By DTC Number |
0x11 | Report Number Of Mirror Memory DTC By Status Mask |
0x12 | Report Number Of Emissions OBD DTC By Status Mask |
0x13 | Report Emissions OBD DTC By Status Mask |
0x14 | Report DTC Fault Detection Counter |
0x15 | Report DTC With Permanent Status |
0x16 | Report DTC Extended Data Record By Record Number |
0x17 | Report User Defined Memory DTC By Status Mask |
0x18 | Report User Defined Memory DTC Snapshot Record By DTC Number |
0x19 | Report User Defined Memory DTC Extended Data Record By DTC Number |
0x1A – 0x41 | ISO SAE Reserved |
0x42 | Report WWH OBD DTC By Mask Record |
0x43 – 0x54 | ISO SAE Reserved |
0x55 | Report WWH OBD DTC With Permanent Status |
0x56 – 0x7F | ISO SAE Reserved |
这次来使用状态掩码读取 DTC,也就是 02 子服务,但掩码是啥呢,定义如下,我们来读 confirmedDTC,也就是 bit3 为 1,其余为 0,0000 1000 => 08
Bit | Meaning |
0 | testFailed |
1 | testFailedThisMonitoringCycle |
2 | pendingDTC |
3 | confirmedDTC |
4 | testNotCompletedSinceLastClear |
5 | testFailedSinceLastClear |
6 | testNotCompletedThisMonitoringCycle |
7 | warningIndicatorRequested |
cansend vcan0 7DF#03190208
收到:7E8#075902083E9F01AB
对收到的数据 3E9F01AB 进行解析,前两位有一个对应关系
00 | P 动力总成 |
01 | C 底盘 |
10 | B 车身 |
11 | U 网络 |
根据这个表进行解析,但根据提示,应该后面还跟着东西,所以把后面的 01 也带上得到:P3E9F-01
参考:https://blog.csdn.net/qq_40309666/article/details/133955750?spm=1001.2014.3001.5501
Secrets in Memory?
题目描述:This challenge is within the Harborbay vehicle simulator on VSEC. From the home page, enter HarborBay. Select the Mach-E UDS Challenge Simulation, then launch the terminal.
It seems the simulation allows access to only some off-chip sections of memory, are there any secrets in the visible memory?
The memory region starts at 0xC3F80000 and the flag is in the format flag{...}.
翻译:这项挑战在 VSEC 上的 Harborbay 车辆模拟器中进行。从主页进入 HarborBay。选择 Mach-E UDS 挑战模拟,然后启动终端。
似乎模拟只允许访问一些片外内存部分,可见内存中有什么秘密吗?
内存区域从 0xC3F80000 开始,标志的格式为 flag{...}。
读 0xC3F80000 这块的内存,那就是用 UDS 的 23 服务了
cansend vcan0 7DF#072314C3F80000FF
其中 07 表示诊断报文的长度,23 表示子功能,14 表示要读取的 size 是用 1 个字节表示的,地址是用 4 个字节表示的,后面紧跟地址 C3F80000 和 size:FF
cansend vcan0 7E0#3000000000000000 再发个流控帧
然后又试了试后面很多地址全是空的,最终忍不了了,写个脚本吧,才发现机器上带着 python-can 的库...
import can
import time
import binascii
bus = can.Bus(interface='socketcan', channel='vcan0')
bus.set_filters([{"can_id": 0x7E8, "can_mask": 0xFFF, "extended": False}])
recvdata = "[DATA]:"
for hex_value in range(0xC3F83000, 0xc3f87000, 0xFF):
byte1 = (hex_value >> 24) & 0xFF
byte2 = (hex_value >> 16) & 0xFF
byte3 = (hex_value >> 8) & 0xFF
byte4 = hex_value & 0xFF
candata=[0x07, 0x23, 0x14, byte1, byte2, byte3, byte4, 0xFF]
message = can.Message(arbitration_id=0x7DF, is_extended_id=False, dlc=8, data=[0x02, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00])
bus.send(message, timeout=0.2)
msg = bus.recv()
message = can.Message(arbitration_id=0x7DF, is_extended_id=False, dlc=8, data=candata)
bus.send(message, timeout=0.2)
msg = bus.recv()
recvdata += binascii.hexlify(msg.data).decode('utf-8')[6:]
message = can.Message(arbitration_id=0x7E0, is_extended_id=False, dlc=8, data=[0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
bus.send(message, timeout=0.2)
temp = 0
while temp < 36:
msg = bus.recv()
tempdata = binascii.hexlify(msg.data).decode('utf-8')[2:]
if tempdata != "00000000000000":
recvdata += tempdata
temp = temp + 1
print("\n========== READMEM ==========")
print(recvdata)
print("========== READMEM ==========\n")
bus.shutdown()
这距离给的地址也太远了吧... 幸亏没手敲
得到 flag:flag{mem+r34d}
Security Access Level 3
题目描述:This challenge is within the Harborbay vehicle simulator on VSEC. From the home page, enter HarborBay. Select the Mach-E UDS Challenge Simulation, then launch the terminal.
The simulation is implementing service 0x27 Security Access Level 3 using MAAATH. Can you find the key and break in?
The flag is the key to unlock with seed 1337 in hex (example a5a5)
Unlock Hint for 0 points
flag is the two bytes of key you send (example: 55aa)
翻译:此挑战在 VSEC 上的 Harborbay 车辆模拟器内进行。从主页进入 HarborBay。选择 Mach-E UDS 挑战模拟,然后启动终端。
模拟正在使用 MAAATH 实现服务 0x27 安全访问级别 3。你能找到钥匙并闯入吗?
标志是使用十六进制种子 1337 解锁的钥匙(例如 a5a5)
解锁提示 0 分
标志是您发送的两个字节的密钥(例如:55aa)
这道题提示了个:MAAATH,应该是 MATH,数学的意思,然后就他妈的没有然后了...
俺想问问看这篇文章的师傅们,让你想,你能想到什么???我写了个脚本爆破了一下,跑了几次就返回 NRC 36 了(尝试获取安全访问次数的次数超过了服务器的安全策略允许的次数)
倒是每次先给 ECU reset 一下是可以的,虽然只有两个字节,但是我感觉不抱希望,而且题目要求你解出来特定 seed 的 key 但爆破成功次数比较少的话怕是也不好找规律吧... 例如题目说种子是 0x1337 时的 key,我不觉得我能恰好爆破到一个 0x1337 的 seed 的 key...
然后在 github 发现了有人写了 wp,说是 seed 取反(一开始机翻是补码,后来看代码应该是直接取反)
0x1337 = 0001001100110111
按位取反
1110110011001000
最终得到 ecc8 也就是 flag
这好歹提示个位操作也行哇... 给自己做个表情包笑死哈哈哈
写了个脚本跑了几次,确实是对的(6704 表示通过了安全访问)
Security Access Level 1
题目描述:This challenge is within the Harborbay vehicle simulator on VSEC. From the home page, enter HarborBay. Select the Mach-E UDS Challenge Simulation, then launch the terminal.
Level 3 provides access to a new diagnostic session and some new memory at 0x1A000, but we still don't have full control of the module. Can you provide a valid key for security access level 1?
The flag is the key to unlock with seed 7D0E1A5C in hex (example 12345678)
翻译:此挑战在 VSEC 上的 Harborbay 车辆模拟器内进行。从主页进入 HarborBay。选择 Mach-E UDS 挑战模拟,然后启动终端。
级别 3 提供对新诊断会话和 0x1A000 处的一些新内存的访问,但我们仍然无法完全控制该模块。您能为安全访问级别 1 提供有效的密钥吗?
该标志是使用十六进制种子 7D0E1A5C(例如 12345678)解锁的密钥
题目说,通过了安全访问级别 3 后可以读取 0x1A000 处的新的内存访问,那就通过安全访问 level3 后读取这块内存看看到底存了些啥
解码也没得到啥:
写个脚本加长长度读一下看看,读取范围设置到 0x1A000 到 0x1AFFF,可以看到,在后面会记录请求的种子,跟在种子后面还有一串值,长度和种子一样的
多请求几次,记录如下:
9102870c c43b2d1b
d64217a8 837bbdbf
241adbeb 712371fc
9bb26411 ce8bce06
找规律,发现两个异或结果始终为:0x5539aa17,因此猜测该算法是使用种子异或 0x5539aa17
根据猜想的算法尝试通过安全访问 level1 成功
因此,此题 flag 为 7D0E1A5C 异或 0x5539aa17 即:2837b04b