做此题需要的预备知识:ESP定律脱壳。如下网站介绍的比较详细且易懂,适合初学者了解:
https://blog.csdn.net/qiurisuixiang/article/details/7649799
扔进ida发现没有函数,只有一堆乱码。于是猜测可能有壳。用OD打开分析一波:
根据 esp定律,我们f8到pushad的下一条指令,记录此时esp的值,并在此处下硬件访问断点。
然后f9,发现eip附近会有pushad,说明成功。然后我们再f8到jmp处即为程序入口点。
此图中sub esp,-0x80指令下一条即为jmp指令,图中只显示了灰色的机器码,但是是可以执行的。
然后jmp进入入口点之后即可用插件dump下来。用ida打开dump出来的文件发现我们能看到可执行的函数了
sub_4018f0函数是联网下载出x,jpg文件,并且从文件中读入数据,首地址存入v8中,数据长度为dwSize。
sub_401740是对密匙key的初始化,sub_401800是对读入的数据进行解密,最后在sub_401220函数中又对解密后的密文进行了异或操作。
一步一步分析然后写出爆破代码。注意一下代码中的dkey和key实际上是一个东西,不过dkey是以int类型存的,而key是以unsigned char 类型储存。
#include
#include
#include
#include
using namespace std;
int main(){
FILE *fp,*dump;
fp =fopen("x.jpg","rb");
dump = fopen("shell.txt","wb");
fseek(fp,0,SEEK_END);
int file_len = ftell(fp);
fseek(fp,0,SEEK_SET);
cout<>(i % 8 * 8)))&0xff);
int dkey[70],temp;
for(int i=0;i<70;i++){
temp = 0;
for(int j=3;j>-1;j--)temp = (temp<<8) + key[4 * i + j];
dkey[i] = temp;
}
char flag[file_len];
for(int i=0;i
最后将得到的文件以hex数据打开
发现在下面的字符串是乱码。仔细观察发现每隔4位会有一个0x68,是push的机器码。所以注意可以猜测这一段是一段汇编代码的机器码。
因此将每个0x68后面4位以小端序排列,即可得到邮箱地址。