跳转至

CAN总线CTF题目

CAN总线CTF题目

2020网鼎杯 青龙组 teslaaaaa

附件需改为 zip,wp:https://blog.csdn.net/Breeze_CAT/article/details/106156567

teslaaaaa.pdf

给了一段 CAN 报文,通过报文数据可以很明显看出来是进行 UDS 诊断的,那就一点一点梳理一下整个流程

4.000621 1  7DF             Tx   d 8 02 3E 80 00 00 00 00 00  会话保持
9.498709 1  7DF             Tx   d 8 02 10 02 AA AA AA AA AA  切换编程会话
9.740585 1  730             Tx   d 8 02 27 05 AA AA AA AA AA  请求安全访问种子
9.741697 1  7B0             Rx   d 8 06 67 05 11 22 33 44 00  返回安全访问种子
9.782739 1  730             Tx   d 8 06 27 06 EE DD CC BB AA  发送安全访问密钥
9.783703 1  7B0             Rx   d 8 02 67 06 00 00 00 00 00  通过安全访问

接下来是用 31 服务,来指定擦除的参数有地址和大小,因为一条 CAN 总线指令不够用,因此是用了流控帧,实际需要将两条指令连起来

9.788131 1  730             Tx   d 8 10 0D 31 01 FF 00 44 08  
9.788431 1  7B0             Rx   d 8 30 08 00 00 00 00 00 00  流控帧
9.788947 1  730             Tx   d 8 21 00 00 00 00 00 20 00
9.789707 1  7B0             Rx   d 8 05 71 01 FF 00 00 00 00  
31 01 FF 00 44 08 00 00 00 00 00 20 00

其中 31 表示 RoutineControl 用来执行一些已经定义好的步骤序列也叫例程,他有三个子功能:01 表示开始,02 表示停止,03 表示获取结果;FF00 表示擦除 flash,44 表示后面两个参数的长度(第7至第4位: memorySize参数的长度,第3至第0位: memoryAddress参数的长度),也就是地址为:0x08000000,长度为:0x00002000

请求下载 34,这个服务没有子功能,后面的 00 有厂商自定义,高半字节指定压缩法,低半字节指定加密法;再后面的 44 和上面一样是参数长度;请求下载地址为:0x08000000,长度为:0x00002000

9.791765 1  730             Tx   d 8 10 0B 34 00 44 08 00 00
9.792061 1  7B0             Rx   d 8 30 08 00 00 00 00 00 00
9.792625 1  730             Tx   d 8 21 00 00 00 20 00 AA AA
9.793715 1  7B0             Rx   d 8 04 74 20 01 02 00 00 00  

然后就是用 36 服务具体传输了,36 后面的 01 是 blockSequenceCounter 这个 block 计数器满了之后再从 0x00 开始

9.795696 1  730             Tx   d 8 10 82 36 01 28 04 00 20
9.795987 1  7B0             Rx   d 8 30 08 00 00 00 00 00 00
9.796548 1  730             Tx   d 8 21 45 01 00 08 21 03 00
9.796790 1  730             Tx   d 8 22 08 23 03 00 08 27 03 

中间刷写具体刷了啥先不看,这样也没法看,到后面刷写完成

10.312946 1  7B0             Rx   d 8 02 76 40 00 00 00 00 00  刷写完成
10.314499 1  730             Tx   d 8 02 37 01 AA AA AA AA AA  退出传输
10.318529 1  730             Tx   d 8 04 31 01 DF FF AA AA AA  
10.322633 1  730             Tx   d 8 04 31 01 FF 01 AA AA AA  这两条应该是后续的检查
10.325697 1  7DF             Tx   d 8 02 11 01 AA AA AA AA AA  ECU复位

那就把这些过程性的东西删一删,然后把所有 RX 的数据也删掉,剩下的就是纯发数据的了

1716277300733-a9961a10-29b7-482b-b574-6a3a474f50d8.png

用 python 过滤一下没用的字符和控制字段,输出为纯二进制文件

f = open('ecu_can_log.asc', 'r')
f1 = open('result', 'wb')

list1 = f.readlines()
data=[]
count=1
for i in list1: 
    if(count%19==0):    #19行是数据传输的最后一行,后面有两个AA是不要的
        data=i[43:57]
    elif(count%19==1):  #每次传输的第一行要去掉传输协议头
        data=i[52:63]
    else:
        data=i[43:63]   #其他中间传输的报文,直接去掉UDS网络层即可
    data = bytes.fromhex(data)
    f1.write(data)
    count+=1

然后用 IDA 打开,通过字符串就可以定位到假的 flag 了... 离谱,但是逻辑很简单,基本复制代码就能解出来

fakeflag = "canoecr7-zd9h-1emi-or8m-f8vm2od81nfk"
a1 = []
for i in fakeflag:
    a1.append(ord(i))
a1[2] -= 13;
a1[11] -= 5;
a1[15] -= 44;
a1[3] -= 11;
a1[5] -= 48;
a1[7] += 43;
a1[28] += 50;
a1[31] += 46;
a1[19] -= 13;
a1[20] -= 66;
a1[1] += 3;
a1[29] -= 55;
a1[24] -= 51;
a1[9] -= 23;
a1[25] -= 6;
a1[27] -= 60;
a1[4] -= 52;
a1[6] -= 14;
a1[30] -= 52;
a1[22] -= 58;
a1[12] -= 48;
a1[16] -= 56;
a1[34] -= 53;
a1[0] -= 48;
a1[14] += 3;
a1[17] -= 5;
a1[33] -= 55;
a1[35] -= 56;
a1[10] -= 2;
a1[26] -= 67;
a1[21] -= 6
print("".join(chr(x) for x in a1))

2023工业信息安全技能大赛-车联网安全锦标赛-线上赛

感谢 g0at 师傅提供题目附件

CAN RSA

https://g1at.github.io/2023/11/24/2023%E5%85%A8%E5%9B%BD%E6%99%BA%E8%83%BD%E9%A9%BE%E9%A9%B6%E6%8C%91%E6%88%98%E8%B5%9B/#CAN-RSA

can通信三字经

https://g1at.github.io/2023/11/24/2023%E5%85%A8%E5%9B%BD%E6%99%BA%E8%83%BD%E9%A9%BE%E9%A9%B6%E6%8C%91%E6%88%98%E8%B5%9B/#can%E9%80%9A%E4%BF%A1%E4%B8%89%E5%AD%97%E7%BB%8F

原文: https://www.yuque.com/hxfqg9/iot/gwd2lzo8ycp5xen9