DVWA SQL Injection

Ciao a tutti, la write-up di oggi riguarderà la vulnerabilità DVWA SQL Injection.
I requisiti sono:

L’app DVWA propone due tipi di vulnerabilità, SQL Injection, e SQL Injection Blind.
Inizierò subito con la vulnerabilità SQL Injection Blind dato che è la più complicata e divertente da scovare.
Il risultato di un attacco SQL Injection nei migliori dei casi restituirà il classico messaggio:

“You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right etc…

Ma non è sempre così, alcune pagine vulnerabili in caso di errore potrebbero mostrare l’intera pagina senza porzioni di testo o immagini che normalmente verrebbero visualizzate.
Per questo procedere all’individuazione delle injection, un po alla cieca, deriva il termine Blind.

DVWA SQL Injection Blind – Low Level

Come al solito nel livello basso non bisogna aspettarsi nessun controllo particolare.
La prima cosa fondamentale è quella di vedere come si comporta la pagina vulnerabile in caso di errori o meno, così da poter confrontare i risultati con i paylods.
La pagina richiede di inserire un numero id, e la mia scelta è ricaduta sul numero1:

DVWA SQL Injection

DVWA SQL Injection 01 – Output Ok

Per riprodurre un errore ho inserito il classico apice:

DVWA SQL Injection

DVWA SQL Injection 02 – Output con Errore

A questo punto avendo tutti e due i tipi di risposta è possibile attaccare lo sctipt per fare dei raffronti.
Iniettando una query mysql che restituisce sempre un risultato falso, mi aspetto di ricevere un risultato identico allo screenshot precedente (fig. 02).
La condizione “AND 1=2 #” restituirà sempre un errore perché 1 non sarà mai uguale a 2. Il cancelletto serve a commentare il proseguo della query vulnerabile.

DVWA SQL Injection

DVWA SQL Injection 03 – Injection Low Level con errore

Per avere la conferma di aver trovato il payload giusto, vado ad iniettare una query che darà un risultato positivo.
La condizione AND 1=1 #” non restituirà mai un errore perché 1 sarà sempre uguale a 1. Il cancelletto serve a commentare il proseguo della query vulnerabile.

DVWA SQL Injection

DVWA SQL Injection 04 – Injection Low Level senza errore

Bingo! Confrontando lo screenshot 04 con lo 01 si può notare il medesimo risultato!

DVWA SQL Injection

DVWA SQL Injection 05 – Sorgente Low Level

Il sorgente è chiaro, non esiste alcun filtro sulla variabile $id:

        // Get input 
        $id = $_GET[ 'id' ];  

Questa è la query originale:

    $getid  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";

Mentre questa è il risultato della query dopo l’injection:

    $getid  = "SELECT first_name, last_name FROM users WHERE user_id = '1' and 1=1 #;"; 

DVWA SQL Injection Blind – Medium Level

In questo livello è necessario utilizzare un plugin o proxy che permetta di intercettare o manipolare le richieste $_POST , io ho optato per il proxy Burp Suite.
Per prima cosa ho configurato il proxy nelle impostazioni del browser FireFox :

DVWA SQL Injection

DVWA SQL Injection 06 – Medium Level Configurazione Burp Suite

Come di consueto controllo la risposta della pagina senza iniettare alcun payload:

DVWA SQL Injection

DVWA SQL Injection 07 – Medium Level Risposta Burp Suite

Tramite metodo $_POST viene inviato un intero tramite la variabile id, vediamo il risultato:

DVWA SQL Injection

DVWA SQL Injection 08 – Medium Level Risposta corretta

L’attacco utilizzato nel precedente livello naturalmente non può funzionare, quindi ho modificato leggermente il payload.
Questa volta testo per prima la condizione positiva senza apice e cancelletto, ovvero “1 and 1=1“.
Per fare ciò modifico la richiesta intercettata dal proxy e la eseguo premendo il bottone “Forward“:

DVWA SQL Injection

DVWA SQL Injection 09 – Medium Level preparazione attacco

La risposta è interessante, sembra a tutti gli effetti identica allo screenshot numero 08.

DVWA SQL Injection

DVWA SQL Injection 10 – Injection Medium Level senza errore

Per verificare la vulnerabilità, tramite il proxy inietto una condizione negativa”1 and 1=2” :

DVWA SQL Injection

DVWA SQL Injection 11 – Medium Level preparazione attacco False

Ottimo! Ricevendo un errore ho la conferma che il payload utilizzato è quello giusto.

DVWA SQL Injection

DVWA SQL Injection 12 – Injection Medium Level con errore

Controlliamo il sorgente:

DVWA SQL Injection

DVWA SQL Injection – Sorgente Medium Level

In questo livello la variabile id viene filtrata tramite la funzione php mysql-real-escape-string() :

        // Get input 
        $id = $_POST[ 'id' ]; 
        $id = mysql_real_escape_string( $id ); 

Tale funzione inserisce il carattere backslashes davanti ai seguenti caratteri \x00, \n, \r, \, , e \x1a  ma in questo caso è inutile perchè la variabile della query non è racchiusa tra apici o virgolette:

    $getid  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";

La query iniettata risulterebbe così:

    $getid  = "SELECT first_name, last_name FROM users WHERE user_id = 1 and 1=1;"

DVWA SQL Injection Blind – High Level

Nel livello più alto vulnerabile ho deciso di utilizzare il plugin di firefox Tamper Data per manipolare le richieste.
Potevo continuare ad utilizzare Burp Suite ma così colgo l’occasione di mostrare un eventuale alternativa.
Per riprodurre il flusso dell’applicazione fondamentalmente si deve cliccare sul link “Click here to change your ID” (fig 13), poi inserire il numero id nella finestra pop-up (fig 14-15), infine leggere la risposta sulla pagina (fig 16).

DVWA SQL Injection

DVWA SQL Injection 13 – Injection High Level

DVWA SQL Injection

DVWA SQL Injection 14 – Injection High Level

DVWA SQL Injection

DVWA SQL Injection 15 – Injection High Level

DVWA SQL Injection

DVWA SQL Injection 16 – Injection High Level

Come sui può notare negli screenshots precedenti l’applicativo ci suggerisce che l’id sarà passato tramite i Cookie.
Per modificare la richieste è necessario attivare il plugin sul browser:

DVWA SQL Injection

DVWA SQL Injection 17 – Injection High Level

Riproduco il flusso precedente, e dopo aver inserito un numero nella finestra pop-up premo il pulsante “Tamper“:

DVWA SQL Injection

DVWA SQL Injection 18 – Injection High Level

A questo punto ho cominciato a cercare il payload giusto iniettandolo nel Cookie…:

DVWA SQL Injection

DVWA SQL Injection 19 – Injection High Level

…fino a quando non ho trovato “1′ and 1=1 #” che non mi ha restituito alcun errore:

DVWA SQL Injection

DVWA SQL Injection 20 – Injection High Level

SQL Injection trovata!
Diamo uno sguardo al sorgente:

DVWA SQL Injection

DVWA SQL Injection 21 – Injection High Level

Come si può notare la variabile $id non è filtrata:

// Get input
$id = $COOKIE[ 'id' ];

DVWA SQL Injection Blind – Impossible Level (mitigazione)

DVWA SQL Injection

DVWA SQL Injection 22 – Injection High Level

Per prima cosa viene controllato se la variabile id è a tutti gli effetti solo un numero,  dopo di che la query viene  eseguita con le prepared statements:

        // Was a number entered? 
        if(is_numeric( $id )) { 
            // Check the database 
            $data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' ); 
            $data->bindParam( ':id', $id, PDO::PARAM_INT ); 
            $data->execute(); 

Le prepared statments sono fondamentali contro gli attacchi sql injection e ci vengono incontro nel caso in cui dovessimo scordarci di filtrare i dati input.
Se sieste sviluppatori vi raccomando di approfondire l’argomento.

DVWA SQL Injection (No Blind) Low, Medium, High + XSS Bonus

A mio parere questa vulnerabilità non merita una write-up a parte perchè gli applicativi e i metodi di exploit sono praticamente identici.
L’unica differenza è che in caso di SQL Injection individuata, l’applicazione risponde con un bel errore MySQL a video.
Una cosa divertente che ci tengo a mostrare è la vulnerabilità XSS presente in tutti e tre i livelli:

DVWA SQL Injection

DVWA SQL Injection 23 – XSS Low Level

DVWA SQL Injection

DVWA SQL Injection 24 – XSS Medium Level

DVWA SQL Injection

DVWA SQL Injection 24 – XSS High Level

Anche per oggi è tutto, e prometto che la prossima volta cercherò di essere più coinciso!
ByEeeE