1 .老规矩,拿到题目,首先进行查壳,收集基本信息
64位,ELF文件
2.使用ida(64bit)进行分析
首先定位到main函数
对它进行简单的分析
这里的mprotect函数,我也不知道是干什么的
那么根据百度所得,这个地方的mprotect函数就是对dword_400000的内存区域的保护属性进行修改,把这个地方的长度为0xF000的保护属性修改为7,这是什么意思我也不晓得,后面看大佬的wp的时候才知道,它是把那段代码修改为了可读可写可执行,那么它的意思是这个程序的运行过程中就会对这个程序的代码进行修改, 即SMC自修改代码
这个时候我们可以观察到sub_402219函数被使用两次,我们跟进这个函数
却找不到它的数据段,那么我们就来到汇编代码进行寻找
3.sub_402219函数
注意这个数据是已经进行了异或的数据,所以我们需要对它进行还原,这个时候就要应用idc脚本进行数据的还原
首先shift+F2调用出编译器
#include <idc.idc>
static main()
{
auto addr = 0x402219;
auto i;
for(i = 0; i <= 223; ++i){
PatchByte(addr+i,Byte(addr+i)^0x99);
}
}
注意将下面的选项改为idc,接下来点击运行
全选数据,然后按C,将数据转化为代码
然后将这段代码声明为函数,即全选代码,然后点击P键,并F5进行反汇编
反汇编后,我们再回头看我们的main函数
发现它紧接着调用了sub_40207B函数,跟进
5.sub_40207B函数
然后在这个函数里面又调用了sub_401CF9函数,但是这个是什么加密呢?
这个时候就要使用我们的插件对这个程序中出现了的加密算法进行检索
发现出现了MD5加密,那么我们就跟进这个MD5加密,发现它跳转到了sub_401CF9函数,那么我们就可以知道,这个函数是MD5加密,其实这个插件就给你直接标出来了
一大堆忽悠人的MD5加密,,也就第10行和14行的MD5加密有用
大体是将base64密码表进行两次sub_401CF9加密然后赋值给参数a1
这里没有用到用户输入,可以动调一下获得加密后的a1
6.动调得到a1
首先这个地方的a1就是unk_603170数组
得到了a1为CB8D493521B47A4CC1AE7E62229266即加密后的密钥
7. 然后看main函数里的sub_402219函数
我们可以知道密文为 BC0AADC0147C5ECCE0B140BC9C51D52B46B2B9434DE5324BAD7FB4B39CDB4B
跟进sub_40194E得到的结果
所以我们可以得到整个过程
1.经过MD5加密后的密钥可以通过动调得出
2.将32位的输入分成两份进行加密
3.最后与密文进行比较
接下来就是通过脚本进行解密
from Crypto.Cipher import AES
from Crypto.Util.number import *
key = long_to_bytes(0xcb8d493521b47a4cc1ae7e62229266ce)
mi = long_to_bytes(0xbc0aadc0147c5ecce0b140bc9c51d52b46b2b9434de5324bad7fb4b39cdb4b5b)
lun = AES.new(key, mode=AES.MODE_ECB)
flag = lun.decrypt(mi)
print(flag)
得到flag
flag为flag{924a9ab2163d390410d0a1f670}
带到网站验证
正确!!!!!!