BUUCTF reverse [网鼎杯 2020 青龙组]singal
时隔两个月再次更新博客~
IDA打开之后进入主函数。
qmemcpy函数是从内存中给v4变量进行赋值。进入vm_operad函数。
vm_opread函数会根据v4函数每一个值进行选择case操作,v4是传入的参数。
v4在内存中所获得的数据时db类型,大小是0x1c8即456,我们可以进入hex获取数据
0A 00 00 00 04 00 00 00 10 00 00 00 08 00 00 00 03 00 00 00 05 00 00 00 01 00 00 00 04 00 00 00 20 00 00 00 08 00 00 00 05 00 00 00 03 00 00 00 01 00 00 00 03 00 00 00 02 00 00 00 08 00 00 00 0B 00 00 00 01 00 00 00 0C 00 00 00 08 00 00 00 04 00 00 00 04 00 00 00 01 00 00 00 05 00 00 00 03 00 00 00 08 00 00 00 03 00 00 00 21 00 00 00 01 00 00 00 0B 00 00 00 08 00 00 00 0B 00 00 00 01 00 00 00 04 00 00 00 09 00 00 00 08 00 00 00 03 00 00 00 20 00 00 00 01 00 00 00 02 00 00 00 51 00 00 00 08 00 00 00 04 00 00 00 24 00 00 00 01 00 00 00 0C 00 00 00 08 00 00 00 0B 00 00 00 01 00 00 00 05 00 00 00 02 00 00 00 08 00 00 00 02 00 00 00 25 00 00 00 01 00 00 00 02 00 00 00 36 00 00 00 08 00 00 00 04 00 00 00 41 00 00 00 01 00 00 00 02 00 00 00 20 00 00 00 08 00 00 00 05 00 00 00 01 00 00 00 01 00 00 00 05 00 00 00 03 00 00 00 08 00 00 00 02 00 00 00 25 00 00 00 01 00 00 00 04 00 00 00 09 00 00 00 08 00 00 00 03 00 00 00 20 00 00 00 01 00 00 00 02 00 00 00 41 00 00 00 08 00 00 00 0C 00 00 00 01 00 00 00 07 00 00 00 22 00 00 00 07 00 00 00 3F 00 00 00 07 00 00 00 34 00 00 00 07 00 00 00 32 00 00 00 07 00 00 00 72 00 00 00 07 00 00 00 33 00 00 00 07 00 00 00 18 00 00 00 07 00 00 00 A7 FF FF FF 07 00 00 00 31 00 00 00 07 00 00 00 F1 FF FF FF 07 00 00 00 28 00 00 00 07 00 00 00 84 FF FF FF 07 00 00 00 C1 FF FF FF 07 00 00 00 1E 00 00 00 07 00 00 00 7A 00 00 00
将这段数据复制出来。
因为储存的db型数据,四个字节是一个整型数据,提取值为。
10, 4, 16, 8, 3, 5, 1, 4, 32, 8, 5, 3, 1, 3, 2, 8, 11, 1, 12, 8, 4, 4, 1, 5, 3, 8, 3, 33, 1, 11, 8, 11, 1, 4, 9, 8, 3, 32, 1, 2, 81, 8, 4, 36, 1, 12, 8, 11, 1, 5, 2, 8, 2, 37, 1, 2, 54, 8, 4, 65, 1, 2, 32, 8, 5, 1, 1, 5, 3, 8, 2, 37, 1, 4, 9, 8, 3, 32, 1, 2, 65, 8, 12, 1, 7, 34, 7, 63, 7, 52, 7, 50, 7, 114, 7, 51, 7, 24, 7, 167, 255, 255, 255, 7, 49, 7, 241, 255, 255, 255, 7, 40, 7, 132, 255, 255, 255, 7, 193, 255, 255, 255, 7, 30, 7, 122
因为vm_operad函数会根据a1数组的值进行选择case操作,由代码中中可以看到,当值等于7时v4数组的值会与a1数组的下一位进行比较,相等的话则继续,不相等的话则报错,那么7后面的数字就是正确输入进行加密后需要与之比较的值,贴上脚本。
#获得v4数组 v4=[] s=[10, 4, 16, 8, 3, 5, 1, 4, 32, 8, 5, 3, 1, 3, 2, 8, 11, 1, 12, 8, 4, 4, 1, 5, 3, 8, 3, 33, 1, 11, 8, 11, 1, 4, 9, 8, 3, 32, 1, 2, 81, 8, 4, 36, 1, 12, 8, 11, 1, 5, 2, 8, 2, 37, 1, 2, 54, 8, 4, 65, 1, 2, 32, 8, 5, 1, 1, 5, 3, 8, 2, 37, 1, 4, 9, 8, 3, 32, 1, 2, 65, 8, 12, 1, 7, 34, 7, 63, 7, 52, 7, 50, 7, 114, 7, 51, 7, 24, 7, 167, 255, 255, 255, 7, 49, 7, 241, 255, 255, 255, 7, 40, 7, 132, 255, 255, 255, 7, 193, 255, 255, 255, 7, 30, 7, 122] for i in range(0,len(s)): if s[i]==7: v4.append(s[i+1])
提取出值为
34,63,52,50,114,51,24,167,49,241,40,132,193,30,122
根据b4数组的值,逆向switch的操作的计算的到需要输入的正确的flag
v4 = [34,63,52,50,114,51,24,167,49,241,40,132,193,30,122] v4.reverse() a=[10, 4, 16, 8, 3, 5, 1, 4, 32, 8, 5, 3, 1, 3, 2, 8, 11, 1, 12, 8, 4, 4, 1, 5, 3, 8, 3, 33, 1, 11, 8, 11, 1, 4, 9, 8, 3, 32, 1, 2, 81, 8, 4, 36, 1, 12, 8, 11, 1, 5, 2, 8, 2, 37, 1, 2, 54, 8, 4, 65, 1, 2, 32, 8, 5, 1, 1, 5, 3, 8, 2, 37, 1, 4, 9, 8, 3, 32, 1, 2, 65, 8, 12, 1] a.reverse() v9 = 0 us=0 v5=0 flag=[] for i in range(0,len(a)): if i ==len(a)-1: flag.append(us) if a[i]==1 and a[i-1]!=1: v5 = v4[v9] v9+=1 flag.append(us) if a[i]==2: if(a[i+1]!=3 and a[i+1]!=4 and a[i+1]!=5): us = v5 - a[i-1] #print(us,v5,a[i-1]) if a[i]==3: if(a[i+1]!=2 and a[i+1]!=4 and a[i+1]!=5): us = v5 + a[i-1] #LOBYTE是al有8位,参与运算的5、33、32是全值,所以LOBYTE可省略 if a[i]==4: if(a[i+1]!=3 and a[i+1]!=2 and a[i+1]!=5): us = v5^a[i-1] if a[i]==5: if(a[i+1]!=3 and a[i+1]!=4 and a[i+1]!=2): us = int(v5/a[i-1]) if a[i]==8: v5 = us if a[i]==11: us = v5 +1 if a[i]==12: us = v5 -1 #print("12:",us) flag.reverse() out='' for j in flag: out +=chr(j) print("flag{"+out+"}")# flag{757515121f3d478}
借鉴博客:https://www.cnblogs.com/blackicelisa/p/12905731.html