BUU[安洵杯 2019]crackMe

分析

首先查壳,无壳32位,放入IDA

先shift+F12找到关键string

image-20220702110620018

这里直接交叉引用它,去找到它

image-20220702110827560

image-20220702110847733

那么新的表为abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/

接着去看一下Handler函数

image-20220702111036622

接着去sub_411172函数看一下

image-20220702111118261

很容易知道v2就是SM4加密的密匙了,然后就这去看一下TopLevelExceptionFilter函数

image-20220702111325299

image-20220702111339600

那么换位之后的Str2为”U1ATIOpkOyWSvGm/YOYFR4!!”

然后看一下sub_41126C函数,确定Str1

image-20220702111525453

发现它是一个base64的加密,但是前面又有一个sub_4110FF函数,点进去看一下

image-20220702111608106

那么新表为”yzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/abcdefghijklmnopqrstuvwx”,然后去看一下sub_411136函数

image-20220702111653662

发现只有Str1=Str2才正确

思路总结

1.因为最后Str1==Str2,所以首先是将Str2进行换表的base64解密

2.然后将解出来的内容再去进行SM4的解密

脚本

import base64#base64换表解密
base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
diy_base = 'yzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/abcdefghijklmnopqrstuvwx'

s = 'U1ATIOpkOyWSvGm/YOYFR4!!'
ss = ''
for i in range(len(s)-2):
ss += base[diy_base.find(s[i])]
ss += '=='
a = base64.b64decode(ss)
print(list(map(hex,a)))

from pysm4 import encrypt, decrypt
cipher_num = 0x59d095290df2400614f48d276906874e#box
mk = 0x77686572655f6172655f755f6e6f773f#key
clear_num = decrypt(cipher_num, mk)
print('flag{'+bytes.fromhex(hex(clear_num)[2:]).decode()+'}')
#flag{SM4foRExcepioN?!}

总结

第一次见SM4的加密,是看别的大佬才知道有这种特征值。这也是第一次遇到base64中还存在其他函数进行换表,长见识了