首页
社区
课程
招聘
[分享]又KO了一个crackme
发表于: 2010-11-10 17:10 5693

[分享]又KO了一个crackme

2010-11-10 17:10
5693
依然是加密与解密的习题,依旧循着前辈们的轨迹~。只不过这次的crackme用了通用的加密算法。

这个crack比较简单,过程就略过了,直接说下分析的结果吧。
首先在运行之初 窗口初始化之前,会通过GetVersion的返回值计算出一个值。
计算方法如下:
004010AB  /$  E8 32090000   CALL <JMP.&kernel32.GetVersion>
004010B0  |.  BB 08000000   MOV EBX,8
004010B5  |.  F7E3          MUL EBX                                            ;  GetVersion返回值乘以8
004010B7  |.  50            PUSH EAX                                           ; /<%X>
004010B8  |.  68 00304000   PUSH kiToKGNm.00403000                             ; |Format = "%X"
004010BD  |.  68 A8314000   PUSH kiToKGNm.004031A8                             ; |s = kiToKGNm.004031A8
004010C2  |.  E8 33090000   CALL <JMP.&user32.wsprintfA>                       ; \wsprintfA
004010C7  |.  83C4 0C       ADD ESP,0C
004010CA  |.  68 DA314000   PUSH kiToKGNm.004031DA                             ;  ASCII "RUQ4MDA4MzA="
004010CF  |.  6A 08         PUSH 8
004010D1  |.  68 A8314000   PUSH kiToKGNm.004031A8                             ;  ASCII "ED800830"
004010D6  |.  E8 C5070000   CALL kiToKGNm.004018A0                             ;  对机器码进行base64加密 放在4031DA
004010DB  |.  68 A8314000   PUSH kiToKGNm.004031A8                             ; /StringToAdd = "ED800830"
004010E0  |.  68 0C324000   PUSH kiToKGNm.0040320C                             ; |ConcatString = "ED800830RUQ4MDA4MzA="
004010E5  |.  E8 FE080000   CALL <JMP.&kernel32.lstrcatA>                      ; \lstrcatA
004010EA  |.  68 DA314000   PUSH kiToKGNm.004031DA                             ; /StringToAdd = "RUQ4MDA4MzA="
004010EF  |.  68 0C324000   PUSH kiToKGNm.0040320C                             ; |ConcatString = "ED800830RUQ4MDA4MzA="
004010F4  |.  E8 EF080000   CALL <JMP.&kernel32.lstrcatA>                      ; \lstrcatA
004010F9  |.  68 3E324000   PUSH kiToKGNm.0040323E                             ;  ASCII "RUQ4MDA4MzBSVVE0TURBNE=="
004010FE  |.  6A 10         PUSH 10
00401100  |.  68 0C324000   PUSH kiToKGNm.0040320C                             ;  ASCII "ED800830RUQ4MDA4MzA="
00401105  |.  E8 96070000   CALL kiToKGNm.004018A0                             ;  对字符串的前16位再次进行base64加密 存放在40323E
0040110A  \.  C3            RETN

先将返回值乘以8,然后进行base64加密 然后再将返回值与加密后的字串连接起来,再进行一次base64加密不过这次加密比较特殊,加密完后取前16位的加密结果,再用'='补充到4的倍数。(这点好像与普通的base64有点不同吧?).
http://baike.baidu.com/view/469071.htm(base64参考资料)
大概过程用C描述如下:
	
int ver = GetVersion();
ver*=8;
wsprintf(str,"%X",ver);
base64_code(str,lstrlen(str),code); 
strcat(str,code);
base64_code(str,16,code);

根据这个题目我写了个base64的加密过程,因为只针对这个题目所以写的很简单没有考虑>74位的情况。首先找到base64的表。

00403060  41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 ABCDEFGHIJKLMNOP
00403070  51 52 53 54 55 56 57 58 59 5A 61 62 63 64 65 66 QRSTUVWXYZabcdef
00403080  67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76  ghijklmnopqrstuv
00403090  77 78 79 7A 30 31 32 33 34 35 36 37 38 39 2B 2F  wxyz0123456789+/
可以看出就是普通的base64的表,没有做过变形。
以下是针对此crackme的base64加密:

char table[128]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int base64_code(char str[] , int len ,char code[])
{
	
	short a,b,c;
	int i,j=0;
	if(len<3)
	{
		return 0;
	}
	for(i=0;i<len;i+=3)
	{
		a=str[i];
		b=str[i+1];
		if(i+1>strlen(str)-1)
			b=0;
		c=str[i+2];
		if(i+2>strlen(str)-1)
			c=0;
		code[j++]=table[a>>2];
		code[j++]=table[((a<<4)+(b>>4))&63];
		code[j++]=table[((b<<2)+(c>>6))&63];
		code[j++]=table[c&63];
	}
	if(len%3==1)
	{
		code[j-2]='=';
		code[j-1]='=';
	}
	if(len%3==2)
		code[j-1]='=';
	code[j]='\0';
	return j;
}

接下来是读入用户名 并且对用户名进行base64加密,并与前面所计算的code进行连接。再对整个连接的字符串进行MD5加密。MD5的3个过程跟进去看了下。初始化,填充都是正常的MD5过程。所以直接拿MD5的源码过来算就好了。
0040110E  |.  C605 D4324000>MOV BYTE PTR DS:[4032D4],0
00401115  |.  6A 32         PUSH 32                                              ; /Count = 32 (50.)
00401117  |.  68 70324000   PUSH kiToKGNm.00403270                             ; |Buffer = kiToKGNm.00403270
0040111C  |.  68 E9030000   PUSH 3E9                                     ; |ControlID = 3E9 00401121  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]          ; |hWnd
00401124  |.  E8 E3080000   CALL <JMP.&user32.GetDlgItemTextA>     ; \读入用户名
00401129  |.  68 A2324000   PUSH kiToKGNm.004032A2   
0040112E  |.  50            PUSH EAX
0040112F  |.  68 70324000   PUSH kiToKGNm.00403270       ;  ASCII "zhangtaopy"
00401134  |.  E8 67070000   CALL kiToKGNm.004018A0       ;  用户名 进行base64加密 存放在4032A2
00401139  |.  68 A2324000   PUSH kiToKGNm.004032A2                             ; /StringToAdd = "emhhbmd0YW9weQ=="
0040113E  |.  68 D4324000   PUSH kiToKGNm.004032D4                 ; |ConcatString = "emhhbmd0YW9weQ==RUQ4MDA4MzBSVVE0TURBNE=="
00401143  |.  E8 A0080000   CALL <JMP.&kernel32.lstrcatA>                      ; \lstrcatA
00401148  |.  68 3E324000   PUSH kiToKGNm.0040323E                             ; /StringToAdd = "RUQ4MDA4MzBSVVE0TURBNE=="
0040114D  |.  68 D4324000   PUSH kiToKGNm.004032D4                             ; |ConcatString = "emhhbmd0YW9weQ==RUQ4MDA4MzBSVVE0TURBNE=="
00401152  |.  E8 91080000   CALL <JMP.&kernel32.lstrcatA>                      ; \lstrcatA
00401157  |.  68 D4324000   PUSH kiToKGNm.004032D4                             ; /String = "emhhbmd0YW9weQ==RUQ4MDA4MzBSVVE0TURBNE=="
0040115C  |.  E8 93080000   CALL <JMP.&kernel32.lstrlenA>                      ; \lstrlenA
00401161  |.  A3 A0314000   MOV DWORD PTR DS:[4031A0],EAX       ;  字符串长度00401166  |.  E8 3D060000   CALL kiToKGNm.004017A8                     ;  MD5初始化
0040116B  |.  FF35 A0314000 PUSH DWORD PTR DS:[4031A0]
00401171  |.  68 D4324000   PUSH kiToKGNm.004032D4                   ;  ASCII "emhhbmd0YW9weQ==RUQ4MDA4MzBSVVE0TURBNE=="
00401176  |.  E8 6D060000   CALL kiToKGNm.004017E8                    ;  MD5 填充函数
0040117B  |.  E8 C8060000   CALL kiToKGNm.00401848                    ;  MD5计算


最后将算出来的32位MD5码 以双字的形式相加,的出来的结果转化成字符串后,将第5个字符变成'-',就得出注册码了:
00401182  |.  0318          ADD EBX,DWORD PTR DS:[EAX]       ;4个双字相加               
00401184  |.  0358 04       ADD EBX,DWORD PTR DS:[EAX+4]
00401187  |.  0358 08       ADD EBX,DWORD PTR DS:[EAX+8]
0040118A  |.  0358 0C       ADD EBX,DWORD PTR DS:[EAX+C]
0040118D  |.  53            PUSH EBX                                           ; /<%X>
0040118E  |.  68 00304000   PUSH kiToKGNm.00403000               ; |Format = "%X"
00401193  |.  68 38334000   PUSH kiToKGNm.00403338              ; |s
00401198  |.  E8 5D080000   CALL <JMP.&user32.wsprintfA>       ; \wsprintfA
0040119D  |.  83C4 0C       ADD ESP,0C                                       ;结果转化成字符串
004011A0  |.  C605 3C334000>MOV BYTE PTR DS:[40333C],2D  ;第5个字符变为'-'
004011A7  |.  6A 32         PUSH 32                                            ; /Count = 32 (50.)
004011A9  |.  68 6A334000   PUSH kiToKGNm.0040336A           ; |Buffer
004011AE  |.  68 EA030000   PUSH 3EA                                  ; |ControlID = 3EA 004011B3  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                          ; |hWnd
004011B6  |.  E8 51080000   CALL <JMP.&user32.GetDlgItemTextA>    ; 
004011BB  |.  68 6A334000   PUSH kiToKGNm.0040336A       ; /String2 = "9B02-52"
004011C0  |.  68 38334000   PUSH kiToKGNm.00403338       ; |String1 = "9B02-52"
004011C5  |.  E8 24080000   CALL <JMP.&kernel32.lstrcmpA>   ; \lstrcmpA 明码比较


分析完毕~~
2L注册机

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 125
活跃值: (161)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
我写的~~base64.h
#include<stdio.h>
#include<string.h>
#include<math.h>
char table[128]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int base64_code(char str[] , int len ,char code[])
{
	
	short a,b,c;
	int i,j=0;
	if(len<3)
	{
		return 0;
	}
	for(i=0;i<len;i+=3)
	{
		a=str[i];
		b=str[i+1];
		if(i+1>strlen(str)-1)
			b=0;
		c=str[i+2];
		if(i+2>strlen(str)-1)
			c=0;
		code[j++]=table[a>>2];
		code[j++]=table[((a<<4)+(b>>4))&63];
		code[j++]=table[((b<<2)+(c>>6))&63];
		code[j++]=table[c&63];
	}
	if(len%3==1)
	{
		code[j-2]='=';
		code[j-1]='=';
	}
	if(len%3==2)
		code[j-1]='=';
	code[j]='\0';
	return j;
}


注册机:
#include"base64.h"
#include<stdio.h>
#include<windows.h>
#include"md5c.c"
#define MASK 0x000000ff;
int main()
{
	MD5_CTX context;
	char str[256],code[256]={0},user[50],szHash[128];
	int a=0,b=0,i,sum=0;
	int ver = GetVersion();
	ver*=8;
	wsprintf(str,"%X",ver);
	base64_code(str,lstrlen(str),code);
	strcat(str,code);
	base64_code(str,16,code); 
	scanf("%s",&user);
	base64_code(user,lstrlen(user),str);
	strcat(str,code);
	MD5Init(&context);
	MD5Update(&context, str, lstrlen(str));
	MD5Final(szHash, &context);
	for(i=0;i<4;i++)
	{
		a=a&0x00000000;
		b=szHash[i*4+3]&MASK;
		a+=b<<24;
		b=szHash[i*4+2]&MASK;
		a+=b<<16;
		b=szHash[i*4+1]&MASK;
		a+=b<<8;
		b=szHash[i*4]&MASK;
		a+=b;
		sum+=a;
	}
	wsprintf(code,"%X",sum);
	code[4]='-';
	printf("%s\n",code);
	return 0;
}


忘记说了 预祝各位明天节日快乐~
上传的附件:
2010-11-10 17:12
0
雪    币: 198
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
不错. 支持...

我还不会呢
2010-11-10 23:49
0
雪    币: 544
活跃值: (55)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
楼主水平真高。佩服
2010-12-6 23:18
0
游客
登录 | 注册 方可回帖
返回
//