WordPress: Sicherheitslücke in 2.8.3

Durch einen Bug in der aktuellen WordPress-Version ist es möglich, das Passwort eines Benutzers bzw. des Admins zu ändern. Wie auch caschy schreibt, hält sich der mögliche Schaden in Grenzen, solange der Angreifer keinen Zugriff auf das Mailkonto des Admins hat, denn der Angreifer kann dass Passwort nicht auf einen beliebigen Wert setzen. Es wird lediglich die Passwort-Reset-Funktion von WordPress durchgeführt, ohne dass der betroffene User davon erfährt. Nach einem erneuten Passwort-Reset durch den User kann dieser sein Konto ganz normal benutzen.

Um diese Sicherheitslücke zu schließen, reicht es, in der wp-login.php einige Zeichen einzufügen. So muss die Zeile 190 von

if ( empty( $key ) )

in

if ( empty( $key ) || is_array( $key ) )

geändert werden.

Der Hintergrund dieser Lücke ist, dass der reset_password-Funktion ein Parameter $key übergeben wird, der den Hashwert zum bestätigen der Passwortänderung darstellt. Ist dieser Wert leer, gibt WordPress in Zeile 190/191 einen Fehler aus

	if ( empty( $key ) )
		return new WP_Error('invalid_key', __('Invalid key'));

Bevor aber geprüft wird, ob $key leer ist, wird ein preg_replace auf den key ausgeführt (Zeile 188)

$key = preg_replace('/[^a-z0-9]/i', '', $key);

Tatsächlich ist mir der Sinn dieser Zeile nicht ganz eindeutig klar; auf jeden Fall gibt preg_replace in diesem Falle einen leeren String zurück, wenn $key nur aus Kombinationen kleiner Buchstaben und Zahlen besteht. Falls jedoch $key ein Array ist, gibt auch preg_replace ein Array zurück. So schließt sich der Kreis zu Zeile 190: Wenn man es schafft, die $key-Variable als Array zu übergeben, wird das Passwort des Users geändert, ohne dass dieser eine Mailbenachrichtigung bekommt, da die Funktion empty($variable) so mit Arrays nicht funktioniert (und für ein nicht-leeres Array false zurückgibt).
Der Angreifer muss es also nur schaffen, den Key als Array zu übergeben. Wie das funktioniert, werde ich hier nicht verraten – wer sich aber für weitere Details der Lücke interessiert, sollte mal hier vorbeischauen.

Es ist sehr leicht, diese Lücke auszunutzen und im Allgemeinen sollte daraus kein großer Schaden entstehen. Ich bitte trotzdem all diejenigen, die im Stande sind, den Exploit anzuwenden, dies nicht zu tun.

Update:
Eine bessere Lösung, statt is_array in Zeile 190:

if ( empty( $key ) || !is_string( $key ) )

9 Kommentare zu WordPress: Sicherheitslücke in 2.8.3

  1. Blubb's Gravatar Blubb
    Geschrieben am 11. August 2009 um 12:13 | Permalink

    “Ich bitte trotzdem all diejenigen, die im Stande sind, den Exploit anzuwenden, dies nicht zu tun.”

    Diejenigen die es tun wollen werden es tun – egal was du hier schreibst :-)

  2. Helge's Gravatar Helge
    Geschrieben am 11. August 2009 um 13:08 | Permalink

    Ich will ja nicht klugscheißen, aber war es nicht die wp-login.php in der das geändert werden muss? Bei Dir steht was von wp-admin.php (diese Datei gibt es auch im Übrigen gar nicht!)

    just my 2 cents.

  3. Geschrieben am 11. August 2009 um 13:58 | Permalink

    @Helge
    Richtig, ist wohl ein Tippfehler.
    Es sollte aber nicht der oben genannte Fix getätigt werden, sondern eher diesen.

  4. Geschrieben am 11. August 2009 um 16:19 | Permalink

    Die Zeile
    $key = preg_replace(‘/[^a-z0-9]/i’, ”, $key);
    macht, dass in $key nur Kleinbuchstaben und Ziffern stehen.
    Alles andere (daher “^a-z0-9″) wird entfernt (Ersetzung durch ”)

  5. Geschrieben am 12. August 2009 um 22:17 | Permalink
    $key = preg_replace('/[^a-z0-9]/i', '', $key);

    Tatsächlich ist mir der Sinn dieser Zeile nicht ganz eindeutig klar; auf jeden Fall gibt preg_replace in diesem Falle einen leeren String zurück, wenn $key nur aus Kombinationen kleiner Buchstaben und Zahlen besteht.

    Auf jeden Fall ist das Blödsinn!
    Wenn in der Variablen $key ein Passwort gespeichert/enthalten ist, dieses aber nicht (^ = Negation) aus Buchstaben oder Zahlen besteht, wird der Inhalt der Variablen $key durch einen Leerstring ersetzt.
    Dadurch greift die nächste Zeile “if ( empty( $key ) …” und generiert einen Error. Durch diese Maßnahme wird das “Einschleusen” von Code oder sonstigen Zeichen unterbunden = Sicherheitsmaßnahme, die hier etwas schluderhaft umgesetzt wurde.
    Übrigens bemerkenswert, wie viele Leute/ Blogbetreiber darüber herziehen, die 0 Ahnung von der Materie haben … ich verzeihe dem Programmierer (lehrt es mich doch selber wieder, Eingaben penibler zu überprüfen).
    Das kleine ‘i’ im regulären Ausdruck macht diesen übrigens ‘Case-Insensitivity’, d.h. Groß- und Kleinschreibung wird nicht beachtet. Statt dessen könnte man auch ‘/[^a-zA-Z0-9]/’ schreiben.

  1. By on 11. August 2009 at 12:41
  2. By on 11. August 2009 at 14:21
  3. By on 11. August 2009 at 16:10
  4. By on 12. August 2009 at 7:45
  5. By on 12. August 2009 at 9:22
  6. By on 12. August 2009 at 13:00
  7. By on 12. August 2009 at 13:42
  8. By on 20. Juni 2014 at 22:09

Einen Kommentar hinterlassen


Fatal error: Class 'OAuthSignatureMethod_HMAC_SHA1' not found in /www/htdocs/w00c048e/filzo.de/wp-content/plugins/twitter-tools/twitteroauth.php on line 62