CTF-RE-Evil exe(Jarvis OJ)

做此题需要的预备知识: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<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
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<<file_len<<endl;
    char file[file_len];
    fread(file,file_len,1,fp);
	fclose(fp);
    unsigned char key[280];
    long long first = 0x4A8754F5745174;
    for(int i=0;i<8;i++)key[i]=0;
    for(int i=0;i<256;i++)key[i+8] = ((i + (first >>(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<file_len;i++){
    	dkey[0]=(dkey[0]+1)%256;
        dkey[1]=(key[dkey[0]+8]+dkey[1])%256;
        swap(key[dkey[0]+8],key[dkey[1]+8]);
        int sum=key[dkey[0]+8]+key[dkey[1]+8];
    	flag[i]=(key[(sum)%256+8]^file[i]^i)%256;
    	fputc(flag[i],dump);
    }
    fclose(dump);
}

最后将得到的文件以hex数据打开

发现在下面的字符串是乱码。仔细观察发现每隔4位会有一个0x68,是push的机器码。所以注意可以猜测这一段是一段汇编代码的机器码。

因此将每个0x68后面4位以小端序排列,即可得到邮箱地址。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值