dtls-fuzzer è uno strumento Java che esegue il fuzzing a livello di protocollo dello stato di server DTLS. Più concretamente, supporta le seguenti funzionalità:
- dato un alfabeto, può generare automaticamente un modello di un'implementazione locale di un server DTLS;
- dato un test (sequenza di input) e un alfabeto, può eseguire il test su un'implementazione di un server DTLS;
- può eseguire un'attività di apprendimento batch, coinvolgendo più esecuzioni di apprendimento.
dtls-fuzzer utilizza [TLS-Attacker][tlsattacker] per generare/analizzare i messaggi DTLS nonché per mantenere lo stato.
A tal fine, TLS-Attacker è stato esteso con il supporto per DTLS.
dtls-fuzzer si basa sulla [versione 3.0b][tlsattackerver] di TLS-Attacker, una versione che implementa il miglioramento DTLS.
Contenuti dell'artefatto
L'artefatto contiene:
- una descrizione della struttura dei file di dtls-fuzzer, inclusi codice sorgente e dati sperimentali coerenti con quanto mostrato nell'articolo;
- una guida per la valutazione di dtls-fuzzer su un SUT (System Under Test)/implementazione di un server DTLS scelto.
Struttura dei file di dtls-fuzzer
Le cartelle più importanti nella directory principale di dtls-fuzzer sono:
- 'src', directory contenente il codice sorgente Java di dtls-fuzzer;
- 'examples', directory contenente esempi di alfabeti, test, specifiche (cioè modelli) e file di argomenti che possono essere forniti a dtls-fuzzer per avviare esperimenti di apprendimento. I file in questa directory vengono utilizzati come input per gli esperimenti di apprendimento;
- 'experiments', directory contenente dati relativi agli esperimenti. Alcuni di questi dati servono anche come input per gli esperimenti di apprendimento. Le cartelle più notevoli sono:
- 'suts', con binari per SUT Java. Questi SUT sono programmi server DTLS realizzati su misura il cui codice sorgente è disponibile pubblicamente;
- 'patches', patch applicate ad alcuni SUT (in particolare alle utilità) prima che il codice sorgente fosse compilato. Lo scopo principale di queste patch era prevenire comportamenti indotti da temporizzazione durante l'apprendimento, abilitare/disabilitare funzionalità nel SUT e configurare parametri come la chiave pre-condivisa;
- 'keystore', materiale crittografico (ad esempio coppie di chiavi pubblico-privata, keystore Java) utilizzato durante l'apprendimento;
- 'results', risultati sperimentali.
Risultati sperimentali
'experiments/results' contiene i risultati sperimentali, che sono l'output principale del lavoro. In particolare:
- 'all_ciphers' contiene le cartelle di output per tutti gli esperimenti eseguiti;
- 'mapper' contiene risultati sperimentali che aiutano a giustificare alcune delle decisioni del mapper (vedi Sezione 5.2)
- 'included' contiene le cartelle di output per gli esperimenti convergenti (convergente significa che l'apprendimento genera con successo un modello).
- si noti che non tutti gli esperimenti in 'all_ciphers' hanno avuto successo/si sono conclusi con un modello finale (in tali casi diciamo che l'apprendimento non è convergente)
Cartelle di output
Le cartelle di output sono denominate in base alla configurazione dell'esperimento, ovvero:
- il SUT/implementazione testato;
- l'alfabeto utilizzato, in termini di algoritmi di scambio chiave coperti, dove 'all' indica che sono stati utilizzati tutti e 4 gli algoritmi di scambio chiave;
- ove applicabile, se era richiesta la certificazione del client (req), opzionale (nreq) o disabilitata (none);
- l'algoritmo di test: random walk (rwalk) o un suo adattamento (stests);
- gli esperimenti che utilizzano l'adattamento non sono stati inclusi nell'articolo
- opzionalmente, se le ritrasmissioni erano incluse/escluse dagli output (incl o excl).
- le ritrasmissioni erano incluse per impostazione predefinita
Ad esempio, il nome della cartella 'jsse-12_rsa_cert_none_rwalk_incl' indica un esperimento sull'implementazione JSSE 12 di DTLS, utilizzando un alfabeto che include input per eseguire handshake RSA, l'autenticazione del certificato client è disabilitata, l'algoritmo di test è random walk e le ritrasmissioni sono incluse.
Una cartella di output contiene:
- 'alphabet.xml', l'alfabeto di input;
- 'command.args', il file degli argomenti utilizzato contenente vari parametri dell'esperimento, in particolare:
- queries, il limite sul numero di test random walk che devono essere superati affinché un'ipotesi sia considerata finale
- equivalenceAlgorithms, algoritmi di test basati su modello impiegati
- runWait e timeout, rispettivamente il timeout di avvio e di risposta (ne parleremo più avanti)
- 'sul.config', configurazione dipendente dal SUT per TLS-Attacker, la stessa configurazione può essere utilizzata per eseguire tracce di workflow sul SUT utilizzando solo TLS-Attacker;
- 'hyp[0-9]+.dot', ipotesi intermedie;
- 'statistics.txt', statistiche dell'esperimento come il numero totale di test, il tempo di apprendimento;
- La Tabella 4 mostra questi dati
- 'nondet.log', log dei comportamenti non deterministici incontrati;
- 'learnedModel.dot', in caso di convergenza dell'apprendimento, il modello appreso (cioè l'ipotesi finale);
- 'error.msg', un messaggio di errore generato nel caso in cui l'esperimento sia fallito/l'apprendimento sia stato interrotto e quindi non sia convergente a un modello finale.
- il principale colpevole è il non-determinismo legato al tempo (gli stessi input portano a risultati diversi).
Il valutatore può verificare (ad esempio) che i risultati sperimentali in 'included' corrispondano a quelli mostrati nella Tabella 4, o che le configurazioni testate nella Tabella 2 appaiano anche in 'all_ciphers'.
Si noti che i modelli apparsi nell'articolo sono il risultato di un significativo pruning/trimming, mentre i modelli che appaiono nelle cartelle di output sono inalterati.
Passaggi di valutazione di dtls-fuzzer
Ai fini della valutazione di dtls-fuzzer è necessario eseguire i seguenti passaggi:
- Assicurarsi che i prerequisiti siano soddisfatti
- Installare dtls-fuzzer
- Configurare il SUT
- Utilizzare dtls-fuzzer per generare modelli per il SUT
- Analizzare i risultati
Questa sezione di valutazione è seguita da una guida sull'uso di dtls-fuzzer che introduce i suoi principali casi d'uso.
Verifica dei prerequisiti
dtls-fuzzer è stato testato su Ubuntu 18.04 e Debian 9 di Linux.
Dovrebbe funzionare su qualsiasi distribuzione Linux recente.
Il supporto per altre piattaforme non è stato testato.
Questa guida presuppone l'uso di una distribuzione basata su Debian (che ha 'apt-get').
È richiesta una VM (Virtual Machine) con JDK (Java Development Kit) 8.
La versione utilizzata per eseguire gli esperimenti è la 1.8.0_222, sebbene versioni successive di Java 8 dovrebbero funzionare.
Si noti che lo strumento non viene compilato con Java 9 o successivo.
Ci affidiamo anche a maven (l'utility 'mvn') per la gestione delle dipendenze/deployment.
Si consiglia di utilizzare una macchina sufficientemente potente, altrimenti parametri di temporizzazione sensibili come il tempo di attesa della risposta potrebbero diventare troppo bassi, causando output diversi da quelli ottenuti nell'articolo.
Peggio ancora, possono far fallire gli esperimenti di apprendimento.
Gli esperimenti originali sono stati eseguiti su un server multi-core, tuttavia ci aspettiamo (anche se non testato a fondo) che l'apprendimento sia possibile su un desktop con processore i7.
L'apprendimento è possibile anche su sistemi meno potenti se i parametri di temporizzazione vengono regolati di conseguenza.
Infine, la visualizzazione dei modelli .dot esportandoli in .pdf richiede l'installazione della libreria [graphviz][graphviz].
Si presuppone che l'utility 'dot' fornita da graphviz si trovi nel PATH di sistema.
In sintesi, i prerequisiti consigliati sono: