CISCN 2023 RE WP
一、moveAside
对strcmp下断,通过黑盒测试,可以发现这里存在测信道攻击
直接pintools + python脚本 爆破
Pintools脚本如下:
#include <iostream> #include <fstream> #include "pin.H" using std::cerr; using std::endl; using std::string; static UINT64 icount = 0; VOID docount(VOID* addr) { if (( int )addr == 0x8049010) { icount++; } } VOID Instruction(INS ins, VOID* v) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)docount, IARG_INST_PTR, IARG_END); } KNOB< string > KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool", "o", "inscount.out", "specify output file name"); VOID Fini(INT32 code, VOID* v) { std::cout << "Count " << icount << endl; } INT32 Usage() { cerr << "This tool counts the number of dynamic instructions executed" << endl; cerr << endl << KNOB_BASE::StringKnobSummary() << endl; return -1; } int main(int argc, char* argv[]) { if (PIN_Init(argc, argv)) return Usage(); INS_AddInstrumentFunction(Instruction, 0); PIN_AddFiniFunction(Fini, 0); PIN_StartProgram(); return 0; }
Python爆破脚本如下:
import subprocess import time import copy import os STR_LEN = 30 start_time = time.time() out_file_path = r"ttext.txt" exe_path = r"./moveAside" dll_path = r"./MyPinTool.so" record_ins_nums = {} # 指令计数器 except_str = "flag{" except_inss = 0 find_str = "" s_map = "0123456789qwertyuiopasdfghjklzxcvbnm{}-" # s_map = "0123456789" def sub_intreaction(input_msg): global start_time sh = subprocess.Popen(['pin','-t',dll_path,'-o',out_file_path,'--',exe_path], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) sh.stdin.write(str.encode(input_msg.ljust(48,"0"))) # 必须补齐,不然后面的sh.stdout 会出错 # 即将缓冲区中的数据立刻写入文件,同时清空缓冲区,不需要是被动的等待输出缓冲区写入 sh.stdin.flush() sh.stdout.flush() sh.stdin.write(str.encode(input_msg.ljust(48,"0"))) sh.stdin.flush() sh.stdout.flush() sh.stdin.write(str.encode(input_msg.ljust(48,"0"))) sh.stdin.flush() sh.stdout.flush() get_input = sh.stdout.readlines() # print(get_input) lenn = int(get_input[2][6:]) if record_ins_nums and lenn > max(record_ins_nums.values()): record_ins_nums[input_msg] = lenn sh.kill() print(input_msg," : ",get_input) return 1 record_ins_nums[input_msg] = lenn sh.kill() print(input_msg," : ",get_input) if b"success" in get_input[1]: print("Oh,my sir, you may got the flag:") print(input_msg) print(time.time() - start_time) exit() return 0 def intreaction(): for i in range(len(s_map)): if sub_intreaction(except_str + s_map[i]) == 1: return def pintools(): global except_str,v,record_ins_nums,except_inss intreaction() for k,v in record_ins_nums.items(): if v >= except_inss: # 出错原因,之前用的 '>' 号,发现input_msg 填充的数据 0 也是input的数据,导致 0123456789 和 01234567890 指令数一样,从而导致无线循环 except_str = copy.deepcopy(k) except_inss = v print(except_str," ",except_inss) record_ins_nums = {} pintools() if __name__ == '__main__': pintools()
爆破过程:
爆破得到flag:
flag{781dda4e-d910-4f06-8f5b-5c3755182337}
二、ezbyte
finger+连点器恢复一些符号(
通过调试发现
程序通过异常处理进入到这个了函数
这里实现了小型虚拟机
经过调试,可以发现虚拟机工作如下:
inp[3] += 0x8b3778 inp[3] ^= 0x1a3dbfb3bbdaeefb inp[3] ^= 0x790b86d78a647422 inp[2] += 0x171378 inp[2] ^= 0xf3fb14121b8606d inp[2] ^= 0x2206872240fc27dc inp[1] += 0x88e3e5 inp[1] ^= 0x10ca3d978ad743e3 inp[1] ^= 0x75fe10f2ba170af1 inp[0] += 0x1ce183 inp[0] ^= 0x112ddf8e50094ca7 inp[0] ^= 0x244fb9eb69445b4f inp[0] += inp[1] inp[0] += inp[2] inp[0] += inp[3] assert inp[0] == 0
exp即为:
from struct import pack , unpack def pt(p): print(p) def pth(p): print(hex(p)) def Q2b(m): return pack("<Q",m) def b2Q(m): return unpack("<Q",m)[0] t1 = (0 ^ 0x112ddf8e50094ca7 ^ 0x244fb9eb69445b4f) - 0x1ce183 t2 = (0 ^ 0x10ca3d978ad743e3 ^ 0x75fe10f2ba170af1) - 0x88e3e5 t3 = (0x2206872240fc27dc ^ 0 ^ 0xf3fb14121b8606d) - 0x171378 t4 = (0x790b86d78a647422 ^ 0 ^ 0x1a3dbfb3bbdaeefb ) - 0x8b3778 pt(Q2b(t1) + Q2b(t2) + Q2b(t3) + Q2b(t4)) # flag{e609efb5-e70e-4e94-ac69-ac31d96c3861}
Flag即为:
flag{e609efb5-e70e-4e94-ac69-ac31d96c3861}
三、BabyRE
Snap! 语言逆向
https://snap.berkeley.edu/snap/snap.html
网址打开后开启js扩展
在这里下断点并显示变量
动态运行,即可拿到密文
加密流程如下:
Exp为:
t1 = [102,10,13,6,28,74,3,1,3,7,85,0,4,75,20,92,92,8,28,25,81,83,7,28,76,88,9,0,29,73,0,86,4,87,87,82,84,85,4,85,87,30] print(len(t1)) for i in range(1,len(t1)): t1[i] = t1[i] ^ t1[i-1] for i in range(len(t1)): print(chr(t1[i]),end = "")
flag即为:
flag{12307bbf-9e91-4e61-a900-dd26a6d0ea4c}
待补充...
四、flutterror
思路一
参考群友的思路
Alt+t搜索CMP ,再在CMP里面搜 #0x2a
即可定位到关键函数
exp:
t = [0, 10, 7, 1, 29, 95, 80, 3, 80, 83, 80, 95, 81, 75, 83, 3, 4, 4, 75, 82, 81, 82, 81, 75, 95, 80, 85, 80, 75, 7, 3, 0, 5, 2, 86, 82, 84, 5, 3, 94, 86, 27] flag = bytearray([i ^ 0x66 for i in t]) print(flag)
flag{96e65697-5ebb-4747-9636-aefcd042ce80}
这个方法的思路是基于flag的长度是42位的(可以看前面的flag,都为42位),猜测.so文件会对输入进行长度比较,从而搜索长度比较汇编代码来找到关键函数
PS:
第二次打国赛,第一天的mov混淆是我没想到的,属实是没活了,第二天的snap!逆向导师眼前一亮,之后的安卓+web题和futter题没整明白,看到有大师傅通过Hook logcat函数来做的,属实是没想到,还是道行太浅
----------------------------------------------|追风赶月莫停留,平芜尽处是春山|----------------------------------------------