本帖最后由 cychk 于 2014-5-17 00:51 编辑
我前几天看了MistHill大神的分析,他算法分析得很好,而且patch也做得挺完美的,让我学到了不少知识啊,我现在就不发一些重复的东西咯,只发一些被忽略的细节问题和隐藏的彩蛋,当然彩蛋我也没解出来,只是发现了。
TLS回调和PEB DEBUG标志陷阱 首先程序有个tls回调,在以前,很多程序喜欢在tls回调里做调试检测,然后直接退出程序,但在这个crackme里,他检测了,但不是反调试,而是用来检测自己是否以调试方式启动 以下为代码片段
[Asm] 纯文本查看 复制代码 00401AD0 833D 90405B00 0>cmp dword ptr [005B4090h] , 00h//判断是否已经检测过
00401AD7 75 22 jne 00401AFBh
00401AD9 FF15 74545500 call dword ptr [00555474h] ; kernel32.IsDebuggerPresent
00401ADF 8B0D 94405B00 mov ecx , dword ptr [005B4094h]
00401AE5 BA 01000000 mov edx , 00000001h
00401AEA 85C0 test eax , eax
00401AEC 0F45CA cmovne ecx , edx
00401AEF 890D 94405B00 mov dword ptr [005B4094h] , ecx//如果是被调试,5b4094为1
00401AF5 8915 90405B00 mov dword ptr [005B4090h] , edx
00401AFB C2 0C00 retn 000Ch
[Asm] 纯文本查看 复制代码
00401BFD 85C0 test eax , eax
00401BFF 74 6C je 00401C6Dh
00401C01 833D 94405B00 0>cmp dword [005B4094h] , 01h //判断前面TLS回调设置的标志位,是否以调试模式创建的, 防止简单破解成直接启动
00401C08 75 63 jne 00401C6Dh
00401C0A 8D4D F0 lea ecx , dword [ebp-10h]
00401C0D 51 push ecx
00401C0E 50 push eax
00401C0F C745 F0 5A77577>mov dword [ebp-10h] , 7257775Ah //构造字符串ZwWriteFile
00401C16 C745 F4 6974654>mov dword [ebp-0Ch] , 46657469h
00401C1D C745 F8 696C650>mov dword [ebp-08h] , 00656C69h
00401C24 FF15 54545500 call dword [00555454h] ; kernel32.GetProcAddress
00401C2A A3 9C405B00 mov dword [005B409Ch] , eax
00401C2F 85C0 test eax , eax
00401C31 74 3A je 00401C6Dh
00401C33 E8 48FC1300 call 00541880h
00401C38 FF15 70545500 call dword [00555470h] ; kernel32.GetCurrentThread
00401C3E 50 push eax
00401C3F E8 1C011400 call 00541D60h
00401C44 68 401A4000 push 00401A40h
00401C49 68 9C405B00 push 005B409Ch
00401C4E E8 0DF51300 call 00541160h //该函数和下面的函数用于InlineHook ZwWriteFile 使
00401C53 E8 98FC1300 call 005418F0h //ZwWriteFile函数跳到0x401a40
00401C58 6A 00 push 00h
00401C5A 6A 00 push 00h
00401C5C 6A 00 push 00h
00401C5E 68 801B4000 push 00401B80h //创建线程 该线程完成文件检验函数和DLL解密加载
00401C63 6A 00 push 00h
00401C65 6A 00 push 00h
00401C67 FF15 6C545500 call dword [0055546Ch] ; kernel32.CreateThread
00401C6D 56 push esi
00401C6E 6A 00 push 00h
00401C70 FF15 50545500 call dword [00555450h] ; kernel32.OutputDebugStringW //配合原始进程
00401C76 8B35 74545500 mov esi , dword [00555474h] ; kernel32.IsDebuggerPresent
00401C7C FFD6 call esi
00401C7E 85C0 test eax , eax
00401C80 74 19 je 00401C9Bh
00401C82 57 push edi
00401C83 8B3D 4C545500 mov edi , dword [0055544Ch] ; kernel32.Sleep
00401C89 8DA424 00000000 lea esp , dword [esp+00000000h]
00401C90 6A 0A push 0Ah
00401C92 FFD7 call edi
00401C94 FFD6 call esi
00401C96 85C0 test eax , eax //判断本进程是否已经退出调试,退出才继续
00401C98 ^ 75 F6 jne 00401C90h
00401C9A 5F pop edi
00401C9B 64:A1 18000000 mov eax,dword ptr fs:[18]
00401CA1 8B40 30 mov eax,dword ptr ds:[eax+30]
00401CA4 C640 02 01 mov byte ptr ds:[eax+2],1 //又往DEBUG标志写1了,在后面判断会用到,防止部分工具PATCH PEB,这里就解释了为什么后面已经退出调试了,但[/b][b]IsDebuggerPresent返回的还是1[/b][/align][align=left][b]00401CA8 8B4D FC mov ecx,dword ptr ss:[ebp-4]
00401CAB 33CD xor ecx,ebp
00401CAD 5E pop esi
00401CAE E8 E9561200 call 破解考题.0052739C
00401CB3 8BE5 mov esp,ebp
00401CB5 5D pop ebp
[Asm] 纯文本查看 复制代码 [/b][/align][align=left][b]00401A40 55 push ebp
00401A41 8BEC mov ebp,esp
00401A43 833D A0405B00 0>cmp dword ptr ds:[5B40A0],0 //判断LSG函数是否已经获取到
00401A4A 56 push esi
00401A4B 8B75 08 mov esi,dword ptr ss:[ebp+8]
00401A4E 74 59 je short 破解考题.00401AA9[attach]281168[/attach]
00401A50 3B35 98405B00 cmp esi,dword ptr ds:[5B4098] //判断句柄是否是自己调用的
00401A56 75 51 jnz short 破解考题.00401AA9
00401A58 FF15 74545500 call dword ptr ds:[555474] ; kernel32.IsDebuggerPresent
00401A5E 83F8 01 cmp eax,1 //判断是否已经1,防止被PATCH PEB
00401A61 75 21 jnz short 破解考题.00401A84
00401A63 E8 48050000 call 破解考题.00401FB0 //调用ZwQueryInformationProcess查询DebugPort判断本进程是否在调试
00401A68 83F8 01 cmp eax,1
00401A6B 74 17 je short 破解考题.00401A84 //有在调试或者PATCH过PEB直接死[/b][/align][align=left][b]
隐藏的彩蛋,这个彩蛋就是除了success外,还有其他成功的字符,也是md5,多了一个crc校验,可能为了防止碰撞,我用crc爆破,碰撞太厉害,半小时就放弃了,现在大家一起试试吧,说不定是很有意思的字符呢
函数都位于DLL里,得dump出来才能分析到 [Asm] 纯文本查看 复制代码 100023D8 F3: movq xmm0 , qword [esp+78h]
100023DE 66:0FD6 movq qword [esp+000000E8h] , xmm0 ; 未知命令
100023E7 C78424 88000000>mov dword [esp+00000088h] , F2835A50h //固定的Success MD5值
100023F2 C78424 8C000000>mov dword [esp+0000008Ch] , F22DC020h
100023FD C78424 90000000>mov dword [esp+00000090h] , 10385CF8h
10002408 C78424 94000000>mov dword [esp+00000094h] , 38EB9CCDh
10002413 8D8C24 88000000 lea ecx , dword [esp+00000088h]
1000241A 8D9424 E0000000 lea edx , dword [esp+000000E0h]
10002421 BE 0C000000 mov esi , 0000000Ch
10002426 8B01 mov eax , dword [ecx]
10002428 3B02 cmp eax , dword [edx] //判断md5
1000242A 0F85 B7000000 jne 100024E7h //失败跳隐藏验证,也就是除了Success还有其他成功的标志
10002430 83C1 04 add ecx , 04h
10002433 83C2 04 add edx , 04h
[Asm] 纯文本查看 复制代码 100024EF C78424 B0000000>mov dword [esp+000000B0h] , 1495EAF5h
100024FA C78424 B4000000>mov dword [esp+000000B4h] , 0754D5B1h
10002505 C78424 B8000000>mov dword [esp+000000B8h] , 253688B4h
10002510 C78424 BC000000>mov dword [esp+000000BCh] , 49E37860h
1000251B C78424 C0000000>mov dword [esp+000000C0h] , 0074006Eh
10002526 C78424 C4000000>mov dword [esp+000000C4h] , 006C0064h
10002531 C78424 C8000000>mov dword [esp+000000C8h] , 002E006Ch
1000253C C78424 CC000000>mov dword [esp+000000CCh] , 006C0064h
10002547 C78424 D0000000>mov dword [esp+000000D0h] , 0000006Ch
10002552 C78424 8C000000>mov dword [esp+0000008Ch] , 436C7452h
1000255D C78424 90000000>mov dword [esp+00000090h] , 75706D6Fh
10002568 C78424 94000000>mov dword [esp+00000094h] , 72436574h //这些代码构造Ntdll模块还有CRC校验函数字符串
10002573 C78424 98000000>mov dword [esp+00000098h] , 00323363h
//还有隐藏的成功MD5 F5EA9514B1D55407B48836256078E349
1000257E FF15 34B00110 call dword [1001B034h] ; kernel32.GetModuleHandleW
10002584 85C0 test eax , eax
10002586 74 71 je 100025F9h
10002588 8D8C24 88000000 lea ecx , dword [esp+00000088h]
1000258F 51 push ecx
10002590 50 push eax
10002591 FF15 2CB00110 call dword [1001B02Ch] ; kernel32.GetProcAddress
10002597 8BD8 mov ebx , eax
10002599 85DB test ebx , ebx
1000259B 74 5C je 100025F9h
1000259D 8D8C24 AC000000 lea ecx , dword [esp+000000ACh]
100025A4 8D9424 E0000000 lea edx , dword [esp+000000E0h]
100025AB BE 0C000000 mov esi , 0000000Ch
100025B0 8B01 mov eax , dword [ecx]
100025B2 3B02 cmp eax , dword [edx] //校验隐藏MD5
100025B4 75 43 jne 100025F9h
100025B6 83C1 04 add ecx , 04h
100025B9 83C2 04 add edx , 04h
100025BC 83EE 04 sub esi , 04h
100025BF ^ 73 EF jnc 100025B0h
100025C1 8D8C24 F0040000 lea ecx , dword [esp+000004F0h]
100025C8 8D51 01 lea edx , dword [ecx+01h]
100025CB EB 03 jmp 100025D0h
100025CD 8D49 00 lea ecx , dword [ecx+00h]
100025D0 8A01 mov al , byte [ecx]
100025D2 41 inc ecx
100025D3 84C0 test al , al
100025D5 ^ 75 F9 jne 100025D0h
100025D7 2BCA sub ecx , edx
100025D9 51 push ecx
100025DA 8D8424 F4040000 lea eax , dword [esp+000004F4h]
100025E1 50 push eax
100025E2 6A 00 push 00h
100025E4 FFD3 call ebx //多了一步校验CRC
100025E6 3D 26111478 cmp eax , 78141126h //CRC校验值
其他算法之类的就不发啦,我感觉还没MistHill分析得完整,不过我还是附上提交的文档,我当时还提交了木马攻防cleanos的破解方法,不过没结果,等我整理完那个也分享过程给大家吧
附件貌似不见了,给个good.gd地址吧http://good.gd/3058908.htm
完整提交.zip
(1.75 MB, 下载次数: 93)
|