统计分析攻击实例
by stalker
by stalker
攻击目标:
target.rar
目标保护方法:
代码与数据结合,把用户输入作为key对已加密的代码进行解码,如果key正确,则解出正确代码,提示成功,否则解出错误代码,程序由Error Handler结束或者直接崩掉。(我最先是在论坛出版的《软件加密技术内幕》一书中学到这一方法)
关键代码如下:
代码:
0040103A . B9 70000000 mov ecx, 70 0040103F . BE 4C104000 mov esi, 0040104C 00401044 > 3006 xor byte ptr [esi], al 00401046 . 49 dec ecx 00401047 . E3 03 jecxz short 0040104C 00401049 . 46 inc esi 0040104A .^ EB F8 jmp short 00401044 0040104C > DC37 fdiv qword ptr [edi] 0040104E . 71 79 jno short 004010C9 00401050 . 57 push edi 00401051 . 56 push esi 00401052 . 67:6F outs dx, dword ptr es:[di] 00401054 . 6E outs dx, byte ptr es:[edi] 00401055 . 66:5F pop di 00401057 . 52 push edx 00401058 . 16 push ss 00401059 . 37 aaa 0040105A . 37 aaa 0040105B . 5F pop edi 0040105C . 17 pop ss 0040105D . 73 58 jnb short 004010B7 0040105F . 59 pop ecx 00401060 . 5F pop edi 00401061 . 60 pushad 00401062 . 52 push edx 00401063 . 5B pop ebx 00401064 . 5B pop ebx 00401065 . BC F35F4416 mov esp, 16445FF3 0040106A . 37 aaa 0040106B . 37 aaa 0040106C . 5F pop edi 0040106D . 52 push edx 0040106E . 17 pop ss 0040106F . 47 inc edi 00401070 . 5B pop ebx 00401071 . 5F pop edi 00401072 . 17 pop ss 00401073 . 53 push ebx 00401074 . 58 pop eax 00401075 . 59 pop ecx 00401076 . 5F pop edi 00401077 . 42 inc edx 00401078 . 1041 52 adc byte ptr [ecx+52], al 0040107B . 5F pop edi 0040107C . 59 pop ecx 0040107D . 17 pop ss 0040107E . 4E dec esi 0040107F . 58 pop eax 00401080 . 5F pop edi 00401081 . 50 push eax 00401082 . 42 inc edx 00401083 . 5C pop esp 00401084 . 56 push esi 00401085 . 5F pop edi 00401086 . 5B pop ebx 00401087 . 17 pop ss 00401088 . 53 push ebx 00401089 . 58 pop eax 0040108A . 5F pop edi 0040108B . 16 push ss 0040108C . 43 inc ebx 0040108D . 52 push edx 0040108E . 5B pop ebx 0040108F . 5F pop edi 00401090 . 5A pop edx 00401091 . 56 push esi 00401092 . 45 inc ebp 00401093 . 43 inc ebx 00401094 . 5F pop edi 00401095 . 44 inc esp 00401096 . 58 pop eax 00401097 . 17 pop ss 00401098 . 44 inc esp 00401099 . 5F pop edi 0040109A . 56 push esi 0040109B . 45 inc ebp 0040109C . 52 push edx 0040109D . 17 pop ss 0040109E . 5F pop edi 0040109F . 4E dec esi 004010A0 . 58 pop eax 004010A1 . 42 inc edx 004010A2 . 17 pop ss 004010A3 . BC EB5D7767 mov esp, 67775DEB 004010A8 . 64:5D pop ebp 004010AA . 37 aaa 004010AB . C8 227B17 enter 7B22, 17 004010AF . 77 37 ja short 004010E8 004010B1 . B4 F3 mov ah, 0F3 004010B3 . 0BDC or ebx, esp 004010B5 . 37 aaa 004010B6 . 57 push edi 004010B7 > 56 push esi 004010B8 . 51 push ecx 004010B9 . 6E outs dx, byte ptr es:[edi] 004010BA . 51 push ecx 004010BB . 66 db 66 ; CHAR 'f'
原理概述:
从上面看到,从40104C到4010BB范围内的代码已经被加密,从xor byte ptr [esi], al这一句代码可以看出,程序采用了简单的xor加密,并且key的长度为1 byte^_^。现在我们只拥有密文(被加密后的代码),如何能获取明文呢(加密前的代码)?因为key的长度仅仅为1 byte,即使使用最笨拙的穷举攻击法,我们也能很快找出正确的key。但是这次我们要使用的是统计分析法,大家需要知道程序代码的一个通用的统计特性------在程序代码中通常0最多。
由于0 xor key = key
因此密文中与之对应的特性就是------在密文(被加密的程序代码)中通常key最多。
现在我们要做的就是统计40104E到4010BD范围内各个数据(0x00->0xFF)出现的次数,然后从出现频率最大的数据开始尝试对密文进行解码。
利用WinHex从crackme.exe中提取出被加密的代码,并用如下程序对其进行统计
代码:
#include<stdio.h> int main(void) { int i,j; unsigned char m[112] = { 0xDC, 0x37, 0x71, 0x79, 0x57, 0x56, 0x67, 0x6F, 0x6E, 0x66, 0x5F, 0x52, 0x16, 0x37, 0x37, 0x5F, 0x17, 0x73, 0x58, 0x59, 0x5F, 0x60, 0x52, 0x5B, 0x5B, 0xBC, 0xF3, 0x5F, 0x44, 0x16, 0x37, 0x37, 0x5F, 0x52, 0x17, 0x47, 0x5B, 0x5F, 0x17, 0x53, 0x58, 0x59, 0x5F, 0x42, 0x10, 0x41, 0x52, 0x5F, 0x59, 0x17, 0x4E, 0x58, 0x5F, 0x50, 0x42, 0x5C, 0x56, 0x5F, 0x5B, 0x17, 0x53, 0x58, 0x5F, 0x16, 0x43, 0x52, 0x5B, 0x5F, 0x5A, 0x56, 0x45, 0x43, 0x5F, 0x44, 0x58, 0x17, 0x44, 0x5F, 0x56, 0x45, 0x52, 0x17, 0x5F, 0x4E, 0x58, 0x42, 0x17, 0xBC, 0xEB, 0x5D, 0x77, 0x67, 0x64, 0x5D, 0x37, 0xC8, 0x22, 0x7B, 0x17, 0x77, 0x37, 0xB4, 0xF3, 0x0B, 0xDC, 0x37, 0x57, 0x56, 0x51, 0x6E, 0x51, 0x66 },s[256] = {0}; //数组m即为从WinHex中提取出来的密文,数组s用于保存每个数据出现的次数 for(i = 0;i < 112;i++) for(j = 0;j <= 255;j++) if(m[i] == j) s[j]++; for(i = 0x00;i <= 0xFF;i++) printf("0x%02X:%d\n",i,s[i]); system("pause"); return 0; }
0x5F:15
0x17:9
0x37:8
0x52:6
0x58:6
0x56:5
0x5B:5
从0x5F开始做key尝试对密文进行解密,最终确定0x37即为正确的key。
在这一个例子中,我们只要对算法稍做改进,例如,每次xor之后对key做一定的变换,就可以使明文的统计特性不被带入密文,从而抵抗统计分析法。
PS.
我是一只菜鸟,刚刚开始看最开始提到的那本书,才发现以前知道的这么一点点东西居然还有科学的名字^_^
感谢经验丰富的程序员天杀,程序代码中通常0最多这一特性是很久以前我和他聊天的时候他告诉我的。