UNIVERSITÀ DEGLI STUDI DI TRIESTE                             FACOLTÀ DI INGEGNERIA                   Corso di laurea magi...
ai miei genitori2
IndiceAbstract...............................................................................................................
3 Realizzazione..............................................................................................................
5.3.3.8.1 Allineamento di coppia e numero di soluzioni possibili.............................73                 5.3.3.8.2 ...
9 Bibliografia...............................................................................................................
AbstractUna delle tecniche di difesa dagli attacchi informatici è lanalisi delle vulnerabilità, che riguardanoessenzialmen...
PARTE PRIMA                          Descrizione generale del lavoro1 IntroduzioneLa presente tesi illustra il lavoro svol...
I test possono essere classificati in due tipologie: test su un modulo singolo, in cui si esaminasoltanto un certo aspetto...
4. Si analizza il problema della generazione delle espressioni regolari, individuando le   caratteristiche rilevanti delle...
2 Analisi e progettazione2.1 Scelta dellambiente di testingIl concetto di test-driven development è così radicato in Pytho...
2.2 Test di integrazione2.2.1 Contesto e obiettiviLobiettivo dei test di integrazione da sviluppare è quello di verificare...
•   numero di porta lato server    •   protocollo di trasporto    •   servizio    •   indirizzo IP del server    •   ogget...
2.2.3 Oggetti mockI test devono utilizzare degli oggetti mock che si sostituiscano agli oggetti Session e Vulnerabilityuti...
La politica di interazione con il client viene definita in un metodo handle di una classe specifica perciascun     simulat...
Questo tipo di interazione con il client è la stessa da utilizzare nel caso del simulatore Checkpoint:FakeRequestHandler p...
2.2.5 Schema consuntivoSi propone di seguito un UML class diagram che evidenzia le interazioni tra le classi interessate d...
2.3 Test su moduli singoli2.3.1 ContestoNella maggior parte dei casi una vulnerabilità interessa soltanto una certa tipolo...
•    essere nota staticamente: la sola conformità della stringa allespressione regolare rende         evidente un certo in...
<!-- WebLogic Server Administration Console</title> Welcome to WebLogic Server Version:FakeServer3</p> --><software name="...
noto ne indica la vulnerabilità consultando una base di conoscenza XML.I file XML sono inclusi in una directory chiamata v...
2.3.2 Tipi di testI test da sviluppare possono essere suddivisi in due tipologie:   •   test su singoli sistemi noti   •  ...
possa essere compensato da un ulteriore errore sulla funzione conducendo a un risultato corretto.2.3.2.2 Test su singoli s...
Per ogni espressione regolare che individua un unico numero di versione, si include nel testunasserzione che verifichi la ...
2.3.2.3 Test di coerenza interna sui file di banners e webapplications (categoria 3)I file XML di banners e webapplication...
2.3.2.3.2 Test di coerenza tra espressione regolare e commentiNellintroduzione di nuovi elementi <software> nel file XML, ...
<re>10 allinterno di <software> provocherebbe invece una trasgressione della sintassi standard, erientra nella casistica p...
•   key=”sp”    •   key=”operating-system.release” e value=”7” in un elemento <software> dove vi sia un        elemento <i...
I numeri di versione contengono spesso dei punti, che nellespressione regolare vengono individuatida ..Se dovesse mancare ...
Figura 4: UML class diagram per i test della categoria 12.3.3.2 Parsing XMLPer il parsing dellXML si sceglie di usare un a...
•    numero di gruppi capturing di ogni espressione regolare    •    espressioni regolari che compaiono più di una volta n...
•   un buffer per lidentificativo della vulnerabilità corrente   •   un buffer per le espressioni regolari associate alla ...
2.3.3.3 Test di coerenza interna XML su banners e webapplications (categoria 3)I test di coerenza sui file XML si basano s...
Figura 6: UML class diagram per i test di categoria 3                         34
2.3.3.4 Test su versions_regexp (categorie 2 e 4)Nel caso dei test su versions_regexp anche i test su singoli moduli utili...
2.3.3.5 Schema consuntivo per le categorie 2, 3 e 4I test delle categorie 2, 3 e 4 condividono linfrastruttura delle class...
3 Realizzazione3.1 Implementazione3.1.1 Codifica test-driven3.1.1.1 Logica di controlloLa metodologia di sviluppo test-dri...
si rileva un eventuale errore nel nome del test16.È utile mantenere questa riga come ultima istruzione per tutta la fase d...
Si preferisce scrivere esplicitamente il test di uguaglianza con loperatore == anziché adottare ilmetodo assertEquals.Dato...
3.1.3 Organizzazione dei sorgentiI file sviluppati nel corso del progetto si collocano nella directory testunits del siste...
3.2 UtilizzoPer lesecuzione dei test si invoca dalla directory testunits/tests del sistema di analisi dellevulnerabilità l...
il messaggio finale OK segnala che tutti i test della campagna hanno avuto esito positivo.In questo secondo esempio si ese...
PARTE SECONDA                        Generazione di espressioni regolari4 Analisi4.1 Descrizione del problemaLa seconda pa...
4.2 Caratteristiche delle espressioni regolari dei file XMLOsservando le espressioni regolari riportate nei file XML di ba...
Esempio<!-- OK Domino IMAP4 Server Release 7.0.2 ready Wed, 11 Jul 2007 14:03:48 +0200x0d --><!-- OK Domino IMAP4 Server R...
4.3 DefinizioniSi elencano una serie di definizioni in riferimento allinsieme delle stringhe banner di esempio, checostitu...
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità
Upcoming SlideShare
Loading in …5
×

Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità

592 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
592
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità

  1. 1. UNIVERSITÀ DEGLI STUDI DI TRIESTE FACOLTÀ DI INGEGNERIA Corso di laurea magistrale in Ingegneria Informatica Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilitàLaureando RelatoreFederico Cecutti chiar.mo prof. Alberto Bartoli Correlatore Enrico Milanese anno accademico 2011/2012
  2. 2. ai miei genitori2
  3. 3. IndiceAbstract.................................................................................................................................................7PARTE PRIMA – Descrizione generale del lavoro1 Introduzione......................................................................................................................................8 1.1 Contesto...............................................................................................................................8 1.2 Obiettivi e vincoli progettuali..............................................................................................8 1.3 Fasi di lavoro e risultati........................................................................................................9 1.4 Articolazione della tesi.........................................................................................................92 Analisi e progettazione...................................................................................................................11 2.1 Scelta dellambiente di testing............................................................................................11 2.2 Test di integrazione............................................................................................................12 2.2.1 Contesto e obiettivi.....................................................................................................12 2.2.2 Classi di test................................................................................................................13 2.2.3 Oggetti mock..............................................................................................................14 2.2.4 Lato server..................................................................................................................14 2.2.5 Schema consuntivo.....................................................................................................17 2.3 Test su moduli singoli........................................................................................................18 2.3.1 Contesto......................................................................................................................18 2.3.1.1 Analisi di banner e pagine web (banners e webapplications)............................18 2.3.1.2 Analisi di numeri di versione (versions_regexp)................................................20 2.3.2 Tipi di test...................................................................................................................22 2.3.2.1 Test su singoli sistemi di banners (categoria 1)..................................................22 2.3.2.2 Test su singoli sistemi noti di versions_regexp (categoria 2).............................23 2.3.2.3 Test di coerenza interna sui file di banners e webapplications (categoria 3).....25 2.3.2.3.1 Test di correttezza sintattica........................................................................25 2.3.2.3.2 Test di coerenza tra espressione regolare e commenti................................26 2.3.2.3.3 Test di coerenza tra espressione regolare ed elementi <info> con type=”re”..............................................................................................26 2.3.2.3.4 Test di coerenza tra espressione regolare, commenti ed elementi <info> con type=”re”....................................................................26 2.3.2.3.5 Test per ripetizioni......................................................................................26 2.3.2.3.6 Test sugli elementi <info> sospetti..............................................................27 2.3.2.3.7 Riepilogo dei test della categoria 3.............................................................28 2.3.2.4 Test di coerenza interna sui file di versions_regexp (categoria 4)......................28 2.3.3 Organizzazione dei test...............................................................................................29 2.3.3.1 Test su singoli sistemi di banners (categoria 1)..................................................29 2.3.3.2 Parsing XML......................................................................................................30 2.3.3.3 Test di coerenza interna XML su banners e webapplications (categoria 3).......33 2.3.3.4 Test su versions_regexp (categorie 2 e 4)...........................................................35 2.3.3.5 Schema consuntivo per le categorie 2, 3 e 4.......................................................36 3
  4. 4. 3 Realizzazione..................................................................................................................................37 3.1 Implementazione................................................................................................................37 3.1.1 Codifica test-driven....................................................................................................37 3.1.1.1 Logica di controllo..............................................................................................37 3.1.1.2 Strategia di sviluppo dei test...............................................................................37 3.1.1.3 Schema assertivo................................................................................................38 3.1.2 Test per errori potenziali.............................................................................................39 3.1.3 Organizzazione dei sorgenti.......................................................................................40 3.1.4 Esecutore dei test........................................................................................................40 3.2 Utilizzo...............................................................................................................................41PARTE SECONDA – Generazione di espressioni regolari4 Analisi.............................................................................................................................................43 4.1 Descrizione del problema...................................................................................................43 4.2 Caratteristiche delle espressioni regolari dei file XML.....................................................44 4.3 Definizioni.........................................................................................................................46 4.4 Definizione dei tipi di soluzione........................................................................................47 4.4.1 Soluzione generica inaccettabile................................................................................48 4.4.2 Soluzione con parole comuni – Common word solution (cws)..................................48 4.4.3 Soluzione con token frequenti da cws – Frequent token solution from cws (ftscw)....48 4.4.4 Soluzione con pattern – Pattern solution (ps).............................................................48 4.4.5 Soluzione con token frequenti da ps – Frequent token solution from ps (ftsp)...........48 4.4.6 Soluzione con pattern complessi di interesse – Complex pattern solution (cps).......49 4.5 Prime considerazioni sulla genericità delle espressioni regolari........................................495 Progettazione..................................................................................................................................52 5.1 Workflow............................................................................................................................52 5.2 Algoritmo di Hunt-McIlroy................................................................................................54 5.2.1 Introduzione................................................................................................................54 5.2.1.1 Regola dei suffissi corrispondenti......................................................................55 5.2.1.2 Regola dei suffissi non corrispondenti...............................................................55 5.2.1.3 Formalizzazione..................................................................................................56 5.2.1.4 Tabella.................................................................................................................56 5.2.1.5 Tabella con traceback..........................................................................................58 5.2.1.6 Numero di sequenze arbitrario............................................................................59 5.2.2 Utilizzo.......................................................................................................................60 5.3 Problema di corrispondenza...............................................................................................61 5.3.1 Tabelle di corrispondenza...........................................................................................61 5.3.2 Modifica a run-time della greediness degli operatori di iterazione............................64 5.3.3 Ricerca strutturale delle corrispondenze....................................................................67 5.3.3.1 Prima regola........................................................................................................68 5.3.3.2 Seconda regola....................................................................................................70 5.3.3.3 Terza regola.........................................................................................................70 5.3.3.4 Common element dei sottoproblemi...................................................................71 5.3.3.5 Criterio di invalidazione.....................................................................................72 5.3.3.6 Criterio di arresto................................................................................................72 5.3.3.7 Assunzioni di corrispondenza e applicabilità delle regole..................................72 5.3.3.8 Osservazioni complementari sulla terza regola..................................................73 4
  5. 5. 5.3.3.8.1 Allineamento di coppia e numero di soluzioni possibili.............................73 5.3.3.8.2 Scelta del common element........................................................................74 5.3.3.8.3 Sottoproblemi generati dalla terza regola...................................................74 5.3.3.9 Algoritmo di ricerca strutturale delle corrispondenze........................................75 5.4 Espressione regolare per il singolo pattern........................................................................79 5.4.1 Introduzione dei token frequenti................................................................................79 5.4.2 Riduzione degli icp a pattern generici........................................................................80 5.4.3 Eliminazione forzata delloperatore di opzionalità.....................................................816 Implementazione............................................................................................................................83 6.1 Struttura della libreria e unità di test..................................................................................83 6.2 Algoritmo di Hunt-McIlroy................................................................................................84 6.3 Algoritmo di corrispondenza..............................................................................................86 6.3.1 Matcher.......................................................................................................................86 6.3.2 Terza regola................................................................................................................88 6.4 Strutture dati per le corrispondenze...................................................................................92 6.4.1 Modello a strutturazione fissa....................................................................................92 6.4.2 Modello a strutturazione variabile..............................................................................94 6.5 Da strutture di corrispondenza a soluzioni.........................................................................97 6.5.1 Espressione regolare per ricavare una tupla di stringhe...........................................103 6.6 Soluzioni con token frequenti..........................................................................................104 6.6.1 Espressione regolare per ricavare i pattern...............................................................1057 Utilizzo e diagnostica...................................................................................................................107 7.1 Esempio di utilizzo...........................................................................................................107 7.1.1 Input della generazione............................................................................................107 7.1.2 File risultato della generazione.................................................................................107 7.1.3 Rappresentazione dei risultati..................................................................................109 7.1.4 Albero delle soluzioni e scelta del risultato migliore...............................................110 7.1.5 Scelta della cws.........................................................................................................111 7.1.6 Confronto tra cws e ftscw...........................................................................................111 7.1.7 Confronto tra ps........................................................................................................111 7.1.8 Confronto tra ps e ftsp...............................................................................................113 7.1.9 Confronto tra ftscw e ftsp............................................................................................113 7.2 Politiche di logging..........................................................................................................114 7.3 Codice di diagnostica.......................................................................................................115PARTE TERZA – Conclusioni e bibliografia8 Conclusioni...................................................................................................................................117 8.1 Obiettivi...........................................................................................................................117 8.2 Valutazione delle prestazioni............................................................................................117 8.2.1 Valore dei test realizzati............................................................................................117 8.2.2 Valutazione del generatore di espressioni regolari...................................................118 8.2.2.1 Cenni al problema di misura di genericità........................................................120 8.3 Sviluppi futuri..................................................................................................................121 8.4 Aspetti quantitativi...........................................................................................................122 8.5 Conclusioni personali.......................................................................................................123 5
  6. 6. 9 Bibliografia...................................................................................................................................124 9.1 Test-driven development..................................................................................................124 9.2 Vulnerabilità.....................................................................................................................124 9.3 Espressioni regolari..........................................................................................................124 9.4 Algoritmo di Hunt-McIlroy e miglioramenti...................................................................124 9.5 Python..............................................................................................................................125 9.6 Framework di test.............................................................................................................125 9.7 Strumenti utilizzati...........................................................................................................125 9.8 Strumenti complementari.................................................................................................125 6
  7. 7. AbstractUna delle tecniche di difesa dagli attacchi informatici è lanalisi delle vulnerabilità, che riguardanoessenzialmente due ambiti: i software e i protocolli.Le vulnerabilità dei software si possono individuare esaminando degli aspetti specifici dei nodiinteressati; ad esempio, per i server, la prima risposta dopo lo stabilirsi della connessione, per iserver web alcuni contenuti di pagina, e in generale il numero di versione di programmi e sistemioperativi.Le vulnerabilità dei protocolli si possono scoprire inviando delle richieste particolari verso i nodi, eanalizzando le risposte.Linsieme di conoscenza degli input da inviare e delle risposte attese, così come dei pattern daricercare, costituisce una base dati che viene ampliata nel tempo, man mano che vengono trovatenuove minacce.La prima parte del lavoro di tesi consiste nello sviluppo di test per la validazione dei nuoviinserimenti in questa base dati.Un supporto fondamentale dellanalisi delle vulnerabilià è costituito dalle espressioni regolari cheindividuano determinate strutture allinterno dei flussi di dati. La generazione automatica di taliespressioni regolari a partire da esempi costituisce la seconda parte della tesi.Gli strumenti software e i test sviluppati nel corso del lavoro sono attualmente impiegatidallazienda committente. 7
  8. 8. PARTE PRIMA Descrizione generale del lavoro1 IntroduzioneLa presente tesi illustra il lavoro svolto presso Emaze Networks S.p.A.1.1 ContestoLazienda realizza il software ipLegion, che comprende un componente detto Scout per lanalisi e ilmonitoraggio delle vulnerabilità informatiche, e aveva la necessità di integrare i test già in uso condelle nuove implementazioni.La base di conoscenza per lanalisi è costituita da dati e logiche dedicate alle diverse vulnerabilità, eviene ampliata man mano che se ne scoprono di nuove. Su tale base il sistema è in grado di asserireche un dato endpoint manifesta una certa vulnerabilità.In prima approssimazione, loperazione avviene interrogando lendpoint secondo una modalità chepuò spaziare dal semplice utilizzo di un protocollo allinvio di particolari richieste, e analizzando lesue risposte.Alcune vulnerabilità sono presenti soltanto se si riscontrano determinate risposte, altre possonoessere presenti se lendpoint risponde, o non risponde, secondo un certo schema.La correttezza di questi schemi costituisce un aspetto cruciale del sistema di analisi di vulnerabilità,perché uneventuale imprecisione potrebbe non far scoprire una vulnerabilità o, al contrario,generare dei falsi positivi.1.2 Obiettivi e vincoli progettualiLobiettivo del lavoro è realizzare dei test che permettano di trovare in modo automatico delleeventuali imprecisioni nella base di conoscenza.I test prendono in esame alcune tipologie di errori, ritenuti particolarmente difficili da rilevare conunanalisi diretta di un operatore umano.Lo sviluppo dei test e del codice correlato deve seguire lapproccio del test-driven development,conformemente alla linea di sviluppo aziendale.Una volta consolidati i test, questi costituiranno lo strumento per il test-driven development di ognifuturo aggiornamento della base dati del sistema. Ogni singolo test garantirà lassenza di un certotipo di errore dalla nuova versione. 8
  9. 9. I test possono essere classificati in due tipologie: test su un modulo singolo, in cui si esaminasoltanto un certo aspetto del sistema di analisi di vulnerabilità, indipendentemente dal resto, e test diintegrazione, in cui si esamina linterazione tra due endpoint.I test più complessi hanno richiesto la progettazione e lo sviluppo di librerie software specifiche, trale quali ha assunto particolare rilievo quella per la generazione automatica di espressioni regolariche catturassero le caratteristiche strutturali di un campione di stringhe noto.Questo modulo è destinato ad essere utilizzato direttamente da un operatore umano, a supporto dellamessa a punto di nuove espressioni regolari nella base di conoscenza del sistema. Permetterà inoltrelo sviluppo di ulteriori test su modulo singolo per la validazione delle espressioni regolari presenti.Il codice dei test e delle librerie è stato sviluppato in Python 2.4.1, lo stesso linguaggio e versionedel sistema di analisi di vulnerabilità. Si è utilizzato lIDE PyCharm.1.3 Fasi di lavoro e risultatiIl lavoro si è articolato in una fase preliminare di studio del linguaggio di programmazione e delsistema di analisi di vulnerabilità, seguita dalla scelta del framework di gestione dei test.Quindi si è trattata la progettazione e la realizzazione dei test; infine ci si è occupati del generatoredi espressioni regolari.Il risultato del lavoro è stato il rilascio di versioni corrette dei file di configurazione interessati daitest e di librerie di utilità generale disponibili per nuovi test futuri.1.4 Articolazione della tesiLa presente tesi si articola in una prima parte riguardante i test e una seconda dedicata al modulo digenerazione di espressioni regolari.Questo modulo ha costituito una parte cospicua del lavoro di tesi e, per il fatto che è interessato daproblematiche diverse dalla quelle specifiche riguardanti i test – anche se rientra nello stessocontesto progettuale – si è ritenuto di considerarlo in una sezione separata.Di seguito, un breve riepilogo dei capitoli: 1. Si esaminano il contesto, gli obiettivi e i vincoli progettuali, le fasi di svoglimento del lavoro e i suoi risultati e la struttura della tesi 2. Si illustrano le scelte per lindividuazione del framework di test e si analizzano e progettano i test da sviluppare, suddividendoli in test di intgrazione e test su moduli singoli 3. Si descrivono gli aspetti rilevanti dellimplementazione dei test e si fornisce un esempio di esecuzione 9
  10. 10. 4. Si analizza il problema della generazione delle espressioni regolari, individuando le caratteristiche rilevanti delle espressioni regolari già esistenti e definendo di conseguenza le tipologie di soluzione5. Si presenta la progettazione del workflow per lalgoritmo di generazione, approfondendo lalgoritmo di Hunt-McIlroy, il problema di corrispondenza e lespressione regolare da associare al singolo pattern6. Si illustrano le modalità di sviluppo test-driven, i punti salienti dellimplementazione degli algoritmi di Hunt-McIlroy e di corrispondenza, le strutture dati utilizzate per la descrizione delle corrispondenze e larticolazione del codice per ottenere le soluzioni con pattern e con token frequenti7. Si presentano degli esempi di utilizzo del generatore di espressioni regolari e si discute il codice aggiuntivo sviluppato per la diagnostica del modulo8. Si delineano le conclusioni del lavoro complessivo, valutandolo sulla base degli obiettivi del progetto9. Si elencano i riferimenti bibliografici 10
  11. 11. 2 Analisi e progettazione2.1 Scelta dellambiente di testingIl concetto di test-driven development è così radicato in Python che la stessa Python StandardLibrary include due framework per scrivere delle unità di test: il più semplice doctest e unittest,che danno il nome ai rispettivi package.Scegliere di fondare i propri test su uno di questi due framework ha indubbiamente i grandivantaggi delle soluzioni standard; in particolare: • ragionevole certezza dellassenza di bug nel framework • garanzia di supporto in versioni future di Python • abbondanza di documentazione disponibileNella scelta del framework giocano un ruolo essenziale la semplicità e la sinteticità nellutilizzo. Ilsorgente del test deve rendere il più possibile evidente la sua finalità e le sue caratteristichespecifiche.doctest, sviluppato nellintento di massimizzare la semplicità di utilizzo, si dimostra non essere unostrumento adeguato per questo progetto, perché presenta le problematiche seguenti: • utilizzo prolisso, per la necessità di riprodurre una sessione interattiva • non è immediatamente distinguibile la parte di test, perché inclusa in una docstring • bassa modularità, perché la parte di test si trova nello stesso file del codice da testareunittest richiede invece la scrittura di un vero codice di test: una soluzione forse meno immediatama molto più sintetica, che offre la possibilità di includere questo sorgente in un modulo separato.Utilizzando unittest, la creazione di una campagna di test è associata alla creazione di scriptsupplementari preposti alla ricerca dei test, alla loro aggregazione ed esecuzione.Esistono vari framework1 che estendono unittest automatizzando queste funzionalità.Spesso è possibile restringere linsieme dei test da eseguire al singolo package, file, classe ometodo, senza dover ricorrere ad alcuno script aggiuntivo.Questa funzionalità è particolarmente interessante, perché in caso di aggiornamenti limitati alla basedi conoscenza del sistema permette di effettuare una validazione rapida eseguendo soltanto i test perle parti modificate.Si sceglie di usare nose, per la sua ampia diffusione e disponibilità di documentazione e perché nonaggiunge a questi requisiti altre funzionalità non di interesse.1 Si veda ad esempio http://packages.python.org/testing/ 11
  12. 12. 2.2 Test di integrazione2.2.1 Contesto e obiettiviLobiettivo dei test di integrazione da sviluppare è quello di verificare la corretta individuazione dialcune vulnerabilità legate allinterazione tra lendpoint da analizzare e un server.Il sistema di analisi memorizza, per ogni vulnerabilità individuata, le informazioni rilevanti. Traqueste vi sono: • codice identificativo aziendale univoco • metodo di rilevazione • numero di porta lato server • protocollo di trasporto • servizio • flag per indicare se linterazione utilizza SSL • una o più risposte rilevanti dellendpoint • nome del software interessatoLa scelta effettiva di quali informazioni memorizzare dipende dalla vulnerabilità specifica.I test riguardano alcuni casi in cui è noto il valore di queste informazioni: si vuole verificare che ivalori rilevati dal sistema di analisi di vulnerabilità corrispondano a quelli noti.Le vulnerabilità oggetto dei test riguardano: • sistemi Check Point (vulnerabilità 10720) e sistemi non Check Point, su cui si testa lassenza della vulnerabilità • sistemi NetBus2 (vulnerabilità 17993) • sistemi multimediali conformi al protocollo H.323 (vulnerabilità 10099): la stessa vulnerabilità è testata in riferimento a varie implementazioni (server Tandberg, server Aethra) e loro servizi (Tandberg Alerting, Aethra Alerting e Aethra Connect) e si testa la sua assenza su un server non H.323Per comunicare con il client da analizzare è necessario predisporre un mock locale che simuli ilcomportamento lato server allorigine della vulnerabilità.Il lato client deve utilizzare la funzione del sistema di analisi di vulnerabilità gatherfunc, che loinizializza e lo collega al server sulla base di queste caratteristiche: 12
  13. 13. • numero di porta lato server • protocollo di trasporto • servizio • indirizzo IP del server • oggetto SessionLoggetto Session è un descrittore dellanalisi di sicurezza del nodo corrente, di cui si tiene contodurante lanalisi di vulnerabilità.Nel sistema di analisi di vulnerabilità ogni protocollo noto o situazione di interesse ha un propriomodulo – nella directory modules – che contiene unimplementazione specifica di gatherfunc.Una volta invocata gatherfunc, si può ottenere la lista delle vulnerabilità rilevate invocandogetIdentifiedVulnerabilities sulloggetto Session.Ogni vulnerabilità è un oggetto Vulnerability da cui si possono ricavare le caratteristiche descritte.2.2.2 Classi di testPoiché ogni classe di test è in corrispondenza uno a uno con le variabili da passare a gatherfunc,queste caratteristiche possono essere incluse come attributi di classe nelle classi di test.Al contrario, le caratteristiche lato server dipendono dal particolare simulatore utilizzato; la stessalogica di test potrebbe avvalersi in futuro di simulatori diversi.Ogni classe di test avrà pertanto queste caratteristiche: • attributi di classe port, transport, service, host_ip e session • metodo setUp per avviare il simulatore lato server • metodo di test, in cui si utilizzano gatherfunc e getIdentifiedVulnerabilities • metodo tearDown per la finalizzazione lato serverI metodi setUp e tearDown implementano quelli definiti in unittest.TestCase2.Dato che ogni protocollo ha una propria implementazione di gatherfunc, limportazione di questafunzione dipende dal protocollo coinvolto nel test.Si sceglie di raggruppare in uno stesso file le classi di test relative a uno stesso protocollo.2 Si tratta più propriamente di un override. Poiché il metodo di unittest.TestCase ha come implementazione la sola istruzione pass, da un punto di vista logico si può pensare come unimplementazione di un interfaccia. In Python non esistono delle vere e proprie interfacce: si tratta comunque di classi, anche se con i metodi contenenti solo pass. 13
  14. 14. 2.2.3 Oggetti mockI test devono utilizzare degli oggetti mock che si sostituiscano agli oggetti Session e Vulnerabilityutilizzati normalmente dal sistema di analisi di vulnerabilità.I mock devono essere utilizzabili da gatherfunc nello stesso modo degli oggetti standard, malimitarsi a modellare gli aspetti delloggetto effettivamente di rilievo nei test.La funzione gatherfunc utilizza un oggetto Session che descrive lanalisi di sicurezza in corso su uncerto endpoint. In particolare ne invoca alcuni metodi.Loggetto mock Session deve tenere traccia di: • indirizzo IP dellendpoint oggetto dellanalisi, di default localhost • parametro sd (utile per test futuri, qui non utilizzato), di default None • una lista di oggetti Vulnerability corrispondenti alle vulnerabilità rilevatee deve implementare i seguenti metodi con queste funzionalità: • getScoutdict: restituisce il parametro sd (utile per test futuri) • getVirtualHost: restituisce lindirizzo IP dellendpoint • getIdentifiedVulnerabilities: restituisce la lista di oggetti Vulnerability • getLogger: restituisce il logger denominato scout3 • reportVulnerability: inserisce un oggetto Vulnerability nella lista; le caratteristiche sono passate come parametri; il metodo deve verificare che i tipi degli argomenti siano correttiPer Vulnerability è sufficiente definire una classe con un attributo per ciascuna informazione checaratterizza la vulnerabilità.2.2.4 Lato serverLa Python Standard Library include un modulo per facilitare la codifica di server, SocketServer.Tutti i test da sviluppare riguardano interazioni sincrone basate su TCP, perciò ha interesseutilizzare la classe SocketServer.TCPServer.La classe inclusa nella libreria standard non fornisce garanzie sulle tempistiche in cui un indirizzolato server possa essere riutilizzato. Dopo la finalizzazione, il socket potrebbe restare in uno stato diTIME_WAIT anche per qualche secondo, e restituire un errore alla richiesta di connessione al proprioindirizzo4.Una classe ReuseTCPSocketServer deve estendere SocketServer.TCPServer ridefinendo server_bind.3 Il sistema di logging standard di Python (modulo logging della Python Standard Library) utilizza una struttura gerarchica di logger identificati da un nome.4 Si veda http://docs.python.org/library/socket.html, in particolare la parte su socket.SO_REUSEADDR. 14
  15. 15. La politica di interazione con il client viene definita in un metodo handle di una classe specifica perciascun simulatore lato server, che implementa il metodo handle diSocketServer.BaseRequestHandler.Per rendere rilevabili le vulnerabilità oggetto dei test, i simulatori devono effettuare le seguentiinterazioni con i client: • Checkpoint: il server deve inviare al client un banner5 cpResp0 specifico e chiudere la connessione • H.323: se il server riceve una certa request H323Req0 deve inviare una response H323Resp0,i, che dipende dal caso specifico di implementazione del protocollo (lindice i è diverso nei casi Tandberg Alerting, Aethra Alerting e Aethra Connect) • Netbus2: se il server riceve una certa request nbReq0 deve inviare una certa response nbResp0 e chiudere la connessioneLattivazione del simulatore lato server da parte di una classe di test deve comportare linizio di unnuovo flusso parallelo di esecuzione, che possa comunicare con il client mentre questultimo è inesecuzione.Una classe MultiThreadTCPServer corrisponde al mock lato server. La classe deve contenere unmetodo spawnServerThread che avvia il servizio in un thread separato.Il metodo deve effettuare il bind del server a un indirizzo IP e un numero di porta specificati eavviare il thread di servizio specificando il gestore di richieste desiderato. MultiThreadTCPServerdeve essere istanziato passando un parametro serverClass per specificare il gestore di richieste.MultiThreadTCPServer deve infine contenere un metodo per la finalizzazione del server.MultiThreadTCPServer delega loperazione di bind al metodo server_bind di ReuseTCPSocketServer,un override del metodo di SocketServer.TCPServer in cui si imposta lopzione del socket che nepermette il riutilizzo anche se in stato di TIME_WAIT.Al momento della creazione di unistanza di MultiThreadTCPServer deve poter essere specificato unattributo opzionale banner, per indicare una stringa che il server invia al client una volta aperta laconnessione.In tutti i test in cui si verifica lassenza di una certa vulnerabilità è sufficiente ricorrere a un requesthandler lato server molto semplice, che si limiti a inviare un banner al client su una connessioneaperta e la chiuda. Si tratta in effetti di un mock di un server qualsiasi che non dia luogo allasituazione della vulnerabilità da testare.Questa logica è inclusa in una classe FakeRequestHandler.5 In questo contesto con banner si intende il primo messaggio che il server invia al client una volta aperta la connessione e terminati eventuali handshake preliminari. 15
  16. 16. Questo tipo di interazione con il client è la stessa da utilizzare nel caso del simulatore Checkpoint:FakeRequestHandler può essere utilizzato anche in questo caso, specificando il banner cpResp0. Figura 1: UML class diagram per i simulatori lato server Figura 2: UML class diagram con le classi dei test da sviluppare 16
  17. 17. 2.2.5 Schema consuntivoSi propone di seguito un UML class diagram che evidenzia le interazioni tra le classi interessate daltest per i sistemi NetBus2.La classe di test Netbus2Test utilizza la funzione gatherfunc per la predisposizione del lato client eper la sua connessione al lato server. gatherfunc si serve delloggetto mock Session per registrare levulnerabilità trovate.Lato server viene creato un oggetto MultiThreadTCPServer, a cui viene passato il callableNetbus2Simulator. Allinvocazione del metodo spawnServerThread, loggetto istanziaReuseTCPSocketServer passando il simulatore come request handler, e lo attiva in un threadseparato. Ad ogni oggetto MultiThreadTCPServer corrisponde un oggetto ReuseTCPSocketServer eviceversa.Gli altri test presentano uninterazione analoga tra le classi, e si differenziano per la classe di test, ilmodulo del sistema di analisi con limplementazione di gatherfunc e il request handler lato server,che hanno comunque strutture analoghe. Alcuni test utilizzano il mock FakeRequestHandler comerequest handler, che viene incluso nello schema riassuntivo come caso di rilievo. Figura 3: UML class diagram riepilogativo con le classi coinvolte nel test per i sistemi NetBus2 17
  18. 18. 2.3 Test su moduli singoli2.3.1 ContestoNella maggior parte dei casi una vulnerabilità interessa soltanto una certa tipologia di nodo, conspecifiche caratteristiche software o hardware.Nellanalisi delle vulnerabilità che potrebbero interessare un endpoint remoto è fondamentalericavare il maggior numero di informazioni possibili riguardo allendpoint.2.3.1.1 Analisi di banner e pagine web (banners e webapplications)Il sistema di analisi di vulnerabilità comprende un modulo che riconosce le caratteristichedellendpoint prendendo in esame una qualche stringa che questo ha generato.I test da sviluppare riguardano in particolare due directory – banners e webapplications – contenentidei file XML, uno per ogni contesto applicativo, che definiscono i legami tra questa stringa e lecaratteristiche dellendpoint.La directory banners è utilizzata nellanalisi delle prime risposte fornite dai server (dette banner), ladirectory webapplications nellanalisi del <body> delle pagine web trasmesse.Ogni file XML comprende degli elementi <software> con degli elementi <info> al loro interno:ogni elemento <software> corrisponde a un insieme di caratteristiche dellendpoint da individuare eogni elemento <info> corrisponde a una singola caratteristica.Ogni elemento <software> ha un attributo name, suo identificativo, e un attributo re, che specificaunespressione regolare. Se la stringa da analizzare è conforme 6 allespressione regolare, il sistemadi analisi riconosce nellendpoint le caratteristiche riportate nellelemento <software>corrispondente.La notazione è leggermente diversa nei file XML della directory webapplications, in cui si utilizzaun elemento <re> interno a <software> anziché un attributo di <software>.A una stringa nota durante lanalisi di vulnerabilità sono applicate tutte le espressioni regolaricontenute negli elementi <software> del file XML afferente allanalisi in corso.La stringa può essere conforme a nessuna, una o più espressioni regolari: ogni match individua uninsieme di certe caratteristiche dellendpoint.Ogni caratteristica può essere individuata in uno di questi due modi:6 Per conformità si intende che la stringa deve generare un match con lespressione regolare. Più precisamente, detta s la stringa, R lespressione regolare e L(R) il linguaggio individuato da R , deve essere s 2 L(R) 18
  19. 19. • essere nota staticamente: la sola conformità della stringa allespressione regolare rende evidente un certo insieme di caratteristiche • essere ricavata a run-time dalla stringa: lespressione regolare comprende un gruppo capturing che individua una porzione di stringa con il valore della caratteristicaLespressione regolare contiene pertanto un gruppo capturing intorno ad ogni caratteristicaindividuata nel secondo modo, e ogni gruppo capturing corrisponde a un elemento <info>.Gli elementi <info> hanno i seguenti attributi: • key: lidentificativo della caratteristica • type: la modalità di valorizzazione della caratteristica ◦ type=”str” per una caratteristica valorizzabile staticamente ◦ type=”re” per una caratteristica valorizzabile con la sottostringa corrispondente a un gruppo capturing dellespressione regolare • value: il valore della caratteristica ◦ se type vale ”str” il valore della caratteristica è riportato letteralmente ◦ se type vale ”re” si specifica il numero del gruppo7 dellespressione regolare da cui ricavare tale valoreAl termine di questa fase dellanalisi di vulnerabilità le caratteristiche dellendpoint che sono stateindividuate vengono memorizzate in un dizionario8, con una chiave per ogni matching che la stringaha provocato sulle espressioni regolari racchiuse negli elementi <software> del file XML.La chiave è il valore dellattributo name dellelemento <software>. Il valore corrispondente allachiave è a sua volta un dizionario, avente per chiavi gli attributi key degli elementi <info> e pervalori le informazioni corrispondenti.Una singola caratteristica può avere uno oppure vari valori possibili, tra i quali non si è in grado discegliere a questo punto dellanalisi di vulnerabilità.In questo caso il relativo valore contenuto nel dizionario è una lista comprensiva di tutte lepossibilità.EsempioSi riportano due elementi <software> estratti dai file XML di configurazione.Sono evidenziati in rosso grassetto i gruppi capturing delle espressioni regolari e i corrispondentiriferimenti negli elementi <info> ai numeri dei gruppi.7 Seguendo lo standard di Python, i numeri dei gruppi iniziano da 1 e conteggiano unicamente i gruppi capturing. Il gruppo 0 individua lintera espressione regolare.8 Inteso come struttura dati di Python. 19
  20. 20. <!-- WebLogic Server Administration Console</title> Welcome to WebLogic Server Version:FakeServer3</p> --><software name="Weblogic" eid="17599"> <re><![CDATA[WebLogic Server Administration Console</title>.*WebLogic Server Version: ([w.]+)</p>]]></re> <info key="version" type="re" value="1"/> <info key="console" type="str" value="detected"/></software><!-- <title>XenServer 5.6.0</title> --><software name="Citrix XenServer"> <re><![CDATA[<title>XenServer ([w.]+)</title>]]></re> <info key="version" type="re" value="1"/></software>Se il file XML fosse composto da questi soli due elementi e la stringa banner fosse <title>XenServer 2.3</title>il dizionario generato sarebbe { Citrix XenServer: {version: 2.3} }Per ogni elemento <software> deve essere riportato nel file XML almeno un commento con unesempio effettivo di possibile stringa attivatrice. Nei file XML contenuti in banners questa stringa èun banner, nei file in webapplications è una porzione del <body> di una pagina web.Il commento può essere inserito in un punto qualsiasi del file.Solitamente viene posto immediatamente al di sopra dellelemento <software> corrispondente,oppure viene posizionato un blocco di commenti prima del relativo blocco di elementi <software>.In ogni caso, si tratta soltanto di consuetudini di comodo che possono essere disattese senzacompromettere il corretto funzionamento del software di analisi di vulnerabilità.2.3.1.2 Analisi di numeri di versione (versions_regexp)Spesso le vulnerabilità riguardano soltanto alcune versioni di un certo software.Il sistema di analisi comprende un modulo che a seconda del numero di versione di un software 20
  21. 21. noto ne indica la vulnerabilità consultando una base di conoscenza XML.I file XML sono inclusi in una directory chiamata versions_regexp.Ogni file XML comprende degli elementi <vulnerability> che hanno come discendenti deglielementi <regexp>. Ogni elemento <vulnerability> ha un attributo id il cui valore identificaunivocamente la vulnerabilità; ogni elemento <regexp> ha un attributo value il cui valore èunespressione regolare.Se il numero di versione che viene esaminato a run-time è conforme a una delle espressioni regolaricontenute in un elemento <vulnerability>, il sistema dichiara che quel numero di versione è affettodalla vulnerabilità avente come identificativo lattributo id di quellelemento <vulnerability>.Tutte le espressioni regolari di questi file devono essere obbligatoriamente terminate da unancoraggio per la fine della stringa. In altre parole, lespressione regolare deve sempre individuare iltermine del numero di versione. Linizio del numero di versione può invece non essere compresonellespressione regolare.9Esempio <vulnerability id="18272"> <regexp value="7.0.[0-6].*$"/> <regexp value="7.0$"/> <regexp value="6.0.[1-2]?[0-9]$"/> <regexp value="6.0.30$"/> <regexp value="6.0$"/> </vulnerability> <vulnerability id="18395"> <regexp value="7.0.1[0-1]$"/> <regexp value="7.0.[0-9]$"/> <regexp value="7.0$"/> </vulnerability>9 Ciò può essere utile per trattare casi del tipo “numero di versione che termina con .2”, in cui cioè non si specifica la parte iniziale del numero di versione. 21
  22. 22. 2.3.2 Tipi di testI test da sviluppare possono essere suddivisi in due tipologie: • test su singoli sistemi noti • test di coerenza interna ai file XMLI primi devono verificare che per alcune configurazioni specifiche, corrispondenti a determinatielementi di singoli file XML, il risultato dellelaborazione da parte del sistema di analisi dellevulnerabilità sia quello atteso.I secondi hanno lo scopo di accertare che i file XML non contengano degli errori interni, che necompromettano la correttezza semantica.È opportuno distinguere i test che analizzano i file XML contenuti nelle directory banners ewebapplications da quelli contenuti in versions_regexp, perché la struttura e il valore semantico deifile sono molto diversi nei due casi.Risultano quindi queste quattro tipologie di test: banners e webapplications versions_regexpSu singoli sistemi test di categoria 1 test di categoria 2Di coerenza interna ai file XML test di categoria 3 test di categoria 4Si prende ora in esame ciascuno di questi casi per formalizzarne i requisiti.2.3.2.1 Test su singoli sistemi di banners (categoria 1)I test da sviluppare riguardano alcuni banner specifici di singoli server SMTP, SNMP e Telnet, einteressano pertanto solo i corrispondenti tre file contenuti in banners.Ciascun test deve richiamare la funzione del sistema di analisi di vulnerabilitàscoutUtils.BannerParser, che prende in input un banner e un file XML e restituisce il dizionarioconsuntivo, e verificare che per un particolare banner il risultato sia quello atteso.Il test deve verificare che nel dizionario siano presenti tutte le chiavi attese e che ogni chiave abbiail valore previsto. Nel caso in cui questo valore sia una lista, è sufficiente verificare che ogni valoredella lista attesa sia presente nella lista risultante.In questo modo si prova la correttezza di alcuni elementi <software> basandosi suscoutUtils.BannerParser; essendo una funzione esterna, questa funzione ha già delle proprie unità ditest che ne avvalorano la correttezza intrinseca.Questo approccio trascura il caso altamente improbabile che un errore su un elemento <software> 22
  23. 23. possa essere compensato da un ulteriore errore sulla funzione conducendo a un risultato corretto.2.3.2.2 Test su singoli sistemi noti di versions_regexp (categoria 2)Si vuole predisporre un test per verificare che le vulnerabilità associate alle versioni del web serverApache Tomcat siano quelle attese. Il test riguarda pertanto un unico file: tomcat.xml.Per ogni vulnerabilità nel file, il test deve verificare che per un certo insieme di numeri di versionela vulnerabilità venga rilevata e per un altro insieme no.Esso deve utilizzare la funzione del sistema di analisi di vulnerabilitàsoftware_version_postscan.isVulnerableSoftwareVersionRegexpList, che prende in input un numerodi versione e la lista di espressioni regolari corrispondenti a una certa vulnerabilità e ne indicalesistenza restituendo True o False.Gli insiemi di numeri di versione oggetto delle asserzioni devono essere determinati a partire dalleespressioni regolari del file XML, in modo che siano rappresentativi di tutti i casi possibili.Il file tomcat.xml ha la seguente struttura (sono state omesse le parti non rilevanti in questocontesto): <vulnerability id="18272"> <regexp value="7.0.[0-6].*$"/> <regexp value="7.0$"/> <regexp value="6.0.[1-2]?[0-9]$"/> <regexp value="6.0.30$"/> <regexp value="6.0$"/> </vulnerability> <vulnerability id="18395"> <regexp value="7.0.1[0-1]$"/> <regexp value="7.0.[0-9]$"/> <regexp value="7.0$"/> </vulnerability>Quasi tutte le espressioni regolari individuano un unico numero di versione o ne specificano unnumero finito, imponendo dei range a cui devono appartenere alcune cifre in posizioni fisse. Èriconoscibile un pattern .* in una sola delle espressioni regolari e una parte opzionale in unaltra.I range sono stati evidenziati in verde e i costrutti .* e lindicatore di opzionalità in rosso. 23
  24. 24. Per ogni espressione regolare che individua un unico numero di versione, si include nel testunasserzione che verifichi la corrispondente vulnerabilità.Per ogni range si verifica che siano vulnerabili le versioni corrispondenti agli estremi, ma non laversione successiva allestremo superiore se questo è minore di 9, né quella precedente allestremoinferiore se questo è maggiore di 0.Per ogni parte opzionale e costrutto .* viene fatta almeno unasserzione positiva che utilizzilelemento e una che non lo utilizzi.Per la vulnerabilità 18272 si fanno delle asserzioni sui seguenti numeri di versione: • 7.0.0, 7.0.6.4: asserzioni positive dagli estremi del range; una utilizza il .* • 7.0.7, 7.0.7.4: asserzioni negative dallestremo superiore del range; una utilizza il .* • 7.0: asserzione positiva per lespressione regolare che individua un unico numero di versione • 6.0.10, 6.0.29, 6.0.0, 6.0.9: asserzioni positive per gli estremi; due utilizzano il ? • 6.0.0.0, 6.0.3.0: asserzioni negative dagli estremi del range opzionale • 6.0.30, 6.0: asserzioni positive dalle espressioni regolari per il singolo numero di versionePer la vulnerabilità 18395 si fanno delle asserzioni sui seguenti numeri di versione: • 7.0.10, 7.0.11: asserzioni positive per gli estremi del range • 7.0.12: asserzione negativa dagli estremi del range • 7.0.0, 7.0.9: asserzioni positive per gli estremi del range (che non ha corrispondenti asserzioni negative) • 7.0: asserzione positiva per lespressione regolare per il singolo numero di versioneA questa base di asserzioni possono essere aggiunte a piacere asserzioni positive o negative per altrinumeri di versione senza compromettere il valore del test.In questo modo si prova la correttezza delle espressioni regolari, demandando alla funzione delsistema di analisi di vulnerabilità la verifica della conformità tra il numero di versione e una delleespressioni regolari che interessano una certa vulnerabilità. Anche in questo caso, la correttezzaintrinseca della funzione esterna è avvalorata da ununità di test già disponibile e valgonoconsiderazioni analoghe a quelle del caso precedente.Il test valida le espressioni regolari del file XML a fronte di esempi. Ciò è particolarmente utile nelmantenimento del file: ogni modifica futura alle espressioni regolari dovrà essere accompagnata dauna modifica o unestensione di questo test. Il test segnalerà eventuali modifiche accidentali. 24
  25. 25. 2.3.2.3 Test di coerenza interna sui file di banners e webapplications (categoria 3)I file XML di banners e webapplications sono elenchi di elementi <software> accompagnati dairelativi commenti. Ad esempio: <!-- <title>XenServer 5.6.0</title> --> <software name="Citrix XenServer"> <re><![CDATA[<title>XenServer ([w.]+)</title>]]></re> <info key="version" type="re" value="1"/> </software>Ognuno di questi blocchi contiene una e una sola espressione regolare, uno o più elementi <info> edè associato a uno o più commenti con esempi di banner conformi allespressione regolare. Permotivi di praticità duso, i commenti sono talvolta raggruppati in una sorta di indice, lontano dairispettivi elementi <software>. Il file può comprendere ulteriori commenti con testo arbitrario.Si vuole verificare che: • non vi siano state alterazioni accidentali dei commenti o delle espressioni regolari, come limmissione di caratteri, la cancellazione o la modifica • non compaiano ripetizioni di porzioni del file XML, e che uno stesso elemento <software> non compaia più di una voltaNon è possibile creare test che soddisfino completamente tali richieste; è possibile approssimare lasoluzione in modo soddisfacente con dei test che rendano queste caratteristiche ideali altamenteprobabili.Tra tutti i test, illustrati di seguito, quelli fondamentali verificano, per ogni file XML ed elemento<software>, la correttezza sintattica dellespressione regolare, e la coerenza tra espressione regolare,commenti ed elementi <info> con type=”re”.2.3.2.3.1 Test di correttezza sintatticaUn test sulla correttezza sintattica del file XML non è necessario, perché gli IDE utilizzati neeffettuano già una validazione continua, e un eventuale errore verrebbe segnalato immediatamentealloperatore.Deve essere invece inclusa in un test la validazione sintattica delle espressioni regolari. Uneventuale errore verrebbe segnalato soltanto nella fase successiva di analisi di vulnerabilità, che puòessere eseguita anche molto tempo dopo laggiornamento della base dati, e comunque in modoindipendente. 25
  26. 26. 2.3.2.3.2 Test di coerenza tra espressione regolare e commentiNellintroduzione di nuovi elementi <software> nel file XML, è possibile che loperatore dimentichidi inserire i commenti corrispondenti, o che non aggiorni correttamente un commento a fronte diuna modifica dellespressione regolare, provocando un disallineamento che non è segnalato neanchedurante lanalisi di vulnerabilità.Considerando le dimensioni del file e la possibile distanza tra lelemento <software> e il relativocommento, la corrispondenza può non essere evidente, ed è possibile incorrere in errori umani.Per provare la coerenza tra espressioni regolari e commenti, è necessario predisporre un test cheverifichi, per ogni file XML, che non vi siano espressioni regolari prive di commenticorrispondenti.2.3.2.3.3 Test di coerenza tra espressione regolare ed elementi <info> con type=”re”Per la coerenza tra espressioni regolari ed elementi <info>, si prevede un test che verifichi lassenzadi gruppi capturing privi del corrispondente elemento <info> con type=”re”.2.3.2.3.4 Test di coerenza tra espressione regolare, commenti ed elementi <info> con type=”re”Per verificare che ogni elemento <info> con type=”re” corrisponda a un gruppo capturing si utilizzaun approccio diverso.Come confermato dal test descritto precedentemente, in ciascun file ogni espressione regolare ha uncommento corrispondente; quindi il test è costruibile passando ogni commento alla funzione delsistema di analisi di vulnerabilità preposta allesame dei banner.La funzione ricerca, nel file specificato, dei match con le espressioni regolari degli elementi<software> e aggiorna di conseguenza il dizionario consuntivo dellanalisi di vulnerabilità.Il test fallisce se si verifica uneccezione, individuando in questo modo i disallineamenti tra i gruppicapturing dellespressione regolare e gli elementi <info> con type=”re” per i commenti del file.2.3.2.3.5 Test per ripetizioniIn alcuni casi, la ripetizione di una porzione di file XML causa un errore di sintassi, o relativa alleregole XML o a quelle della base di conoscenza del sistema.Entrambi questi casi non sono interessanti, per le ragioni già discusse: il primo è rilevatoimmediatamente dal validatore a bordo dellIDE, il secondo è difficilmente producibile da unoperatore, e viene comunque segnalato nellanalisi di vulnerabilità.Rimane aperta la possibilità di ripetizioni di elementi <info> allinterno di elementi <software>, o dielementi <software> allinterno del file XML. Nei file di webapplications, la ripetizione di elementi 26
  27. 27. <re>10 allinterno di <software> provocherebbe invece una trasgressione della sintassi standard, erientra nella casistica precedente.La ripetizione di elementi <info> non produce errori e non è necessario predisporre dei test che neverifichino lassenza.Al contrario, è fondamentale garantire che ogni elemento <software> sia unico allinterno del file,se non altro per ragioni di manutenibilità. Se vi fossero due ripetizioni di uno stesso elemento,loperatore potrebbe modificare una delle due copie senza modificare la seconda, di cui potrebbeperfino ignorarne lesistenza.Poiché ogni elemento <software> è in corrispondenza uno a uno con lespressione regolare al suointerno, è sufficiente testare lunicità di ogni espressione regolare allinterno di ciascun file.2.3.2.3.6 Test sugli elementi <info> sospettiUn caso di alterazione particolarmente insidioso per la sua difficoltà di rilevazione manuale è quelloin cui lattributo type=”re” di un elemento <info> sia stato erroneamente scambiato con type=”str”.Si definisce sospetto un elemento <info> per cui è plausibile che sia avvenuto tale scambio. Sidichiara sospetto un elemento <info> per cui sussistono le condizioni seguenti: • type vale ”str” • value è un numero naturale piccolo • lelemento non è incluso in una lista di <info> da escludere a prioriGli elementi <software> della base di conoscenza del sistema hanno espressioni regolari chetipicamente comprendono due o tre elementi <info>, talvolta quattro e solo raramente un numeromaggiore.Poiché in questo tipo di casi di errore il value si riferisce a un gruppo di unespressione regolare, èragionevole aspettarsi che si tratti di un numero naturale piccolo. In prima approssimazione, una sualimitazione superiore può essere costituita dal numero di gruppi capturing dellespressione regolare.È conveniente introdurre una certa tolleranza a questa valutazione, per escludere quei rari casi diaggiornamento errato in cui si riduce il numero di gruppi dellespressione regolare senza eliminaregli elementi <info> corrispondenti.Questo tipo di errore non verrebbe rilevato dal sistema di analisi di vulnerabilità, perché type=”str”induce il sistema a considerare il numero come il valore letterale di una caratteristica.Si ritiene ragionevole fissare questa tolleranza a 10, nella convinzione che è pressoché impossibileche loperatore elimini ben dieci gruppi capturing dallespressione regolare senza notare diecielementi <info> di troppo.Prendendo in considerazione quello che nella pratica è molto frequente, un elemento <info> cheabbia una delle seguenti caratteristiche non è mai considerato sospetto:10 Si utilizzano elementi <re> soltanto nei file di webapplications. In quelli di banners lespressione regolare è contenuta nellattributo re di <software>. 27
  28. 28. • key=”sp” • key=”operating-system.release” e value=”7” in un elemento <software> dove vi sia un elemento <info key=”operating-system.type” type=”str” value=”Windows”/> e non vi siano altri elementi <info> con la stessa keyQueste due regole escludono dai casi sospetti i numeri di service pack (qui indicato con “sp”) e larelease 7 di Windows.Si predispone un test che, per ogni value di un elemento <info> sospetto, verifica che tale valuecompaia nellespressione regolare dellelemento <software> in cui è contenuto lelemento <info>.In caso di fallimento, questo test segnala una situazione solo potenzialmente errata.2.3.2.3.7 Riepilogo dei test della categoria 3Ognuno dei seguenti test si sviluppa in una versione per banners e una per webapplications; tutti itest prendono in esame singolarmente ogni file XML della directory: • ogni espressione regolare deve essere sintatticamente corretta • ogni espressione regolare deve essere conforme ad almeno un commento • ogni gruppo capturing di ciascuna espressione regolare deve avere un corrispondente11 elemento <info> con type=”re” • ogni elemento <info> con type=”re” deve corrispondere ad un gruppo capturing nellespressione regolare • ogni espressione regolare deve essere unica • ogni elemento <info> sospetto deve avere un value che compare nellespressione regolare corrispondente2.3.2.4 Test di coerenza interna sui file di versions_regexp (categoria 4)Lobiettivo di questi test è quello di rendere improbabili eventuali errori umani nellimmissione delleespressioni regolari utilizzate per filtrare i numeri di versione.Innanzitutto è opportuno predisporre due test per verificare rispettivamente la correttezza sintatticadelle espressioni regolari e la conformità rispetto alla regola di terminazione con lancoraggio per lafine della stringa.11 Con “corrispondente” si intende che deve trovarsi nello stesso elemento <software>. 28
  29. 29. I numeri di versione contengono spesso dei punti, che nellespressione regolare vengono individuatida ..Se dovesse mancare lescaping del carattere speciale ., lespressione regolare presenterebbe unerrore che il sistema di analisi di vulnerabilità non potrebbe individuare automaticamente. Infattilespressione regolare risulterebbe: • sintatticamente corretta • più generale di quella correttarendendo lerrore non individuabile né dal test precedente né da alcun test puntuale sui matchingattesi.È opportuno testare esplicitamente la presenza del carattere di escape prima di ogni punto contenutoin unespressione regolare. Vista la frequenza dello schema .* nella base di conoscenza, il test devepermettere che non vi sia un backslash prima di esso.Il test rileva un anomalia anche nel caso di utilizzo corretto del punto non preceduto da backslash,comunque altamente improbabile in questo contesto. Nel suo output, il test deve rendere evidenteche i casi individuati sono errori soltanto potenziali.Riassumendo, i test da realizzare devono verificare: • correttezza sintattica delle espressioni regolari • presenza nelle espressioni regolari dellancoraggio per il termine della stringa • presenza nelle espressioni regolari dellescaping per ogni ., a meno che questo non preceda un *2.3.3 Organizzazione dei testLaspetto più complesso dei test descritti è il parsing XML. I test della categoria 1 possonodemandarlo alla funzione scoutUtils.BannerParser, per gli altri serve unimplementazione specifica.I test della categoria 1 possono essere progettati a parte.2.3.3.1 Test su singoli sistemi di banners (categoria 1)Ricordando che il risultato dellanalisi di vulnerabilità è un dizionario con chiavi corrispondenti astringhe singole o a liste, è opportuno svincolare la logica di test da questa distinzione.Si sceglie quindi di definire BaseTestCaseForBanners con un metodo assert_inStrOrList, unaversione specializzata di unittest.TestCase. Tutte le classi contenenti i test ereditano daBaseTestCaseForBanners. 29
  30. 30. Figura 4: UML class diagram per i test della categoria 12.3.3.2 Parsing XMLPer il parsing dellXML si sceglie di usare un approccio di tipo SAX 12, per il quale è disponibile unmodulo della Python Standard Library.Si tratta di implementare linterfaccia13 xml.sax.ContentHandler, e in particolare le callbackrichiamate allindividuazione di un tag di inzio di un elemento, di fine di un elemento e di caratteriinterni agli elementi.Una prima implementazione dellinterfaccia è costituita da BaseReValidatorXmlHandler, che corredail parser di un attributo lista per salvare le espressioni regolari trovate.Viene implementato il metodo __init__, per linizializzazione della lista, e reset, per ripristinare lasituazione iniziale in cui la lista è vuota.Le specializzazioni successive sono invece distinte tra classi per banners e webapplications e classiper versions_regexp, perché nei due casi serve tenere traccia di informazioni diverse.Nel primo caso i dati da salvare sono i seguenti:12 Simple API for XML.13 Non esistendo delle vere e proprie interfacce in Python, si tratta in realtà di una classe i cui metodi contengono esclusivamente listruzione pass. Visto che la distinzione tra classe e interfaccia riguarda più lereditarietà che non lentità in sé, nei diagrammi UML delle classi si preferisce utilizzare comunque la freccia tratteggiata verso la classe base, ma omettendo lesplicito prefisso <<interface>> al nome della classe base. 30
  31. 31. • numero di gruppi capturing di ogni espressione regolare • espressioni regolari che compaiono più di una volta nel file • valori sospetti dellattributo value di <info>, associati allespressione regolare corrispondenteDovranno perciò essere ridefiniti i metodi __init__ e reset per inizializzare e reinizializzare lerelative strutture dati.Deve essere introdotta unulteriore specializzazione per distinguere il parsing dei file in banners daquelli in webapplications, perché nei due contesti le espressioni regolari sono specificate inposizioni diverse dellXML.Nei file di banners lespressione regolare è riportata come valore di un attributo re, in quelli diwebapplications è il contenuto di un elemento <re>.La specializzazione per i file di banners può finalmente effettuare il parsing.Si aggiungono a questo livello degli attributi per salvare lo stato del parser, cioè delle variabiliriferite allultima espressione regolare rilevata, che alla ricezione del tag di chiusura </software>devono essere inserite nelle strutture dati consuntive definite in RegexTestReValidatorXmlHandler.La specializzazione per i file di webapplications può essere definita in modo analogo, ma il fattoche le espressioni regolari non si trovino allinterno di tag rende necessaria limplementazione delmetodo characters14 e lintroduzione di variabili aggiuntive: • flag per indicare se è in corso il parsing di unespressione regolare • buffer per lespressione regolareIl flag viene inizializzato prima che il parser inizi lanalisi del file XML a un valore False. Ciòrichiede loverride dei metodo __init__ e reset.Poiché il flag è definito durante tutto il parsing, il metodo characters può bufferizzare lespressioneregolare solo nel caso in cui il valore del flag è True.Nel caso dei numeri di versione, la sola informazione da salvare sono le espressioni regolariassociate a ciascuna vulnerabilità.La classe VersionREValidatorXmlHandler deve comprendere un dizionario di espressioni regolari –dello stesso livello degli attributi di RegexTestREValidatorXmlHandler – e alcune variabili utili nelcorso del parsing, analoghe a quelle di BannerREValidatorXmlHandler eWebappREValidatorXmlHandler.In particolare servono: • un flag per indicare se il parser sta analizzando linterno di un elemento <vulnerability>14 Callback invocata alla ricezione di caratteri di dati, ossia di stringhe contenute allinterno di elementi XML. 31
  32. 32. • un buffer per lidentificativo della vulnerabilità corrente • un buffer per le espressioni regolari associate alla vulnerabilità correnteI metodi di parsing da implementare sono startElement ed endElement; non serve implementarecharacters perché in questo tipo di file XML tutti i dati utili sono contenuti negli attributi allinternodei tag.Il buffer per le espressioni regolari associate alla vulnerabilità corrente deve essere inizializzatoprima che inizi il parsing, in modo che alla lettura di </vulnerability> questo sia effettivamentepronto per luso. Figura 5: UML class diagram per le classi di parsing XML 32
  33. 33. 2.3.3.3 Test di coerenza interna XML su banners e webapplications (categoria 3)I test di coerenza sui file XML si basano sui dati trovati nei file dai parser.È conveniente che il parsing XML sia svolto prima di ogni test, e che i dati rilevanti vengano inclusicome attributi di classe nelle classi di test.Si sceglie di inserire il codice che attiva il parsing nel metodo setUpClass, ereditato daunittest.TestCase, che viene eseguito alla creazione del relativo oggetto.Poiché i test riguardano tutti i file delle due directory, in questa fase deve essere effettuato il parsingdi ciascun file.Si sceglie di utilizzare un parser per banners e uno per webapplications; ognuno deve analizzareciascun file della propria directory.Per ciascun file della directory setUpClass deve: • effettuare il parsing del file • bufferizzare le informazioni estratte dal parser salvandole negli attributi di RegexTest • invocare il reset del parserLa classe deve comprendere varie strutture dati, una per ogni informazione di interesse, in cui sonocompresi tutti i dati derivanti dal parsing.Ogni struttura dati deve organizzare queste informazioni raggruppandole a seconda del file diprovenienza.Si sceglie di utilizzare due strutture dati separate per le informazioni dei file di banners e diwebapplications, perché si riferiscono a due contesti operativi diversi.Analogamente, si sceglie di rendere specifici per luna o laltra directory anche i metodi di test. Inquesto modo un test per una certa directory contiene asserzioni soltanto su una struttura dati riferitaa quella stessa directory, e la suddivisione tra i moduli banners e webapplications del sistema dianalisi di vulnerabilità si riflette anche sulle sue unità di test.Si predispone un attributo di classe logger a cui indirizzare i messaggi da visualizzare al termine deitest che devono segnalare degli errori potenziali15.15 La politica di default di nose è quella di mostrare i messaggi dello standard output ( sys.stdout) solo in caso di fallimento o errore di un test. Per messaggi da visualizzare sempre non è opportuno usare lo standard output. 33
  34. 34. Figura 6: UML class diagram per i test di categoria 3 34
  35. 35. 2.3.3.4 Test su versions_regexp (categorie 2 e 4)Nel caso dei test su versions_regexp anche i test su singoli moduli utilizzano le informazionicontenute nei file XML.Il parsing viene richiamato, in modo del tutto analogo al caso precedente, da una classe baseTestCaseForVersions estesa da VersionRegexpTest, che comprende i test di coerenza interna ai fileXML (categoria 4), e da TomcatVersionsTest, che comprende il test su moduli singoli (categoria 2).La logica che verifica che un numero di versione sia vulnerabile o meno non dipende dal modulosingolo oggetto dei test di categoria 2, quindi si sceglie di inserirla come metodo della classe base.Se in estensioni future del sistema si volesse predisporre ununità di test di categoria 2 su un sistemadiverso da Apache Tomcat, la relativa classe dovrebbe estendere la classe base. Figura 7: UML class diagram per i test delle categorie 2 e 4 35
  36. 36. 2.3.3.5 Schema consuntivo per le categorie 2, 3 e 4I test delle categorie 2, 3 e 4 condividono linfrastruttura delle classi preposte al parsing XML,mentre i test della categoria 1 si basano su un sistema di classi indipendente.Lo schema seguente riepiloga le classi coinvolte nei test delle categorie 2, 3 e 4. In particolare: • la parte sinistra è preposta ai test di categoria 3 • la parte centrale è preposta al parsing XML • la parte destra è preposta ai test delle categorie 2 ( TomcatVersionsTest) e 4 (VersionRegexpTest) Figura 8: UML class diagram riassuntivo per i test delle categorie 2, 3 e 4 36
  37. 37. 3 Realizzazione3.1 Implementazione3.1.1 Codifica test-driven3.1.1.1 Logica di controlloLa metodologia di sviluppo test-driven si basa sulla messa a punto di una logica di controllo – leunità di test – come prima fase dellimplementazione, prima ancora di procedere alla scrittura delcodice.Come strategia di sviluppo, il sorgente deve essere implementato verificandone continuamente lacorrettezza mediante il codice di controllo. Dopo ogni nuovo inserimento nel sorgente vieneeseguito il codice di test, in modo da avere un riscontro continuo sulla correttezzadellimplementazione.Il principio di base è quello di individuare eventuali errori il prima possibile, evidenziandone lacausa.Il sorgente da sviluppare è costituito dalle unità di test, da affiancare a risorse preesistenti, costituitedai file di configurazione.I file di configurazione possono essere utilizzati come logica di controllo per i test da sviluppare,rendendo non strettamente necessario scrivere delle unità di test per limplementazione dei test.Con questa modalità di sviluppo i test vengono validati dai file di configurazione, che possono aloro volta contenere errori: si può procedere in questo modo solo nei casi in cui gli errori nei file diconfigurazione sono indipendenti da quelli dei test da sviluppare. In altre parole, i test devonoindividuare gli errori dei file di configurazione e i file di configurazione quelli dei test.Ciò è vero nei casi in cui il sorgente dei test è particolarmente semplice, e questa proprietà risultabanalmente vera. Per ogni aspetto più complesso dei test è necessario predisporre ununità di test disecondo livello specifica. Questo sarà lapproccio tipico nellimplementazione del generatore diespressioni regolari.3.1.1.2 Strategia di sviluppo dei testConformemente alla logica di controllo descritta, si adottano le regole di codifica seguenti.Il primo test viene effettuato con una prima stesura dellunità di test, in cui si riportano gli importnecessari al file e uno stub della classe di test, che estende unittest.TestCase e viene implementatacon la sola istruzione pass. In questo modo si possono rilevare eventuali errori causati dagli import.Si procede quindi con lintroduzione di un metodo di test, implementato con listruzione: self.fail(UNIMPLEMENTED)Il relativo test accerta che nose rilevi correttamente il test e ne segnali linsuccesso. A questo punto 37
  38. 38. si rileva un eventuale errore nel nome del test16.È utile mantenere questa riga come ultima istruzione per tutta la fase di implementazione delmetodo di test, e procedere inserendo il codice prima.Siccome nose segnala il primo punto di fallimento di un test e ne interrompe lesecuzione, tutti glieventuali errori imputabili al codice di nuova introduzione hanno la precedenza sul fallimentocausato dallistruzione finale.In questo modo si ha la certezza che nessun test di cui non è stata terminata limplementazionepossa essere dimenticato dal programmatore: fino al momento di rimozione dellistruzione difallimento il test continuerà ad essere segnalato da nose come fallimentare.Sia nellunità di test che nel sorgente del software è conveniente utilizzare listruzione pass comesegnaposto per istruzioni non implementate, in modo da rendere evidente il punto in cui proseguirecon limplementazione.Per annotare queste parti con indicazioni su come proseguire, o come modificare il sorgente, siricorre a commenti che inizino con todo, quasi una parola chiave nello sviluppo test-driven.Molti IDE, tra cui PyCharm, evidenziano questi commenti provvisori in un modo particolare epermettono di creare delle liste delle azioni ancora da fare.È preferibile che ununità di test effettui delle verifiche eterogenee sulla logica da testare, cercandodi spaziare su tutto il suo dominio.Se il dominio presenta dei casi limite, è utile introdurre dei test per la loro verifica.3.1.1.3 Schema assertivoOgni metodo di test è fondato su una o più asserzioni, che costituiscono le istruzioni di verifica dicorrettezza.unittest.TestCase mette a disposizione vari metodi per effettuare asserzioni, tra cui si sceglie diutilizzarne un numero molto ristretto, in modo da rendere più evidente possibile la finalitàdellasserzione: • assertTrue: il metodo utilizzato più comunemente • assertFalse: utilizzato quando laspetto più importante da testare è la falsità dellargomento • fail: utilizzato durante la fase di sviluppo dei test • assertRaises: utilizzato per segnalare che unistruzione solleva uneccezione specificata16 nose impone che sorgenti, package, directory di test siano conformi allespressione regolare (?:^|[b_.-])[Tt]est), detta testMatch. In questi file vengono individuati solo i test con nome conforme a testMatch e inclusi in classi che ereditano da unittest.TestCase con nome conforme a testMatch. Si veda https://nose.readthedocs.org/en/latest/usage.html . 38
  39. 39. Si preferisce scrivere esplicitamente il test di uguaglianza con loperatore == anziché adottare ilmetodo assertEquals.Dato che in caso di test fallimentare o errato nose riporta il codice della riga di errore e un eventualemessaggio, si aggiunge un messaggio di spiegazione se la riga di asserzione non rende evidente lanatura dellerrore.3.1.2 Test per errori potenzialiSe il test per i valori <info> sospetti o quello di coerenza interna dei file XML di versions_regexprilevano una situazione anomala, non si può avere la certezza che si tratti di un errore. Loutput deveessere un messaggio che segnali il caso potenzialmente errato.Anziché ricorrere ad asserzioni, si utilizzano dei messaggi nel log di nose nose.result, mappato daun attributo logger della classe di test.Per i valori sospetti, ad esempio, un messaggio di livello logging.WARNING viene generato selelemento <info> sospetto ha un value che non compare nellespressione regolare corrispondente eun messaggio di livello logging.INFO riassume il numero di casi totali trovati.Il comportamento di default di nose prevede di includere nelloutput i messaggi indirizzati ai loggergestiti dal framework.Utilizzare unasserzione sarebbe inopportuno anche perché i test si interromperebbero al primo casoanomalo incontrato, già da solo sufficiente per dichiarare scorretta la configurazione in corso di test.Dato che ogni caso anomalo per questi test potrebbe non essere un errore, è sensato ricercarli tutti. Figura 9: Test per i valori <info> sospetti 39
  40. 40. 3.1.3 Organizzazione dei sorgentiI file sviluppati nel corso del progetto si collocano nella directory testunits del sistema di analisidelle vulnerabilità.Lorganizzazione della gerarchia interna a questa directory è stata definita tenendo conto dellepossibili estensioni future: • tests: per i test, le loro librerie e le estensioni future • extlib: per le librerie necessarie allesecuzione dei test (nose) • oldtests: per vecchi testLa directory tests si articola in: • integration_tests: per i sorgenti dei test di integrazione • unit_tests: per i sorgenti dei test su singolo modulo • lib: per librerie utilizzate dai test • mocks: per oggetti mock utilizzati dai test • resources: per risorse aggiuntive di scenari specifici (request handler dei simulatori lato server)I test allinterno di unit_tests sono raggruppati a seconda del modulo del sistema di analisi divulnerabilità a cui si riferiscono. Allinterno di unit_tests vi sono le due directory: • bannersAndWebapps: per i sorgenti dei test sui file XML di banners e webapplications • versions: per i sorgenti dei test sui file XML di versions_regexp3.1.4 Esecutore dei testAllinterno della directory testunits/tests si predispone uno script in Python che effettua la ricerca eil lancio dei test nelle subdirectory.Allo script possono essere passati gli argomenti standard di nose17, con i quali si possono adesempio specificare dei criteri di filtraggio per eseguire soltanto un sottoinsieme dei test presenti.17 Si veda http://nose.readthedocs.org/en/latest/usage.html. 40
  41. 41. 3.2 UtilizzoPer lesecuzione dei test si invoca dalla directory testunits/tests del sistema di analisi dellevulnerabilità linterprete Python, passando come argomento lo script esecutore main.py.Di default, lo script avvia la ricerca e lesecuzione di tutti i test presenti nella directory; utilizzandodei parametri aggiuntivi, secondo le specifiche di nose, è possibile specificare quali test eseguire.Nel suo output, nose genera un carattere per ogni test eseguito che ne riassume lesito: • . per un test con esito positivo • F per un test con esito negativo (asserzione disattesa) • E per un test con erroriPer i test con esito negativo o con errori viene generata una sezione con lindicazione della riga cheha fatto fallire il test, il suo codice e il tipo di errore generato ed eventuali messaggi correlati.Si includono i messaggi indirizzati ai log gestiti da nose.Infine nose mostra delle righe aggiuntive, con il numero di test eseguiti, il tempo di esecuzionecomplessivo e lesito della campagna di test, con il numero di test fallimentari o con errori se questisono presenti.EsempiPer eseguire i test di verifica dei file XML contenuti in banners e webapplications si procede inquesto modo:In questo esempio ci si serve della variabile python, valorizzata con il percorso dellinterprete.A main.py è passata come argomento la directory tests/bannersAndWebapps, in cui ricercare edeseguire i test.Seguono alcuni caratteri punto, uno per ogni test eseguito, e il messaggio indirizzato al lognose.result, che indica che non ci sono banner sospetti.Dopo altri due punti e una riga di separazione sono riportati i dati consuntivi della campagna di test; 41
  42. 42. il messaggio finale OK segnala che tutti i test della campagna hanno avuto esito positivo.In questo secondo esempio si eseguono i test contenuti nellunità di test test_transformPatterns, perla funzione transformPatterns.In questo caso la campagna di test è lanciata con il parametro -v (verbose). Per ogni test nose generaun output più prolisso, che comprende nome e percorso del test, o stringa di documentazione, edesito.Si mostra infine un esempio più significativo, non incluso nel progetto, con dei test fallimentari: 42
  43. 43. PARTE SECONDA Generazione di espressioni regolari4 Analisi4.1 Descrizione del problemaLa seconda parte di questa tesi prende spunto da un problema riscontrato dopo aver messo a punto itest su moduli singoli per i file XML di banners e webapplications.I test hanno evidenziato che le espressioni regolari associate ai blocchi <software>, il punto crucialenellanalisi degli endpoint remoti, spesso presentavano delle imprecisioni dovute ad errori umani.Molti errori tipici sono stati individuati dai test sviluppati nella prima parte; tuttavia nessunacampagna di test può garantire la totale assenza di errori umani, perché molti possibili errori nondipendono soltanto dalla coerenza con gli esempi di banner (i commenti del file XML) o con glielementi <info>.Si sviluppa uno strumento di generazione automatica che prenda in input degli esempi di banner18 efornisca delle possibili espressioni regolari conformi a tutti i banner di esempio. In altre parole, ogniespressione regolare generata deve individuare un linguaggio in cui devono essere contenute tutte lestringhe banner di input.Lo strumento vuole essere innanzitutto un ausilio alloperatore umano, del quale si richiedecomunque un intervento finale di scelta dellespressione regolare più adatta, o di aggiunta dicaratteristiche note che non risultino evidenti dagli esempi di input. Inoltre, in espansioni futurepotrà essere utilizzato per costruire nuovi test.Come obiettivo generale, le espressioni regolari in output devono riflettere il più possibile lecaratteristiche delle stringhe banner.Questa linea guida deve essere precisata nel corso della fase di analisi, in cui si definiscono lecaratteristiche esatte che devono avere le espressioni regolari soluzioni del problema, anche inrelazione allo scenario applicativo.18 Per praticità di trattazione, si includono nel termine generico “banner” anche le stringhe riportate nei file di webapplications, parti del <body> di pagine web. 43
  44. 44. 4.2 Caratteristiche delle espressioni regolari dei file XMLOsservando le espressioni regolari riportate nei file XML di banners e webapplications si nota chenella quasi totalità dei casi esse sono composte da una struttura scheletro di parole riportateletteralmente, entro la quale si inseriscono delle parti variabili, come parti opzionali, insiemi dicaratteri validi, parti ripetute.Unespressione regolare con questa struttura individua delle stringhe in cui sono presenti certamentedelle sottostringhe comuni, che compaiono in un ordine fisso.Si nota inoltre che le parti variabili non compaiono quasi mai allinterno di parole: tipicamente èpresente un carattere separatore tra una parola e una parte variabile.Spesso le parole comprendono dei caratteri numerici (ad es. IMAP4, POP3).Spesso le espressioni regolari comprendono tra le parti variabili delle character class 19, in molti casiincluse in dei character set20 insieme ad altre character class o caratteri fissi.In molti casi le character class sono w o d, a cui spesso si affiancano il carattere fisso punto,talvolta anche il trattino, lunderscore o lo spazio, singolarmente o congiuntamente.In particolare è frequente il character set [d.] in corrispondenza ai numeri di versione.Spesso sono presenti delle parti generiche indicate con .*.Le espressioni regolari non sono quasi mai ancorate allinizio o alla fine della stringa.Ovviamente, le espressioni regolari includono dei gruppi capturing intorno alle strutture di interessecorrispondenti agli elementi <info>, perlopiù intorno a parti variabili.Questi costrutti conferiscono a porzioni di espressione regolare un valore semantico; dal punto divista della corrispondenza tra espressione regolare e stringhe banner di esempio sono del tuttoirrilevanti.19 Una character class è un costrutto delle espressioni regolari che individua nelle stringhe una certa tipologia predefinita di carattere. Ad esempio: w individua un carattere alfanumerico, d un carattere numerico.20 Un character set è un costrutto delle espressioni regolari che individua nelle stringhe una certa tipologia di carattere definita esplicitamente. Nella definizione si possono usare le character class. Ad esempio [ws.] individua un carattere che è un alfanumerico o un carattere di spaziatura o un punto. 44
  45. 45. Esempio<!-- OK Domino IMAP4 Server Release 7.0.2 ready Wed, 11 Jul 2007 14:03:48 +0200x0d --><!-- OK Domino IMAP4 Server Release 7.0.2FP1 ready Fri, 9 Jan 2009 13:32:07 +0100 --><!-- OK Domino IMAP4 Server Release 7.0.2FP3 ready Tue, 28 Jul 2009 16:08:50 +0200 --><software name="Lotus Domino" re="Domino IMAP4 Server Release ([w.]+) ready"> <info key="version" type="re" value="1"/></software><!-- <h1>BEA WebLogic Server 9.2 --><software name="Weblogic"> <re>074h1076BEA WebLogic Server ([d.]+)</re> <info key="version" type="re" value="1"/> <info key="cpe_version" type="re" value="1"/></software><!-- hostname POP3 server (Post.Office v3.6.3 release 105 with ZPOP version 1.0 ID# --><!-- hostname POP3 server (Post.Office v3.5.3 release 223 with ZPOP version 1.0 ID# --><software name="PostOffice" re="([w.-_]+) POP3 server (Post.Office v([w.]+)release"> <info key="hostname" type="re" value="1"/> <info key="version" type="re" value="2"/> <info key="operating-system.type" type="str" value="MacOSX"/></software><!-- Microsoft Windows CE Version 4.10 (Build 908) --><!-- Microsoft Windows CE Version 5.0 (Build 1400) --><software name="Microsoft SNMP" re="Microsoft Windows CE Version ([d.]+)"> <info key="operating-system.type" type="str" value="Windows"/> <info key="operating-system.version" type="str" value="CE"/> <info key="version" type="re" value="1"/></software><!-- <title>Apache Tomcat/7.0.22</title> --><!-- Apache Tomcat/5.0.30 --><software name="Tomcat"> <re>Tomcat/([d.]+)</re> <info key="version" type="re" value="1"/> <info key="cpe_version" type="re" value="1"/></software><!-- >Tomcat Server Administration< --><software name="Tomcat" eid="10711"><re>076Tomcat Server Administration074</re> <info key="None" type="str" value="Tomcat"/> <info key="console" type="str" value="detected"/></software> 45
  46. 46. 4.3 DefinizioniSi elencano una serie di definizioni in riferimento allinsieme delle stringhe banner di esempio, checostituiscono linput del generatore di espressioni regolari.In ogni stringa è individuabile uno scheletro di sottostringhe comuni a tutte le stringhe dellinsieme,poste sempre nello stesso ordine. Si definiscono: • token (t): sottostringa, significativa secondo un determinato criterio • common token (ct): una sottostringa presente in tutte le stringhe • inter-common token (ict o interCT): la sottostringa delimitata da due ct o dai limiti della stringaVista la centralità delle parole nel contesto applicativo, si definiscono: • word token (wt): la più grande sottostringa composta da caratteri alfanumerici consecutivi • common word token (cwt): wt che siano anche ctSi definiscono: • pattern: porzione di espressione regolare di significato compiuto • common pattern (cp): un pattern presente in tutte le stringhe • inter-common pattern (icp): la sottosequenza di pattern delimitata da due cp o dai limiti della sequenza di patternPer generalizzare le definizioni riguardanti i token e i pattern si definiscono: • common element (ce): un elemento presente in tutte le stringhe (ct o cp) • inter-common element (ice): la sottostringa o sottosequenza di pattern delimitata da due ce (due ct o due cp) o dai limiti della stringa o della sequenzaInoltre si utilizza il suffisso Seq per indicare una sequenza degli elementi precedentemente definiti(ad es. cpSeq per una sequenza di common pattern).Si definiscono poi quattro tipologie di pattern, schemi di base ispirati alle character class frequenti.Ogni stringa è conforme a una sequenza di pattern di questi tipi fondamentali: • S (spaziature): porzione di stringa conforme a s+ • D (cifre): porzione di stringa conforme a d+ • W (parola): porzione di stringa conforme a w+ • P (punteggiatura): porzione di stringa conforme a [^sw]+ 46

×