-
-
[原创]自动化解KCTF2021第二题南冥神功
-
2021-5-13 23:45 4279
-
switch case结构的优化
switch 1,2,3,4,5会转化为switch 0,1,2,3,4,然后通过一个jmp table 实现 switch,table [0,1,2,3,4]
ida调试的时候发现不对劲要去查看汇编代码,否则这些优化会让c伪代码调试看起来很奇怪
递归自动走迷宫
在复原代码的过程中,我发现他很像一个迷宫,通过我们的输入走迷宫,迷宫不是简单的上下左右,有6种情况,我也不去分析这六种情况到底是什么样了,我打算写个脚本自动走这个迷宫
思路是使用递归,是每一步都尝试,如果这一步不合法,那就终止此尝试,如果合法,就在这一步的基础上再次尝试
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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | map2 = [ 0x53 , 0x00 , 0x01 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x01 , 0x01 , 0x01 , 0x01 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 , 0x00 , 0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x00 , 0x00 , 0x01 , 0x01 , 0x00 , 0x01 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x01 , 0x01 , 0x01 , 0x01 , 0x00 , 0x01 , 0x01 , 0x01 , 0x00 , 0x01 , 0x00 , 0x01 , 0x00 , 0x00 , 0x01 , 0x01 , 0x01 , 0x01 , 0x00 , 0x01 , 0x00 , 0x01 , 0x00 , 0x01 , 0x01 , 0x00 , 0x00 , 0x01 , 0x00 , 0x01 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x01 , 0x01 , 0x00 , 0x00 ] # for i in range(9): # print() # for j in range(10): # if map2[10*i+j] == 1: # print("x",end ="") # elif map2[10*i+j] == 0x53: # print("S",end ="") # elif map2[10*i+j] == 0: # print("o",end ="") try_time = 0 def exp(v9_in,v21_in,list2_in,map2): global try_time for i in range ( 0 , 6 ): list2 = list2_in.copy() v9 = v9_in v21 = v21_in map1 = map2.copy() v10 = i is_ok = 0 if v10 = = 0 : v9 + = (v21 & 1 = = 0 ) v21 - = 1 if v10 = = 5 : v9 - = (v21 & 1 ! = 0 ) v21 - = 1 if v10 = = 3 : v9 - = (v21 & 1 ! = 0 ) v21 + = 1 if v10 = = 2 : v9 + = (v21 & 1 = = 0 ) v21 + = 1 if v10 = = 1 : v9 + = 1 if v10 = = 4 : v9 - = 1 if v21 > 8 or v9 > 9 or 10 * v21 + v9 < 0 or v21 < 0 or v9 < 0 : is_ok = 0 else : if map1[ 10 * v21 + v9] = = 0 : map1[ 10 * v21 + v9] = 1 is_ok = 1 # 如果这一步合法,就可以递归,否则结束 if is_ok = = 0 : if len (list2) = = 46 : print (list2) else : list2.append(i) exp(v9,v21,list2,map1) try_time + = 1 map1 = map2.copy() exp( 0 , 0 ,[],map1) print (try_time) |
脚本编写的过程中要注意exp函数的参数问题,传入的参数要是副本才行,不同的尝试之间不能互相影响,我在编写脚本的时候就犯了这个错误,浪费了一些时间
爆破可以解放自己
最后得到了迷宫的走法,但是题目还有一些限制
本来我想逆向还原了,后来6取余又减法的把我绕晕了,最后选择了爆破
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 | final = [ 1 , 2 , 3 , 4 , 3 , 2 , 1 , 2 , 3 , 4 , 3 , 2 , 1 , 1 , 0 , 1 , 2 , 1 , 0 , 0 , 5 , 0 , 5 , 4 , 3 , 4 , 5 , 0 , 5 , 0 , 1 , 2 , 1 , 0 , 1 , 2 , 1 , 2 , 3 , 4 , 3 , 2 , 2 , 3 , 2 , 1 ] final1 = [] final2 = [] for i in range ( 0 , len (final) / / 2 ): final1.append(final[ 2 * i]) final2.append(final[ 2 * i + 1 ]) # for i in range(len(final1)): # final1[i] = 5 - final1[i] # # for i in range(1,len(final1)): # final1[i] = (6 - ((i-1)%6) + final[i])%6 print (final1) print (final2) # for i in range(0,len(final2)): # x = final1[2*i]+(final2[2*i+1]-i%6)*6 # print(chr(table1[x]),end = '') str1 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" v4 = 0 kk = [] for j in range ( len (final1)): for i in range ( len (str1)): v5 = i v7 = (v4 + v5 / / 6 ) % 6 v8 = v5 + v4 v20 = v7 v10 = 5 - v8 % 6 if v10 = = final1[j] and v7 = = final2[j]: kk.append(i) v4 + = 1 break print (kk) for i in range ( len (kk)): print (str1[kk[i]],end = "") # GJ0V4LA4VKEVQZSVCNGJ00N |
验证一下,正确
说下感受
说下感受吧,逆向是一个缓慢的过程,一步一步发现程序的奥秘,期间会踩很多坑(有一些坑是自己的失误造成的),慢慢调试不能急就是了
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界
赞赏
看原图