📄 md5+rsa crackme破解实例(娃娃).txt
字号:
:004011CA 50 push eax
:004011CB 8D542448 lea edx, dword ptr [esp+48]
:004011CF 56 push esi /ESI=Name=娃娃[CCG]
:004011D0 52 push edx /EDX="0123456789ABCDEFFEDEBA9876543210"
:004011D1 E85A060000 call 00401830
:004011D6 8D442418 lea eax, dword ptr [esp+18]
:004011DA 50 push eax
:004011DB E800070000 call 004018E0
* Reference To: USER32.wsprintfA, Ord:0000h
|
:004011E0 8B1DECB04000 mov ebx, dword ptr [0040B0EC]
:004011E6 83C410 add esp, 00000010
:004011E9 33F6 xor esi, esi
:004011EB 8D7C2420 lea edi, dword ptr [esp+20]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401208(C)
|
:004011EF 33C9 xor ecx, ecx
:004011F1 8A4C340C mov cl, byte ptr [esp+esi+0C]
:004011F5 51 push ecx
* Possible StringData Ref from Data Obj ->"%02lX"
|
:004011F6 681CC34000 push 0040C31C
:004011FB 57 push edi
:004011FC FFD3 call ebx
:004011FE 83C40C add esp, 0000000C
:00401201 46 inc esi
:00401202 83C702 add edi, 00000002
:00401205 83FE10 cmp esi, 00000010
:00401208 7CE5 jl 004011EF
:0040120A 8B8424141A0000 mov eax, dword ptr [esp+00001A14]
:00401211 8D542420 lea edx, dword ptr [esp+20]
:00401215 52 push edx
:00401216 50 push eax
* Reference To: KERNEL32.lstrcpyA, Ord:0000h
|
:00401217 FF1510B04000 Call dword ptr [0040B010]
:0040121D 5F pop edi
:0040121E 5E pop esi
:0040121F 5B pop ebx
:00401220 81C4001A0000 add esp, 00001A00
:00401226 C3 ret
由004011D0处可以根据Hash计算的常量“0123456789ABCDEFFEDEBA9876543210”推算出程序的第一部分
Hash计算使用的是MD5算法 关于MD5算法算法我在这篇文章里面就不多说了 如果对它感兴趣的话可以参看
我以前发布在看雪论坛上面的《MD5的介绍,算法和实现》 我想多多少少会对您有点帮助 根据MD5的特性-单向不可逆
所以在这个CrackMe中MD5算法只是起到一个计算中间值的作用 只要能看出来是MD5算法其他的都不用管了
**********************************Call(1)分析结束**********************************************
**********************************关键Call(2)**************************************************
* Referenced by a CALL at Address:
|:0040165F
|
:004010D0 51 push ecx
:004010D1 53 push ebx
:004010D2 55 push ebp
:004010D3 56 push esi
:004010D4 57 push edi
:004010D5 6A00 push 00000000
:004010D7 6A64 push 00000064
:004010D9 E832180000 call 00402910
:004010DE 6A00 push 00000000
:004010E0 8944241C mov dword ptr [esp+1C], eax
:004010E4 E887170000 call 00402870
:004010E9 6A00 push 00000000
:004010EB 8BF0 mov esi, eax
:004010ED E87E170000 call 00402870
:004010F2 6A00 push 00000000
:004010F4 8BF8 mov edi, eax
:004010F6 E875170000 call 00402870
:004010FB 6A00 push 00000000
:004010FD 8BD8 mov ebx, eax
:004010FF E86C170000 call 00402870
:00401104 8B4C2430 mov ecx, dword ptr [esp+30]
:00401108 8BE8 mov ebp, eax
:0040110A 8B442428 mov eax, dword ptr [esp+28]
:0040110E 51 push ecx
:0040110F 55 push ebp
:00401110 C7803802000010000000 mov dword ptr [ebx+00000238], 00000010
:0040111A E891260000 call 004037B0
* Possible StringData Ref from Data Obj ->"24DFDA27FA14D3F27DDF62CEA5D2381F9" /*N*/
|
:0040111F 68F0C24000 push 0040C2F0
:00401124 57 push edi
:00401125 E886260000 call 004037B0
* Possible StringData Ref from Data Obj ->"E401C1B" /*E*/
|
:0040112A 6814C34000 push 0040C314
:0040112F 53 push ebx
:00401130 E87B260000 call 004037B0
:00401135 56 push esi
:00401136 57 push edi
:00401137 53 push ebx
:00401138 55 push ebp
:00401139 E8422D0000 call 00403E80
:0040113E 8B54245C mov edx, dword ptr [esp+5C]
:00401142 83C440 add esp, 00000040
:00401145 52 push edx
:00401146 56 push esi
:00401147 E8F4280000 call 00403A40
:0040114C 57 push edi
:0040114D E8BE1C0000 call 00402E10
:00401152 53 push ebx
:00401153 E8B81C0000 call 00402E10
:00401158 55 push ebp
:00401159 E8B21C0000 call 00402E10
:0040115E 56 push esi
:0040115F E8AC1C0000 call 00402E10
:00401164 83C418 add esp, 00000018
:00401167 5F pop edi
:00401168 5E pop esi
:00401169 5D pop ebp
:0040116A 5B pop ebx
:0040116B 59 pop ecx
:0040116C C3 ret
一个很明显的RSA算法Call 在分析这个Call之前 让我们以最快的速度来复习一下关于RSA的概念和公式 以及通过
公式分析破解这个CrackMe
_______下面一小段引自dr0于2000年08月22日发表在看雪论坛的文章-《Windows优化大师v2.9+的注册码加密算法》_____
RSA算法简述
1、取两个素数p和q
2、计算n=pq,f=(p-1)(q-1)
3、随机选取整数e,满足条件gcd(e, f)=1,其中gcd为最大公约数
4、计算d,使得乘积de对f求余的结果为1,即de和1对f同余
上述只有e和n对外公开,用于加密
加密过程(符号^表示乘幂,mod表示求余) 设e为加密密钥,明文为m,密文为c 则加密公式如下c = (m ^ e) mod n
解密过程(设e为加密密钥,明文为m,密文为c,d为解密密钥) 则解密公式如下 m= (c ^ d) mod n
_______________________ 引用结束 感谢dr0 ____________________________________________________
现在我们已知 N=24DFDA27FA14D3F27DDF62CEA5D2381F9 E=E401C1B 如上所说我们的首要任务就是求出D
运行RSATool(其实BigInt Calculator Pro 1.2也有RSATool的功能 但是感觉上没有tE!的RSATool完善
并且在这个CrackMe中分解P和Q时会使系统没有响应 ) 求得P=16F54CE422ACC40EB Q=19B2CF048CA1B2FAB
所以D=1E2D9B52ADCBC20DCCDE3C721AA740E83
**********************************Call(2)分析结束**********************************************
到此 我们已经可以分析出这个CrackMe得基本算法了 不妨列出个等式方便分析:
CrackMe实际上是对比MD5的Hash运算结果与RSA算法中的密文 若相等则认为注册成功,根据上面的分析 RSA的加密
公式为c = (m ^ e) mod n 换中说法就是比较MD5的Hash运算结果是否等于 (M^E) MOD N
所以: (Registeration Code ^ E ) MOD N = MD5(Name + Organization)
即: Registeration Code = [ MD5( Name + Organization ) ^ D ] MOD N
因为: MD5(娃娃[CCG])=3E32771176B5CE99ED7C920DD28EADD6
得出等式:Registeration Code = [ 3E32771176B5CE99ED7C920DD28EADD6 ^ 1E2D9B52ADCBC20DCCDE3C721AA740E83 ] MOD 24DFDA27FA14D3F27DDF62CEA5D2381F9
这时就需要用到BigInt Calculator了 设 X=82674165571952145171965745053779799510 Y=641818296898666730290105568133836443267 Z=784232236484777663526392470596418241017 然后计算 X^Y%Z
得出结果为:362487173057627226939435819421597555030
在将其转换成十六进制得到:110B47D7782077078380A409E3295D956
字符串110B47D7782077078380A409E3295D956即为有效Key 分析完成~~~~~~~
给出两组有效Key 方便各位加深理解
Name: 娃娃
Organization: [CCG]
Registeration Code: 110B47D7782077078380A409E3295D956
Name: NYDoll
Organization: CHiNA CrACKiNG GrOUp
Registeration Code: 188B6DE7B64A99CA1DFE50084A6372ADE
*********************************注册机(VC源代码)****************************************************
/*
Lockless CrackMe #4 注册机 娃娃/[CCG]制作
RSA算法的源代码引用自tE! 的 PowerStrip keygenerator
MD5算法引用 Colin Plumb 和 John Walker 编写的模板
程序使用 freelip 的动态连接库
*/
#include <windows.h>
#include <lip.h>
#include <memory.h>
#define DLG_MAIN 111
#define BT_GENERATE 1008
#define EDIT_NAME 1009
#define EDIT_CODE 1010
#define EDIT_ORG 1011
typedef unsigned long uint32;
struct MD5Context {
uint32 buf[4];
uint32 bits[2];
unsigned char in[64];
};
void MD5Transform(uint32*, uint32*);
void byteReverse(buf, longs)
unsigned char *buf; unsigned longs;
{
uint32 t;
do {
t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
((unsigned) buf[1] << 8 | buf[0]);
*(uint32 *) buf = t;
buf += 4;
} while (--longs);
}
void MD5Init(ctx)
struct MD5Context *ctx;
{
ctx->buf[0] = 0x67452301;
ctx->buf[1] = 0xefcdab89;
ctx->buf[2] = 0x98badcfe;
ctx->buf[3] = 0x10325476;
ctx->bits[0] = 0;
ctx->bits[1] = 0;
}
void MD5Update(ctx, buf, len)
struct MD5Context *ctx; unsigned char *buf; unsigned len;
{
uint32 t;
t = ctx->bits[0];
if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
ctx->bits[1]++; /* Carry from low to high */
ctx->bits[1] += len >> 29;
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
/* Handle any leading odd-sized chunks */
if (t) {
unsigned char *p = (unsigned char *) ctx->in + t;
t = 64 - t;
if (len < t) {
memcpy(p, buf, len);
return;
}
memcpy(p, buf, t);
byteReverse(ctx->in, 16);
MD5Transform(ctx->buf, (uint32 *) ctx->in);
buf += t;
len -= t;
}
/* Process data in 64-byte chunks */
while (len >= 64) {
memcpy(ctx->in, buf, 64);
byteReverse(ctx->in, 16);
MD5Transform(ctx->buf, (uint32 *) ctx->in);
buf += 64;
len -= 64;
}
/* Handle any remaining bytes of data. */
memcpy(ctx->in, buf, len);
}
void MD5Final(digest, ctx)
unsigned char digest[16]; struct MD5Context *ctx;
{
unsigned count;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -