
Proof-of-Concept-Exploit für CVE-2018-1000533, eine Sicherheitslücke zur Remote-Code-Ausführung in GitList 0.6.0 durch unsanitisierte Eingabe in der Suchfunktion, die beliebige Befehlsausführung ermöglicht.
GitList ist ein moderner Git-Repository-Viewer.
In GitList 0.6.0 und früheren Versionen existiert eine Schwachstelle, bei der nicht ordnungsgemäß validierte Eingaben an Systemfunktionen übergeben werden, sodass beliebige Befehle mit den PHP-Benutzerrechten ausgeführt werden können.
Um den GitList-Server 0.6.0 zu starten, führe den folgenden Befehl aus:
docker compose up -d
Installiere die Abhängigkeiten vor dem Ausführen von poc.py.
pip install requests
Sobald die Umgebung eingerichtet ist, rufe http://127.0.0.1:8080 auf und überprüfe, ob das Test-Repository example existiert.
GitList verwendet git grep, um im Repository nach Code zu suchen.
public function searchTree($query, $branch)
{
if (empty($query)) {
return null;
}
$query = escapeshellarg($query);
try {
$results = $this->getClient()->run($this, "grep -i --line-number {$query} $branch");
} catch (\RuntimeException $e) {
return false;
}
Hierbei bezeichnet $query das Suchschlüsselwort und $branch den zu durchsuchenden Branch.
Wenn ein Angreifer als Suchbegriff --open-files-in-pager=id; übergibt, wird der Befehl id auf dem System ausgeführt.
Diese Schwachstelle tritt aus zwei Gründen auf:
Grenzen der Funktion escapeshellarg()
Theoretisch wird die Eingabe durch die Codezeile $query = escapeshellarg($query); in einen von einfachen Anführungszeichen umschlossenen String umgewandelt. Allerdings verhindert escapeshellarg() zwar eine Injection aus Sicht der Shell, aber nicht, dass der Option-Parser von git selbst einen String, der mit -- beginnt, als Option interpretiert.
Besonderheit der Option --open-files-in-pager
Diese Option von git grep dient dazu, ein externes Pager-Programm anzugeben, das die Suchergebnisse anzeigen soll. Sie hat die Eigenschaft, den übergebenen Wert direkt als Systembefehl auszuführen.
[repo_name]/tree/[keyword]/search), enthält zwei Argumente: [repo_name] und [keyword].[repo_name] muss ein in GitList vorhandenes Repository sein, und [keyword] muss ein Suchbegriff sein, der mindestens ein Suchergebnis liefert.
(Für diese Reproduktion wurde das Repository example und das Schlüsselwort a verwendet.)Führe poc.py mit dem folgenden Befehl aus.
Durch das Skript wird touch /tmp/success_dddo0 ausgeführt, wodurch im Verzeichnis /tmp des Servers eine leere Datei namens success_dddo0 erstellt wird.
python3 poc.py http://127.0.0.1:8080
Nachdem die Anfrage gesendet wurde, überprüfe mit folgendem Befehl, ob success_dddo0 erfolgreich erstellt wurde.
docker compose exec web ls -l /tmp/success_dddo0
Nach der Ausführung des PoC kann festgestellt werden, dass ein beliebiger Systembefehl (touch /tmp/success_dddo0) erfolgreich auf dem Server ausgeführt wurde und die Datei erstellt wurde.

docker compose down
GitList sollte auf die neueste Version aktualisiert werden.
Code-Änderungen:
public function searchTree($query, $branch)
{
if (empty($query)) {
return null;
}
$query = preg_replace('/(--?[A-Za-z0-9\-]+)/', '', $query);
$query = escapeshellarg($query);
try {
$results = $this->getClient()->run($this, "grep -i --line-number -- {$query} $branch");
} catch (\RuntimeException $e) {
return false;
}
GitList hat diese Schwachstelle behoben, indem es mittels regulärem Ausdruck illegale --Präfixe aus dem Suchbegriff ($query) entfernt und dem git grep-Befehl ein -- (Kennzeichnung des Endes der Optionen) hinzugefügt hat, sodass alle nachfolgenden Eingaben nicht mehr als Befehlsoptionen, sondern nur als normale Zeichenketten (Suchbegriff) behandelt werden.