这一题前一部分分析起来很容易atoi函数将我们输入的字符串转为整数,也就是输入“123456”,得到整数123456。第一阶段必须输入6个字符,然后经过sub_40100a函数处理函数里面是这个样子,将我们输入的字符串经过复杂的处理存储在String1中,直接丢给chatgpt是一种哈希算法,找一个在线的计算哈希值的小工具,将我们的输入加上@DBApp计算哈希值进行计算动态调试可以查看string1的值,更改哈希算法的类型,哪种算法和动调得出的数据相同sub_40100a就是哪种哈希算法,最后得知使sha1。我对哈希算法了解不多,但知道他一般是不可逆的,然后先继续往下看。再次输入一个长度为6的字符串,然后将刚才拼接的那个字符串连接在后面,然后进入sub_401019函数,点进去和上面差不多,一眼哈希。继续使用上面的方法可以得出这是进行了MD5加密。好,就结束了,我们只要使用给出的那个比较字符串进行md5解密即可。事情没这么简单,尝试了很多在线工具都没有求出(MD5不可逆,解密工具的原理是通过穷举法造出了一个md5的对照库)在翻阅wp的时候发现有的师傅找到了可以直接查询到的小工具,牛。然而,如果没有这样的工具我们要如何往下进行工作呢?天无绝人之路,船到桥头自然直,继续往下看。查看这个sub_40100f函数,看着很令人头大,一堆北见过的函数,丢给gpt分析,其实逻辑很简单:查找资源标识为0x65,类型为"AAA",加载这个资源,IpBuffer这个指针指向这个资源,经过sub_401005处理,IpBuffer所指的内容发生改变(简单的异或),最后将创建一个rtf文件,并将内容写入。可以使用 ResourceHacker工具查看AAA文件这是sub_401005函数他将AAA的前18个字节的内容与input数组进行异或。为什么是18个字节呢?最开始输入6个字节,然后拼接给出的六个字节的内容,得到一个长度为12的字符串,第二次再次输入长度为6的字符串,拼接上之前的12就是18字节长了。
敲重点:创建了一个rtf文件 ,其实只是创建了一个空白的文件,我们要填入指定格式内容,他才能被真正解析为一个rtf文件,所以经过处理之后的数据(经由sub_401005处理得到的IpBuffer处的内容)一定是符合rtf格式的,经查看rtf格式的文件前面几十个字节都是固定的我们只需复制前18个字节的内容,将其与AAA的前十八个字节进行异或即可
#include<stdio.h>
int main()
{
unsigned char data[] = "{\\rtf1\\ansi\\ansicpg12";
char aaa[]={0x05,0x7D,0x41,0x15,0x26,0x01,0x6D,0x53,0x5D,0x40,0x5B,0x6D,0x21,0x2A,0x31,0x28,0x13,0x00,0x19,0x18,0x00,0x57};
for(int i=0;i<18;i++)
{
printf("%c",aaa[i]^data[i]);
}
}
//~!3a@0123321@DBApp
只需要将123321 和 ~!3a@0依次输入,即可自动生成一个rtf文件
参考文章:BUUCTF reverse:CrackRTF_cryptcreatehash(phprov, 0x8004u, 0, 0, &phhash)-CSDN博客