找回密码
 注册
搜索
热搜: 回贴

HappyTown的第21个CrackMe分析 ,CrackMe,加密算法

2010-1-22 18:37| 发布者: admin| 查看: 79| 评论: 0|原作者: 九天玄女


HappyTown的第21个CrackMe分析 ,CrackMe,加密算法
2008年06月22日 星期日 下午 11:47
【文章标题】: HappyTown的第21个CrackMe分析

【文章作者】: Horst Stein

【作者邮箱】: horststein@hotmail.com

【软件名称】: HappyTown’s CrackMe_0021

【保护方式】: 序列号

【使用工具】: OD,PEiD,Kanal,IDA,W32DSAM,DAMN_HashCalc,OpenSSL库

【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!

--------------------------------------------------------------------------------

【详细过程】

首先感谢HappyTown为我们带来这么好的CrackMe。

用到了OpenSSL库。



一、基本情况分析:

1. 用PEiD分析,发现未加壳;

2. 用Kanal查看得知使用了MD5,用IDA加载openssl的sig文件后,导出MAP文件;

3. 随便输入信息,发现未有出错提示;

4. 但用W32DASM发现了Congratulations。它的前面有个je的跳转,再往前有个call 00401130在00401081处。



二、正式开工:

1. OD载入,用bp 401081下断点,并加载刚才生成的MAP文件;

2. 运行程序,输入假码:

name: HorstStein

sn:9876543210ABCDEF (为什么是16个字符,请看下面)

3. 点击Check被断,进入00401130:



00401130 />sub esp, 3CC

00401136 |>push ebx

00401137 |>push ebp

00401138 |>push esi

00401139 |>push edi

0040113A |>mov ecx, 31

0040113F |>xor eax, eax

00401141 |>lea edi, [esp 165]

00401148 |>mov byte ptr [esp 164], 0

00401150 |>rep stos dword ptr es:[edi]

00401152 |>stos word ptr es:[edi]

00401154 |>stos byte ptr es:[edi]

00401155 |>mov ecx, 31

0040115A |>xor eax, eax

0040115C |>lea edi, [esp 41]

00401160 |>mov byte ptr [esp 40], 0

00401165 |>rep stos dword ptr es:[edi]

00401167 |>stos word ptr es:[edi]

00401169 |>stos byte ptr es:[edi]

0040116A |>mov esi, [esp 3E0]

00401171 |>xor eax, eax

00401173 |>mov edi, [<&USER32.GetDlgItemTextA>] ; USER32.GetDlgItemTextA

00401179 |>mov [esp 29], eax

0040117D |>mov [esp 2D], eax

00401181 |>xor ecx, ecx

00401183 |>lea edx, [esp 164]

0040118A |>mov [esp 31], eax

0040118E |>mov [esp 21], ecx

00401192 |>push 0C9 ; /Count = C9 (201.)

00401197 |>push edx ; |Buffer

00401198 |>mov [esp 3D], ax ; |

0040119D |>mov ebx, 4 ; |

004011A2 |>mov [esp 2D], cx ; |

004011A7 |>push 3E8 ; |ControlID = 3E8 (1000.)

004011AC |>push esi ; |hWnd

004011AD |>mov byte ptr [esp 38], 0 ; |

004011B2 |>mov [esp 47], al ; |

004011B6 |>mov [esp 20], bl ; |//密钥从[esp 20]开始;bl=04

004011BA |>mov byte ptr [esp 21], 0B5 ; |

004011BF |>mov byte ptr [esp 22], 52 ; |

004011C4 |>mov byte ptr [esp 23], 6C ; |

004011C9 |>mov byte ptr [esp 24], 0DC ; |

004011CE |>mov byte ptr [esp 25], 6 ; |

004011D3 |>mov byte ptr [esp 26], 0C4 ; |

004011D8 |>mov byte ptr [esp 27], 0DF ; |

004011DD |>mov byte ptr [esp 28], 87 ; |

004011E2 |>mov byte ptr [esp 29], 0C2 ; |

004011E7 |>mov byte ptr [esp 2A], 0AA ; |

004011EC |>mov byte ptr [esp 2B], 75 ; |

004011F1 |>mov byte ptr [esp 2C], 0DE ; |

004011F6 |>mov byte ptr [esp 2D], 7 ; |

004011FB |>mov [esp 2E], bl ; |bl=04

004011FF |>mov byte ptr [esp 2F], 8 ; |\\密钥到[esp 2F]结束,长度16

00401204 |>mov [esp 30], al ; |

00401208 |>mov [esp 37], cl ; |

0040120C |>call edi ; \GetDlgItemTextA

0040120E |>mov ebp, eax ; len(name)

00401210 |>cmp ebp, ebx ; name长度不小于4

00401212 |>jge short 00401221

00401214 |>pop edi

00401215 |>pop esi

00401216 |>pop ebp

00401217 |>xor eax, eax

00401219 |>pop ebx

0040121A |>add esp, 3CC

00401220 |>retn

00401221 |>lea eax, [esp 40]

00401225 |>push 0C9

0040122A |>push eax

0040122B |>push 3E9

00401230 |>push esi

00401231 |>call edi ; 取输入的sn

00401233 |>cmp eax, 10 ; 注册码长度必须为16

00401236 |>je short 00401245

00401238 |>pop edi

00401239 |>pop esi

0040123A |>pop ebp

0040123B |>xor eax, eax

0040123D |>pop ebx

0040123E |>add esp, 3CC

00401244 |>retn

00401245 |>xor esi, esi

00401247 |>/cmp dword ptr [4082E8], 1 ; // 检查输入的序列号sn是否为16进制数,同时转化为小写

0040124E |>|jle short 00401265

00401250 |>|movsx ecx, byte ptr [esp esi 40]

00401255 |>|push 80

0040125A |>|push ecx

0040125B |>|call <__isctype>

00401260 |>|add esp, 8

00401263 |>|jmp short 00401277

00401265 |>|movsx edx, byte ptr [esp esi 40]

0040126A |>|mov eax, [4080DC]

0040126F |>|mov al, [eax edx*2]

00401272 |>|and eax, 80

00401277 |>|test eax, eax

00401279 |>|je short 00401214

0040127B |>|movsx ecx, byte ptr [esp esi 40]

00401280 |>|push ecx

00401281 |>|call <_tolower>

00401286 |>|add esp, 4

00401289 |>|mov [esp esi 40], al

0040128D |>|inc esi

0040128E |>|cmp esi, 10

00401291 |>\jl short 00401247 ; \\

00401293 |>xor edi, edi

00401295 |>lea esi, [esp 41]

00401299 |>/cmp dword ptr [4082E8], 1 ; //把sn转化成对应的十六进制

004012A0 |>|jle short 004012B3

004012A2 |>|movsx edx, byte ptr [esi-1]

004012A6 |>|push 2

004012A8 |>|push edx

004012A9 |>|call <__isctype>

004012AE |>|add esp, 8

004012B1 |>|jmp short 004012C3

004012B3 |>|movsx eax, byte ptr [esi-1]

004012B7 |>|mov ecx, [4080DC] ; CrackMe_.004080E6

004012BD |>|mov al, [ecx eax*2]

004012C0 |>|and eax, 2

004012C3 |>|mov bl, [esi-1]

004012C6 |>|test eax, eax

004012C8 |>|jnz short 004012CF

004012CA |>|sub bl, 30

004012CD |>|jmp short 004012D2

004012CF |>|sub bl, 57

004012D2 |>|cmp dword ptr [4082E8], 1

004012D9 |>|jle short 004012EB

004012DB |>|movsx edx, byte ptr [esi]

004012DE |>|push 2

004012E0 |>|push edx

004012E1 |>|call <__isctype>

004012E6 |>|add esp, 8

004012E9 |>|jmp short 004012FA

004012EB |>|movsx eax, byte ptr [esi]

004012EE |>|mov ecx, [4080DC] ; CrackMe_.004080E6

004012F4 |>|mov al, [ecx eax*2]

004012F7 |>|and eax, 2

004012FA |>|test eax, eax

004012FC |>|mov al, [esi]

004012FE |>|jnz short 00401304

00401300 |>|sub al, 30

00401302 |>|jmp short 00401306

00401304 |>|sub al, 57

00401306 |>|shl bl, 4

00401309 |>|or bl, al

0040130B |>|add esi, 2

0040130E |>|mov [esp edi 20], bl

00401312 |>|inc edi

00401313 |>|cmp edi, 8

00401316 |>\jl short 00401299 ; \\

00401318 |>lea edx, [esp 108]

0040131F |>push edx

00401320 |>call



//MD5_Init:

00401B80 >/>mov eax, [esp 4] ; MD5_Init

00401B84 |>xor ecx, ecx

00401B86 |>mov dword ptr [eax], 67452301 ; //MD5的4个常数

00401B8C |>mov dword ptr [eax 4], EFCDAB89

00401B93 |>mov dword ptr [eax 8], 98BADCFE

00401B9A |>mov dword ptr [eax C], 10325476 ; \\

00401BA1 |>mov [eax 10], ecx

00401BA4 |>mov [eax 14], ecx

00401BA7 |>mov [eax 58], ecx

00401BAA |>mov eax, 1

00401BAF \>retn

\\



00401325 |>lea eax, [esp 168]

0040132C |>push ebp ; len(name)

0040132D |>lea ecx, [esp 110]

00401334 |>push eax ; name

00401335 |>push ecx

00401336 |>call

0040133B |>lea edx, [esp 118]

00401342 |>lea eax, [esp 38]

00401346 |>push edx

00401347 |>push eax ; //在这里先d eax

00401348 |>call

0040134D |>lea ecx, [esp 244] ; \\看内存区,MD5(HorstStein)=82E0134547E6AF1C4D677811201710E7

00401354 |>lea edx, [esp 28]

00401358 |>push ecx ; 由openssl库idea.h头文件可知此乃IDEA_KEY_SCHEDULE结构,即存放子密钥的地方

00401359 |>push edx ; 用于IDEA的key:04 B5 52 6C...向上翻翻看:D

0040135A |>call <_idea_set_encrypt_key> ; 设置IDEA加密密钥

0040135F |>lea eax, [esp 324]

00401366 |>lea ecx, [esp 24C]

0040136D |>push eax

0040136E |>push ecx

0040136F |>call ; 设置IDEA解密密钥

00401374 |>lea edx, [esp 32C]

0040137B |>lea eax, [esp 60]

0040137F |>push edx

00401380 |>lea ecx, [esp 4C]

00401384 |>push eax

00401385 |>push ecx ; sn

00401386 |>call <_idea_ecb_encrypt> ; 解密sn(ecb模式)

0040138B |>add esp, 34

0040138E |>mov ecx, 2

00401393 |>lea edi, [esp 28]

00401397 |>lea esi, [esp 38]

0040139B |>xor edx, edx

0040139D |>repe cmps dword ptr es:[edi], dword ptr [esi]

0040139F |>pop edi

004013A0 |>mov eax, edx

004013A2 |>pop esi

004013A3 |>pop ebp

004013A4 |>sete al

004013A7 |>pop ebx

004013A8 |>add esp, 3CC

004013AE \>retn



三、其验证算法:

1. h=MD5(name);

2. x=IDEA(sn,Decrypt);

3. 判断h=x否,相等则成功,不等则失败



两组可用的注册码:

name:HorstStein

sn:03CDCA61C437218C



name:pediy

sn:6A46FF71FCCAAC76



四、注册机算法及其代码:

1. 算法:IDEA(MD5(name),Encrypt)。

2. 代码(用到了OpenSSL库):



int main()

{

int i;

int nLenName; //name长度

char szName[150] = {0}; //存放name

MD5_CTX md5;

unsigned char MD5Name[16] = {0}; //存放MD5(szName)的消息摘要

unsigned char cSerial_test[8] = {0}; //临时存放注册码

unsigned char outEn[8]; //存放IDEA的输出

unsigned char szBuffer[150]={0}; //存放注册码

IDEA_KEY_SCHEDULE key; //存放IDEA加密子密钥

unsigned char k[16] = { 0x04,0xB5,0x52,0x6C,0xDC,0x06,0xC4,0xDF,

0x87,0xC2,0xAA,0x75,0xDE,0x07,0x04,0x08};//IDEA密钥



printf("Enter your name:");

scanf("%s",szName);



//MD5(szName)

MD5_Init( &md5);

MD5_Update( &md5, szName, nLenName);

MD5_Final( MD5Name, &md5);



//设置IDEA加密密钥

idea_set_encrypt_key(k,&key);



for (i=0; i<8; i )

{

cSerial_test[i] = MD5Name[i];

}



//加密MD5(name)

idea_ecb_encrypt(cSerial_test,outEn,&key);



for (i=0; i<8; i )

{

wsprintf(&szBuffer[i*2], " X", *(byte*)(outEn i));

}

printf("\nSN:%s\n",szBuffer);

return 0;

}



--------------------------------------------------------------------------------

【经验总结】

这个CrackMe的验证方式和很多使用RSA的CrackMe的验证方式类似,所以,值得我等菜鸟一学。



--------------------------------------------------------------------------------

【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!


最新评论

QQ|小黑屋|最新主题|手机版|微赢网络技术论坛 ( 苏ICP备08020429号 )

GMT+8, 2024-9-30 03:33 , Processed in 0.254882 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

返回顶部