Nell’analisi di applicazioni web spesso ci troviamo di fronte a situazioni nuove, mai viste e che necessitano di essere capite per poter identificare la presenza di bug o problemi nel codice del server. In questo articolo andremo a vedere come evadere una serie di filtri JavaScript, il che ci potrà essere utile in diverse situazioni.
Il primo segnale, da parte di un’applicazione web, di una possibile vulnerabilità di tipo XSS (Cross-Site-Scripting), è la presenza, nelle risposte emesse dal server, di stringhe che l’utente genera in input. Per fare un semplice esempio, immaginiamo che l’URL del nostro target sia
http://www.google.com
Se, richiedendo l’URL modificato
http://www.google.com/stringamalevola
l’applicazione inserisce “stringamalevola” in un messaggio di errore che viene mandato a schermo, allora l’applicazione potrebbe presentare una vulnerabilità di tipo XSS.
Notare che tale vulnerabilità potrebbe essere presente anche se la stringa “stringamalevola” fosse inserita dall’applicazione in qualche altro punto della sua risposta, cioè anche se non fosse mandata a schermo ma magari inserita in un virgolettato all’interno di un header. La presenza, all’interno della risposta dell’applicazione, della stringa da noi creata, è, tuttavia, condizione necessaria ma non sufficiente perchè la suddetta applicazione risulti vulnerabile a cross-site-scripting.
Allo stesso tempo, infatti, deve anche verificarsi, da parte dell’applicazione, una** fallace sanitizzazione della stringa inserita** in input dall’utente. Supponiamo di richiedere l’URL
http://google.com/<span style="color: #0d1f63;"><script>alert(123)</script></span>
Immaginiamo allora che l’applicazione risponda con il seguente messaggio: “Error Message, the requested url http://www.google.com/%3Cscript%3Ealert(123)%3C%2Fscript%3E_ was not found_”. In questo caso, l’applicazione ha sanitizzato correttamente i caratteri “<”, “>” e “/”, impedendo che lo script da noi inserito fosse eseguito.
Di fronte ad un tentativo, da parte dell’applicazione web, di sanitizzare le nostre stringhe malevole, esistono differenti stratagemmi che possiamo mettere in atto per** aggirare tale protezione** e fare in modo che l’applicazione esegua comunque i nostri script. Nei prossimi paragrafi vedremo i principali metodi per aggirare la sanitizzazione di codice Javascript.
Potenzialmente, esistono infiniti modi di creare nella nostra applicazione vittima un comportamento inatteso e, dunque, una sanitizzazione fallace del nostro codice. Quantunque sia impossibile elencarli tutti, è tuttavia possibile ridurre queste infinite possibilità a pochi e semplici schemi di pensiero ricorrenti, che possono facilmente essere ricordati e, di conseguenza, applicati. Vediamoli insieme:
Una delle possibilità più frequenti è che l’applicazione si protegga dai caratteri script, “<”, “>”. In questo caso, esistono principalmente due modi di ingannare tale schema di difesa:
<<script>>
o la stringa <<scr<<script>>ipt>>
, la sanitizzazione fallisca e il vostro codice venga eseguito con successo. Notate che non vi è un unico modo di eseguire questo attacco. A seconda della risposta dell’applicazione alle vostre stringhe, dovrete regolarvi adattando il vostro input, quindi anche le stringhe <scr<SCRIPT>ipt>
o <scr%00ipt> potrebbero funzionare.Il trucco è capire, osservando la risposta del server, quale schema di sanitizzazione viene utilizzato e cercare di romperlo innestando una stringa dentro l’altra, raddoppiando i tag, utilizzando null-bytes (%00), maiuscole o codificando il vostro codice.Talvolta, è possibile che l’applicazione non sanitizzi affatto il vostro codice e lo lasci così com’è, ma si protegga in altro modo. Facciamo conto di inviare in input il codice
<script>alert(123)</script>.
Osserviamo, quindi, la risposta del server:
<p> var err = “<script>alert(123)</script>”, var x = 2 </p>
Notate che, pur non avendo modificato il vostro codice, l’applicazione previene l’esecuzione dello stesso, inserendolo nel virgolettato. Quello che dobbiamo chiederci è, quindi, come evadere da questo virgolettato. Il modo più semplice è quello di chiudere il virgolettato prima che il vostro codice venga immesso nell’applicazione, inserendo il seguente codice:
“<script>alert(123)</script>
Il risultato sarà che le prime virgolette, inserite dall’applicazione, vengono chiuse da quelle inserite da voi all’inizio del vostro codice. Segue poi il codice che, come detto sopra, non viene sanitizzato, e poi le virgolette finali che non hanno più alcun significato e che vengono quindi ignorate dall’applicazione stessa. In questo modo, il vostro codice verrà eseguito con successo:
<p> var err = “”<script>alert(123)</script>”, var x = 2 </p>
Tuttavia, non sempre le cose risultano così semplici. Se l’applicazione si protegge da questo tipo di attacco sanitizzando il virgolettato (talvolta sia quello singolo che quello doppio), infatti, la tattica spiegata prima risulterà inefficace. Un modo di rispondere ad una tale tattica di difesa, può essere, nè più nè meno, quello spiegato all’interno del 1° caso.
nel caso che la vostra stringa venga incorporata direttamente all’interno di due caratteri di tag, è possibile ottenere che il nostro codice venga eseguito anche senza utilizzare “”. Ciò risulta fattibile grazie all’utilizzo degli event-handlers come, per esempio, onload, onclick, onmouseover. Il nostro payload sarà quindi simile al seguente:
http://www.google.com/”onload=”alert(123)”
che risulterà nella seguente risposta da parte dell’applicazione:
<h2 var err=”” onload=”alert(123)” var x = 2> Benvenuti</h2>
Nell’URL: poniamo il caso che il nostro URL si presenti come:
http://www.google.com/search=home
inserendo il nostro codice Javascript come valore di una variabile inesistente, potremmo ottenere che esso non venga sanitizzato:
http://www.google.com/search=home&pippo=<script>alert(123)</script>
Ciò potrebbe funzionare anche con una variabile già esistente dell’URL. In particolare, è importante sottolineare che ogni singolo entry-point dell’applicazione web va testato singolarmente per code-injection attraverso il nostro intercepting proxy (Burp, ZAP o altri). Infatti, criteri di sanitizzazione diversi potrebbero essere applicati a entry-point diversi o, addirittura, alcuni entry-point potrebbero essere sprovvisti di difese. 5. inviando la nostra richiesta dopo il carattere “#”, l’applicazione potrebbe fallire nell’applicare i suoi criteri di sanitizzazione. Un esempio, è il seguente URL:
http://www.google.com/#<script>alert(123)</script>
Non sempre sarà possibile bypassare i criteri di sanitizzazione di un’applicazione web ma, applicando le linee guida brevemente spiegate in questo articolo, potrete massimizzare le probabilità di riuscire ad eseguire il vostro codice sull’applicazione vittima. Ricordate che un’ultima forma di difesa può essere applicata dal browser, di conseguenza, quando testate un’applicazione, assicuratevi di disabilitare la protezione XSS nel browser e usate browser diversi, poichè, ognuno di essi, implementa difese differenti. Per chi volesse testare le proprie capacità consiglio XSS Game e alert(1) to win.