BUUCTF --CrackRTF
BUUCTF --CrackRTF
无壳,ida打开

第一个密码
大致分析一下,第一个密码是六位的数字(通过strlen函数与atoi函数判断),然后对这个密码用strcat加字符串@DBApp后到sub_40100A()函数进行加密,最后把加密字符串用strcmp与6E32D0943418C2C33385BC35A1470250DD8923A9进行比较
分析sub_40100A()函数

我是直接拿给gpt分析的,结果就是这是一个未魔改的sha1加密
这里有一个sha1标识符0x8004u
因为前面已经提示只有数字,我们直接爆破即可
from hashlib import *
enc = '6e32d0943418c2c33385bc35a1470250dd8923a9'
flag1 = ''
for i in range(10000,999999):
if sha1((str(i) + "@DBApp").encode("utf8")).hexdigest() == enc:
flag1 += str(i) + "@DBApp"
print(flag1)
得到第一段密码123321
可以输入程序进行验证一下

成功
第二个密码

第二个密码也是六个字符,但未告知字符串组成类型
分析sub_401019()

这里有md5加密的标识符,丢个gpt分析可知道这就是个普通的md5加密
因此,第二个密码就是通过md5加密(注意这里把第一个密码用strcat拼接到了第二个密码上,所以加密内容是18位的字符串)后与字符串27019e688a4e62a649fd99cadaafdb4e进行比较验证
由于没有告知字符串组成并且数据庞大,因此用脚本爆破并不现实
当然也有在线网站可以爆破,贴个网站MD5解密-BeJSON.com

几秒就爆出来了,太强了
不使用爆破解出第二个密码
他这里嵌套了两个if条件,大概给了两条路来解题吧
分析sub_40100F()

我把函数中的变量名改了一下让我自己好看一点
咱来逐步分析
这个程序先用FindResourceA()来寻找exe文件中名为0x65,类为AAA的资源
随后用LoadResource()加载获取的资源
最后用LockResource()锁定资源,让get_info这个变量作为指针访问找到的资源
sub_401005()
大概知道上面的流程是什么后,再来分析sub_401005()函数

简单来说就是用a2与lpString的值进行异或操作,最后得到加密值
a2 : 从资源文件0x65中获得的值
lpString:第二个密码(6位)
解密
sub_401005()加密结束后,使用CreateFileA()创建了一个名为dbapp.rtf的文件
随用将加密后的get_info通过WriteFile函数写入dbapp.rtf
那现在大概就明了了,由于 sub_401005()是异或操作,那a2和加密后的结果肯定也是六位,那么我们直接分dbapp.rtf和0x65中提取前六位hex值
这里使用Resourse Hacker 软件查询exe的资源文件

从这里提取前六位hex值: [0x05, 0x7D, 0x41, 0x15, 0x26, 0x01]
从网上查询rtf的文件头:[0x7B, 0x5C, 0x72, 0x74, 0x66, 0x31]
随后进行异或
rtf_header = [0x7B, 0x5C, 0x72, 0x74, 0x66, 0x31]
AAA = [0x05, 0x7D, 0x41, 0x15, 0x26, 0x01]
flag2 = ''
for i in range(len(AAA)):
flag2 += chr(rtf_header[i] ^ AAA[i])
print(flag2)
解出密码2 :~!3a@0
将密码输入进程序,就会生成一个rtf文件

打开即可获得flag:Flag{N0_M0re_Free_Bugs}