1.样本概况
1.1 应用程序信息
应用程序名称:010Editor801.exe
MD5值:0A34A58D5314C83273710B57F3CB8B53
SHA1值:849ED2027B4F40BF5BF85A638E54D15C05C87E29
1.2 分析环境及工具
系统环境: 十五派信息安全教育实验环境win7专业版 32位
工具: Ollydbg(动态调试代码)、
IDA Pro(静态调试代码)、
LordPE/PEID/Exeinfo PE(PE工具、查壳、查编译环境)、
Vistual Studio 2019(开发环境)
1.3 分析目标
对程序进行暴力破解过验证
对分析算法编写注册机过验证
2.具体分析过程
2.1 样本详细
2.1.1 启动程序
通过Exeinfo PE我们可以看出010Editor这个程序是使用QT编写的程序
2.1.2 注册界面
我们随便输入一段用户名和密码之后,弹出失败对话框。
2.2 敏感字符串
2.2.1 查找通过敏感字符串
我们通过注册失败的对话框直接搜索字符串进行查找,这里继续通过对话框进行查找,我们对CreateWindowEx进行下断分析。
在点击Check License按钮之后,通过栈回溯发现在这个位置有敏感字符的关键信息
2.2.2 通过敏感字符串查找关键代码
在这个位置继续分析代码发现向下的关键跳转位置,而CMP EDI,0xDB是决定这个跳转的关键数据,继续往上分析
通过继续逆向分析代码我们来找这段代码区域,通过初步分析推断是关于网络验证和账号密码算法相关的区域
2.2.3 修改关键跳转暴力破解
根据目前分析的结果我们现在可以通过修改指令进行暴力破解,通过关键跳转可以看到在网络验证完毕之后会跳到关键跳转的位置,我们直接将JE修改为JMP,当跳到关键跳转的时候,直接越过对比的结果,不进行跳转,将跳转用NOP填充掉,就完成了暴力破解。这个位置如果进行跳转就会提示失败的信息。
网络验证位置的信息跳转
判断失败的关键跳转
爆破结果通过验证
2.3 算法
2.3.1分析相关函数
我们分析这个CALL是相关算法的代码,我们跟进去对改代码进行解析
我们在这个CALL中发现指向用户名和密码存储地址的指针,在下面的指令地址中发现调用用户名的信息,还有密码的信息
2.3.2 密码算法相关的
这段代码上来将密码的第三个元素和第五个元素赋值给了BL 和 BH 并且密码第三个元素必须等于0x9C,0xFC,0xAC这个三个值的其中一个。
通过解析第一个CALL先处理的处理k[0]和k[6]的数据 AL = (((k[0] ^ k[6]) ^ 0x18) + 0x3D) ^ 0xA7。
第二个CALL处理的是PUSH ESI = ((k[1] ^ k[7] & 0xFF) + (k[2] ^ k[5] & 0xFF)) & 0xFFFF
EAX = (((((((k[1] ^ k[7] & 0xFF) + (k[2] ^ k[5] & 0xFF)) & 0xFFFF) ^ 0x7892) + 0x4D30) ^ 0x3421)&FFFF)/0xB 计算后判断余数为0返回商,否则返回0
下面的跳转根据两组CALL的返回值进行跳转
2.3.3 密码算法验证
srand(time(NULL));
int dwRet = 0x3E8;
byte k[10] = {
0x11,0x22,0x33,0x9c,0x55,0x66,0x77,0x88,0x99,0xAA };
//用户名经过加密
DWORD dwKey = EnCodeUsername("www.15pb.com", 1, 0, dwRet);
k[4] = dwKey & 0xFF;
k[5] = dwKey >> 0x8 & 0xFF;
k[6] = dwKey >> 0x10 & 0xFF;
k[7] = dwKey >> 0x18 & 0xFF;
//处理k[0]和k[6]的数据 AL = (((k[0] ^ k[6]) ^ 0x18) + 0x3D) ^ 0xA7
while (true)
{
byte k0 = rand() % 0xFF;
byte k6 = rand() % 0xFF;
byte AL = (((k0 ^ k6) ^ 0x18) + 0x3D) ^ 0xA7;
if (AL >= 9)
{
k[0] = k0;
k[6] = k6;
break;
}
}
//PUSH ESI = (((k[1] ^ k[7] & 0xFF) * 0x100) + (k[2] ^ k[5] & 0xFF)) & 0xFFFF
//EAX = ((((ESI ^ 0x7892) + 0x4D30) ^ 0x3521)&FFFF)/0xB
//计算后判断余数为0返回商,否则返回0
while (true)
{
byte k1 = rand() % 0xFF;
byte k2 = rand() % 0xFF;
byte k5 = rand() % 0xFF;
byte k7 = rand() % 0xFF;
DWORD ESI = (((k1 ^ k7 & 0xFF) * 0x100) + (k2 ^ k5 &