Una delle principali tattiche di autodifesa dei malware è l’offuscamento. Lo scopo dell’offuscamento è rendere difficile l’attività degli analisti, i quali hanno il compito di comprendere il funzionamento del codice ostile, per poter sviluppare delle contromisure (firme per antivirus e ids, strategie di contenimento…).

I principali obiettivi delle tecniche di offuscamento sono:

Nascondere i path: il malware può essere incluso in un file legittimo; il percorso del malware può essere offuscato

Confondere i nomi di variabile: spesso nel codice offuscato, le variabili hanno nomi generati in maniera casuale, per non dare riferimenti circa il loro utilizzo. lo scopo del malware writer è quello di far perdere le tracce delle variabili all’interno dello stesso script.

Offuscare i nomi delle funzioni: analizzare i nomi delle funzioni è la cosa più semplice per capire come funziona un codice; offuscare questi nomi, rende estremamente arduo il compito dell’analista. Inoltre, gli strumenti automatici che cercano particolari parole chiave (nomi di funzioni in questo caso) per stabilire l’eventuale pericolosità di uno script, vengono messi fuori gioco da queste tecniche.

All’interno di uno stesso script, possono convivere diverse tecniche di offuscamento stratificate; per esempio, lo stesso script può contenere codice criptato codificato in base64; path e nomi di funzioni possono sfruttare codifica esadecimale, e possono essere generati dinamicamente.A queste tecniche si possono  aggiungere trucchi come l’inserimento di spazi o la rimozione di carriage return (per ottenere codice su una sola riga). 

Le tecniche presentate in questo articolo, sono state rilevate durante l’analisi di malware identificati su siti recentemente compromessi.

Base64

Una delle codifiche più utilizzate è la codifica base64. Questa codifica è utilizzata spesso per codificare file binari in caratteri visualizzabili. Tutti i linguaggi di programmazione hanno funzioni per gestire questo tipo di codifica. Esempio di codifica base64: la frase “Hello world!”, corrisponde a “SGVsbG8gd29ybGQh”.

Esadecimale

Un’altra codifica molto utilizzata è la codifica esadecimale. Nella codifica esadecimale, lettere e numeri sono sostituiti dal valore esadecimale della loro rappresentazione ASCII; per esempio, la lettera ‘A’, codice ASCII 65, diventa x41 in esadecimale. Quindi, la frase “Hello world!”, codificata in esadecimale, diventa

“\x48\x65\x6c\x6c\x6f\x20\x77\x6f\x72\x6c\x64\x21”

Esadecimale ibrido

Una variante a questa codifica si ottiene mischiando codici esadecimale e lettere in chiaro:

Per esempio, nell’esempio di prima si potrebbe codificare l’intera frase, ad eccezione della lettera ‘o’:

 “\x48\x65\x6c\x6co\x20\x77\x6f\x72\x6c\x64\x21” (notare la ‘o’ tra ‘\x6c’ e ‘\x20’)

Per rendere tutto più intricato, a queste codifiche, si aggiungono spesso alcune tecniche criptografiche. In genere vengono utilizzati algoritmi semplici, come xor, o addirittura rot13, per aggiungere un ulteriore strato di offuscamento.

Offuscamento in Php

Vediamo ora nel dettaglio come queste tecniche vengono utilizzate nei malware Php. La codifica esadecimale ibrida, può essere utilizzata per offuscare un path utilizzato per includere un malware:

@include “\x2f\x68\x6f\x6d\x65\x2f\x77\x77\x77.\x78\x78\x78\x78\x78\x78\x2e\x78\x78\x78\x2f\x68\x74\x64\x6f\x63\x73\x2f\x77\x70\x2f\x77\x70\x2d\x69\x6e\x63\x6c\x75\x64\x65\x73\x2f\x77\x69\x64\x67\x65\x74\x73\x2f\x66\x61\x76\x69\x63\x6f\x6e\x5f\x78\x78\x78\x78\x78\x78\x2e\x69\x63\x6f”;

In questo esempio, identificato recentemente in un sito WordPress attaccato tramite una vulnerabilità nota, il path, inserito nell’index.php, punta ad un malware nascosto in un file di tipo .ico.

Nascondere le variabili

La codifica esadecimale, può essere utilizzata anche per offuscare i nomi delle variabili; per esempio il seguente codice:

${“\x47\x4c\x4fB\x41\x4c\x53”}[‘x4g7289’] =  “\x48\x65\x6c\x6c\x6f\x20\x77\x6f\x72\x6c\x64\x21”;

equivale a:

$GLOBALS[‘x4g7289’] = “Hello world!”;

o più semplicemente ancora:

$x4g7289 = “Hello world!”;

ovvero, alla variabile globale $x4g7289, viene assegnato il valore di tipo stringa “Hello world!”. In uno script non offuscato, la stessa cosa poteva essere scritta così:

$message = “Hello world!”;

Offuscare i nomi delle funzioni

Per offuscare i nomi di funzioni, possono essere utilizzate le tecniche e le codifiche viste sopra; ma può anche essere aggiunta confusione, utilizzando tabelle di codifica. Le tabelle di codifica sono tabelle contenenti set di caratteri dalle quali attingere per formare dinamicamente stringhe da utilizzare per invocare funzioni.

Innanzitutto diciamo che in Php, alle variabili possono essere assegnati nomi di funzioni; per esempio:

$a = base64_decode(“SGVsbG8gd29ybGQh”);

può anche essere scritto:

$f = “base64_decode”;

$a = $f(“SGVsbG8gd29ybGQh”);

dove alla variabile $f viene assegnato il valore “base64_decode”, ovvero il nome di una funzione; la funzione viene quindi eseguita invocando il nome della variabile, seguito dalle parentesi tonde: $f(“SGVsbG8gd29ybGQh”);  L’interprete Php espande il codice di sopra come base64_decode(“SGVsbG8gd29ybGQh”).

A questa tecnica, può essere aggiunto un ulteriore livello di confusione, rendendo dinamica la composizione della stringa contenente il nome della funzione, sfruttando tabelle di codifica. Questa tecnica, consiste nel creare una tabella contenente i caratteri necessari per la creazione dei nomi della funzioni. Questa tabella può essere una stringa, offuscata con le tecniche che abbiamo visto sopra:

$cod_table = “abcdefghijklmnopqrstuvwxyz_-.()0123456789”;

oppure, con nome casuale e contenuto offuscato:

$x4g7289 = “\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6f\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x5f\x28\x29\x3b”;

E’ possibile accedere a qualsiasi elemento di questa stringa tramite indice (di fatto si tratta di un array); Quindi: $x4g7289[0] equivale a “\x61”, ovvero la lettera “a”. Concatenando i singoli caratteri “estratti” da questa tabella, è possibile comporre stringhe complesse. Le seguenti istruzioni:

$f = $x4g7289[1] . $x4g7289[0] . $x4g7289[18] . $x4g7289[4] . $x4g7289[37] . $x4g7289[35] . $x4g7289[26] . $x4g7289[3] . $x4g7289[4] . $x4g7289[2] . $x4g7289[14] . $x4g7289[3] . $x4g7289[4]

generano la stringa:

$f = “base64_decode”

Le tecniche che abbiamo visto sopra possono essere mischiate, per ottenere una versione ancora più sconcertante del codice:

${“\x47\x4c\x4fB\x41\x4c\x53”}[‘f’] =  $x4g7289[1] . $x4g7289[0] . $x4g7289[18] . $x4g7289[4] . $x4g7289[37] . $x4g7289[35] . $x4g7289[26] . $x4g7289[3] . $x4g7289[4] . $x4g7289[2] . $x4g7289[14] . $x4g7289[3] . $x4g7289[4];

oppure, ancora più offuscato:

${“\x47\x4c\x4fB\x41\x4c\x53”}[‘f’] = $GLOBAL[‘x4g7289’][1] . $GLOBAL[‘x4g7289’][0] . $GLOBAL[‘x4g7289’][18] . $GLOBAL[‘x4g7289’][4] . $GLOBAL[‘x4g7289’][37] . $GLOBAL[‘x4g7289’][35] . $GLOBAL[‘x4g7289’][26] . $GLOBAL[‘x4g7289’][3] . $GLOBAL[‘x4g7289’][4] . $GLOBAL[‘x4g7289’][2] . $GLOBAL[‘x4g7289’][14] . $GLOBAL[‘x4g7289’][3] . $GLOBAL[‘x4g7289’][4];

Alla fine, sarà possibile eseguire la funzione base64_decode:

${“\x47\x4c\x4fB\x41\x4c\x53”}[‘f’](“SGVsbG8gd29ybGQh”);

Il risultato, ancora una volta, sarà “Hello world!”.

Ma non basta: la tabella di codifica potrebbe essere “mischiata”, i caratteri potrebbero essere messi alla rinfusa, o potrebbero addirittura essere inseriti caratteri non utilizzati al solo scopo di rendere ancora più intricata la situazione. Inoltre, il dato codificato in base64, potrebbe essere cifrato con una chiave fornita come parametro in tempo reale durante la chiamata dello script, attraverso le variabili $_GET, $_POST, oppure attraverso cookie (o altri headers HTTP).

Conclusione

L’offuscamento è una tattica utilizzata dai malware writer per ostacolare l’analisi e rendere quindi più difficile la creazione di contromisure (firme per antivirus e ids). In questo articolo abbiamo mostrato alcune tecniche di offuscamento di codice Php identificate in malware analizzati recentemente.