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)
§ MATER Liber Nonus §
indice
1. come
si comportano gli antivirus
Per quanto banale motore polimorfo possa saltare
l'uso di semplici scan string fisse da parte degli AVs, al giorno d'oggi ci
sono molti modi che gli AVers usano per trovare virus polimorfi. Vediamoli:
a.
Scan string variabili - questo modo di ricerca e' abbastanza banale e
funziona solo con MP più semplici. In pratica delle scan string variabili (ad
esempio, codice puramente inventato, 10 20 xx 30 xx 30 30 * 10 2 dove con xx si
intende un qualsiasi byte, ad esempio una chiave, e con * un dato numero
qualsiasi di bytes) che sono sicuramente fisse (e magari anche fisse in certe
posizioni). Questo tipo di scan string, che già di per se e' inefficiente dato
che gli AVs devono usare delle scan string abbastanza lunghe per evitare falsi
positivi, è evitato creando RC che non hanno sequenze prestabilite e creando un
gran numero di variazioni, cosicché l'unico modo per gli AV per applicare
questo metodo sarebbe quello di inserire migliaia di scan string, il che è impossibile.
b.
Crittoanalisi - In questo
caso l'AV potrebbe cercare di trovare una parte conosciuta del virus crittato e
cercare di decrittarla basandosi sulla conoscenza dell'algoritmo usato. Questo
è evitato dai MP creando più livelli di
crittazione, quindi creando un encryptor (che usa un dato algoritmo scelto a caso su un dato tipo di
dati scelto a caso, es. xor su words) che, oltre a crittare il corpo del virus
critta anche un secondo decryptor che usa algoritmo e tipo di dato a caso (es.
rol su dword) e magari a sua volta un terzo e cosi' via. Questa creazione di
più livelli di crittazione (layers) e' indubbiamente un metodo efficace, a
volte vengono immesse più istruzioni di crittazione direttamente in un solo
loop. Si utilizza anche un tipo di crittazione cambiandone spesso la chiave in
qualche modo. In questo modo avendo
molti algoritmi applicati su tipi di dati diversi, la crittoanalisi diventa
inutilizzabile (questo modo non e' in pratica utilizzato dai maggiori
antivirus).
c.
Analisi algoritmica del codice - Un altro modo per poter scovare un motore polimorfo
è l'analisi algoritmica del codice generato dal MP. Questo metodo di basa sulla
conoscenza del codice che il motore può generare. L'antivirus analizza nel
codice sospetto le istruzioni usate e le confronta con quelle che il MP
dovrebbe poter generare. Se viene riscontrata un'istruzione che il MP non
dovrebbe poter generare, allora probabilmente il codice sospetto non e' generato da un MP. In caso
compaiano solo istruzioni che quella poly genera, allora la possibilità che sia
codice generato dal MP sono maggiori. A questo tipo di ricerca vengono
aggiunti ancora dei check aggiuntivi
(come la tipica lunghezza delle RC generate con quel motore o alcuni pezzi
stabili nel decryptor) o abbinati a scansioni del primo o del secondo tipo per
poter cosi' definire la presenza di un dato motore polimorfo. Per saltare
questo tipo di analisi i vwriters generano molti tipi di garbage (in tal modo
non avrebbe molto senso cercare le istruzioni mancanti, dato che non ce ne sarebbero molte e probabilmente quelle mancherebbero
anche in un programma normale) e creare RC molto varie in tipo e in lunghezza.
d.
Emulazione - Mentre i tre tipi di
scansione possono essere saltati anche da un mediocre MP, il vero problema e'
l'emulazione degli AV. I migliori
antivirus al giorno d'oggi infatti per cercare virus polimorfi conosciuti ma anche virus (polimorfi e
non) sconosciuti, si affidano all'emulazione del codice da controllare. Il
codice del programma sospetto viene
eseguito istruzione per istruzione in una specie di virtual machine isolata dell'antivirus. In questo modo il
decryptor (o un qualunque pezzo di codice) viene eseguito solo sotto sicurezza
e qui l'antivirus può poi analizzarne
gli effetti e alla fin fine eseguire tutto il decryptor ed ottenere cosi' la copia
decrittata del virus. A questo punto, eseguito il decryptor, l'antivirus può
usare il vecchio metodo di ricerca di scan
strings sul corpo decrittato. E' chiaro che, essendo l'emulazione fatta
tutta via software in una "macchina" isolata, dipende dalla persona
che l'ha scritta quanto e che istruzioni emulerà. In generale quasi tutte
le istruzioni su/tra registri,
immediati e cose del genere vengono emulati e i risultati tenuti da parte.
Vengono emulati anche i risultati di alcune chiamate a interrupts, le letture
dalla memoria di solito sono semplicemente ignorate se sono lontane
dall'attuale posizione del IP, mentre vengono registrate se sembrano nei pressi
del punto di esecuzione e in ogni caso vengono registrate tutte le scritture o
operazioni che cambiano (potrebbe essere decrittano) la memoria. E' ovvio però
che non tutti gli emulatori possano emulare qualsiasi cosa del sistema, dato
che questo comporterebbe problemi e costi in termini di tempo troppo grossi.
Per poter saltare il problema dell'emulazione si usano dei costrutti che fanno uso di risorse note del sistema,
che tuttavia si suppone l'emulatore non sia in grado di emulare.
Un
esempio:
mov ah,30h ; richiedi versione DOS
int 21h
cmp al,03h
jae fine ; salta se >= 3
mov ah,4ch ; allora esci
int 21h
fine:
In questo caso generiamo una richiesta della
versione del DOS. In caso questa sia minore di 3, allora e' molto probabile che
siamo in una situazione di emulazione. In caso sia >=3 continueremo con il
nostro decryptor, altrimenti potremmo simulare un'uscita dal programma (ah=4ch
con int 21h). In tal modo l'emulatore incontrando l'uscita penserà ad un uscita
normale del programma.
e.
Esecuzione passo-passo - Un altro
modo che ormai pochissimi antivirus generici usano, ma che può essere usato da un antivirus specifico (o
da una persona in carne ed ossa) e' quello di eseguire il virus passo-passo
sulla macchina. Ciò viene effettuato mediante la tecnica dell’int 01h. Per
ovviare a questa tecnica i vwriters inseriscono nel codice generato qualche
routine di antidebugging.
·
Segmenti
usati. Oltre ovviamente a dover essere sicuri che i segmenti usati puntino
effettivamente dove vogliono (magari
inizializzandoli nella prima fase), gli scrittori di un MP curano molto la
forzatura implicita dei segmenti. In genere le operazioni con tutti i puntatori
si riferiscono a DS tranne per BP che invece si riferisce allo stack segment, quindi SS.
Quindi
mentre:
xor [di],1010h ; 81 35 10 10
xor ds:[di],1010h ; 3E 81 35 10 10
hanno lo stesso effetto, ciò non vale per:
xor [bp],1010h ;
81 76 00 10 10
xor
ds:[bp],1010h ; 3E 81 76 00 10
10
dato che il BP lavora sempre
con SS per default. Quindi attenzione alla non forzatura del segmento.
Dall'esempio poi si nota
un'altra cosa: le opcodes per BP sono tutte un po' particolari e quando questo
viene usato come puntatore il codice
generato e' più lungo e contiene un byte 00 prima del operando.
·
Generazione
sequenze random. Gran parte delle operazioni in un MP sono affidate a una
routine per generare sequenze di numeri casuali. Indubbiamente il metodo più
semplice e' quello di prendere il
numero del timer (in al,40h), ma questo e' in effetti un numero
pseudocasuale. La qualità di questa routine dà l’impronta alla qualità del MP.
·
Polimorfismo
lento. Un’altra tecnica usata dai vwriters e' il polimorfismo lento, ovvero
generare i numeri casuali in base ad un dato che cambia abbastanza lentamente.
·
Antibait,
ovvero tecniche anti-cavia. Nelle routine di infezione i vwriters si
preoccupano di non infettare files sospetti che potrebbero essere cavie create
appositamente dagli AV per far riprodurre un gran numero di generazioni del
motore polimorfo. In genere a ciò i virus contrappongono tali accorgimenti:
- non infettare troppi files in tempi brevissimi;
- non infettare files che sono divisibili per 512 o
1024;
- non infettare files con numeri nel nome (molto
improbabile in files normali);
- non infettate files creati molto di recente.