SlideShare a Scribd company logo
1 of 125
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                                            Relatore
Federico Cecutti                                     chiar.mo prof. Alberto Bartoli


                                                     Correlatore
                                                     Enrico Milanese




                            anno accademico 2011/2012
ai miei genitori




2
Indice

Abstract.................................................................................................................................................7

PARTE PRIMA – Descrizione generale del lavoro

1 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.........................................................................................................9

2 Analisi e progettazione...................................................................................................................11
    2.1 Scelta dell'ambiente 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
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...............................................................................................................................41


PARTE SECONDA – Generazione di espressioni regolari

4 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........................................49

5 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.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 dell'operatore di opzionalità.....................................................81

6 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...............................................................105

7 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.......................................................................................................115


PARTE TERZA – Conclusioni e bibliografia

8 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
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
Abstract


Una delle tecniche di difesa dagli attacchi informatici è l'analisi delle vulnerabilità, che riguardano
essenzialmente due ambiti: i software e i protocolli.
Le vulnerabilità dei software si possono individuare esaminando degli aspetti specifici dei nodi
interessati; ad esempio, per i server, la prima risposta dopo lo stabilirsi della connessione, per i
server web alcuni contenuti di pagina, e in generale il numero di versione di programmi e sistemi
operativi.
Le vulnerabilità dei protocolli si possono scoprire inviando delle richieste particolari verso i nodi, e
analizzando le risposte.


L'insieme di conoscenza degli input da inviare e delle risposte attese, così come dei pattern da
ricercare, costituisce una base dati che viene ampliata nel tempo, man mano che vengono trovate
nuove minacce.
La prima parte del lavoro di tesi consiste nello sviluppo di test per la validazione dei nuovi
inserimenti in questa base dati.


Un supporto fondamentale dell'analisi delle vulnerabilià è costituito dalle espressioni regolari che
individuano determinate strutture all'interno dei flussi di dati. La generazione automatica di tali
espressioni regolari a partire da esempi costituisce la seconda parte della tesi.


Gli strumenti software e i test sviluppati nel corso del lavoro sono attualmente impiegati
dall'azienda committente.




                                                   7
PARTE PRIMA

                          Descrizione generale del lavoro


1 Introduzione
La presente tesi illustra il lavoro svolto presso Emaze Networks S.p.A.




1.1 Contesto
L'azienda realizza il software ipLegion, che comprende un componente detto Scout per l'analisi e il
monitoraggio delle vulnerabilità informatiche, e aveva la necessità di integrare i test già in uso con
delle nuove implementazioni.
La base di conoscenza per l'analisi è costituita da dati e logiche dedicate alle diverse vulnerabilità, e
viene ampliata man mano che se ne scoprono di nuove. Su tale base il sistema è in grado di asserire
che un dato endpoint manifesta una certa vulnerabilità.
In prima approssimazione, l'operazione avviene interrogando l'endpoint secondo una modalità che
può spaziare dal semplice utilizzo di un protocollo all'invio di particolari richieste, e analizzando le
sue risposte.
Alcune vulnerabilità sono presenti soltanto se si riscontrano determinate risposte, altre possono
essere presenti se l'endpoint risponde, o non risponde, secondo un certo schema.


La correttezza di questi schemi costituisce un aspetto cruciale del sistema di analisi di vulnerabilità,
perché un'eventuale imprecisione potrebbe non far scoprire una vulnerabilità o, al contrario,
generare dei falsi positivi.




1.2 Obiettivi e vincoli progettuali
L'obiettivo del lavoro è realizzare dei test che permettano di trovare in modo automatico delle
eventuali imprecisioni nella base di conoscenza.
I test prendono in esame alcune tipologie di errori, ritenuti particolarmente difficili da rilevare con
un'analisi diretta di un operatore umano.
Lo sviluppo dei test e del codice correlato deve seguire l'approccio 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 ogni
futuro aggiornamento della base dati del sistema. Ogni singolo test garantirà l'assenza di un certo
tipo di errore dalla nuova versione.


                                                   8
I test possono essere classificati in due tipologie: test su un modulo singolo, in cui si esamina
soltanto un certo aspetto del sistema di analisi di vulnerabilità, indipendentemente dal resto, e test di
integrazione, in cui si esamina l'interazione tra due endpoint.


I test più complessi hanno richiesto la progettazione e lo sviluppo di librerie software specifiche, tra
le quali ha assunto particolare rilievo quella per la generazione automatica di espressioni regolari
che catturassero le caratteristiche strutturali di un campione di stringhe noto.
Questo modulo è destinato ad essere utilizzato direttamente da un operatore umano, a supporto della
messa a punto di nuove espressioni regolari nella base di conoscenza del sistema. Permetterà inoltre
lo 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 versione
del sistema di analisi di vulnerabilità. Si è utilizzato l'IDE PyCharm.




1.3 Fasi di lavoro e risultati
Il lavoro si è articolato in una fase preliminare di studio del linguaggio di programmazione e del
sistema 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 generatore
di espressioni regolari.
Il risultato del lavoro è stato il rilascio di versioni corrette dei file di configurazione interessati dai
test e di librerie di utilità generale disponibili per nuovi test futuri.




1.4 Articolazione della tesi
La presente tesi si articola in una prima parte riguardante i test e una seconda dedicata al modulo di
generazione di espressioni regolari.
Questo modulo ha costituito una parte cospicua del lavoro di tesi e, per il fatto che è interessato da
problematiche diverse dalla quelle specifiche riguardanti i test – anche se rientra nello stesso
contesto 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 l'individuazione 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 dell'implementazione dei test e si fornisce un esempio di
       esecuzione

                                                    9
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 soluzione
5. Si presenta la progettazione del workflow per l'algoritmo di generazione, approfondendo
   l'algoritmo di Hunt-McIlroy, il problema di corrispondenza e l'espressione regolare da
   associare al singolo pattern
6. Si illustrano le modalità di sviluppo test-driven, i punti salienti dell'implementazione degli
   algoritmi di Hunt-McIlroy e di corrispondenza, le strutture dati utilizzate per la descrizione
   delle corrispondenze e l'articolazione del codice per ottenere le soluzioni con pattern e con
   token frequenti
7. Si presentano degli esempi di utilizzo del generatore di espressioni regolari e si discute il
   codice aggiuntivo sviluppato per la diagnostica del modulo
8. Si delineano le conclusioni del lavoro complessivo, valutandolo sulla base degli obiettivi del
   progetto
9. Si elencano i riferimenti bibliografici




                                              10
2 Analisi e progettazione

2.1 Scelta dell'ambiente di testing
Il concetto di test-driven development è così radicato in Python che la stessa Python Standard
Library 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 grandi
vantaggi delle soluzioni standard; in particolare:
    •   ragionevole certezza dell'assenza di bug nel framework
    •   garanzia di supporto in versioni future di Python
    •   abbondanza di documentazione disponibile


Nella scelta del framework giocano un ruolo essenziale la semplicità e la sinteticità nell'utilizzo. Il
sorgente del test deve rendere il più possibile evidente la sua finalità e le sue caratteristiche
specifiche.
doctest, sviluppato nell'intento di massimizzare la semplicità di utilizzo, si dimostra non essere uno
strumento 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 testare


unittest richiede invece la scrittura di un vero codice di test: una soluzione forse meno immediata
ma 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 script
supplementari preposti alla ricerca dei test, alla loro aggregazione ed esecuzione.
Esistono vari framework1 che estendono unittest automatizzando queste funzionalità.
Spesso è possibile restringere l'insieme dei test da eseguire al singolo package, file, classe o
metodo, senza dover ricorrere ad alcuno script aggiuntivo.
Questa funzionalità è particolarmente interessante, perché in caso di aggiornamenti limitati alla base
di conoscenza del sistema permette di effettuare una validazione rapida eseguendo soltanto i test per
le parti modificate.


Si sceglie di usare nose, per la sua ampia diffusione e disponibilità di documentazione e perché non
aggiunge a questi requisiti altre funzionalità non di interesse.



1 Si veda ad esempio http://packages.python.org/testing/

                                                           11
2.2 Test di integrazione

2.2.1 Contesto e obiettivi
L'obiettivo dei test di integrazione da sviluppare è quello di verificare la corretta individuazione di
alcune vulnerabilità legate all'interazione tra l'endpoint da analizzare e un server.


Il sistema di analisi memorizza, per ogni vulnerabilità individuata, le informazioni rilevanti. Tra
queste vi sono:
   •   codice identificativo aziendale univoco
   •   metodo di rilevazione
   •   numero di porta lato server
   •   protocollo di trasporto
   •   servizio
   •   flag per indicare se l'interazione utilizza SSL
   •   una o più risposte rilevanti dell'endpoint
   •   nome del software interessato


La 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 i
valori 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 l'assenza
       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.323



Per comunicare con il client da analizzare è necessario predisporre un mock locale che simuli il
comportamento lato server all'origine della vulnerabilità.


Il lato client deve utilizzare la funzione del sistema di analisi di vulnerabilità gatherfunc, che lo
inizializza e lo collega al server sulla base di queste caratteristiche:


                                                    12
•   numero di porta lato server
    •   protocollo di trasporto
    •   servizio
    •   indirizzo IP del server
    •   oggetto Session


L'oggetto Session è un descrittore dell'analisi di sicurezza del nodo corrente, di cui si tiene conto
durante l'analisi di vulnerabilità.


Nel sistema di analisi di vulnerabilità ogni protocollo noto o situazione di interesse ha un proprio
modulo – nella directory modules – che contiene un'implementazione specifica di gatherfunc.


Una volta invocata gatherfunc, si può ottenere la lista delle vulnerabilità rilevate invocando
getIdentifiedVulnerabilities sull'oggetto Session.
Ogni vulnerabilità è un oggetto Vulnerability da cui si possono ricavare le caratteristiche descritte.




2.2.2 Classi di test
Poiché 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 stessa
logica 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 server


I metodi setUp e tearDown implementano quelli definiti in unittest.TestCase2.


Dato che ogni protocollo ha una propria implementazione di gatherfunc, l'importazione di questa
funzione 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 un'implementazione 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
2.2.3 Oggetti mock
I test devono utilizzare degli oggetti mock che si sostituiscano agli oggetti Session e Vulnerability
utilizzati normalmente dal sistema di analisi di vulnerabilità.
I mock devono essere utilizzabili da gatherfunc nello stesso modo degli oggetti standard, ma
limitarsi a modellare gli aspetti dell'oggetto effettivamente di rilievo nei test.


La funzione gatherfunc utilizza un oggetto Session che descrive l'analisi di sicurezza in corso su un
certo endpoint. In particolare ne invoca alcuni metodi.
L'oggetto mock Session deve tenere traccia di:
    •   indirizzo IP dell'endpoint oggetto dell'analisi, di default 'localhost'
    •   parametro sd (utile per test futuri, qui non utilizzato), di default None
    •   una lista di oggetti Vulnerability corrispondenti alle vulnerabilità rilevate


e deve implementare i seguenti metodi con queste funzionalità:
    •   getScoutdict: restituisce il parametro sd (utile per test futuri)

    •   getVirtualHost: restituisce l'indirizzo IP dell'endpoint
    •   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 corretti


Per Vulnerability è sufficiente definire una classe con un attributo per ciascuna informazione che
caratterizza la vulnerabilità.




2.2.4 Lato server
La 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 interesse
utilizzare la classe SocketServer.TCPServer.
La classe inclusa nella libreria standard non fornisce garanzie sulle tempistiche in cui un indirizzo
lato server possa essere riutilizzato. Dopo la finalizzazione, il socket potrebbe restare in uno stato di
TIME_WAIT anche per qualche secondo, e restituire un errore alla richiesta di connessione al proprio
indirizzo4.
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
La politica di interazione con il client viene definita in un metodo handle di una classe specifica per
ciascun     simulatore      lato     server,    che      implementa    il    metodo       handle     di
SocketServer.BaseRequestHandler.


Per rendere rilevabili le vulnerabilità oggetto dei test, i simulatori devono effettuare le seguenti
interazioni 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 (l'indice 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 connessione




L'attivazione del simulatore lato server da parte di una classe di test deve comportare l'inizio di un
nuovo flusso parallelo di esecuzione, che possa comunicare con il client mentre quest'ultimo è in
esecuzione.
Una classe MultiThreadTCPServer corrisponde al mock lato server. La classe deve contenere un
metodo 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 e
avviare il thread di servizio specificando il gestore di richieste desiderato. MultiThreadTCPServer
deve 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 l'operazione di bind al metodo server_bind di ReuseTCPSocketServer,
un override del metodo di SocketServer.TCPServer in cui si imposta l'opzione del socket che ne
permette il riutilizzo anche se in stato di TIME_WAIT.


Al momento della creazione di un'istanza di MultiThreadTCPServer deve poter essere specificato un
attributo opzionale banner, per indicare una stringa che il server invia al client una volta aperta la
connessione.


In tutti i test in cui si verifica l'assenza di una certa vulnerabilità è sufficiente ricorrere a un request
handler lato server molto semplice, che si limiti a inviare un banner al client su una connessione
aperta e la chiuda. Si tratta in effetti di un mock di un server qualsiasi che non dia luogo alla
situazione 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
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
2.2.5 Schema consuntivo
Si propone di seguito un UML class diagram che evidenzia le interazioni tra le classi interessate dal
test per i sistemi NetBus2.
La classe di test Netbus2Test utilizza la funzione gatherfunc per la predisposizione del lato client e
per la sua connessione al lato server. gatherfunc si serve dell'oggetto mock Session per registrare le
vulnerabilità trovate.
Lato server viene creato un oggetto MultiThreadTCPServer, a cui viene passato il callable
Netbus2Simulator. All'invocazione del metodo spawnServerThread, l'oggetto istanzia
ReuseTCPSocketServer passando il simulatore come request handler, e lo attiva in un thread
separato. Ad ogni oggetto MultiThreadTCPServer corrisponde un oggetto ReuseTCPSocketServer e
viceversa.


Gli altri test presentano un'interazione analoga tra le classi, e si differenziano per la classe di test, il
modulo del sistema di analisi con l'implementazione di gatherfunc e il request handler lato server,
che hanno comunque strutture analoghe. Alcuni test utilizzano il mock FakeRequestHandler come
request 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
2.3 Test su moduli singoli

2.3.1 Contesto
Nella maggior parte dei casi una vulnerabilità interessa soltanto una certa tipologia di nodo, con
specifiche caratteristiche software o hardware.
Nell'analisi delle vulnerabilità che potrebbero interessare un endpoint remoto è fondamentale
ricavare il maggior numero di informazioni possibili riguardo all'endpoint.




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 caratteristiche
dell'endpoint prendendo in esame una qualche stringa che questo ha generato.


I test da sviluppare riguardano in particolare due directory – banners e webapplications – contenenti
dei file XML, uno per ogni contesto applicativo, che definiscono i legami tra questa stringa e le
caratteristiche dell'endpoint.
La directory banners è utilizzata nell'analisi delle prime risposte fornite dai server (dette banner), la
directory webapplications nell'analisi 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 dell'endpoint da individuare e
ogni elemento <info> corrisponde a una singola caratteristica.
Ogni elemento <software> ha un attributo name, suo identificativo, e un attributo re, che specifica
un'espressione regolare. Se la stringa da analizzare è conforme 6 all'espressione regolare, il sistema
di analisi riconosce nell'endpoint le caratteristiche riportate nell'elemento <software>
corrispondente.
La notazione è leggermente diversa nei file XML della directory webapplications, in cui si utilizza
un elemento <re> interno a <software> anziché un attributo di <software>.


A una stringa nota durante l'analisi di vulnerabilità sono applicate tutte le espressioni regolari
contenute negli elementi <software> del file XML afferente all'analisi in corso.
La stringa può essere conforme a nessuna, una o più espressioni regolari: ogni match individua un
insieme di certe caratteristiche dell'endpoint.



Ogni caratteristica può essere individuata in uno di questi due modi:

6 Per conformità si intende che la stringa deve generare un match con l'espressione regolare.
  Più precisamente, detta s la stringa, R l'espressione regolare e L(R) il linguaggio individuato da R , deve essere
  s 2 L(R)

                                                        18
•    essere nota staticamente: la sola conformità della stringa all'espressione regolare rende
         evidente un certo insieme di caratteristiche
    •    essere ricavata a run-time dalla stringa: l'espressione regolare comprende un gruppo
         capturing che individua una porzione di stringa con il valore della caratteristica
L'espressione regolare contiene pertanto un gruppo capturing intorno ad ogni caratteristica
individuata nel secondo modo, e ogni gruppo capturing corrisponde a un elemento <info>.


Gli elementi <info> hanno i seguenti attributi:
     •   key: l'identificativo 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 dell'espressione 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 dell'espressione regolare da cui
           ricavare tale valore



Al termine di questa fase dell'analisi di vulnerabilità le caratteristiche dell'endpoint che sono state
individuate vengono memorizzate in un dizionario8, con una chiave per ogni matching che la stringa
ha provocato sulle espressioni regolari racchiuse negli elementi <software> del file XML.
La chiave è il valore dell'attributo name dell'elemento <software>. Il valore corrispondente alla
chiave è a sua volta un dizionario, avente per chiavi gli attributi key degli elementi <info> e per
valori le informazioni corrispondenti.
Una singola caratteristica può avere uno oppure vari valori possibili, tra i quali non si è in grado di
scegliere a questo punto dell'analisi di vulnerabilità.
In questo caso il relativo valore contenuto nel dizionario è una lista comprensiva di tutte le
possibilità.




Esempio
Si riportano due elementi <software> estratti dai file XML di configurazione.
Sono evidenziati in rosso grassetto i gruppi capturing delle espressioni regolari e i corrispondenti
riferimenti 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 l'intera espressione regolare.
8 Inteso come struttura dati di Python.

                                                        19
<!-- 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 un
esempio 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 dell'elemento <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 senza
compromettere 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
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 degli
elementi <regexp>. Ogni elemento <vulnerability> ha un attributo id il cui valore identifica
univocamente la vulnerabilità; ogni elemento <regexp> ha un attributo value il cui valore è
un'espressione regolare.
Se il numero di versione che viene esaminato a run-time è conforme a una delle espressioni regolari
contenute in un elemento <vulnerability>, il sistema dichiara che quel numero di versione è affetto
dalla vulnerabilità avente come identificativo l'attributo id di quell'elemento <vulnerability>.


Tutte le espressioni regolari di questi file devono essere obbligatoriamente terminate da un
ancoraggio per la fine della stringa. In altre parole, l'espressione regolare deve sempre individuare il
termine del numero di versione. L'inizio del numero di versione può invece non essere compreso
nell'espressione regolare.9




Esempio


         <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
2.3.2 Tipi di test
I test da sviluppare possono essere suddivisi in due tipologie:
   •   test su singoli sistemi noti
   •   test di coerenza interna ai file XML

I primi devono verificare che per alcune configurazioni specifiche, corrispondenti a determinati
elementi di singoli file XML, il risultato dell'elaborazione da parte del sistema di analisi delle
vulnerabilità sia quello atteso.
I secondi hanno lo scopo di accertare che i file XML non contengano degli errori interni, che ne
compromettano la correttezza semantica.


È opportuno distinguere i test che analizzano i file XML contenuti nelle directory banners e
webapplications da quelli contenuti in versions_regexp, perché la struttura e il valore semantico dei
file sono molto diversi nei due casi.


Risultano quindi queste quattro tipologie di test:
                                      banners e webapplications                   versions_regexp
Su singoli sistemi                          test di categoria 1                  test di categoria 2
Di coerenza interna ai file XML             test di categoria 3                  test di categoria 4


Si 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, e
interessano 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 dizionario
consuntivo, 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 abbia
il valore previsto. Nel caso in cui questo valore sia una lista, è sufficiente verificare che ogni valore
della lista attesa sia presente nella lista risultante.


In questo modo si prova la correttezza di alcuni elementi <software> basandosi su
scoutUtils.BannerParser; essendo una funzione esterna, questa funzione ha già delle proprie unità di
test che ne avvalorano la correttezza intrinseca.
Questo approccio trascura il caso altamente improbabile che un errore su un elemento <software>

                                                     22
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 server
Apache 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 versione
la 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 numero
di versione e la lista di espressioni regolari corrispondenti a una certa vulnerabilità e ne indica
l'esistenza restituendo True o False.


Gli insiemi di numeri di versione oggetto delle asserzioni devono essere determinati a partire dalle
espressioni 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 questo
contesto):


        <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 un
numero 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 un'altra.
I range sono stati evidenziati in verde e i costrutti '.*' e l'indicatore di opzionalità in rosso.


                                                     23
Per ogni espressione regolare che individua un unico numero di versione, si include nel test
un'asserzione che verifichi la corrispondente vulnerabilità.
Per ogni range si verifica che siano vulnerabili le versioni corrispondenti agli estremi, ma non la
versione successiva all'estremo superiore se questo è minore di 9, né quella precedente all'estremo
inferiore se questo è maggiore di 0.
Per ogni parte opzionale e costrutto '.*' viene fatta almeno un'asserzione positiva che utilizzi
l'elemento 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 dall'estremo superiore del range; una utilizza il '.*'
   •   7.0: asserzione positiva per l'espressione 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 versione


Per 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 l'espressione regolare per il singolo numero di versione


A questa base di asserzioni possono essere aggiunte a piacere asserzioni positive o negative per altri
numeri di versione senza compromettere il valore del test.


In questo modo si prova la correttezza delle espressioni regolari, demandando alla funzione del
sistema di analisi di vulnerabilità la verifica della conformità tra il numero di versione e una delle
espressioni regolari che interessano una certa vulnerabilità. Anche in questo caso, la correttezza
intrinseca della funzione esterna è avvalorata da un'unità di test già disponibile e valgono
considerazioni analoghe a quelle del caso precedente.


Il test valida le espressioni regolari del file XML a fronte di esempi. Ciò è particolarmente utile nel
mantenimento del file: ogni modifica futura alle espressioni regolari dovrà essere accompagnata da
una modifica o un'estensione di questo test. Il test segnalerà eventuali modifiche accidentali.




                                                   24
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 dai
relativi 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 all'espressione regolare. Per
motivi di praticità d'uso, i commenti sono talvolta raggruppati in una sorta di indice, lontano dai
rispettivi 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
       l'immissione 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 volta


Non è possibile creare test che soddisfino completamente tali richieste; è possibile approssimare la
soluzione in modo soddisfacente con dei test che rendano queste caratteristiche ideali altamente
probabili.
Tra tutti i test, illustrati di seguito, quelli fondamentali verificano, per ogni file XML ed elemento
<software>, la correttezza sintattica dell'espressione regolare, e la coerenza tra espressione regolare,
commenti ed elementi <info> con type=”re”.




2.3.2.3.1 Test di correttezza sintattica
Un test sulla correttezza sintattica del file XML non è necessario, perché gli IDE utilizzati ne
effettuano già una validazione continua, e un eventuale errore verrebbe segnalato immediatamente
all'operatore.


Deve essere invece inclusa in un test la validazione sintattica delle espressioni regolari. Un
eventuale errore verrebbe segnalato soltanto nella fase successiva di analisi di vulnerabilità, che può
essere eseguita anche molto tempo dopo l'aggiornamento della base dati, e comunque in modo
indipendente.




                                                  25
2.3.2.3.2 Test di coerenza tra espressione regolare e commenti
Nell'introduzione di nuovi elementi <software> nel file XML, è possibile che l'operatore dimentichi
di inserire i commenti corrispondenti, o che non aggiorni correttamente un commento a fronte di
una modifica dell'espressione regolare, provocando un disallineamento che non è segnalato neanche
durante l'analisi di vulnerabilità.
Considerando le dimensioni del file e la possibile distanza tra l'elemento <software> e il relativo
commento, 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 che
verifichi, per ogni file XML, che non vi siano espressioni regolari prive di commenti
corrispondenti.




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 l'assenza
di 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 utilizza
un approccio diverso.
Come confermato dal test descritto precedentemente, in ciascun file ogni espressione regolare ha un
commento corrispondente; quindi il test è costruibile passando ogni commento alla funzione del
sistema di analisi di vulnerabilità preposta all'esame dei banner.
La funzione ricerca, nel file specificato, dei match con le espressioni regolari degli elementi
<software> e aggiorna di conseguenza il dizionario consuntivo dell'analisi di vulnerabilità.
Il test fallisce se si verifica un'eccezione, individuando in questo modo i disallineamenti tra i gruppi
capturing dell'espressione regolare e gli elementi <info> con type=”re” per i commenti del file.




2.3.2.3.5 Test per ripetizioni
In alcuni casi, la ripetizione di una porzione di file XML causa un errore di sintassi, o relativa alle
regole XML o a quelle della base di conoscenza del sistema.
Entrambi questi casi non sono interessanti, per le ragioni già discusse: il primo è rilevato
immediatamente dal validatore a bordo dell'IDE, il secondo è difficilmente producibile da un
operatore, e viene comunque segnalato nell'analisi di vulnerabilità.


Rimane aperta la possibilità di ripetizioni di elementi <info> all'interno di elementi <software>, o di
elementi <software> all'interno del file XML. Nei file di webapplications, la ripetizione di elementi



                                                  26
<re>10 all'interno di <software> provocherebbe invece una trasgressione della sintassi standard, e
rientra nella casistica precedente.
La ripetizione di elementi <info> non produce errori e non è necessario predisporre dei test che ne
verifichino l'assenza.
Al contrario, è fondamentale garantire che ogni elemento <software> sia unico all'interno del file,
se non altro per ragioni di manutenibilità. Se vi fossero due ripetizioni di uno stesso elemento,
l'operatore potrebbe modificare una delle due copie senza modificare la seconda, di cui potrebbe
perfino ignorarne l'esistenza.
Poiché ogni elemento <software> è in corrispondenza uno a uno con l'espressione regolare al suo
interno, è sufficiente testare l'unicità di ogni espressione regolare all'interno di ciascun file.




2.3.2.3.6 Test sugli elementi <info> sospetti
Un caso di alterazione particolarmente insidioso per la sua difficoltà di rilevazione manuale è quello
in cui l'attributo 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. Si
dichiara sospetto un elemento <info> per cui sussistono le condizioni seguenti:
    •    type vale ”str”
    •    value è un numero naturale piccolo

    •    l'elemento non è incluso in una lista di <info> da escludere a priori


Gli elementi <software> della base di conoscenza del sistema hanno espressioni regolari che
tipicamente comprendono due o tre elementi <info>, talvolta quattro e solo raramente un numero
maggiore.
Poiché in questo tipo di casi di errore il value si riferisce a un gruppo di un'espressione regolare, è
ragionevole aspettarsi che si tratti di un numero naturale piccolo. In prima approssimazione, una sua
limitazione superiore può essere costituita dal numero di gruppi capturing dell'espressione regolare.
È conveniente introdurre una certa tolleranza a questa valutazione, per escludere quei rari casi di
aggiornamento errato in cui si riduce il numero di gruppi dell'espressione regolare senza eliminare
gli 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é impossibile
che l'operatore elimini ben dieci gruppi capturing dall'espressione regolare senza notare dieci
elementi <info> di troppo.


Prendendo in considerazione quello che nella pratica è molto frequente, un elemento <info> che
abbia una delle seguenti caratteristiche non è mai considerato sospetto:


10 Si utilizzano elementi <re> soltanto nei file di webapplications. In quelli di banners l'espressione regolare è contenuta
   nell'attributo re di <software>.

                                                            27
•   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 key


Queste due regole escludono dai casi sospetti i numeri di service pack (qui indicato con “sp”) e la
release 7 di Windows.


Si predispone un test che, per ogni value di un elemento <info> sospetto, verifica che tale value
compaia nell'espressione regolare dell'elemento <software> in cui è contenuto l'elemento <info>.
In caso di fallimento, questo test segnala una situazione solo potenzialmente errata.




2.3.2.3.7 Riepilogo dei test della categoria 3
Ognuno dei seguenti test si sviluppa in una versione per banners e una per webapplications; tutti i
test 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
        nell'espressione regolare
    •   ogni espressione regolare deve essere unica
    •   ogni elemento <info> sospetto deve avere un value che compare nell'espressione regolare
        corrispondente




2.3.2.4 Test di coerenza interna sui file di versions_regexp (categoria 4)
L'obiettivo di questi test è quello di rendere improbabili eventuali errori umani nell'immissione delle
espressioni regolari utilizzate per filtrare i numeri di versione.


Innanzitutto è opportuno predisporre due test per verificare rispettivamente la correttezza sintattica
delle espressioni regolari e la conformità rispetto alla regola di terminazione con l'ancoraggio per la
fine della stringa.



11 Con “corrispondente” si intende che deve trovarsi nello stesso elemento <software>.

                                                         28
I numeri di versione contengono spesso dei punti, che nell'espressione regolare vengono individuati
da '.'.
Se dovesse mancare l'escaping del carattere speciale '.', l'espressione regolare presenterebbe un
errore che il sistema di analisi di vulnerabilità non potrebbe individuare automaticamente. Infatti
l'espressione regolare risulterebbe:
   •   sintatticamente corretta
   •   più generale di quella corretta
rendendo l'errore non individuabile né dal test precedente né da alcun test puntuale sui matching
attesi.
È opportuno testare esplicitamente la presenza del carattere di escape prima di ogni punto contenuto
in un'espressione regolare. Vista la frequenza dello schema '.*' nella base di conoscenza, il test deve
permettere 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 evidente
che i casi individuati sono errori soltanto potenziali.


Riassumendo, i test da realizzare devono verificare:
   •   correttezza sintattica delle espressioni regolari
   •   presenza nelle espressioni regolari dell'ancoraggio per il termine della stringa
   •   presenza nelle espressioni regolari dell'escaping per ogni '.', a meno che questo non preceda
       un '*'




2.3.3 Organizzazione dei test
L'aspetto più complesso dei test descritti è il parsing XML. I test della categoria 1 possono
demandarlo alla funzione scoutUtils.BannerParser, per gli altri serve un'implementazione 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 dell'analisi di vulnerabilità è un dizionario con chiavi corrispondenti a
stringhe singole o a liste, è opportuno svincolare la logica di test da questa distinzione.
Si sceglie quindi di definire BaseTestCaseForBanners con un metodo assert_inStrOrList, una
versione specializzata di unittest.TestCase. Tutte le classi contenenti i test ereditano da
BaseTestCaseForBanners.




                                                   29
Figura 4: UML class diagram per i test della categoria 1




2.3.3.2 Parsing XML
Per il parsing dell'XML si sceglie di usare un approccio di tipo SAX 12, per il quale è disponibile un
modulo della Python Standard Library.
Si tratta di implementare l'interfaccia13 xml.sax.ContentHandler, e in particolare le callback
richiamate all'individuazione di un tag di inzio di un elemento, di fine di un elemento e di caratteri
interni agli elementi.


Una prima implementazione dell'interfaccia è costituita da BaseReValidatorXmlHandler, che correda
il parser di un attributo lista per salvare le espressioni regolari trovate.
Viene implementato il metodo __init__, per l'inizializzazione della lista, e reset, per ripristinare la
situazione iniziale in cui la lista è vuota.


Le specializzazioni successive sono invece distinte tra classi per banners e webapplications e classi
per 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 l'istruzione pass.
   Visto che la distinzione tra classe e interfaccia riguarda più l'ereditarietà che non l'entità in sé, nei diagrammi UML
   delle classi si preferisce utilizzare comunque la freccia tratteggiata verso la classe base, ma omettendo l'esplicito
   prefisso <<interface>> al nome della classe base.

                                                           30
•    numero di gruppi capturing di ogni espressione regolare
    •    espressioni regolari che compaiono più di una volta nel file
    •    valori sospetti dell'attributo value di <info>, associati all'espressione regolare corrispondente


Dovranno perciò essere ridefiniti i metodi __init__ e reset per inizializzare e reinizializzare le
relative strutture dati.


Deve essere introdotta un'ulteriore specializzazione per distinguere il parsing dei file in banners da
quelli in webapplications, perché nei due contesti le espressioni regolari sono specificate in
posizioni diverse dell'XML.
Nei file di banners l'espressione regolare è riportata come valore di un attributo re, in quelli di
webapplications è 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 variabili
riferite all'ultima 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 fatto
che le espressioni regolari non si trovino all'interno di tag rende necessaria l'implementazione del
metodo characters14 e l'introduzione di variabili aggiuntive:
    •    flag per indicare se è in corso il parsing di un'espressione regolare
    •    buffer per l'espressione regolare


Il flag viene inizializzato prima che il parser inizi l'analisi del file XML a un valore False. Ciò
richiede l'override dei metodo __init__ e reset.
Poiché il flag è definito durante tutto il parsing, il metodo characters può bufferizzare l'espressione
regolare solo nel caso in cui il valore del flag è True.



Nel caso dei numeri di versione, la sola informazione da salvare sono le espressioni regolari
associate a ciascuna vulnerabilità.
La classe VersionREValidatorXmlHandler deve comprendere un dizionario di espressioni regolari –
dello stesso livello degli attributi di RegexTestREValidatorXmlHandler – e alcune variabili utili nel
corso     del     parsing,     analoghe     a    quelle    di   BannerREValidatorXmlHandler         e
WebappREValidatorXmlHandler.
In particolare servono:
    •    un flag per indicare se il parser sta analizzando l'interno di un elemento <vulnerability>

14 Callback invocata alla ricezione di caratteri di dati, ossia di stringhe contenute all'interno di elementi XML.

                                                            31
•   un buffer per l'identificativo della vulnerabilità corrente
   •   un buffer per le espressioni regolari associate alla vulnerabilità corrente


I metodi di parsing da implementare sono startElement ed endElement; non serve implementare
characters perché in questo tipo di file XML tutti i dati utili sono contenuti negli attributi all'interno
dei tag.
Il buffer per le espressioni regolari associate alla vulnerabilità corrente deve essere inizializzato
prima che inizi il parsing, in modo che alla lettura di </vulnerability> questo sia effettivamente
pronto per l'uso.




                     Figura 5: UML class diagram per le classi di parsing XML




                                                   32
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 inclusi
come attributi di classe nelle classi di test.
Si sceglie di inserire il codice che attiva il parsing nel metodo setUpClass, ereditato da
unittest.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 parsing
di ciascun file.
Si sceglie di utilizzare un parser per banners e uno per webapplications; ognuno deve analizzare
ciascun 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 parser


La classe deve comprendere varie strutture dati, una per ogni informazione di interesse, in cui sono
compresi tutti i dati derivanti dal parsing.
Ogni struttura dati deve organizzare queste informazioni raggruppandole a seconda del file di
provenienza.


Si sceglie di utilizzare due strutture dati separate per le informazioni dei file di banners e di
webapplications, perché si riferiscono a due contesti operativi diversi.
Analogamente, si sceglie di rendere specifici per l'una o l'altra directory anche i metodi di test. In
questo modo un test per una certa directory contiene asserzioni soltanto su una struttura dati riferita
a quella stessa directory, e la suddivisione tra i moduli banners e webapplications del sistema di
analisi 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 dei
test 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
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 utilizzano le informazioni
contenute nei file XML.
Il parsing viene richiamato, in modo del tutto analogo al caso precedente, da una classe base
TestCaseForVersions estesa da VersionRegexpTest, che comprende i test di coerenza interna ai file
XML (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 modulo
singolo 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 un'unità di test di categoria 2 su un sistema
diverso 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
2.3.3.5 Schema consuntivo per le categorie 2, 3 e 4
I test delle categorie 2, 3 e 4 condividono l'infrastruttura 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
3 Realizzazione

3.1 Implementazione

3.1.1 Codifica test-driven

3.1.1.1 Logica di controllo
La metodologia di sviluppo test-driven si basa sulla messa a punto di una logica di controllo – le
unità di test – come prima fase dell'implementazione, prima ancora di procedere alla scrittura del
codice.
Come strategia di sviluppo, il sorgente deve essere implementato verificandone continuamente la
correttezza mediante il codice di controllo. Dopo ogni nuovo inserimento nel sorgente viene
eseguito il codice di test, in modo da avere un riscontro continuo sulla correttezza
dell'implementazione.
Il principio di base è quello di individuare eventuali errori il prima possibile, evidenziandone la
causa.


Il sorgente da sviluppare è costituito dalle unità di test, da affiancare a risorse preesistenti, costituite
dai 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 l'implementazione dei test.
Con questa modalità di sviluppo i test vengono validati dai file di configurazione, che possono a
loro volta contenere errori: si può procedere in questo modo solo nei casi in cui gli errori nei file di
configurazione sono indipendenti da quelli dei test da sviluppare. In altre parole, i test devono
individuare 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à risulta
banalmente vera. Per ogni aspetto più complesso dei test è necessario predisporre un'unità di test di
secondo livello specifica. Questo sarà l'approccio tipico nell'implementazione del generatore di
espressioni regolari.




3.1.1.2 Strategia di sviluppo dei test
Conformemente alla logica di controllo descritta, si adottano le regole di codifica seguenti.
Il primo test viene effettuato con una prima stesura dell'unità di test, in cui si riportano gli import
necessari al file e uno stub della classe di test, che estende unittest.TestCase e viene implementata
con la sola istruzione pass. In questo modo si possono rilevare eventuali errori causati dagli import.


Si procede quindi con l'introduzione di un metodo di test, implementato con l'istruzione:
       self.fail('UNIMPLEMENTED')
Il relativo test accerta che nose rilevi correttamente il test e ne segnali l'insuccesso. A questo punto

                                                    37
si rileva un eventuale errore nel nome del test16.


È utile mantenere questa riga come ultima istruzione per tutta la fase di implementazione del
metodo di test, e procedere inserendo il codice prima.
Siccome nose segnala il primo punto di fallimento di un test e ne interrompe l'esecuzione, tutti gli
eventuali errori imputabili al codice di nuova introduzione hanno la precedenza sul fallimento
causato dall'istruzione finale.
In questo modo si ha la certezza che nessun test di cui non è stata terminata l'implementazione
possa essere dimenticato dal programmatore: fino al momento di rimozione dell'istruzione di
fallimento il test continuerà ad essere segnalato da nose come fallimentare.


Sia nell'unità di test che nel sorgente del software è conveniente utilizzare l'istruzione pass come
segnaposto per istruzioni non implementate, in modo da rendere evidente il punto in cui proseguire
con l'implementazione.
Per annotare queste parti con indicazioni su come proseguire, o come modificare il sorgente, si
ricorre 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 e
permettono di creare delle liste delle azioni ancora da fare.



È preferibile che un'unità di test effettui delle verifiche eterogenee sulla logica da testare, cercando
di 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 assertivo
Ogni metodo di test è fondato su una o più asserzioni, che costituiscono le istruzioni di verifica di
correttezza.
unittest.TestCase mette a disposizione vari metodi per effettuare asserzioni, tra cui si sceglie di
utilizzarne un numero molto ristretto, in modo da rendere più evidente possibile la finalità
dell'asserzione:
    •    assertTrue: il metodo utilizzato più comunemente
    •    assertFalse: utilizzato quando l'aspetto più importante da testare è la falsità dell'argomento

    •    fail: utilizzato durante la fase di sviluppo dei test
    •    assertRaises: utilizzato per segnalare che un'istruzione solleva un'eccezione specificata


16 nose impone che sorgenti, package, directory di test siano conformi all'espressione 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
Si preferisce scrivere esplicitamente il test di uguaglianza con l'operatore == anziché adottare il
metodo assertEquals.
Dato che in caso di test fallimentare o errato nose riporta il codice della riga di errore e un eventuale
messaggio, si aggiunge un messaggio di spiegazione se la riga di asserzione non rende evidente la
natura dell'errore.




3.1.2 Test per errori potenziali
Se il test per i valori <info> sospetti o quello di coerenza interna dei file XML di versions_regexp
rilevano una situazione anomala, non si può avere la certezza che si tratti di un errore. L'output deve
essere un messaggio che segnali il caso potenzialmente errato.
Anziché ricorrere ad asserzioni, si utilizzano dei messaggi nel log di nose nose.result, mappato da
un attributo logger della classe di test.
Per i valori sospetti, ad esempio, un messaggio di livello logging.WARNING viene generato se
l'elemento <info> sospetto ha un value che non compare nell'espressione regolare corrispondente e
un messaggio di livello logging.INFO riassume il numero di casi totali trovati.
Il comportamento di default di nose prevede di includere nell'output i messaggi indirizzati ai logger
gestiti dal framework.
Utilizzare un'asserzione sarebbe inopportuno anche perché i test si interromperebbero al primo caso
anomalo 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
3.1.3 Organizzazione dei sorgenti
I file sviluppati nel corso del progetto si collocano nella directory testunits del sistema di analisi
delle vulnerabilità.
L'organizzazione della gerarchia interna a questa directory è stata definita tenendo conto delle
possibili estensioni future:
    •    tests: per i test, le loro librerie e le estensioni future
    •    extlib: per le librerie necessarie all'esecuzione dei test (nose)

    •    oldtests: per vecchi test


La 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 all'interno di unit_tests sono raggruppati a seconda del modulo del sistema di analisi di
vulnerabilità a cui si riferiscono. All'interno 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_regexp




3.1.4 Esecutore dei test
All'interno della directory testunits/tests si predispone uno script in Python che effettua la ricerca e
il lancio dei test nelle subdirectory.
Allo script possono essere passati gli argomenti standard di nose17, con i quali si possono ad
esempio 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
3.2 Utilizzo
Per l'esecuzione dei test si invoca dalla directory testunits/tests del sistema di analisi delle
vulnerabilità l'interprete Python, passando come argomento lo script esecutore main.py.
Di default, lo script avvia la ricerca e l'esecuzione di tutti i test presenti nella directory; utilizzando
dei 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 l'esito:
    •   '.' per un test con esito positivo
    •   'F' per un test con esito negativo (asserzione disattesa)

    •   'E' per un test con errori
Per i test con esito negativo o con errori viene generata una sezione con l'indicazione della riga che
ha 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 esecuzione
complessivo e l'esito della campagna di test, con il numero di test fallimentari o con errori se questi
sono presenti.




Esempi


Per eseguire i test di verifica dei file XML contenuti in banners e webapplications si procede in
questo modo:




In questo esempio ci si serve della variabile python, valorizzata con il percorso dell'interprete.
A main.py è passata come argomento la directory tests/bannersAndWebapps, in cui ricercare ed
eseguire i test.
Seguono alcuni caratteri punto, uno per ogni test eseguito, e il messaggio indirizzato al log
nose.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
il messaggio finale 'OK' segnala che tutti i test della campagna hanno avuto esito positivo.


In questo secondo esempio si eseguono i test contenuti nell'unità di test test_transformPatterns, per
la funzione transformPatterns.
In questo caso la campagna di test è lanciata con il parametro -v (verbose). Per ogni test nose genera
un output più prolisso, che comprende nome e percorso del test, o stringa di documentazione, ed
esito.




Si mostra infine un esempio più significativo, non incluso nel progetto, con dei test fallimentari:




                                                  42
PARTE SECONDA

                        Generazione di espressioni regolari


4 Analisi

4.1 Descrizione del problema
La seconda parte di questa tesi prende spunto da un problema riscontrato dopo aver messo a punto i
test 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 cruciale
nell'analisi degli endpoint remoti, spesso presentavano delle imprecisioni dovute ad errori umani.
Molti errori tipici sono stati individuati dai test sviluppati nella prima parte; tuttavia nessuna
campagna di test può garantire la totale assenza di errori umani, perché molti possibili errori non
dipendono soltanto dalla coerenza con gli esempi di banner (i commenti del file XML) o con gli
elementi <info>.


Si sviluppa uno strumento di generazione automatica che prenda in input degli esempi di banner18 e
fornisca delle possibili espressioni regolari conformi a tutti i banner di esempio. In altre parole, ogni
espressione regolare generata deve individuare un linguaggio in cui devono essere contenute tutte le
stringhe banner di input.
Lo strumento vuole essere innanzitutto un ausilio all'operatore umano, del quale si richiede
comunque un intervento finale di scelta dell'espressione regolare più adatta, o di aggiunta di
caratteristiche note che non risultino evidenti dagli esempi di input. Inoltre, in espansioni future
potrà essere utilizzato per costruire nuovi test.


Come obiettivo generale, le espressioni regolari in output devono riflettere il più possibile le
caratteristiche delle stringhe banner.
Questa linea guida deve essere precisata nel corso della fase di analisi, in cui si definiscono le
caratteristiche esatte che devono avere le espressioni regolari soluzioni del problema, anche in
relazione 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
4.2 Caratteristiche delle espressioni regolari dei file XML
Osservando le espressioni regolari riportate nei file XML di banners e webapplications si nota che
nella quasi totalità dei casi esse sono composte da una struttura scheletro di parole riportate
letteralmente, entro la quale si inseriscono delle parti variabili, come parti opzionali, insiemi di
caratteri validi, parti ripetute.
Un'espressione regolare con questa struttura individua delle stringhe in cui sono presenti certamente
delle sottostringhe comuni, che compaiono in un ordine fisso.
Si nota inoltre che le parti variabili non compaiono quasi mai all'interno 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 casi
incluse 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, l'underscore 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 all'inizio o alla fine della stringa.


Ovviamente, le espressioni regolari includono dei gruppi capturing intorno alle strutture di interesse
corrispondenti agli elementi <info>, perlopiù intorno a parti variabili.
Questi costrutti conferiscono a porzioni di espressione regolare un valore semantico; dal punto di
vista della corrispondenza tra espressione regolare e stringhe banner di esempio sono del tutto
irrilevanti.




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
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
4.3 Definizioni
Si elencano una serie di definizioni in riferimento all'insieme delle stringhe banner di esempio, che
costituiscono l'input del generatore di espressioni regolari.


In ogni stringa è individuabile uno scheletro di sottostringhe comuni a tutte le stringhe dell'insieme,
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
       stringa


Vista 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 ct


Si 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 pattern


Per 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 sequenza


Inoltre 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
Si definisce patternizzazione l'operazione in cui si individua la sequenza di pattern corrispondente a
una stringa.
Poiché ogni pattern di tipo D è anche di tipo W, questa operazione deve ricercare i pattern di tipo D
prima di quelli di tipo W.
Dal risultato è facilmente costruibile un'espressione regolare composta da pattern, conforme alla
stringa originaria.




Esempio
Stringa:                       'Welcome to Pure-FTPd 1.0.14'
Sequenza di tipi di pattern:   WSWSWPWSDPDPD
Espressione regolare:          '^w+s+w+s+w+[^sw]+w+s+d+[^sw]+d+[^sw]+d+$'




Come convenzione di comodo si immaginerà che ogni stringa dell'insieme di banner sia disposta su
una propria riga; si definiscono allora i concetti di:
   •   elaborazione orizzontale: interessa una singola stringa e considera tutti i suoi element
   •   elaborazione verticale: interessa la corrispondenza di un singolo element in tutte le stringhe




4.4 Definizione dei tipi di soluzione
L'output della generazione deve essere un insieme di tipologie fisse di espressioni regolari, perlopiù
a livelli successivi di specificità.


Tutti i tipi di soluzioni devono considerare le stringhe banner fornite in input nella loro interezza, e
generare delle espressioni regolari con gli ancoraggi per individuare l'inizio e la fine delle stringhe.
Un'espressione regolare E priva di ancoraggi è logicamente equivalente a un'espressione regolare
Ea, ottenuta inserendo in E gli ancoraggi e separandoli con '.*'.




                                                  47
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à

More Related Content

What's hot

Progetto Tecnologia Meccanica II
Progetto Tecnologia Meccanica IIProgetto Tecnologia Meccanica II
Progetto Tecnologia Meccanica IIPieroEro
 
Pattern Recognition Lecture Notes
Pattern Recognition Lecture NotesPattern Recognition Lecture Notes
Pattern Recognition Lecture NotesRobertoMelfi
 
Interfaccia utente basata su eye-tracking per sistemi di controllo ambientale
Interfaccia utente basata su eye-tracking per sistemi di controllo ambientaleInterfaccia utente basata su eye-tracking per sistemi di controllo ambientale
Interfaccia utente basata su eye-tracking per sistemi di controllo ambientaleLuigi De Russis
 
Joseki : un server per interrogare risorse RDF attraverso un interfaccia Web
Joseki : un server per interrogare risorse RDF attraverso un interfaccia WebJoseki : un server per interrogare risorse RDF attraverso un interfaccia Web
Joseki : un server per interrogare risorse RDF attraverso un interfaccia WebCyclope86
 
24546913 progettazione-e-implementazione-del-sistema-di-controllo-per-un-pend...
24546913 progettazione-e-implementazione-del-sistema-di-controllo-per-un-pend...24546913 progettazione-e-implementazione-del-sistema-di-controllo-per-un-pend...
24546913 progettazione-e-implementazione-del-sistema-di-controllo-per-un-pend...maaske
 
Monitoraggio di applicazioni software mediante modelli di Markov
Monitoraggio di applicazioni software mediante modelli di MarkovMonitoraggio di applicazioni software mediante modelli di Markov
Monitoraggio di applicazioni software mediante modelli di Markovrkjp
 
Libro "La valutazione dei rischi di incendio" L. Fiorentini (TECSA S.p.A.), L...
Libro "La valutazione dei rischi di incendio" L. Fiorentini (TECSA S.p.A.), L...Libro "La valutazione dei rischi di incendio" L. Fiorentini (TECSA S.p.A.), L...
Libro "La valutazione dei rischi di incendio" L. Fiorentini (TECSA S.p.A.), L...lucafiore1
 
Tesi Laurea Sergio Taddia
Tesi Laurea Sergio TaddiaTesi Laurea Sergio Taddia
Tesi Laurea Sergio TaddiaSergio Taddia
 
Abstract Domenico Brigante
Abstract   Domenico BriganteAbstract   Domenico Brigante
Abstract Domenico Brigantedox82
 
Apprendimento di movimenti della testa tramite Hidden Markov Model
Apprendimento di movimenti della testa tramite Hidden Markov ModelApprendimento di movimenti della testa tramite Hidden Markov Model
Apprendimento di movimenti della testa tramite Hidden Markov ModelFausto Intilla
 
Sviluppo e confronto di tecniche di stima della traiettoria di sensori 3D
Sviluppo e confronto di tecniche di stima della traiettoria di sensori 3D Sviluppo e confronto di tecniche di stima della traiettoria di sensori 3D
Sviluppo e confronto di tecniche di stima della traiettoria di sensori 3D Andrea Bidinost
 
Learning of non-homogeneous Continuous Times Bayesian Networks Thesis
Learning of non-homogeneous Continuous Times Bayesian Networks ThesisLearning of non-homogeneous Continuous Times Bayesian Networks Thesis
Learning of non-homogeneous Continuous Times Bayesian Networks ThesisGuido Colangiuli
 
Orchestrazione delle risorse umane nel BPM
Orchestrazione delle risorse umane nel BPMOrchestrazione delle risorse umane nel BPM
Orchestrazione delle risorse umane nel BPMMichele Filannino
 
Profilazione utente in ambienti virtualizzati
Profilazione utente in ambienti virtualizzatiProfilazione utente in ambienti virtualizzati
Profilazione utente in ambienti virtualizzatiPietro Corona
 
I promessi sposi 3.0 Mobile User Experience & Usability nel settore dei beni...
I promessi sposi 3.0  Mobile User Experience & Usability nel settore dei beni...I promessi sposi 3.0  Mobile User Experience & Usability nel settore dei beni...
I promessi sposi 3.0 Mobile User Experience & Usability nel settore dei beni...RiccardoPietra
 

What's hot (20)

A.Dionisi Thesis
A.Dionisi ThesisA.Dionisi Thesis
A.Dionisi Thesis
 
Monitoraggio di rete con nagios
Monitoraggio di rete con nagiosMonitoraggio di rete con nagios
Monitoraggio di rete con nagios
 
Progetto Tecnologia Meccanica II
Progetto Tecnologia Meccanica IIProgetto Tecnologia Meccanica II
Progetto Tecnologia Meccanica II
 
Pattern Recognition Lecture Notes
Pattern Recognition Lecture NotesPattern Recognition Lecture Notes
Pattern Recognition Lecture Notes
 
Tesi Tamiazzo09
Tesi Tamiazzo09Tesi Tamiazzo09
Tesi Tamiazzo09
 
Interfaccia utente basata su eye-tracking per sistemi di controllo ambientale
Interfaccia utente basata su eye-tracking per sistemi di controllo ambientaleInterfaccia utente basata su eye-tracking per sistemi di controllo ambientale
Interfaccia utente basata su eye-tracking per sistemi di controllo ambientale
 
Tesi peiretti
Tesi peirettiTesi peiretti
Tesi peiretti
 
Joseki : un server per interrogare risorse RDF attraverso un interfaccia Web
Joseki : un server per interrogare risorse RDF attraverso un interfaccia WebJoseki : un server per interrogare risorse RDF attraverso un interfaccia Web
Joseki : un server per interrogare risorse RDF attraverso un interfaccia Web
 
24546913 progettazione-e-implementazione-del-sistema-di-controllo-per-un-pend...
24546913 progettazione-e-implementazione-del-sistema-di-controllo-per-un-pend...24546913 progettazione-e-implementazione-del-sistema-di-controllo-per-un-pend...
24546913 progettazione-e-implementazione-del-sistema-di-controllo-per-un-pend...
 
Monitoraggio di applicazioni software mediante modelli di Markov
Monitoraggio di applicazioni software mediante modelli di MarkovMonitoraggio di applicazioni software mediante modelli di Markov
Monitoraggio di applicazioni software mediante modelli di Markov
 
Libro "La valutazione dei rischi di incendio" L. Fiorentini (TECSA S.p.A.), L...
Libro "La valutazione dei rischi di incendio" L. Fiorentini (TECSA S.p.A.), L...Libro "La valutazione dei rischi di incendio" L. Fiorentini (TECSA S.p.A.), L...
Libro "La valutazione dei rischi di incendio" L. Fiorentini (TECSA S.p.A.), L...
 
Tesi Laurea Sergio Taddia
Tesi Laurea Sergio TaddiaTesi Laurea Sergio Taddia
Tesi Laurea Sergio Taddia
 
Abstract Domenico Brigante
Abstract   Domenico BriganteAbstract   Domenico Brigante
Abstract Domenico Brigante
 
PSA - Azzurra Orlando
PSA - Azzurra OrlandoPSA - Azzurra Orlando
PSA - Azzurra Orlando
 
Apprendimento di movimenti della testa tramite Hidden Markov Model
Apprendimento di movimenti della testa tramite Hidden Markov ModelApprendimento di movimenti della testa tramite Hidden Markov Model
Apprendimento di movimenti della testa tramite Hidden Markov Model
 
Sviluppo e confronto di tecniche di stima della traiettoria di sensori 3D
Sviluppo e confronto di tecniche di stima della traiettoria di sensori 3D Sviluppo e confronto di tecniche di stima della traiettoria di sensori 3D
Sviluppo e confronto di tecniche di stima della traiettoria di sensori 3D
 
Learning of non-homogeneous Continuous Times Bayesian Networks Thesis
Learning of non-homogeneous Continuous Times Bayesian Networks ThesisLearning of non-homogeneous Continuous Times Bayesian Networks Thesis
Learning of non-homogeneous Continuous Times Bayesian Networks Thesis
 
Orchestrazione delle risorse umane nel BPM
Orchestrazione delle risorse umane nel BPMOrchestrazione delle risorse umane nel BPM
Orchestrazione delle risorse umane nel BPM
 
Profilazione utente in ambienti virtualizzati
Profilazione utente in ambienti virtualizzatiProfilazione utente in ambienti virtualizzati
Profilazione utente in ambienti virtualizzati
 
I promessi sposi 3.0 Mobile User Experience & Usability nel settore dei beni...
I promessi sposi 3.0  Mobile User Experience & Usability nel settore dei beni...I promessi sposi 3.0  Mobile User Experience & Usability nel settore dei beni...
I promessi sposi 3.0 Mobile User Experience & Usability nel settore dei beni...
 

Viewers also liked

Slide - Tecniche di Test-driven development in ambito sicurezza informatica e...
Slide - Tecniche di Test-driven development in ambito sicurezza informatica e...Slide - Tecniche di Test-driven development in ambito sicurezza informatica e...
Slide - Tecniche di Test-driven development in ambito sicurezza informatica e...fcecutti
 
Presentazione Laurea triennale - X509 e PGP
Presentazione Laurea triennale - X509 e PGPPresentazione Laurea triennale - X509 e PGP
Presentazione Laurea triennale - X509 e PGPFabio Pustetto
 
Da Cesare ai quanti - Workshop@UNINA - NaLUG - Crittografia - polialfabetici ...
Da Cesare ai quanti - Workshop@UNINA - NaLUG - Crittografia - polialfabetici ...Da Cesare ai quanti - Workshop@UNINA - NaLUG - Crittografia - polialfabetici ...
Da Cesare ai quanti - Workshop@UNINA - NaLUG - Crittografia - polialfabetici ...Mario Rossano
 
VULNERABILITA’ DELLE COSTRUZIONI AI FENOMENI GEOLOGICI E IDROGEOLOGICI Parte I
VULNERABILITA’ DELLE COSTRUZIONI AI FENOMENI GEOLOGICI E IDROGEOLOGICI Parte IVULNERABILITA’ DELLE COSTRUZIONI AI FENOMENI GEOLOGICI E IDROGEOLOGICI Parte I
VULNERABILITA’ DELLE COSTRUZIONI AI FENOMENI GEOLOGICI E IDROGEOLOGICI Parte IStroNGER2012
 
Proteggere i dispositivi mobili - ISACA Venice - festival ICT 2015
Proteggere i dispositivi mobili - ISACA Venice - festival ICT 2015Proteggere i dispositivi mobili - ISACA Venice - festival ICT 2015
Proteggere i dispositivi mobili - ISACA Venice - festival ICT 2015festival ICT 2016
 
Lungiswa Ntombini (Detailed resume)
Lungiswa Ntombini (Detailed resume)Lungiswa Ntombini (Detailed resume)
Lungiswa Ntombini (Detailed resume)lungiswa ntombini
 
Certificato laurea con esami
Certificato laurea con esamiCertificato laurea con esami
Certificato laurea con esamimarco bonifazi
 
Cybersecurity e Vulnerabilita' dei sistemi SCADA
Cybersecurity e Vulnerabilita' dei sistemi SCADACybersecurity e Vulnerabilita' dei sistemi SCADA
Cybersecurity e Vulnerabilita' dei sistemi SCADAiDIALOGHI
 
Presentazione Tesi di Laurea sulla Sicurezza delle Reti Informatiche: Le vuln...
Presentazione Tesi di Laurea sulla Sicurezza delle Reti Informatiche: Le vuln...Presentazione Tesi di Laurea sulla Sicurezza delle Reti Informatiche: Le vuln...
Presentazione Tesi di Laurea sulla Sicurezza delle Reti Informatiche: Le vuln...Riccardo Melioli
 
Tesi di Laurea sulla Sicurezza delle Reti Informatiche: Le vulnerabilità
Tesi di Laurea sulla Sicurezza delle Reti Informatiche: Le vulnerabilitàTesi di Laurea sulla Sicurezza delle Reti Informatiche: Le vulnerabilità
Tesi di Laurea sulla Sicurezza delle Reti Informatiche: Le vulnerabilitàRiccardo Melioli
 
Cosa Vuol Dire Sicurezza Informatica
Cosa Vuol Dire Sicurezza InformaticaCosa Vuol Dire Sicurezza Informatica
Cosa Vuol Dire Sicurezza Informaticagpopolo
 
Continui attacchi informatici: raggiungere l'eccellenza operativa per la nuov...
Continui attacchi informatici: raggiungere l'eccellenza operativa per la nuov...Continui attacchi informatici: raggiungere l'eccellenza operativa per la nuov...
Continui attacchi informatici: raggiungere l'eccellenza operativa per la nuov...Accenture Italia
 
S/MIME & E-mail Security (Network Security)
S/MIME & E-mail Security (Network Security)S/MIME & E-mail Security (Network Security)
S/MIME & E-mail Security (Network Security)Prafull Johri
 

Viewers also liked (16)

Vulnerabilità exploit
Vulnerabilità exploitVulnerabilità exploit
Vulnerabilità exploit
 
Expo viernes
Expo viernesExpo viernes
Expo viernes
 
Slide - Tecniche di Test-driven development in ambito sicurezza informatica e...
Slide - Tecniche di Test-driven development in ambito sicurezza informatica e...Slide - Tecniche di Test-driven development in ambito sicurezza informatica e...
Slide - Tecniche di Test-driven development in ambito sicurezza informatica e...
 
Presentazione Laurea triennale - X509 e PGP
Presentazione Laurea triennale - X509 e PGPPresentazione Laurea triennale - X509 e PGP
Presentazione Laurea triennale - X509 e PGP
 
Da Cesare ai quanti - Workshop@UNINA - NaLUG - Crittografia - polialfabetici ...
Da Cesare ai quanti - Workshop@UNINA - NaLUG - Crittografia - polialfabetici ...Da Cesare ai quanti - Workshop@UNINA - NaLUG - Crittografia - polialfabetici ...
Da Cesare ai quanti - Workshop@UNINA - NaLUG - Crittografia - polialfabetici ...
 
VULNERABILITA’ DELLE COSTRUZIONI AI FENOMENI GEOLOGICI E IDROGEOLOGICI Parte I
VULNERABILITA’ DELLE COSTRUZIONI AI FENOMENI GEOLOGICI E IDROGEOLOGICI Parte IVULNERABILITA’ DELLE COSTRUZIONI AI FENOMENI GEOLOGICI E IDROGEOLOGICI Parte I
VULNERABILITA’ DELLE COSTRUZIONI AI FENOMENI GEOLOGICI E IDROGEOLOGICI Parte I
 
Proteggere i dispositivi mobili - ISACA Venice - festival ICT 2015
Proteggere i dispositivi mobili - ISACA Venice - festival ICT 2015Proteggere i dispositivi mobili - ISACA Venice - festival ICT 2015
Proteggere i dispositivi mobili - ISACA Venice - festival ICT 2015
 
Lungiswa Ntombini (Detailed resume)
Lungiswa Ntombini (Detailed resume)Lungiswa Ntombini (Detailed resume)
Lungiswa Ntombini (Detailed resume)
 
Certificato laurea con esami
Certificato laurea con esamiCertificato laurea con esami
Certificato laurea con esami
 
Cybersecurity e Vulnerabilita' dei sistemi SCADA
Cybersecurity e Vulnerabilita' dei sistemi SCADACybersecurity e Vulnerabilita' dei sistemi SCADA
Cybersecurity e Vulnerabilita' dei sistemi SCADA
 
Presentazione Tesi di Laurea sulla Sicurezza delle Reti Informatiche: Le vuln...
Presentazione Tesi di Laurea sulla Sicurezza delle Reti Informatiche: Le vuln...Presentazione Tesi di Laurea sulla Sicurezza delle Reti Informatiche: Le vuln...
Presentazione Tesi di Laurea sulla Sicurezza delle Reti Informatiche: Le vuln...
 
Tesi di Laurea sulla Sicurezza delle Reti Informatiche: Le vulnerabilità
Tesi di Laurea sulla Sicurezza delle Reti Informatiche: Le vulnerabilitàTesi di Laurea sulla Sicurezza delle Reti Informatiche: Le vulnerabilità
Tesi di Laurea sulla Sicurezza delle Reti Informatiche: Le vulnerabilità
 
Cosa Vuol Dire Sicurezza Informatica
Cosa Vuol Dire Sicurezza InformaticaCosa Vuol Dire Sicurezza Informatica
Cosa Vuol Dire Sicurezza Informatica
 
pgp s mime
pgp s mimepgp s mime
pgp s mime
 
Continui attacchi informatici: raggiungere l'eccellenza operativa per la nuov...
Continui attacchi informatici: raggiungere l'eccellenza operativa per la nuov...Continui attacchi informatici: raggiungere l'eccellenza operativa per la nuov...
Continui attacchi informatici: raggiungere l'eccellenza operativa per la nuov...
 
S/MIME & E-mail Security (Network Security)
S/MIME & E-mail Security (Network Security)S/MIME & E-mail Security (Network Security)
S/MIME & E-mail Security (Network Security)
 

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

Porting evolutivo di un’applicazione per la gestione di note spese in ambient...
Porting evolutivo di un’applicazione per la gestione di note spese in ambient...Porting evolutivo di un’applicazione per la gestione di note spese in ambient...
Porting evolutivo di un’applicazione per la gestione di note spese in ambient...enriconatella
 
mastertesi
mastertesimastertesi
mastertesiReply
 
Il Modello Pragmatico Elementare per lo sviluppo di Sistemi Adattivi - Tesi
Il Modello Pragmatico Elementare per lo sviluppo di Sistemi Adattivi - TesiIl Modello Pragmatico Elementare per lo sviluppo di Sistemi Adattivi - Tesi
Il Modello Pragmatico Elementare per lo sviluppo di Sistemi Adattivi - TesiFrancesco Magagnino
 
Implementazione di protocolli e simulatori MATLAB per lo sviluppo del livello...
Implementazione di protocolli e simulatori MATLAB per lo sviluppo del livello...Implementazione di protocolli e simulatori MATLAB per lo sviluppo del livello...
Implementazione di protocolli e simulatori MATLAB per lo sviluppo del livello...michael_mozzon
 
Esperimenti_laboratorio di fisica per la scuola superiore
Esperimenti_laboratorio di fisica per la scuola superioreEsperimenti_laboratorio di fisica per la scuola superiore
Esperimenti_laboratorio di fisica per la scuola superiorevaleriodinoia35
 
Imparare c n.104
Imparare c  n.104Imparare c  n.104
Imparare c n.104Pi Libri
 
Validation and analysis of mobility models
Validation and analysis of mobility modelsValidation and analysis of mobility models
Validation and analysis of mobility modelsUmberto Griffo
 
Openfisca Managing Tool: a tool to manage fiscal sistems
Openfisca Managing Tool: a tool to manage fiscal sistemsOpenfisca Managing Tool: a tool to manage fiscal sistems
Openfisca Managing Tool: a tool to manage fiscal sistemsLorenzo Stacchio
 
Piano Nazionale Scuola Digitale (risorse integrative)
Piano Nazionale Scuola Digitale (risorse integrative)Piano Nazionale Scuola Digitale (risorse integrative)
Piano Nazionale Scuola Digitale (risorse integrative)Ministry of Public Education
 
Uno studio sull'efficacia di checker automatici per la modernizzazione di cod...
Uno studio sull'efficacia di checker automatici per la modernizzazione di cod...Uno studio sull'efficacia di checker automatici per la modernizzazione di cod...
Uno studio sull'efficacia di checker automatici per la modernizzazione di cod...Idriss Riouak
 
Progetto per lo sviluppo di un sistema di gestione della conoscenza per il pr...
Progetto per lo sviluppo di un sistema di gestione della conoscenza per il pr...Progetto per lo sviluppo di un sistema di gestione della conoscenza per il pr...
Progetto per lo sviluppo di un sistema di gestione della conoscenza per il pr...Nicola Cerami
 
CaputiDomenicoMagistrale
CaputiDomenicoMagistraleCaputiDomenicoMagistrale
CaputiDomenicoMagistraleDomenico Caputi
 
Dispensa Interazione Uomo Macchina
Dispensa Interazione Uomo MacchinaDispensa Interazione Uomo Macchina
Dispensa Interazione Uomo MacchinaStefano Bussolon
 
Tesi Zorzin
Tesi ZorzinTesi Zorzin
Tesi Zorzinshadow82
 
Tecniche per la rilevazione e correzione di errori nell'elaborazione automati...
Tecniche per la rilevazione e correzione di errori nell'elaborazione automati...Tecniche per la rilevazione e correzione di errori nell'elaborazione automati...
Tecniche per la rilevazione e correzione di errori nell'elaborazione automati...Matteo Gazzin
 

Similar to Tecniche di Test-driven development in ambito sicurezza informatica e rilevazione vulnerabilità (20)

repairpdf_Oy51nCFX
repairpdf_Oy51nCFXrepairpdf_Oy51nCFX
repairpdf_Oy51nCFX
 
Porting evolutivo di un’applicazione per la gestione di note spese in ambient...
Porting evolutivo di un’applicazione per la gestione di note spese in ambient...Porting evolutivo di un’applicazione per la gestione di note spese in ambient...
Porting evolutivo di un’applicazione per la gestione di note spese in ambient...
 
mastertesi
mastertesimastertesi
mastertesi
 
Guida C# By Megahao
Guida C# By MegahaoGuida C# By Megahao
Guida C# By Megahao
 
Tesi
TesiTesi
Tesi
 
Tesi
TesiTesi
Tesi
 
Il Modello Pragmatico Elementare per lo sviluppo di Sistemi Adattivi - Tesi
Il Modello Pragmatico Elementare per lo sviluppo di Sistemi Adattivi - TesiIl Modello Pragmatico Elementare per lo sviluppo di Sistemi Adattivi - Tesi
Il Modello Pragmatico Elementare per lo sviluppo di Sistemi Adattivi - Tesi
 
Implementazione di protocolli e simulatori MATLAB per lo sviluppo del livello...
Implementazione di protocolli e simulatori MATLAB per lo sviluppo del livello...Implementazione di protocolli e simulatori MATLAB per lo sviluppo del livello...
Implementazione di protocolli e simulatori MATLAB per lo sviluppo del livello...
 
Esperimenti_laboratorio di fisica per la scuola superiore
Esperimenti_laboratorio di fisica per la scuola superioreEsperimenti_laboratorio di fisica per la scuola superiore
Esperimenti_laboratorio di fisica per la scuola superiore
 
Imparare c n.104
Imparare c  n.104Imparare c  n.104
Imparare c n.104
 
Validation and analysis of mobility models
Validation and analysis of mobility modelsValidation and analysis of mobility models
Validation and analysis of mobility models
 
Openfisca Managing Tool: a tool to manage fiscal sistems
Openfisca Managing Tool: a tool to manage fiscal sistemsOpenfisca Managing Tool: a tool to manage fiscal sistems
Openfisca Managing Tool: a tool to manage fiscal sistems
 
Piano Nazionale Scuola Digitale (risorse integrative)
Piano Nazionale Scuola Digitale (risorse integrative)Piano Nazionale Scuola Digitale (risorse integrative)
Piano Nazionale Scuola Digitale (risorse integrative)
 
Uno studio sull'efficacia di checker automatici per la modernizzazione di cod...
Uno studio sull'efficacia di checker automatici per la modernizzazione di cod...Uno studio sull'efficacia di checker automatici per la modernizzazione di cod...
Uno studio sull'efficacia di checker automatici per la modernizzazione di cod...
 
Progetto per lo sviluppo di un sistema di gestione della conoscenza per il pr...
Progetto per lo sviluppo di un sistema di gestione della conoscenza per il pr...Progetto per lo sviluppo di un sistema di gestione della conoscenza per il pr...
Progetto per lo sviluppo di un sistema di gestione della conoscenza per il pr...
 
CaputiDomenicoMagistrale
CaputiDomenicoMagistraleCaputiDomenicoMagistrale
CaputiDomenicoMagistrale
 
Dispensa Interazione Uomo Macchina
Dispensa Interazione Uomo MacchinaDispensa Interazione Uomo Macchina
Dispensa Interazione Uomo Macchina
 
Tesi Zorzin
Tesi ZorzinTesi Zorzin
Tesi Zorzin
 
Dynamic Scheduling
Dynamic SchedulingDynamic Scheduling
Dynamic Scheduling
 
Tecniche per la rilevazione e correzione di errori nell'elaborazione automati...
Tecniche per la rilevazione e correzione di errori nell'elaborazione automati...Tecniche per la rilevazione e correzione di errori nell'elaborazione automati...
Tecniche per la rilevazione e correzione di errori nell'elaborazione automati...
 

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

  • 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 Relatore Federico Cecutti chiar.mo prof. Alberto Bartoli Correlatore Enrico Milanese anno accademico 2011/2012
  • 3. Indice Abstract.................................................................................................................................................7 PARTE PRIMA – Descrizione generale del lavoro 1 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.........................................................................................................9 2 Analisi e progettazione...................................................................................................................11 2.1 Scelta dell'ambiente 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. 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...............................................................................................................................41 PARTE SECONDA – Generazione di espressioni regolari 4 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........................................49 5 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.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 dell'operatore di opzionalità.....................................................81 6 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...............................................................105 7 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.......................................................................................................115 PARTE TERZA – Conclusioni e bibliografia 8 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. 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. Abstract Una delle tecniche di difesa dagli attacchi informatici è l'analisi delle vulnerabilità, che riguardano essenzialmente due ambiti: i software e i protocolli. Le vulnerabilità dei software si possono individuare esaminando degli aspetti specifici dei nodi interessati; ad esempio, per i server, la prima risposta dopo lo stabilirsi della connessione, per i server web alcuni contenuti di pagina, e in generale il numero di versione di programmi e sistemi operativi. Le vulnerabilità dei protocolli si possono scoprire inviando delle richieste particolari verso i nodi, e analizzando le risposte. L'insieme di conoscenza degli input da inviare e delle risposte attese, così come dei pattern da ricercare, costituisce una base dati che viene ampliata nel tempo, man mano che vengono trovate nuove minacce. La prima parte del lavoro di tesi consiste nello sviluppo di test per la validazione dei nuovi inserimenti in questa base dati. Un supporto fondamentale dell'analisi delle vulnerabilià è costituito dalle espressioni regolari che individuano determinate strutture all'interno dei flussi di dati. La generazione automatica di tali espressioni regolari a partire da esempi costituisce la seconda parte della tesi. Gli strumenti software e i test sviluppati nel corso del lavoro sono attualmente impiegati dall'azienda committente. 7
  • 8. PARTE PRIMA Descrizione generale del lavoro 1 Introduzione La presente tesi illustra il lavoro svolto presso Emaze Networks S.p.A. 1.1 Contesto L'azienda realizza il software ipLegion, che comprende un componente detto Scout per l'analisi e il monitoraggio delle vulnerabilità informatiche, e aveva la necessità di integrare i test già in uso con delle nuove implementazioni. La base di conoscenza per l'analisi è costituita da dati e logiche dedicate alle diverse vulnerabilità, e viene ampliata man mano che se ne scoprono di nuove. Su tale base il sistema è in grado di asserire che un dato endpoint manifesta una certa vulnerabilità. In prima approssimazione, l'operazione avviene interrogando l'endpoint secondo una modalità che può spaziare dal semplice utilizzo di un protocollo all'invio di particolari richieste, e analizzando le sue risposte. Alcune vulnerabilità sono presenti soltanto se si riscontrano determinate risposte, altre possono essere presenti se l'endpoint risponde, o non risponde, secondo un certo schema. La correttezza di questi schemi costituisce un aspetto cruciale del sistema di analisi di vulnerabilità, perché un'eventuale imprecisione potrebbe non far scoprire una vulnerabilità o, al contrario, generare dei falsi positivi. 1.2 Obiettivi e vincoli progettuali L'obiettivo del lavoro è realizzare dei test che permettano di trovare in modo automatico delle eventuali imprecisioni nella base di conoscenza. I test prendono in esame alcune tipologie di errori, ritenuti particolarmente difficili da rilevare con un'analisi diretta di un operatore umano. Lo sviluppo dei test e del codice correlato deve seguire l'approccio 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 ogni futuro aggiornamento della base dati del sistema. Ogni singolo test garantirà l'assenza di un certo tipo di errore dalla nuova versione. 8
  • 9. I test possono essere classificati in due tipologie: test su un modulo singolo, in cui si esamina soltanto un certo aspetto del sistema di analisi di vulnerabilità, indipendentemente dal resto, e test di integrazione, in cui si esamina l'interazione tra due endpoint. I test più complessi hanno richiesto la progettazione e lo sviluppo di librerie software specifiche, tra le quali ha assunto particolare rilievo quella per la generazione automatica di espressioni regolari che catturassero le caratteristiche strutturali di un campione di stringhe noto. Questo modulo è destinato ad essere utilizzato direttamente da un operatore umano, a supporto della messa a punto di nuove espressioni regolari nella base di conoscenza del sistema. Permetterà inoltre lo 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 versione del sistema di analisi di vulnerabilità. Si è utilizzato l'IDE PyCharm. 1.3 Fasi di lavoro e risultati Il lavoro si è articolato in una fase preliminare di studio del linguaggio di programmazione e del sistema 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 generatore di espressioni regolari. Il risultato del lavoro è stato il rilascio di versioni corrette dei file di configurazione interessati dai test e di librerie di utilità generale disponibili per nuovi test futuri. 1.4 Articolazione della tesi La presente tesi si articola in una prima parte riguardante i test e una seconda dedicata al modulo di generazione di espressioni regolari. Questo modulo ha costituito una parte cospicua del lavoro di tesi e, per il fatto che è interessato da problematiche diverse dalla quelle specifiche riguardanti i test – anche se rientra nello stesso contesto 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 l'individuazione 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 dell'implementazione dei test e si fornisce un esempio di esecuzione 9
  • 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 soluzione 5. Si presenta la progettazione del workflow per l'algoritmo di generazione, approfondendo l'algoritmo di Hunt-McIlroy, il problema di corrispondenza e l'espressione regolare da associare al singolo pattern 6. Si illustrano le modalità di sviluppo test-driven, i punti salienti dell'implementazione degli algoritmi di Hunt-McIlroy e di corrispondenza, le strutture dati utilizzate per la descrizione delle corrispondenze e l'articolazione del codice per ottenere le soluzioni con pattern e con token frequenti 7. Si presentano degli esempi di utilizzo del generatore di espressioni regolari e si discute il codice aggiuntivo sviluppato per la diagnostica del modulo 8. Si delineano le conclusioni del lavoro complessivo, valutandolo sulla base degli obiettivi del progetto 9. Si elencano i riferimenti bibliografici 10
  • 11. 2 Analisi e progettazione 2.1 Scelta dell'ambiente di testing Il concetto di test-driven development è così radicato in Python che la stessa Python Standard Library 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 grandi vantaggi delle soluzioni standard; in particolare: • ragionevole certezza dell'assenza di bug nel framework • garanzia di supporto in versioni future di Python • abbondanza di documentazione disponibile Nella scelta del framework giocano un ruolo essenziale la semplicità e la sinteticità nell'utilizzo. Il sorgente del test deve rendere il più possibile evidente la sua finalità e le sue caratteristiche specifiche. doctest, sviluppato nell'intento di massimizzare la semplicità di utilizzo, si dimostra non essere uno strumento 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 testare unittest richiede invece la scrittura di un vero codice di test: una soluzione forse meno immediata ma 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 script supplementari preposti alla ricerca dei test, alla loro aggregazione ed esecuzione. Esistono vari framework1 che estendono unittest automatizzando queste funzionalità. Spesso è possibile restringere l'insieme dei test da eseguire al singolo package, file, classe o metodo, senza dover ricorrere ad alcuno script aggiuntivo. Questa funzionalità è particolarmente interessante, perché in caso di aggiornamenti limitati alla base di conoscenza del sistema permette di effettuare una validazione rapida eseguendo soltanto i test per le parti modificate. Si sceglie di usare nose, per la sua ampia diffusione e disponibilità di documentazione e perché non aggiunge a questi requisiti altre funzionalità non di interesse. 1 Si veda ad esempio http://packages.python.org/testing/ 11
  • 12. 2.2 Test di integrazione 2.2.1 Contesto e obiettivi L'obiettivo dei test di integrazione da sviluppare è quello di verificare la corretta individuazione di alcune vulnerabilità legate all'interazione tra l'endpoint da analizzare e un server. Il sistema di analisi memorizza, per ogni vulnerabilità individuata, le informazioni rilevanti. Tra queste vi sono: • codice identificativo aziendale univoco • metodo di rilevazione • numero di porta lato server • protocollo di trasporto • servizio • flag per indicare se l'interazione utilizza SSL • una o più risposte rilevanti dell'endpoint • nome del software interessato La 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 i valori 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 l'assenza 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.323 Per comunicare con il client da analizzare è necessario predisporre un mock locale che simuli il comportamento lato server all'origine della vulnerabilità. Il lato client deve utilizzare la funzione del sistema di analisi di vulnerabilità gatherfunc, che lo inizializza e lo collega al server sulla base di queste caratteristiche: 12
  • 13. numero di porta lato server • protocollo di trasporto • servizio • indirizzo IP del server • oggetto Session L'oggetto Session è un descrittore dell'analisi di sicurezza del nodo corrente, di cui si tiene conto durante l'analisi di vulnerabilità. Nel sistema di analisi di vulnerabilità ogni protocollo noto o situazione di interesse ha un proprio modulo – nella directory modules – che contiene un'implementazione specifica di gatherfunc. Una volta invocata gatherfunc, si può ottenere la lista delle vulnerabilità rilevate invocando getIdentifiedVulnerabilities sull'oggetto Session. Ogni vulnerabilità è un oggetto Vulnerability da cui si possono ricavare le caratteristiche descritte. 2.2.2 Classi di test Poiché 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 stessa logica 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 server I metodi setUp e tearDown implementano quelli definiti in unittest.TestCase2. Dato che ogni protocollo ha una propria implementazione di gatherfunc, l'importazione di questa funzione 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 un'implementazione 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. 2.2.3 Oggetti mock I test devono utilizzare degli oggetti mock che si sostituiscano agli oggetti Session e Vulnerability utilizzati normalmente dal sistema di analisi di vulnerabilità. I mock devono essere utilizzabili da gatherfunc nello stesso modo degli oggetti standard, ma limitarsi a modellare gli aspetti dell'oggetto effettivamente di rilievo nei test. La funzione gatherfunc utilizza un oggetto Session che descrive l'analisi di sicurezza in corso su un certo endpoint. In particolare ne invoca alcuni metodi. L'oggetto mock Session deve tenere traccia di: • indirizzo IP dell'endpoint oggetto dell'analisi, di default 'localhost' • parametro sd (utile per test futuri, qui non utilizzato), di default None • una lista di oggetti Vulnerability corrispondenti alle vulnerabilità rilevate e deve implementare i seguenti metodi con queste funzionalità: • getScoutdict: restituisce il parametro sd (utile per test futuri) • getVirtualHost: restituisce l'indirizzo IP dell'endpoint • 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 corretti Per Vulnerability è sufficiente definire una classe con un attributo per ciascuna informazione che caratterizza la vulnerabilità. 2.2.4 Lato server La 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 interesse utilizzare la classe SocketServer.TCPServer. La classe inclusa nella libreria standard non fornisce garanzie sulle tempistiche in cui un indirizzo lato server possa essere riutilizzato. Dopo la finalizzazione, il socket potrebbe restare in uno stato di TIME_WAIT anche per qualche secondo, e restituire un errore alla richiesta di connessione al proprio indirizzo4. 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. La politica di interazione con il client viene definita in un metodo handle di una classe specifica per ciascun simulatore lato server, che implementa il metodo handle di SocketServer.BaseRequestHandler. Per rendere rilevabili le vulnerabilità oggetto dei test, i simulatori devono effettuare le seguenti interazioni 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 (l'indice 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 connessione L'attivazione del simulatore lato server da parte di una classe di test deve comportare l'inizio di un nuovo flusso parallelo di esecuzione, che possa comunicare con il client mentre quest'ultimo è in esecuzione. Una classe MultiThreadTCPServer corrisponde al mock lato server. La classe deve contenere un metodo 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 e avviare il thread di servizio specificando il gestore di richieste desiderato. MultiThreadTCPServer deve 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 l'operazione di bind al metodo server_bind di ReuseTCPSocketServer, un override del metodo di SocketServer.TCPServer in cui si imposta l'opzione del socket che ne permette il riutilizzo anche se in stato di TIME_WAIT. Al momento della creazione di un'istanza di MultiThreadTCPServer deve poter essere specificato un attributo opzionale banner, per indicare una stringa che il server invia al client una volta aperta la connessione. In tutti i test in cui si verifica l'assenza di una certa vulnerabilità è sufficiente ricorrere a un request handler lato server molto semplice, che si limiti a inviare un banner al client su una connessione aperta e la chiuda. Si tratta in effetti di un mock di un server qualsiasi che non dia luogo alla situazione 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. 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. 2.2.5 Schema consuntivo Si propone di seguito un UML class diagram che evidenzia le interazioni tra le classi interessate dal test per i sistemi NetBus2. La classe di test Netbus2Test utilizza la funzione gatherfunc per la predisposizione del lato client e per la sua connessione al lato server. gatherfunc si serve dell'oggetto mock Session per registrare le vulnerabilità trovate. Lato server viene creato un oggetto MultiThreadTCPServer, a cui viene passato il callable Netbus2Simulator. All'invocazione del metodo spawnServerThread, l'oggetto istanzia ReuseTCPSocketServer passando il simulatore come request handler, e lo attiva in un thread separato. Ad ogni oggetto MultiThreadTCPServer corrisponde un oggetto ReuseTCPSocketServer e viceversa. Gli altri test presentano un'interazione analoga tra le classi, e si differenziano per la classe di test, il modulo del sistema di analisi con l'implementazione di gatherfunc e il request handler lato server, che hanno comunque strutture analoghe. Alcuni test utilizzano il mock FakeRequestHandler come request 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. 2.3 Test su moduli singoli 2.3.1 Contesto Nella maggior parte dei casi una vulnerabilità interessa soltanto una certa tipologia di nodo, con specifiche caratteristiche software o hardware. Nell'analisi delle vulnerabilità che potrebbero interessare un endpoint remoto è fondamentale ricavare il maggior numero di informazioni possibili riguardo all'endpoint. 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 caratteristiche dell'endpoint prendendo in esame una qualche stringa che questo ha generato. I test da sviluppare riguardano in particolare due directory – banners e webapplications – contenenti dei file XML, uno per ogni contesto applicativo, che definiscono i legami tra questa stringa e le caratteristiche dell'endpoint. La directory banners è utilizzata nell'analisi delle prime risposte fornite dai server (dette banner), la directory webapplications nell'analisi 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 dell'endpoint da individuare e ogni elemento <info> corrisponde a una singola caratteristica. Ogni elemento <software> ha un attributo name, suo identificativo, e un attributo re, che specifica un'espressione regolare. Se la stringa da analizzare è conforme 6 all'espressione regolare, il sistema di analisi riconosce nell'endpoint le caratteristiche riportate nell'elemento <software> corrispondente. La notazione è leggermente diversa nei file XML della directory webapplications, in cui si utilizza un elemento <re> interno a <software> anziché un attributo di <software>. A una stringa nota durante l'analisi di vulnerabilità sono applicate tutte le espressioni regolari contenute negli elementi <software> del file XML afferente all'analisi in corso. La stringa può essere conforme a nessuna, una o più espressioni regolari: ogni match individua un insieme di certe caratteristiche dell'endpoint. Ogni caratteristica può essere individuata in uno di questi due modi: 6 Per conformità si intende che la stringa deve generare un match con l'espressione regolare. Più precisamente, detta s la stringa, R l'espressione regolare e L(R) il linguaggio individuato da R , deve essere s 2 L(R) 18
  • 19. essere nota staticamente: la sola conformità della stringa all'espressione regolare rende evidente un certo insieme di caratteristiche • essere ricavata a run-time dalla stringa: l'espressione regolare comprende un gruppo capturing che individua una porzione di stringa con il valore della caratteristica L'espressione regolare contiene pertanto un gruppo capturing intorno ad ogni caratteristica individuata nel secondo modo, e ogni gruppo capturing corrisponde a un elemento <info>. Gli elementi <info> hanno i seguenti attributi: • key: l'identificativo 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 dell'espressione 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 dell'espressione regolare da cui ricavare tale valore Al termine di questa fase dell'analisi di vulnerabilità le caratteristiche dell'endpoint che sono state individuate vengono memorizzate in un dizionario8, con una chiave per ogni matching che la stringa ha provocato sulle espressioni regolari racchiuse negli elementi <software> del file XML. La chiave è il valore dell'attributo name dell'elemento <software>. Il valore corrispondente alla chiave è a sua volta un dizionario, avente per chiavi gli attributi key degli elementi <info> e per valori le informazioni corrispondenti. Una singola caratteristica può avere uno oppure vari valori possibili, tra i quali non si è in grado di scegliere a questo punto dell'analisi di vulnerabilità. In questo caso il relativo valore contenuto nel dizionario è una lista comprensiva di tutte le possibilità. Esempio Si riportano due elementi <software> estratti dai file XML di configurazione. Sono evidenziati in rosso grassetto i gruppi capturing delle espressioni regolari e i corrispondenti riferimenti 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 l'intera espressione regolare. 8 Inteso come struttura dati di Python. 19
  • 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 un esempio 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 dell'elemento <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 senza compromettere 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. 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 degli elementi <regexp>. Ogni elemento <vulnerability> ha un attributo id il cui valore identifica univocamente la vulnerabilità; ogni elemento <regexp> ha un attributo value il cui valore è un'espressione regolare. Se il numero di versione che viene esaminato a run-time è conforme a una delle espressioni regolari contenute in un elemento <vulnerability>, il sistema dichiara che quel numero di versione è affetto dalla vulnerabilità avente come identificativo l'attributo id di quell'elemento <vulnerability>. Tutte le espressioni regolari di questi file devono essere obbligatoriamente terminate da un ancoraggio per la fine della stringa. In altre parole, l'espressione regolare deve sempre individuare il termine del numero di versione. L'inizio del numero di versione può invece non essere compreso nell'espressione regolare.9 Esempio <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. 2.3.2 Tipi di test I test da sviluppare possono essere suddivisi in due tipologie: • test su singoli sistemi noti • test di coerenza interna ai file XML I primi devono verificare che per alcune configurazioni specifiche, corrispondenti a determinati elementi di singoli file XML, il risultato dell'elaborazione da parte del sistema di analisi delle vulnerabilità sia quello atteso. I secondi hanno lo scopo di accertare che i file XML non contengano degli errori interni, che ne compromettano la correttezza semantica. È opportuno distinguere i test che analizzano i file XML contenuti nelle directory banners e webapplications da quelli contenuti in versions_regexp, perché la struttura e il valore semantico dei file sono molto diversi nei due casi. Risultano quindi queste quattro tipologie di test: banners e webapplications versions_regexp Su singoli sistemi test di categoria 1 test di categoria 2 Di coerenza interna ai file XML test di categoria 3 test di categoria 4 Si 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, e interessano 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 dizionario consuntivo, 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 abbia il valore previsto. Nel caso in cui questo valore sia una lista, è sufficiente verificare che ogni valore della lista attesa sia presente nella lista risultante. In questo modo si prova la correttezza di alcuni elementi <software> basandosi su scoutUtils.BannerParser; essendo una funzione esterna, questa funzione ha già delle proprie unità di test che ne avvalorano la correttezza intrinseca. Questo approccio trascura il caso altamente improbabile che un errore su un elemento <software> 22
  • 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 server Apache 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 versione la 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 numero di versione e la lista di espressioni regolari corrispondenti a una certa vulnerabilità e ne indica l'esistenza restituendo True o False. Gli insiemi di numeri di versione oggetto delle asserzioni devono essere determinati a partire dalle espressioni 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 questo contesto): <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 un numero 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 un'altra. I range sono stati evidenziati in verde e i costrutti '.*' e l'indicatore di opzionalità in rosso. 23
  • 24. Per ogni espressione regolare che individua un unico numero di versione, si include nel test un'asserzione che verifichi la corrispondente vulnerabilità. Per ogni range si verifica che siano vulnerabili le versioni corrispondenti agli estremi, ma non la versione successiva all'estremo superiore se questo è minore di 9, né quella precedente all'estremo inferiore se questo è maggiore di 0. Per ogni parte opzionale e costrutto '.*' viene fatta almeno un'asserzione positiva che utilizzi l'elemento 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 dall'estremo superiore del range; una utilizza il '.*' • 7.0: asserzione positiva per l'espressione 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 versione Per 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 l'espressione regolare per il singolo numero di versione A questa base di asserzioni possono essere aggiunte a piacere asserzioni positive o negative per altri numeri di versione senza compromettere il valore del test. In questo modo si prova la correttezza delle espressioni regolari, demandando alla funzione del sistema di analisi di vulnerabilità la verifica della conformità tra il numero di versione e una delle espressioni regolari che interessano una certa vulnerabilità. Anche in questo caso, la correttezza intrinseca della funzione esterna è avvalorata da un'unità di test già disponibile e valgono considerazioni analoghe a quelle del caso precedente. Il test valida le espressioni regolari del file XML a fronte di esempi. Ciò è particolarmente utile nel mantenimento del file: ogni modifica futura alle espressioni regolari dovrà essere accompagnata da una modifica o un'estensione di questo test. Il test segnalerà eventuali modifiche accidentali. 24
  • 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 dai relativi 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 all'espressione regolare. Per motivi di praticità d'uso, i commenti sono talvolta raggruppati in una sorta di indice, lontano dai rispettivi 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 l'immissione 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 volta Non è possibile creare test che soddisfino completamente tali richieste; è possibile approssimare la soluzione in modo soddisfacente con dei test che rendano queste caratteristiche ideali altamente probabili. Tra tutti i test, illustrati di seguito, quelli fondamentali verificano, per ogni file XML ed elemento <software>, la correttezza sintattica dell'espressione regolare, e la coerenza tra espressione regolare, commenti ed elementi <info> con type=”re”. 2.3.2.3.1 Test di correttezza sintattica Un test sulla correttezza sintattica del file XML non è necessario, perché gli IDE utilizzati ne effettuano già una validazione continua, e un eventuale errore verrebbe segnalato immediatamente all'operatore. Deve essere invece inclusa in un test la validazione sintattica delle espressioni regolari. Un eventuale errore verrebbe segnalato soltanto nella fase successiva di analisi di vulnerabilità, che può essere eseguita anche molto tempo dopo l'aggiornamento della base dati, e comunque in modo indipendente. 25
  • 26. 2.3.2.3.2 Test di coerenza tra espressione regolare e commenti Nell'introduzione di nuovi elementi <software> nel file XML, è possibile che l'operatore dimentichi di inserire i commenti corrispondenti, o che non aggiorni correttamente un commento a fronte di una modifica dell'espressione regolare, provocando un disallineamento che non è segnalato neanche durante l'analisi di vulnerabilità. Considerando le dimensioni del file e la possibile distanza tra l'elemento <software> e il relativo commento, 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 che verifichi, per ogni file XML, che non vi siano espressioni regolari prive di commenti corrispondenti. 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 l'assenza di 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 utilizza un approccio diverso. Come confermato dal test descritto precedentemente, in ciascun file ogni espressione regolare ha un commento corrispondente; quindi il test è costruibile passando ogni commento alla funzione del sistema di analisi di vulnerabilità preposta all'esame dei banner. La funzione ricerca, nel file specificato, dei match con le espressioni regolari degli elementi <software> e aggiorna di conseguenza il dizionario consuntivo dell'analisi di vulnerabilità. Il test fallisce se si verifica un'eccezione, individuando in questo modo i disallineamenti tra i gruppi capturing dell'espressione regolare e gli elementi <info> con type=”re” per i commenti del file. 2.3.2.3.5 Test per ripetizioni In alcuni casi, la ripetizione di una porzione di file XML causa un errore di sintassi, o relativa alle regole XML o a quelle della base di conoscenza del sistema. Entrambi questi casi non sono interessanti, per le ragioni già discusse: il primo è rilevato immediatamente dal validatore a bordo dell'IDE, il secondo è difficilmente producibile da un operatore, e viene comunque segnalato nell'analisi di vulnerabilità. Rimane aperta la possibilità di ripetizioni di elementi <info> all'interno di elementi <software>, o di elementi <software> all'interno del file XML. Nei file di webapplications, la ripetizione di elementi 26
  • 27. <re>10 all'interno di <software> provocherebbe invece una trasgressione della sintassi standard, e rientra nella casistica precedente. La ripetizione di elementi <info> non produce errori e non è necessario predisporre dei test che ne verifichino l'assenza. Al contrario, è fondamentale garantire che ogni elemento <software> sia unico all'interno del file, se non altro per ragioni di manutenibilità. Se vi fossero due ripetizioni di uno stesso elemento, l'operatore potrebbe modificare una delle due copie senza modificare la seconda, di cui potrebbe perfino ignorarne l'esistenza. Poiché ogni elemento <software> è in corrispondenza uno a uno con l'espressione regolare al suo interno, è sufficiente testare l'unicità di ogni espressione regolare all'interno di ciascun file. 2.3.2.3.6 Test sugli elementi <info> sospetti Un caso di alterazione particolarmente insidioso per la sua difficoltà di rilevazione manuale è quello in cui l'attributo 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. Si dichiara sospetto un elemento <info> per cui sussistono le condizioni seguenti: • type vale ”str” • value è un numero naturale piccolo • l'elemento non è incluso in una lista di <info> da escludere a priori Gli elementi <software> della base di conoscenza del sistema hanno espressioni regolari che tipicamente comprendono due o tre elementi <info>, talvolta quattro e solo raramente un numero maggiore. Poiché in questo tipo di casi di errore il value si riferisce a un gruppo di un'espressione regolare, è ragionevole aspettarsi che si tratti di un numero naturale piccolo. In prima approssimazione, una sua limitazione superiore può essere costituita dal numero di gruppi capturing dell'espressione regolare. È conveniente introdurre una certa tolleranza a questa valutazione, per escludere quei rari casi di aggiornamento errato in cui si riduce il numero di gruppi dell'espressione regolare senza eliminare gli 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é impossibile che l'operatore elimini ben dieci gruppi capturing dall'espressione regolare senza notare dieci elementi <info> di troppo. Prendendo in considerazione quello che nella pratica è molto frequente, un elemento <info> che abbia una delle seguenti caratteristiche non è mai considerato sospetto: 10 Si utilizzano elementi <re> soltanto nei file di webapplications. In quelli di banners l'espressione regolare è contenuta nell'attributo re di <software>. 27
  • 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 key Queste due regole escludono dai casi sospetti i numeri di service pack (qui indicato con “sp”) e la release 7 di Windows. Si predispone un test che, per ogni value di un elemento <info> sospetto, verifica che tale value compaia nell'espressione regolare dell'elemento <software> in cui è contenuto l'elemento <info>. In caso di fallimento, questo test segnala una situazione solo potenzialmente errata. 2.3.2.3.7 Riepilogo dei test della categoria 3 Ognuno dei seguenti test si sviluppa in una versione per banners e una per webapplications; tutti i test 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 nell'espressione regolare • ogni espressione regolare deve essere unica • ogni elemento <info> sospetto deve avere un value che compare nell'espressione regolare corrispondente 2.3.2.4 Test di coerenza interna sui file di versions_regexp (categoria 4) L'obiettivo di questi test è quello di rendere improbabili eventuali errori umani nell'immissione delle espressioni regolari utilizzate per filtrare i numeri di versione. Innanzitutto è opportuno predisporre due test per verificare rispettivamente la correttezza sintattica delle espressioni regolari e la conformità rispetto alla regola di terminazione con l'ancoraggio per la fine della stringa. 11 Con “corrispondente” si intende che deve trovarsi nello stesso elemento <software>. 28
  • 29. I numeri di versione contengono spesso dei punti, che nell'espressione regolare vengono individuati da '.'. Se dovesse mancare l'escaping del carattere speciale '.', l'espressione regolare presenterebbe un errore che il sistema di analisi di vulnerabilità non potrebbe individuare automaticamente. Infatti l'espressione regolare risulterebbe: • sintatticamente corretta • più generale di quella corretta rendendo l'errore non individuabile né dal test precedente né da alcun test puntuale sui matching attesi. È opportuno testare esplicitamente la presenza del carattere di escape prima di ogni punto contenuto in un'espressione regolare. Vista la frequenza dello schema '.*' nella base di conoscenza, il test deve permettere 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 evidente che i casi individuati sono errori soltanto potenziali. Riassumendo, i test da realizzare devono verificare: • correttezza sintattica delle espressioni regolari • presenza nelle espressioni regolari dell'ancoraggio per il termine della stringa • presenza nelle espressioni regolari dell'escaping per ogni '.', a meno che questo non preceda un '*' 2.3.3 Organizzazione dei test L'aspetto più complesso dei test descritti è il parsing XML. I test della categoria 1 possono demandarlo alla funzione scoutUtils.BannerParser, per gli altri serve un'implementazione 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 dell'analisi di vulnerabilità è un dizionario con chiavi corrispondenti a stringhe singole o a liste, è opportuno svincolare la logica di test da questa distinzione. Si sceglie quindi di definire BaseTestCaseForBanners con un metodo assert_inStrOrList, una versione specializzata di unittest.TestCase. Tutte le classi contenenti i test ereditano da BaseTestCaseForBanners. 29
  • 30. Figura 4: UML class diagram per i test della categoria 1 2.3.3.2 Parsing XML Per il parsing dell'XML si sceglie di usare un approccio di tipo SAX 12, per il quale è disponibile un modulo della Python Standard Library. Si tratta di implementare l'interfaccia13 xml.sax.ContentHandler, e in particolare le callback richiamate all'individuazione di un tag di inzio di un elemento, di fine di un elemento e di caratteri interni agli elementi. Una prima implementazione dell'interfaccia è costituita da BaseReValidatorXmlHandler, che correda il parser di un attributo lista per salvare le espressioni regolari trovate. Viene implementato il metodo __init__, per l'inizializzazione della lista, e reset, per ripristinare la situazione iniziale in cui la lista è vuota. Le specializzazioni successive sono invece distinte tra classi per banners e webapplications e classi per 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 l'istruzione pass. Visto che la distinzione tra classe e interfaccia riguarda più l'ereditarietà che non l'entità in sé, nei diagrammi UML delle classi si preferisce utilizzare comunque la freccia tratteggiata verso la classe base, ma omettendo l'esplicito prefisso <<interface>> al nome della classe base. 30
  • 31. numero di gruppi capturing di ogni espressione regolare • espressioni regolari che compaiono più di una volta nel file • valori sospetti dell'attributo value di <info>, associati all'espressione regolare corrispondente Dovranno perciò essere ridefiniti i metodi __init__ e reset per inizializzare e reinizializzare le relative strutture dati. Deve essere introdotta un'ulteriore specializzazione per distinguere il parsing dei file in banners da quelli in webapplications, perché nei due contesti le espressioni regolari sono specificate in posizioni diverse dell'XML. Nei file di banners l'espressione regolare è riportata come valore di un attributo re, in quelli di webapplications è 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 variabili riferite all'ultima 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 fatto che le espressioni regolari non si trovino all'interno di tag rende necessaria l'implementazione del metodo characters14 e l'introduzione di variabili aggiuntive: • flag per indicare se è in corso il parsing di un'espressione regolare • buffer per l'espressione regolare Il flag viene inizializzato prima che il parser inizi l'analisi del file XML a un valore False. Ciò richiede l'override dei metodo __init__ e reset. Poiché il flag è definito durante tutto il parsing, il metodo characters può bufferizzare l'espressione regolare solo nel caso in cui il valore del flag è True. Nel caso dei numeri di versione, la sola informazione da salvare sono le espressioni regolari associate a ciascuna vulnerabilità. La classe VersionREValidatorXmlHandler deve comprendere un dizionario di espressioni regolari – dello stesso livello degli attributi di RegexTestREValidatorXmlHandler – e alcune variabili utili nel corso del parsing, analoghe a quelle di BannerREValidatorXmlHandler e WebappREValidatorXmlHandler. In particolare servono: • un flag per indicare se il parser sta analizzando l'interno di un elemento <vulnerability> 14 Callback invocata alla ricezione di caratteri di dati, ossia di stringhe contenute all'interno di elementi XML. 31
  • 32. un buffer per l'identificativo della vulnerabilità corrente • un buffer per le espressioni regolari associate alla vulnerabilità corrente I metodi di parsing da implementare sono startElement ed endElement; non serve implementare characters perché in questo tipo di file XML tutti i dati utili sono contenuti negli attributi all'interno dei tag. Il buffer per le espressioni regolari associate alla vulnerabilità corrente deve essere inizializzato prima che inizi il parsing, in modo che alla lettura di </vulnerability> questo sia effettivamente pronto per l'uso. Figura 5: UML class diagram per le classi di parsing XML 32
  • 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 inclusi come attributi di classe nelle classi di test. Si sceglie di inserire il codice che attiva il parsing nel metodo setUpClass, ereditato da unittest.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 parsing di ciascun file. Si sceglie di utilizzare un parser per banners e uno per webapplications; ognuno deve analizzare ciascun 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 parser La classe deve comprendere varie strutture dati, una per ogni informazione di interesse, in cui sono compresi tutti i dati derivanti dal parsing. Ogni struttura dati deve organizzare queste informazioni raggruppandole a seconda del file di provenienza. Si sceglie di utilizzare due strutture dati separate per le informazioni dei file di banners e di webapplications, perché si riferiscono a due contesti operativi diversi. Analogamente, si sceglie di rendere specifici per l'una o l'altra directory anche i metodi di test. In questo modo un test per una certa directory contiene asserzioni soltanto su una struttura dati riferita a quella stessa directory, e la suddivisione tra i moduli banners e webapplications del sistema di analisi 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 dei test 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. Figura 6: UML class diagram per i test di categoria 3 34
  • 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 informazioni contenute nei file XML. Il parsing viene richiamato, in modo del tutto analogo al caso precedente, da una classe base TestCaseForVersions estesa da VersionRegexpTest, che comprende i test di coerenza interna ai file XML (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 modulo singolo 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 un'unità di test di categoria 2 su un sistema diverso 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. 2.3.3.5 Schema consuntivo per le categorie 2, 3 e 4 I test delle categorie 2, 3 e 4 condividono l'infrastruttura 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. 3 Realizzazione 3.1 Implementazione 3.1.1 Codifica test-driven 3.1.1.1 Logica di controllo La metodologia di sviluppo test-driven si basa sulla messa a punto di una logica di controllo – le unità di test – come prima fase dell'implementazione, prima ancora di procedere alla scrittura del codice. Come strategia di sviluppo, il sorgente deve essere implementato verificandone continuamente la correttezza mediante il codice di controllo. Dopo ogni nuovo inserimento nel sorgente viene eseguito il codice di test, in modo da avere un riscontro continuo sulla correttezza dell'implementazione. Il principio di base è quello di individuare eventuali errori il prima possibile, evidenziandone la causa. Il sorgente da sviluppare è costituito dalle unità di test, da affiancare a risorse preesistenti, costituite dai 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 l'implementazione dei test. Con questa modalità di sviluppo i test vengono validati dai file di configurazione, che possono a loro volta contenere errori: si può procedere in questo modo solo nei casi in cui gli errori nei file di configurazione sono indipendenti da quelli dei test da sviluppare. In altre parole, i test devono individuare 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à risulta banalmente vera. Per ogni aspetto più complesso dei test è necessario predisporre un'unità di test di secondo livello specifica. Questo sarà l'approccio tipico nell'implementazione del generatore di espressioni regolari. 3.1.1.2 Strategia di sviluppo dei test Conformemente alla logica di controllo descritta, si adottano le regole di codifica seguenti. Il primo test viene effettuato con una prima stesura dell'unità di test, in cui si riportano gli import necessari al file e uno stub della classe di test, che estende unittest.TestCase e viene implementata con la sola istruzione pass. In questo modo si possono rilevare eventuali errori causati dagli import. Si procede quindi con l'introduzione di un metodo di test, implementato con l'istruzione: self.fail('UNIMPLEMENTED') Il relativo test accerta che nose rilevi correttamente il test e ne segnali l'insuccesso. A questo punto 37
  • 38. si rileva un eventuale errore nel nome del test16. È utile mantenere questa riga come ultima istruzione per tutta la fase di implementazione del metodo di test, e procedere inserendo il codice prima. Siccome nose segnala il primo punto di fallimento di un test e ne interrompe l'esecuzione, tutti gli eventuali errori imputabili al codice di nuova introduzione hanno la precedenza sul fallimento causato dall'istruzione finale. In questo modo si ha la certezza che nessun test di cui non è stata terminata l'implementazione possa essere dimenticato dal programmatore: fino al momento di rimozione dell'istruzione di fallimento il test continuerà ad essere segnalato da nose come fallimentare. Sia nell'unità di test che nel sorgente del software è conveniente utilizzare l'istruzione pass come segnaposto per istruzioni non implementate, in modo da rendere evidente il punto in cui proseguire con l'implementazione. Per annotare queste parti con indicazioni su come proseguire, o come modificare il sorgente, si ricorre 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 e permettono di creare delle liste delle azioni ancora da fare. È preferibile che un'unità di test effettui delle verifiche eterogenee sulla logica da testare, cercando di 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 assertivo Ogni metodo di test è fondato su una o più asserzioni, che costituiscono le istruzioni di verifica di correttezza. unittest.TestCase mette a disposizione vari metodi per effettuare asserzioni, tra cui si sceglie di utilizzarne un numero molto ristretto, in modo da rendere più evidente possibile la finalità dell'asserzione: • assertTrue: il metodo utilizzato più comunemente • assertFalse: utilizzato quando l'aspetto più importante da testare è la falsità dell'argomento • fail: utilizzato durante la fase di sviluppo dei test • assertRaises: utilizzato per segnalare che un'istruzione solleva un'eccezione specificata 16 nose impone che sorgenti, package, directory di test siano conformi all'espressione 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. Si preferisce scrivere esplicitamente il test di uguaglianza con l'operatore == anziché adottare il metodo assertEquals. Dato che in caso di test fallimentare o errato nose riporta il codice della riga di errore e un eventuale messaggio, si aggiunge un messaggio di spiegazione se la riga di asserzione non rende evidente la natura dell'errore. 3.1.2 Test per errori potenziali Se il test per i valori <info> sospetti o quello di coerenza interna dei file XML di versions_regexp rilevano una situazione anomala, non si può avere la certezza che si tratti di un errore. L'output deve essere un messaggio che segnali il caso potenzialmente errato. Anziché ricorrere ad asserzioni, si utilizzano dei messaggi nel log di nose nose.result, mappato da un attributo logger della classe di test. Per i valori sospetti, ad esempio, un messaggio di livello logging.WARNING viene generato se l'elemento <info> sospetto ha un value che non compare nell'espressione regolare corrispondente e un messaggio di livello logging.INFO riassume il numero di casi totali trovati. Il comportamento di default di nose prevede di includere nell'output i messaggi indirizzati ai logger gestiti dal framework. Utilizzare un'asserzione sarebbe inopportuno anche perché i test si interromperebbero al primo caso anomalo 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. 3.1.3 Organizzazione dei sorgenti I file sviluppati nel corso del progetto si collocano nella directory testunits del sistema di analisi delle vulnerabilità. L'organizzazione della gerarchia interna a questa directory è stata definita tenendo conto delle possibili estensioni future: • tests: per i test, le loro librerie e le estensioni future • extlib: per le librerie necessarie all'esecuzione dei test (nose) • oldtests: per vecchi test La 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 all'interno di unit_tests sono raggruppati a seconda del modulo del sistema di analisi di vulnerabilità a cui si riferiscono. All'interno 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_regexp 3.1.4 Esecutore dei test All'interno della directory testunits/tests si predispone uno script in Python che effettua la ricerca e il lancio dei test nelle subdirectory. Allo script possono essere passati gli argomenti standard di nose17, con i quali si possono ad esempio 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. 3.2 Utilizzo Per l'esecuzione dei test si invoca dalla directory testunits/tests del sistema di analisi delle vulnerabilità l'interprete Python, passando come argomento lo script esecutore main.py. Di default, lo script avvia la ricerca e l'esecuzione di tutti i test presenti nella directory; utilizzando dei 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 l'esito: • '.' per un test con esito positivo • 'F' per un test con esito negativo (asserzione disattesa) • 'E' per un test con errori Per i test con esito negativo o con errori viene generata una sezione con l'indicazione della riga che ha 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 esecuzione complessivo e l'esito della campagna di test, con il numero di test fallimentari o con errori se questi sono presenti. Esempi Per eseguire i test di verifica dei file XML contenuti in banners e webapplications si procede in questo modo: In questo esempio ci si serve della variabile python, valorizzata con il percorso dell'interprete. A main.py è passata come argomento la directory tests/bannersAndWebapps, in cui ricercare ed eseguire i test. Seguono alcuni caratteri punto, uno per ogni test eseguito, e il messaggio indirizzato al log nose.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. il messaggio finale 'OK' segnala che tutti i test della campagna hanno avuto esito positivo. In questo secondo esempio si eseguono i test contenuti nell'unità di test test_transformPatterns, per la funzione transformPatterns. In questo caso la campagna di test è lanciata con il parametro -v (verbose). Per ogni test nose genera un output più prolisso, che comprende nome e percorso del test, o stringa di documentazione, ed esito. Si mostra infine un esempio più significativo, non incluso nel progetto, con dei test fallimentari: 42
  • 43. PARTE SECONDA Generazione di espressioni regolari 4 Analisi 4.1 Descrizione del problema La seconda parte di questa tesi prende spunto da un problema riscontrato dopo aver messo a punto i test 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 cruciale nell'analisi degli endpoint remoti, spesso presentavano delle imprecisioni dovute ad errori umani. Molti errori tipici sono stati individuati dai test sviluppati nella prima parte; tuttavia nessuna campagna di test può garantire la totale assenza di errori umani, perché molti possibili errori non dipendono soltanto dalla coerenza con gli esempi di banner (i commenti del file XML) o con gli elementi <info>. Si sviluppa uno strumento di generazione automatica che prenda in input degli esempi di banner18 e fornisca delle possibili espressioni regolari conformi a tutti i banner di esempio. In altre parole, ogni espressione regolare generata deve individuare un linguaggio in cui devono essere contenute tutte le stringhe banner di input. Lo strumento vuole essere innanzitutto un ausilio all'operatore umano, del quale si richiede comunque un intervento finale di scelta dell'espressione regolare più adatta, o di aggiunta di caratteristiche note che non risultino evidenti dagli esempi di input. Inoltre, in espansioni future potrà essere utilizzato per costruire nuovi test. Come obiettivo generale, le espressioni regolari in output devono riflettere il più possibile le caratteristiche delle stringhe banner. Questa linea guida deve essere precisata nel corso della fase di analisi, in cui si definiscono le caratteristiche esatte che devono avere le espressioni regolari soluzioni del problema, anche in relazione 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. 4.2 Caratteristiche delle espressioni regolari dei file XML Osservando le espressioni regolari riportate nei file XML di banners e webapplications si nota che nella quasi totalità dei casi esse sono composte da una struttura scheletro di parole riportate letteralmente, entro la quale si inseriscono delle parti variabili, come parti opzionali, insiemi di caratteri validi, parti ripetute. Un'espressione regolare con questa struttura individua delle stringhe in cui sono presenti certamente delle sottostringhe comuni, che compaiono in un ordine fisso. Si nota inoltre che le parti variabili non compaiono quasi mai all'interno 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 casi incluse 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, l'underscore 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 all'inizio o alla fine della stringa. Ovviamente, le espressioni regolari includono dei gruppi capturing intorno alle strutture di interesse corrispondenti agli elementi <info>, perlopiù intorno a parti variabili. Questi costrutti conferiscono a porzioni di espressione regolare un valore semantico; dal punto di vista della corrispondenza tra espressione regolare e stringhe banner di esempio sono del tutto irrilevanti. 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. 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. 4.3 Definizioni Si elencano una serie di definizioni in riferimento all'insieme delle stringhe banner di esempio, che costituiscono l'input del generatore di espressioni regolari. In ogni stringa è individuabile uno scheletro di sottostringhe comuni a tutte le stringhe dell'insieme, 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 stringa Vista 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 ct Si 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 pattern Per 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 sequenza Inoltre 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
  • 47. Si definisce patternizzazione l'operazione in cui si individua la sequenza di pattern corrispondente a una stringa. Poiché ogni pattern di tipo D è anche di tipo W, questa operazione deve ricercare i pattern di tipo D prima di quelli di tipo W. Dal risultato è facilmente costruibile un'espressione regolare composta da pattern, conforme alla stringa originaria. Esempio Stringa: 'Welcome to Pure-FTPd 1.0.14' Sequenza di tipi di pattern: WSWSWPWSDPDPD Espressione regolare: '^w+s+w+s+w+[^sw]+w+s+d+[^sw]+d+[^sw]+d+$' Come convenzione di comodo si immaginerà che ogni stringa dell'insieme di banner sia disposta su una propria riga; si definiscono allora i concetti di: • elaborazione orizzontale: interessa una singola stringa e considera tutti i suoi element • elaborazione verticale: interessa la corrispondenza di un singolo element in tutte le stringhe 4.4 Definizione dei tipi di soluzione L'output della generazione deve essere un insieme di tipologie fisse di espressioni regolari, perlopiù a livelli successivi di specificità. Tutti i tipi di soluzioni devono considerare le stringhe banner fornite in input nella loro interezza, e generare delle espressioni regolari con gli ancoraggi per individuare l'inizio e la fine delle stringhe. Un'espressione regolare E priva di ancoraggi è logicamente equivalente a un'espressione regolare Ea, ottenuta inserendo in E gli ancoraggi e separandoli con '.*'. 47