-
-
[原创]KCTFQ3题目提交 第五题:魅影舞姬 ——CrackMe
-
发表于: 2019-8-15 15:01 2967
-
团队名称:只会签到题的蒻鶸
参赛题目:lost.exe
题目类型:CrackMe(Windows)
攻击脚本:见exp.py(python3)
题目答案:VXX/8AKlVXV8/wCpVXV9/DCogeWKJMtrmeY=
(序列号长度为36,有且只有一个)
设计说明:crackme使用了梅森翻转算法、xxtea加密算法、md5哈希算法、base64decode、3DES(128bits_key)解密算法、4个迷宫分别检查4个部分,同时对关键函数、变量名进行了字符串混淆。
总体思路:输入一个字符串,第一个check,check长度是否小于等于48,第二个check使用了梅森翻转算法、xxtea加密算法,check字符串的第一个字节,以第一个字节作为随机数种子,由梅森翻转算法得到三个32bits整数,将第一个、第三个整数通过xxtea加密,密钥直接给出,为{0X67452301, 0XEFCDAB89, 0X98BADCFE, 0X10325476},得到的结果相加得到v,由梅森翻转算法得到的第二个整数减去v得到res,检查是否等于2768546039,梅森翻转算法得到的随机数可预测,xxtea可逆,但是sm限定字符集为[33,126],直接正向爆破秒解,脚本见crack.cpp文件。第三个check,check输入的字符串与"Welcome/to/this/very/simple/challenge"相加之后的md5是否等于44e4403b63620a2075d3fb2e0a6207d2,此处不可逆,主要是check长度,当然以上说的都是废话,因为上面所有的算法都是唬人的,直接跳过上面的check逆下面的算法就可以得到sm,之所以设计上面的算法而不进行混淆是为了误导解题者,而不用以上算法对sm进行check是因为简便的设计原则,而不是通过算法堆叠提高难度。以下是真正的check且可逆,首先程序将输入的字符串取前36个字节进行base64decode,得到decode后的字节,应为26bytes,(此处暴露了sm长度应该为36个字节),之后对这26个字节进行分割,分割为v1,v2,v3,c,分别为6、6、6、8个字节,对输入的36个字节字符串前二十四个进行分割,分割为key1,key2,key3,均为8字节,之后进行3DES解密,密钥为key1key2key3,密文为c,即des_decrypt(key3,c),des_encrypt(key2,c),des_crypt(key3,c),最终得到的c为8字节明文,这里视为v4,之后是md5校验(此处如上所说并没有用),最终的校验是4个迷宫check,将上述得到的v1,v2,v3,v4分别送入迷宫check,正确的话预设值+1,最终检验预设值是否为4,即四个迷宫都要走完,迷宫均为13*13矩阵,起点为'@',终点为‘#’,除第一个显示给出外,其余三个均为在第一个迷宫的基础上动态生成。
解题思路:
去混淆,整理出四个迷宫,依据迷宫规则推导出v1,v2,v3,v4,其中v1、v2、v3为6bytes,v4为8bytes,前三个迷宫有且只有一条长度为18的路径,第四个迷宫有且只有一条长度为24的路径,至于v1、v2、v3、v4的长度由程序可以直接得到,根据迷宫规则目测即可非常快速的得到路径,也可写脚本得到,之后对v1、v2、v3分别进行base64encode得到key1,key2,key3,对v4进行3des加密,密钥为key1,key2,key3,最后对得到的结果c进行base64encode得到一个12bytes的字符串,将key1,key2,key3和c拼接就可得到长度为36bytes的序列号
编译环境:win10,g++ --std=c++11,devc++
其他说明:遵从从简的原则,不进行套娃,无壳无虚拟机无花指令,使用cpp实现,对关键函数、变量进行混淆,但是对假的check不进行混淆以误导解题者,有任何问题烦请QQ联系。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)