2024 第四届“长城杯”网络安全大赛 Reverse Writeup
封面:X@篤見唯子
虽然比赛时间短,但至少不用像羊城杯一样熬夜
Reverse
easyre
根据反编译代码结合动调后发现只是简单的异或,但只能得到部分flag,后来发现在比较的数据下面有更全的加密后数据,提取出来解密可得
1 2 3 4 5 6 7 8 data = '0d774a04070301575303555405574F4B5100564C4E540102191B00570549140A04030D5F05051D1C060D0A54' last = 50 for i in range (43 , -1 , -1 ): char = int (data[i * 2 :i * 2 + 2 ], 16 ) ^ last print (chr (char), end='' ) last = char
tmaze
动态调试发现迷宫存在内存中,利用地址跳转来走迷宫。经分析后发现和之前数字中国创新大赛半决赛的 HardTree 大同小异,直接把之前的脚本改改就能用了。
首先开启动调后将迷宫所在的内存使用脚本dump出来
1 2 3 4 auto i,fp; fp = fopen("E:\\a\\ctf\\ccb\\re\\tmaze_16A051A0000_16A051B3000.dmp" ,"wb" );for (i = 0x16A051A0000 ; i <= 0x16A051B3000 ; i++) fputc(Byte(i),fp);
然后走迷宫
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 base_addr = 0x16A051A0000 start_addr = 0x16A051B1480 - base_addr end_addr = 0x16A051B1840 - base_addr dump_file = open ('tmaze_16A051A0000_16A051B3000.dmp' , 'rb' ) file = dump_file.read()def bytes_to_addr (byte_str ): num = 0 for ch in byte_str[::-1 ]: num *= 256 num += ch return num have_node = [] node_path = []def read_node (node ): if node not in have_node: if node == end_addr: print ('' .join(node_path)) exit() have_node.append(node) x_node = bytes_to_addr(file[node:node + 8 ]) - base_addr y_node = bytes_to_addr(file[node + 8 :node + 16 ]) - base_addr z_node = bytes_to_addr(file[node + 16 :node + 24 ]) - base_addr if x_node > 0 and file[node+24 ] == 0 : node_path.append('x' ) read_node(x_node) node_path.pop() if y_node > 0 and file[node+25 ] == 0 : node_path.append('y' ) read_node(y_node) node_path.pop() if z_node > 0 and file[node+26 ] == 0 : node_path.append('z' ) read_node(z_node) node_path.pop() have_node.pop() read_node(start_addr)
得到flag{4bb5dac3-c578-66a2-d97a-664be7965820}
脚本真的就只加了个节点而已(