In questo articolo vedremo come creare un Threat Model per applicazioni web, che permetta di effettuare sessioni di penetration testing ben strutturate.
Il Threat Model non e' altro che un documento creato dall'attivita' di Threat Modelling.
All'interno del Threat Model e' presente (tra le altre cose) una lista delle minacce (ing. Threats)
identificate. Tale lista prende il nome di Threat Profile.
Perche' creare un Threat Model?
Come vedremo a breve, il threat model e' utile per guidare la maggior parte delle attivita',
il cui compito e' quello di aumentare il livello di sicurezza della mia applicazione (si pensi ad esempio alle attivita'
di security testing o di code review, oppure al fatto che permetta di poter quantificare se l'applicazione sta' migliorando o peggiorando in termini di sicurezza).
Noi ci soffermeremo in particolare sulla creazione del Threat Model come documento guida per
l'attivita' di penetration test.
In genere l'attivita' di penetration test e' svolta nel seguente modo, dopo una prima fase di "profiling" dell'applicazione,
si passa alla ricerca di vulnerabilita', senza tener conto di una qualsiasi struttura. In pratica, si procede alla
cieca nella ricerca di vulnerabilita'. Cio' comporta alcuni svantaggi, tra cui:
Andremo ora a descrivere quali sono le attivita' o fasi, da svolgere per creare un Threat Model. Tra i primi libri (se non il primo) a descrivere un processo per la creazione del Threat Model e' [3]. Nel nostro caso, comunque, prenderemo come modello le fasi suggerite in [4], e faremo le opportune modifiche dove necessario. Prima pero' e' necessario una definizione dei vari termini che utilizzeremo all'interno di questo articolo:
Identificare il Target di analisi e' di fondamentale importanza. Serve al tester per specificare
i limiti dell'attivita' di Threat Modelling. In questo modo, si evita di ritrovarsi in
situazioni di ambiguita' con il cliente. Se ad esempio non decidete di includere come target
l'analisi di vulnerabilita' del web server, avrete un buon motivo per evitare che il vostro
cliente vi faccia causa nel caso in cui degli attaccanti fossero penetrati nel suo sistema proprio attraverso un bug presente nel web server.
Indice
I Livelli di fiducia dell'applicazione sono concetti molto semplici. In pratica
identifico i ruoli all'interno dell'applicazione. Ad ogni ruolo andro' ad associargli un identificativo univoco
e una breve descrizione. I livelli di fiducia servono per meglio identificare le minacce e per fornire una migliore
valutazione del rischio associato. Un semplice esempio di elenco di livelli di fiducia e'
il seguente:
| Identificativo | Nome | Descrizione |
| TL.1 | Utente remoto anonimo | Rappresenta un utente che non si e' ancora autenticato (o che non puo' autenticarsi) all'interno dell'applicazione |
| TL.2 | Utente remoto autenticato | Rappresenta un utente che possiede delle credenziali valide e che si e' gia' autenticato nell'applicazione |
| Identificativo | Nome | Descrizione |
| TL.1 | Web Site Administrator | Amministratore dell'applicazione web |
| TL.1.1 | Utente remoto autenticato | Rappresenta un utente che possiede delle credenziali valide e che si e' gia' autenticato nell'applicazione |
| TL.1.1.1 | Utente remoto anonimo | Rappresenta un utente che non si e' ancora autenticato (o che non puo' autenticarsi) all'interno dell'applicazione |
Tra le prime fasi da intraprendere nell'attivita' di Threat Modelling vi e' l'identificazione degli Entry Points dell'applicazione.
Per dirla breve gli Entry Points sono i punti di ingresso con cui interagire con l'applicazione.
Pensando dal punto di vista dell'attaccante i vari entry point non sono altro che i parametri passati e tutti i
vari campi del protocollo HTTP. Qualcuno potrebbe obiettare sul fatto che anche ulteriori porte aperte sul
web server rappresentino degli entry points. Cio' e' vero, il tutto sta' nel definire quali sono i limiti
che ci si e' posti nella creazione del Threat Model. Ecco perche' abbiamo sottolineato l'importanza dell'identificazione del target.
Pur essendo questo un articolo teorico, non dobbiamo tralasciare l'aspetto pratico. L'identificazione di tutti gli entry points,
puo' essere un'operazione decisamente tediosa (dipende dalla dimensione dell'applicazione). Per fortuna ci vengono in aiuto
la presenza di svariati strumenti di spidering e web crawling (cercate queste parole sul vostro motore di ricerca preferito). Tramite il loro utilizzo e' possibile ottenere automaticamante
la maggior parte degli entry points dell'applicazione (prestate comunque attenzione, questi strumenti non sono del tutto affidabili e potrebbero
mancare qualche entry point fondamentale, per cui ricontrollate il tutto una volta finito lo scanning).
Un'altro consiglio e' quello di elencare gli entry points secondo uno schema gerarchico, cio' e' possibile soltanto assegnando ad ogni entry point un identificativo.
Facciamo un esempio, supponiamo di avere una pagina chiamata home.php.
Da questa e' possibile autenticarsi presso l'applicazione (i dati dell'utente e l'autenticazione vengono fatti sempre da home.php, non e' il
massimo del design ma va bene per il nostro esempio), inoltre sempre home.php permette di visualizzare degli articoli passandogli
come input un identificativo. A questo punto ho due diversi entry points, uno per il login e
uno per la visualizzazione dei prodotti. Questi entry points possono essere classificati
utilizzando la seguente numerazione:
| Identificativo | Nome | Descrizione | Livello di fiducia |
| E.1 | home page | Pagina iniziale dell'applicazione | TL.1 TL.2 |
| E.1.1 | Login Function | Funzione di login dell'utente | TL.1 TL.2 |
| E.1.2 | Product View | Funzioni di visualizzazione prodotto | TL.1 TL.2 |
Identificare gli assets da proteggere e' un'altra operazione di fondamentale importanza. Ogni minaccia e' rivolta ad un particolare asset, senza asset da proteggere
non esistono minacce. Gli assets possono essere di vario tipo, i primi a venire in mente sono
quelli di tipo concreto (perche' i piu' facili da identificare), come ad esempio le credenziali degli utenti, i loro dati personali, o le
loro carte di credito. Altrettanto importanti sono gli assets di tipo astratto, ovvero degli asset che non
sono concretamente identificabili, ma rappresentano comunque un bene da proteggere per l'azienda. Un tipico esempio
di asset astratto e' la credibilita' dell'azienda, si pensi ad esempio all'inpatto che si otterebbe se si venisse a sapere
che tutte le carte di credito dei miei clienti sono state trafugate.
Gli assets possono
essere elencati all'interno di una tabella e corredati da ulteriori informazioni. Cosi' come fatto per
gli entry points, anche per gli assets specificheremo il livello di fiducia che deve essere necessario per
poter avere accesso all'asset.
Introduciamo anche una colonna relativa ad una valutazione di
tipo qualitativo dell'asset, ad esempio e' sufficiente una valutazione a tre valori: High (H), Medium (M) e Low (L). In questo modo riuschiremo ad identificare in modo piu' preciso
la pericolosita' delle varie minacce associate.
Un tipico esempio di tabella e' proposto di seguito (supponiamo di analizzare un sito di e-commerce):
| Identificativo | Nome | Descrizione | Livello di fiducia | Rilevanza |
| A.1 | Credit Card | Il numero di carta di credito dei clienti dell'azienda | TL.1 | H |
| A.2 | Dati personali dell'utente | I dati personali dei clienti dell'azienda | TL.1 | H |
| A.3 | Affidabilita' | Rappresenta la fiducia che hanno i clienti nella sicurezza che l'azienda rivolge ai dati dei propri clienti | TL.1 | H |
| A.4 | Disponibilita' | Rappresenta la disponibilita' dei servizi del sito verso i clienti | TL.1 (soltanto l'amministratore ha il diritto di manipolare la disponibilita' del sito) | M |
In questa fase viene creato un diagramma ad alto livello dell'applicazione. La sua creazione sara' utile
in futuro per identificare piu' facilmente le minacce. Il tester tenendo sott'occhio gli assets da proteggere e il seguente diagramma,
andra' alla ricerca delle minacce. In questa sezione presenteremo comunque una metodologia che si discosta leggermente da quanto consigliato nei
vari articoli sul threat modelling. In [3] e [4] vengono suggeriti i Data Flow Diagrams (DFD) come strumento di
modellazione dell'applicazione. I DFD sono molto utili nel caso il Threat Model venga creato secondo una vista Feature-Level,
ovvero si crea il Threat Model concentrandosi sulle varie funzionalita' dell'applicazione. Rispetto a quanto da noi fatto, il feature-level Threat Modelling
e' un'attivita' di tipo verticale (ci si concentra su una singola funzionalita' dell'applicazione), mentre l'application-level Threat Modelling (quello da noi adottato) e' di tipo
orizzontale (ci si concentra sulla totalita' dell'applicazione). A causa della natura black box dell'attivita' di pen testing, non si hanno ha disposizione
sufficienti informazioni per creare un DFD che sia di una minima utilita'.
Ecco perche' in questo caso consiglio di utilizzare una Mappa di Navigazione (ing. Navigation Map, per ulteriori informazioni si guardi [5]). Un esempio di mappa di navigazione e' mostrata di seguito (immagine di esempio presa da google):

Una mappa di navigazione permette di creare una mappa che esprime in che modo ci si dovrebbe "muovere" all'interno
dell'applicazione, per chi mastica un po' di UML, assomiglia molto ad un diagramma di flusso (ing. flowchart).
I nomi dei vari nodi dovrebbero essere i nomi del file fisici, il loro titolo, oppure un nome significativo.
Nel caso in cui il sito risultasse di dimensioni sostenute, conviene scomporre la mappa di
navigazione in piu' parti a seconda ad esempio dei casi d'uso. Un'ulteriore miglioria e' quella di includere nei vari link anche eventuali
parametri passati all'url o informazioni rilevanti (ad esempio particolare campi HTTP, hidden parameters, cookie, etc...).
La mappa di navigazione non ha lo scopo di dimostrare che il tester ha una buona conoscenza del linguaggio
di modellazione UML, ma di fornire un aiuto al tester. Per cui non e' necessario creare un diagramma perfettamente corretto, optate meglio
per un diagramma abozzato, che non vi fossilizzi su tale processo di modellazione ma che vi possa essere di aiuto.
Indice
Siamo finalmente arrivati alla fase principale dell'attivita' di Threat Modelling. L'identificazione delle
minacce e' sicuramente la fase piu' difficile di tutto il processo. Arrivati a questo punto abbiamo
tutto cio' che ci serve per identificare le minacce. Cosi' come nell'identificazione degli assets anche in questa fase
dovremmo far affidamento anche sull'aiuto dei nostri committenti (o sui loro dipendenti) per riuscire ad identificare tutte
le minacce possibili. E' di fondamentale importanza che tutte le minacce siano correttamente
identificate. Cio' e' importante perche' in seguito andremo ad effettuare i nostri test in base alle
minacce identificate. Non solo tutte le minacce devono essre correttamente identificate, ma devono essere identificate
il prima possibile. Supponiamo ad esempio di mancarne una e di cominciare a testare la nostra applicazione.
Siamo quasi arrivati alla fine del nostro lavoro, quando ci accorgiamo di aver dimenticato di
includere nel Threat Profile una minaccia con alta priorita'. Se siamo fortunati, potremo includerla e
testarla il prima possibile, ma se il nostro lavoro e quasi al termine, potremmo non avere il tempo necessario ad
effettuare il testing, lasciando l'applicazione in uno stato in cui, nonostante i test effettuati e' ancora
altamente insicura.
Per cui la parola d'ordine in questa fase del threat modelling e':
Identificare tutte le minacce, e identificarle il prima possibile.
Come sempre andremo ad elencare le minacce con le relative informazioni in un'opportuna tabella. Cosi'
come fatto con gli assets, andremo a fornire, per ogni minaccia, una valutazione qualitativa (ad esempio High (H), Medium (M) e Low (L)).
Per stimare la priorita' di una miaccia non esistono al momento modelli consolidati (si tenga presenta che i vari modelli come DREAD e
compagnia bella servono a valutare il rischio di una vulnerabilita' associata ad una specifica minaccia).
Per toglierci dagli impicci, potremmo classificare ogni minaccia con la stessa importanza data al relativo asset associato.
Inoltre per comodita' future inseriremo anche un campo che ci indichera' se tale minaccia e' stata
testata (e con che esito) oppure no. Vediamo un esempio di tale tabella:
| Id: T.1 | Nome: Alterazione delle query inviate DB | Rilevanza: H | Esito Verifica: NON VERIFICATA | |||||||||||
| ||||||||||||||
| Id: T.2 | Nome: Disclosure of Login Information | Rilevanza: H | Esito Verifica: NON VERIFICATA | |||||||||||
| ||||||||||||||
Questa e' la fase piu' divertente, nonche' tra le piu' complicate (seconda solo all'identificazione delle minacce).
Arrivati a questo punto non rimane altro che identificare le possibili vulnerabilita' della nostra applicazione.
Dal nostro punto di vista identificare le vulnerabilita' in modo teorico guardando soltanto cio'
che e' stato fino ad ora prodotto, e' impossibile. Per cui e' ora di sporcarsi le mani sull'applicazione
ed iniziare la tanto agognata sessione di penetration test. La scoperta delle vulnerabilita'
dipende fortemente dal livello tecnico del tester, e spesso e' meglio affidarsi a professionisti del settore.
L'dentificazione delle vulnerabilita' deve avvenire secondo un preciso ordine. Per prima si analizzano
le minacce ad impatto maggiore. Scelta la minaccia da analizzare si comincia ad esaminare le possibili vulnerabilita', se e' presente un attack tree
esso puo' tornare utile in questo momento. A differenza delle minacce, per le vulnerabilita' non e' strettamente necessario identificarle tutte
immediatamente (si intende vulnerabilita' relative ad una stessa minaccia). Se durante l'analisi di una minaccia vi
rendete conto che esiste un'ulteriore possibile vulnerabilita', dovrete per prima cosa aggiornare le informazioni relative
alla minaccia (ad esempio l'eventuale attack tree) e in seguito procedere (appena possibile) al testing della vulnerabilita'.
Da qui si intuisce il motivo del perche' non e' strettamente fondamentale trovare tutte le vulnerabilita' subito, infatti
l'importante e' non mancare di identificare la minaccia, una volta che e' stata identificata e valutata, si puo'
agire con piu' serenita', ed eventualmente aggiornarla durante il processo di penetration test.
Come sempre per ogni vulnerabilita' trovata verranno registrate particolari informazioni in una
tabella. Un esempio di possibile tabella di vulnerabilita' e' la seguente:
| Identificativo | Nome | Descrizione | Valutazione rischio | Entry points | Minaccia associata | Mitigata |
| V.1 | SQL Injection | E' possibile eseguire un attacco di
tipo Sql Injection per autenticarsi senza essere in possesso di un account valido | 10 (DREAD) | E.1.1 | T.1 | NO |
| V.2 | Cross Site Scripting (XSS) | E' possibile eseguire un attacco di
tipo XSS per rubare il token di sessione di un utente e sfruttarlo per impersonificarlo | 6 (DREAD) | E.1.2 | T.3 | NO |
In questo articolo e' stato preso in esame il processo di Threat Modelling (per ulteriori informazioni vedere [11], [12], [13], [14], [15] e [16]) dal punto di
vista di un tester che sta' per eseguire una sessione di penetration test.
Nelle fasi iniziali e' necessario identificare quali sono gli Entry Points, i
vari Assets da proteggere e la creazione di una Mappa di navigazione. Prendendo in esame
questi tre documenti si procede con l'identificazione di tutte le possibili minacce e ad una loro
valutazione. Nel passo finale il tester puo' mettersi all'opera e cominciare la sessione
di penetration test, basandosi sulle minacce identificate. Per ogni vulnerabilita' scoperta andra'
a riempire la relativa riga all'interno della tabella delle vulnerabilita'. La scoperta
delle vulnerabilita' sara' guidata dall'ordinamento delle varie minacce.
In questo articolo e' stata presentata la teoria del threat modelling, in un successivo
articolo vedremo un esempio concreto dell'applicazione di quanto appena detto.
Concludiamo, sottolineando nuovamente l'importanza di eseguire un'attivita' di penetration testing di tipo strutturato che
sia guidato dal rischio, rispetto ad un processo di testing casuale.
Indice