freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

新160个CrackMe分析-第3组:21-30(下)
2022-09-14 23:08:33
所属地 辽宁省

作者:selph

目录:

• 021-DIS-Serialme1

• 022-CM_22

• 023-TraceMe3

• 024-reverseMe4

• 025-CRC32crackme5

• 026-KeygenMe6

• 027-MexeliteCRK17

• 028-ArturDents-CrackMe38

• 029-figugegl19

• 030-AcidBytes410

前半篇请看上集

1.      026-KeygenMe

算法难度:⭐⭐⭐

爆破难度:

信息收集

运行情况:

查壳与脱壳:

识别的是UPX壳,实际上则无壳,识别错误应该是

调试分析

通过MessageBox函数交叉引用定位校验的位置,就分析主要逻辑吧,前面那些初始化无关紧要

前面省略了给NameSerial赋值的API调用,直接从校验逻辑开始看

这里获取Name字符串长度遍历计算使用

然后一个循环,计算一个累加值到esi

每一轮取一个字符到ebx,累加ebx平方,累加ebx右移一位后+3后乘以ebx再减去ebx,然后esi乘以2(这样描述不清楚,具体看下文反汇编注释和注册机代码)

最后算出一个累加值和序列号字符串进行对比,没看错,是直接和字符串对比,输入的字符串会直接当成数字对待

输入的字符,这里esi是计算出来的累加和,下面那一行是输入的序列号,直接用ascii当数字来对比了!!!

注册机

注册码生成算法:因为对输入的用户名有要求,太长太短都不行,还得是能满足要求的字符,所以这里就使用随机字符串来生成满足要求的Name

#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#define Random(x)(rand()%x) // 生成x以内的随机数
// 参数:生成随机字符串长度
void GetRandomString(LPSTR str,SIZE_T nLength) {
srand((int)time(NULL)); // 
随机数种子
for (size_t i = 0; i < nLength; i++) {
switch (Random(2)){
case 0: str[i] = 'a' + Random(26); break;
case 1: str[i] = 'A' + Random(26); break;
default: break;
}
}
}

bool SerialCheck(char* serial) {
bool res = true;
for (int i = 0; i < 3; i++) {
char tmp = serial[i];
if (0x21 <= tmp && tmp <= 0x7E) continue;
res = false;
break;
}
return res;
}

int main()
{
int esi = 0;
char name[20] = { 0 };
char serial[20] = { 0 };
bool flag = false;

while (!flag) {
memset(name, 0, sizeof(name));
GetRandomString(name, 7);
esi = 0;
for (int i = 0; name[i]; i++)
{
int ebx = name[i];
esi += ebx * ebx;
esi += ebx * ((ebx >> 1) + 2);
esi += esi;
}
*(int*)&serial = esi;
if (SerialCheck(serial)) {
std::cout << name << std::endl;
std::cout << serial;
break;

}
}
}

效果:

总结

算法不难,但写注册机还是有些麻烦的

2.      027-MexeliteCRK1

算法难度:

爆破难度:

信息收集

运行情况:

输入序列号,下面那个框显示状态

查壳与脱壳:

无壳,是Delphi程序

调试分析

硬编码序列号验证

效果:

3.      028-ArturDents-CrackMe3

算法难度:⭐⭐

爆破难度:

信息收集

运行情况:

查壳与脱壳:

一个没见过的壳出现了,Petite壳,老样子,依然是ESP定律可以解决

调试分析

Delphi程序,通过IDR反汇编找到按钮控件事件,然后复制出来分析

首先是获取输入,Name长度和Serial长度不能为0

接下来紧接着是序列号生成:根据Name生成一个字符串

最后是比对环节:

注册机

注册码生成算法:

#define _CRT_SECURE_NO_WARNINGS
#include

int main()
{
char name[100] = { 0 };
char num[100] = { 0 };

std::cin >> name;
for (int i = 0; i < strlen(name); i++)
{
char tmp_str[100] = { 0 };
_itoa(name[i] / 3, tmp_str, 10);
strcat(num, tmp_str);
}

std::cout << "ADCM3-" << num << std::endl;
return 0;
}

效果:

4.      029-figugegl1

算法难度:⭐⭐

爆破难度:

信息收集

运行情况:

查壳与脱壳:

无壳

字符串:

存在提示信息:

调试分析

从字符串提示入手,找到校验点开始分析

首先是获取输入,用户名需要长度大于等于5

然后是校验和对比了:

校验算法:Serial == Name[i]-i

简单到可以口算的序列号生成:1234511111

效果:

注册机

注册码生成算法:

#include

int main()
{
char serial[100] = { 0 };
char name[100] = { 0 };
std::cin >> name;
for (int i = 0; name[i]; i++)
{
serial[i] = name[i] - i;
}
std::cout << serial;
}

5.      030-AcidBytes4

算法难度:⭐⭐⭐

爆破难度:

信息收集

运行情况:

查壳与脱壳:

UPX,无脑ESP定律即可

调试分析

Delphi程序,IDR走起

首先是获取NameSerial校验长度

然后是进行一个计算,根据Name计算Serial

相同的操作会进行6次:取一个字节,乘以2,然后累加起来,会操作的就是Name的前6个字符

最后把这个累加值保存起来,给这个累加值加上个Name长度的两倍,转字符串(十进制,就是真码了

注册机

注册码生成算法:

#include

int main()
{
char name[100] = { 0 };
int sum = 0;

std::cin >> name;
for (int i = 0; i < 6; i++) sum += name[i] * 2;
sum += strlen(name)*2;

if (sum >> 0x1f == 0)std::cout << sum;
}

结果:

总结

又是这种,把能写进循环的东西写了超级多段落,不难,只要有Delphi的符号,分析起来还是挺快的

# 系统安全
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录