瑞星卡卡安全论坛技术交流区反病毒/反流氓软件论坛 新版“熊猫烧香”病毒壳+驱动分析+免疫程序下载(9楼)

12   1  /  2  页   跳转

[原创] 新版“熊猫烧香”病毒壳+驱动分析+免疫程序下载(9楼)

新版“熊猫烧香”病毒壳+驱动分析+免疫程序下载(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
本帖被评分 2 次
最后编辑闪电风暴 最后编辑于 2008-07-17 18:20:19
分享到:
gototop
 

回复:新版“熊猫烧香”病毒壳+驱动分析。

提供一种比较XX的防范方法:
开启OD,什么事也别做!
然后病毒就无法运行!
gototop
 

回复:新版“熊猫烧香”病毒壳+驱动分析。

当然用户不可能一直开着OD,我们可以编写一个程序HOOK掉FindWindowA,一旦发现OLLYDBG就总返回不为0的数字,使得病毒认为自己被调试从而主动退出。

HWND _stdcall Hook_FindWindowA(char* pClassName, char* pTitle)
{
      if(lstrcmpiA(pClassName, "OllyDbg") == 0)
                return 0x12345678; // 随便一点,返回一个不为0的数据
      else
                return Real_FindWindowA(pClassName, pTitle);
}

或者直接创建一个类名为"OLLYDBG"的窗口也行。
最后编辑闪电风暴 最后编辑于 2008-07-17 17:58:51
gototop
 

回复:新版“熊猫烧香”病毒壳+驱动分析。

也想写个免疫程序
最后编辑闪电风暴 最后编辑于 2008-07-17 18:20:37
gototop
 

回复: 新版“熊猫烧香”病毒壳+驱动分析。

原来没有那么复杂。由于这个病毒查TrainerSpy XP + NT / 2000 / XP + Coded By BofeN的窗口是根据窗口名而不是类名判断的,所以直接创建一个窗口名为TrainerSpy XP + NT / 2000 / XP + Coded By BofeN的工程就行了。

不需要自己写一行源代码,打开VC,利用VC的向导生成一个MFC EXE,打开对话框资源将标题改为“TrainerSpy XP + NT / 2000 / XP + Coded By BofeN”(不包括引号)就行了。

下载:

附件: MyStopIt.rar (2008-7-17 18:17:58, 90.21 K)
该附件被下载次数 201


gototop
 

回复:新版“熊猫烧香”病毒壳+驱动分析+免疫程序下载(9楼)

在运行了MyStopIt之后再运行病毒文件        .exe,那东西就会自杀
gototop
 

回复:新版“熊猫烧香”病毒壳+驱动分析+免疫程序下载(9楼)

如果已经感染,那么运行MyStopIt后用其它工具结束掉病毒进程它就不会起来了。。。
gototop
 

回复:新版“熊猫烧香”病毒壳+驱动分析+免疫程序下载(9楼)

瑞星现在 还不报毒。
这个东西的行为和熊猫烧香是一致的,开启后都要在drivers目录下创建一文件,然后用那个文件启动。
可见瑞星的启发特征提得不是很恰当。
gototop
 

回复:新版“熊猫烧香”病毒壳+驱动分析+免疫程序下载(9楼)

OD的中文汉化版中有一些插件可以防止OD被被调试程序发现。比如屏蔽IsDebuggerPresent等等。
这个不是标准的UPX壳,标准的UPX应该不会有太多的反调试功能。
这个壳经过修改,既然PEID无法认出,可能瑞星也没有正确认出,所以无法脱壳。因此里面的熊猫也就没事了。
gototop
 

回复:新版“熊猫烧香”病毒壳+驱动分析+免疫程序下载(9楼)

瑞星最新的病毒库可以查杀此病毒了。
gototop
 
12   1  /  2  页   跳转
页面顶部
Powered by Discuz!NT