
Un fuzzer evolutivo basato sulla conoscenza
Questo documento mira a spiegare brevemente la teoria alla base di Choronzon. Inoltre, fornisce dettagli sul suo funzionamento interno e su come estendere Choronzon per soddisfare nuovi requisiti. Una panoramica dell'architettura di Choronzon è stata presentata inizialmente alla ZeroNights 2015 Conference. Sono disponibili anche una registrazione della presentazione e le slide.
Choronzon è un fuzzer evolutivo. Cerca di imitare il processo evolutivo per continuare a produrre risultati migliori. Per raggiungere questo obiettivo, dispone di un sistema di valutazione per classificare quali dei file fuzzati sono interessanti e quali devono essere scartati.
Inoltre, Choronzon è un fuzzer basato sulla conoscenza. Utilizza informazioni definite dall'utente per leggere e scrivere file del formato di destinazione. Per familiarizzare con la terminologia di Choronzon, considera che ogni file è rappresentato da un chromosome. Gli utenti devono descrivere la struttura elementare del formato del file in esame. Una visione di alto livello del formato del file è preferita rispetto alla descrizione di ogni dettaglio e aspetto. Ciascuna di quelle strutture elementari definite dall'utente è considerata un gene. Ogni chromosome contiene un albero di geni ed è in grado di costruire il file corrispondente a partire da esso.
Choronzon è suddiviso in tre sottosistemi: il modulo Tracer, il modulo Chromosome e il fuzzer.
Brevemente, il componente Chromosome viene utilizzato per descrivere il formato del file di destinazione. Gli utenti possono scrivere i propri moduli per supportare formati nuovi o personalizzati. Come caso di test, con Choronzon viene fornito un modulo PNG.
Il componente Tracer, invece, è responsabile del monitoraggio dell'applicazione di destinazione e della raccolta di varie informazioni sulla sua esecuzione. Questa versione di Choronzon utilizza lo strumento di strumentazione binaria Intel's Pin per registrare i blocchi di base visitati durante l'esecuzione. Tuttavia, Choronzon è in grado di supportare anche altri backend di tracciamento. Tieni presente che nella prossima versione di Choronzon, Pin verrà sostituito a causa del suo impatto significativo sulle prestazioni.
Infine, il componente fuzzer viene utilizzato per alterare il contenuto dei file da testare. Il modulo contiene un corpus di Mutators e Recombinators. I Mutators, semplicemente, modificano il file come fanno i fuzzer comuni. Ad esempio, eseguono byte flipping, byte swapping, mutazione casuale di byte e così via. Ma Choronzon ha un'altra caratteristica non comune tra i fuzzer. I Recombinators utilizzano le informazioni sulla struttura del formato del file, fornite dal modulo Chromosome, per eseguire fuzzing intelligente.
Nella directory chromosome/parsers puoi trovare il file PNG.py. Questo
modulo Python descrive il formato del file PNG al fuzzer. Puoi aggiungere i tuoi
moduli personalizzati per altri formati di file in questa directory.
L'idea fondamentale alla base del sottosistema Chromosome è convertire i file seed iniziali utilizzando un Deserializer in un albero di Genes. A un certo punto, i Genes (fuzzati) verranno scritti in un file, utilizzando un Serializer.
Considera che in Choronzon l'obiettivo del modulo parser è fornire la struttura elementare del formato del file, invece di ogni minimo dettaglio. Questo aiuterà il fuzzer a costruire file per lo più corretti, evitando l'uscita anticipata dall'applicazione target. Inoltre, questo approccio fa risparmiare tempo, perché descrivere ogni aspetto del formato del file è dispendioso e introduce un overhead di sviluppo significativo.
Un nuovo modulo parser deve importare:
e deve implementare
Nell'esempio fornito con Choronzon, ogni PNGGene corrisponde a un chunk PNG. In generale, puoi pensare a un Gene come a una struttura dati elementare del formato di destinazione. Ogni Chromosome è composto da un albero di Genes e rappresenta un file unico. Ogni Gene deve essere in grado di produrre una stringa di byte che contenga i propri dati combinati con i dati dei Genes inferiori nell'albero.
Il PNGSerializer deve essere in grado di produrre un file (per lo più corretto) quando gli viene fornita una lista di Genes. D'altra parte, PNGDeserializer deve essere in grado di analizzare un file valido del formato di destinazione e deserializzarlo in un albero di Genes.
Controlla chromosome/parsers/PNG.py per un esempio commentato per il formato PNG.
Il modulo Tracer viene utilizzato per disassemblare l'applicazione target (e/o una o più delle sue librerie). In questa versione di Choronzon ciò viene realizzato con IDA. Abbiamo usato questo approccio perché possiamo correlare eventuali informazioni interessanti dalla campagna di fuzzing con i nostri IDB. Tuttavia, potremmo eliminare la dipendenza da IDA nel prossimo futuro per rendere Choronzon più portabile e accessibile.
Un file viene testato su un'applicazione con l'aiuto di un'utility Pin. Nella
directory analyzer/coverage c'è il codice sorgente di questo strumento Pin, che
inietta hook all'inizio di ogni blocco base nell'applicazione target.
Al termine dell'esecuzione, correliamo il blocco base che è stato colpito con
il blocco base del binario. Così possiamo calcolare metriche che sono
preziose per noi (copertura, ecc).
Il componente Fuzzer utilizza la rappresentazione Chromosome per fuzzare un file. Come accennato in precedenza, ci sono due metodi di fuzzing in Choronzon.
Per il primo metodo, Choronzon prende il contenuto da uno o più geni
e applica uno dei Mutators. I Mutators implementano metodi di fuzzing comuni ma
efficaci come mutazione casuale di byte, impostazione del bit alto, byte swapping
e molti altri. Puoi anche scrivere i tuoi mutator personalizzati e aggiungerli in
fuzzers/mutators.py.
Il secondo metodo di fuzzing si chiama ricombinazione. I Recombinators vengono utilizzati per modificare la struttura del file. Ecco un esempio con il formato PNG.
I file PNG sono composti da chunk consecutivi che contengono quattro campi:
Supponiamo di avere un file PNG che contiene solo chunk IHDR, IDAT e IEND. La sua struttura sarebbe simile alla seguente:
[ firma PNG ] [ IHDR ] [ IDAT ] [ IEND ]
Poiché Choronzon è a conoscenza delle strutture di base (cioè i chunk PNG), è in grado di alterarne la sequenza. Dopo una ricombinazione riuscita, il file PNG fuzzato in output può apparire così:
[ firma PNG ] [ IDAT ] [ IHDR ] [ IEND ]
Choronzon contiene molte altre strategie di ricombinazione che lo rendono in grado di gestire anche formati di file complicati.
Choronzon è stato testato con Python 2.7, Pin 3, IDA Pro dalla 6.6 alla 6.9, su Ubuntu 16.04 LTS (kernel Linux 4.4) e Windows 10.
Per eseguirlo, è necessario installare il pacchetto Python sortedcontainers. Puoi trovarlo qui o installarlo tramite pip.
Inoltre, Choronzon necessita di IDA Pro (in realtà, la sua versione terminale). Il percorso di IDA Pro deve essere specificato nel tuo file di configurazione in questo modo:
DisassemblerPath = 'C:\\Program Files (x86)\\IDA 6.6'
È stato testato con successo con IDA Pro 6.6, 6.7, 6.8 e 6.9.
Lo strumento di copertura Pin di Choronzon si trova in analyzer/coverage e deve essere
compilato. Puoi consultare la documentazione di Pin per i dettagli, oppure eseguire
i seguenti passaggi:
coverage.cpp e makefile.rules in
/path/to/pin/source/tools/MyPinToolmake. Se sei su Windows, devi eseguire la riga di comando di Visual
Studio e utilizzare l'utility make e le sue dipendenze da
Cygwin/path/to/choronzon/analysis/coverage la directory
obj-intel64 appena creata (o obj-ia32 per sistemi a 32 bit)Per fuzzare con Choronzon, devi fornire un file di configurazione.
Nella directory settings c'è un esempio di configurazione di Choronzon.