Minima Anonyma Tabularia Ex Reti
nihil vacuum neque sine signo
apud MATER
Questa pubblicazione contiene
informazioni e codice sorgente relativi alla sicurezza informatica. Lo
scopo di queste informazioni è di aiutare gli utenti ad accrescere la propria
capacità di programmazione. Questo materiale è a puro scopo didattico e non
include codice distruttivo né documenti attinenti ad alcuna attività illegale.
Si declina ogni responsabilità nel caso chiunque utilizzi le suddette
informazioni per creare, compilare e diffondere intenzionalmente programmi
diretti a danneggiare o interrompere un sistema informatico o telematico,
ovvero a provocarne l'interruzione, totale o parziale, o l'alterazione del suo
funzionamento Art. 615-quinquies (Legge n. 547/93 pubblicata in Gazzetta
Ufficiale n. 305 del 30.12.1993)
Editoriale
Contagiati dall’italica usanza di
alzare la manina al comparire di una telecamera e di sbrodolare dinastie
parentali alla voce telefonica della Carrà, cominciamo questo numero con una
serie di saluti.
Cari saluti a tutti i figliocci dispersi
di familia, a Foschia innanzitutto (ma sarai ancora vivo ?), a Windo e le sue
matematiche esoteriche, a Kxanemacchina e la sua discarica. Salutoni a Simo (…e
l’amore, come va ?). Un ciaone a Matteo (non dimenticare lo studio !), a
Natalia e Lella (non ti sei fatta più viva…) e a tutta la squadra dei bulgari
assassini. Un ciaone a Baranovich e alla sua ospitalità. Una strettina di mano
anche a Thorin, che anche se fa il birichino in realtà è una pasta d’uomo. Più
che un saluto, un continente di solidarietà a tutti i diseredati, disperati,
reietti, abbandonati e affamati di giustizia della Terra: ragazzi, siamo dei
vostri !
Questo numero di MATER inaugura lo
studio del polimorfismo. Essendo la materia vasta e un pochino intricata, verrà
svolta in più numeri. Eccovi il piano di lavoro:
POLIMORFISMO
1- MATER 7 – definizioni, livelli di
polimorfismo, azioni di un motore polimorfico;
POLIMORFISMO
2- MATER 8 – istruzioni e codici; formato
istruzioni INTEL; codifica; esempi;
POLIMORFISMO
3- MATE R 9 – come si comportano gli AV; particolarità;
POLIMORFISMO
4- MATER 10 – un
esempio di motore polimorfico.
Buona lettura.
Ictus/Familia
§ MATER Liber Septimus §
indice
3.cosa fa un
motore polimorfico
L’esistenza del polimorfismo è connessa
all’esistenza dei software antivirus. Quando ancora non esistevano i motori polimorfici, un programma AV effettuava una
scansione dei files infetti alla ricerca di una stringa comune che rivelasse la
presenza di codice virale. Da qui nacque l’esigenza da parte dei programmatori
di virus di crittografare il codice virus ad ogni nuova infezione. Tuttavia
c’era un problema: tutti i virus crittografati dovevano forzatamente possedere
una routine di crittografazione non crittografata (vedi sezione sulla
crittografia), routine che era suscettibile di essere rivelata dal software AV
perché sempre uguale. Le energie dei code writers si concentrarono allora sullo
studio di un software che potesse essere interamente crittografato (quindi
compresa la routine di crittografazione stessa), e modificabile ad ogni
infezione. Nacque così il polimorfismo.
Il polimorfismo può essere definito come
l’eliminazione di tutti i possibili bytes costanti all’interno dell’unica
porzione di un codice virus crittografato: la routine di crittografazione.
Quindi il polimorfismo per un virus significa l’abilità di modificare interamente il proprio codice ad ogni
nuova infezione. Dal punto di vista tecnico il polimorfismo consiste nel
costruire una routine di crittografazione variabile.
I programmatori AV hanno dato un nome ad ogni
livello di polimorfismo. Ecco un piccolo estratto di AVPVE:
I virus
polimorfici sono suddivisi in base alla complessità del codice della loro
routine di crittografazione (d’ora in poi per brevità RC) in base ad un sistema
introdotto da Alan Solomon e sviluppato da Vesselin Bontchev.
Livello 1: il virus ha un set di RC con codice
costante. Durante l’infezione viene scelto uno di questi set. Questi virus sono
chiamati “semi-polimorfici” o “oligomorfici”. esempi: "Cheeba",
"Slovakia", "Whale".
Livello 2: la RC contiene una di varie istruzioni
costanti, mentre il resto è modificabile.
Livello 3: la RC contiene istruzioni non utilizzate,
chiamate istruzioni "junk" come NOP, CLI, STI,etc.
Livello 4: la RC usa istruzioni intercambiabili e
modifica il loro ordine (instructions mixing). L’algoritmo di crittografazione
rimane inalterato.
Livello 5: sono utilizzate tutte le tecniche sopra
citate, l’algoritmo di crittografazione è modificabile, c’è ripetizione della
crittografazione del codice virus ed è possibile ogni parziale crittografazione
della RC.
Livello 6: (permutating viruses). Il codice
principale del virus è soggetto a vari tipi di modificazione, è suddiviso in
blocchi che sono posizionati casualmente (random) durante l’infezione.
La possibilità di riconoscere il codice della RC
varia a seconda dei livelli:
Livello 1:
per trovare il virus è sufficiente avere diverse maschere.
Livello 2:
come 1, ma con l’utilizzo di "wild cards".
Livello 3:
la presenza della RC è rivelata dall’utilizzo di maschere, dopo aver eliminato
le istruzioni "junk".
Livello 4:
la maschera contiene parecchie versioni di possibile codice “algoritmico”.
Livello 5:
non è possibile rivelare la presenza del virus utilizzando maschere.
Come si è visto, l'idea su cui si basa il polimorfismo
e' appunto il cambiare forma ogni volta che ci sia questa necessita' (ad
esempio ad ogni infezione), non lasciando quindi una stringa fissa agli
antivirus researchers.
Un motore
polimorfo e' infatti proprio un pezzo di codice da poter aggiungere ad un
codice virus che ha il compito di renderlo ogni volta differente. Per poter
raggiungere tale scopo un motore polimorfo (d’ora in poi per brevità MP) dovrà svolgere due compiti fondamentali:
1.
Criptare
il virus (e se stesso ovviamente) con un qualche algoritmo cambiando la chiave
ad ogni generazione in modo che non possa venire più ricercata una
semplice stringa di scansione
2.
Generare
un pezzo di codice che decritti il virus al momento opportuno, cioè quando il
virus dovrà entrare in azione.
Le operazioni matematiche più semplici che possono
essere facilmente utilizzate per criptare il corpo del virus disponibili su x86
sono ad esempio le istruzioni ADD, SUB, XOR, e sono le più usate.
Si può facilmente verificare che semplicemente
usando una di queste tre operazioni e crittando byte per byte abbiamo 256
possibili mutazioni del corpo del virus. Combinandone alcune (ad esempio
cambiando la chiave ad ogni byte) o crittando word per word o addirittura
prendendo in considerazione un dword alla volta le possibili mutazioni crescono
notevolmente.
Un inconveniente che vwriters cercano di evitare e'
che, con la parte crittata del virus nelle sue possibili variazioni è
necessario inserire anche il codice che decritti le istruzioni volute. Infatti
nel momento in cui il virus dovrà essere eseguito i bytes criptati non sono
ovviamente eseguibili.
Scrivendo semplicemente il pezzo di codice che
decritti la parte crittata saremmo arrivati di nuovo al punto di prima: infatti
gli AV dovrebbero solo usare la routine di decrittazione come stringa di
scansione e troverebbero il virus. La parte più' interessante - ed impegnativa
- nella scrittura di un MP e' appunto la scrittura del codice che crea il
decryptor (d’ora in poi routine RC), che abbiamo già incontrato parlando della
crittografia.
Un esempio chiarirà meglio le idee. Supponiamo ad
esempio di aver crittato il nostro codice usando un xor a bytes con il valore
12h (che sarebbe la cosiddetta chiave), allora la RC potrebbe essere:
; routine di
decrittazione
mov
cx,bytes_da_decrittare
mov di,codice_da_decrittare
dloop:
xor byte ptr [di],12h
inc di
loop dloop
Quindi partendo dal puntatore DI (che si presume
punti alla parte crittata, cioè codice_da_decrittare) per il dato numero di
bytes messi in cx eseguiremo la decrittazione (dato che ((A xor B) xor B) = A).
Ovviamente utilizzando una simile RC (o ad esempio solamente cambiando la
chiave) vorrebbe dire dare agli AV abbastanza codice fisso per localizzare una
stringa caratteristica.
La stessa RC si può ad esempio anche scrivere:
mov
si,codice_da_decrittatre
mov
bx,bytes_da_decrittare
dloop:
dec bx
xor byte ptr [si],12h
inc si
or bx,bx
jnz dloop
O in altri mille modi. Tra un’istruzione e l'altra dell’RC
generalmente vanno inserite delle istruzioni casuali (garbage) il cui effetto è
ininfluente ai fini del funzionamento della routine principale. Il compito di
un MP è infatti quello di generare il maggior numero possibile di routine per
la decrittazione in modo tale che l'antivirus non possa usare queste (o parti
di queste) come stringa per la scansione.
Questa è l'idea basilare. I moderni MP fanno anche
altro, come vedremo in seguito.