Vor kurzem wurde eine sehr sicherheitsbedenkliche Schwachstelle bei WordPress entdeckt. Diese Schwachstelle ermöglicht es über die REST-API, einem nicht authentifizierten Benutzer, den Inhalt eines Posts oder einer Seite innerhalb einer WordPress-Website zu ändern.

WordPress selbst hat das Problem bereits erkannt und ein neues Update veröffentlicht. Die neue Version trägt die Nummer 4.7.2. Wie immer sollten Updates von WordPress umgehend eingespielt und die CMS-Software ausschließlich mit der neuesten Version betrieben werden.
An dieser Stelle weisen wir auch noch einmal auf die Wichtigkeit der Updates hin: Auch alle eingesetzten Plugins und Templates sollten regelmäßig auf Updates überprüft werden und diese auch stets zeitnah installiert werden.

Was ist die REST-API und wozu benötige ich sie?

REST steht für Representational State Transfer. Es handelt sich um ein zustandsloses Client-Server-Protokoll, das überwiegend über das HTTP-Protokoll verwendet wird. Kurz gesagt, REST wird verwendet, damit andere Websites, mobile Anwendungen, Desktop/Server-Software und andere Komponenten, Daten einfach und automatisch empfangen können, ohne der Notwendigkeit über den Browser auf die Website zuzugreifen.

Sind Sie davon betroffen?

Diese Schwachstelle welche eine Rechteausweitung („privilege escalation“) zur Folge hat wirkt sich auf die WordPress REST API aus, die kürzlich hinzugefügt und standardmäßig seit WordPress 4.7.0 aktiviert wurde.

Durch Manipulationen der URL bzw. von GET- oder POST-Variablen kann ein Angreifer beliebige Artikel und Beiträge ändern und schadhaften Code einschleusen, wodurch die komplette Website kompromittiert und verseucht werden kann.

Die REST-API ist standardmäßig auf allen Websites mit WordPress 4.7.0 oder 4.7.1 aktiviert. Wenn Ihr WordPress eine dieser Versionen hat, dann ist ihr System derzeit anfällig und sollte unbedingt auf 4.7.2 aktualisiert werden.

Technische Details

Sieht man sich die Probleme im Detail an, stößt man zuallererst auf diese Datei: ./wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php

wpimg_1

Die registrierte Route ist so ausgelegt, dass die Variable ID Ziffern entgegennimmt. Wenn Sie zum Beispiel eine Anfrage an /wp-json/wp/v2/posts/1234 senden, wird der ID-Parameter auf 1234 gesetzt.

Diese Methodik ist ein guter Weg um vorzubeugen, dass der Angreifer andere Zeichen als nummerische eingibt und somit böswillige ID-Werte erstellt.Wenn wir uns jedoch genauer ansehen wie die REST-API den Zugriff verwaltet, sehen wir, dass die $_GET and $_POST Variablen, welche über die regular expression der Route erzeugt werden, priorisiert werden.

Dies ermöglicht es einem Angreifer, eine Anfrage wie: /wp-json/wp/v2/posts/1234?id=12345beliebigeZeichenkette zu schicken – 12345beliebigeZeichenkette würde nun dem ID-Parameter zugeordnet werden und würde somit mehr als nur nummerische Zeichen beinhalten.

Betrachtet man die Callbacks (im Screenshot oben) ist einer davon sehr interessant: das update_item und seine Berechtigungsprüfmethode update_item_permissions_check.

wpimg_2

Die Kurzfassung: es wird ein alphanumerischer ID-Wert an die get_post()-Funktion übergeben. Diese Funktion validiert die Anforderung, indem überprüft wird ob der Beitrag tatsächlich existiert und ob der Benutzer die Berechtigung hat, diesen Beitrag zu bearbeiten.

Damit wird die Anfrage aber nicht völlig korrekt validiert. Wird nämlich eine ID gesendet welche keinen entsprechenden Beitrag hat, kann die Berechtigungsprüfung ausgehebelt und die Ausführung in der update_item-Funktion fortgesetzt werden!

Was könnte die Funktion get_post() also dazu bringen, dass sie keine Beiträge findet? Die Funktion get_post() verwendet die statische Funktion get_instance() um auf Beiträge zuzugreifen.

wpimg_3

Wie man im Code sieht, würde jeder Input fehlschlagen der nicht komplett aus numerischen Zeichen besteht – also 123ABC würde nicht funktionieren.

Für einen Angreifer würde das bedeuten, dass WordPress die update_item Funktion aufrufen würde. Diese Funktion sieht wie folgt aus:

wpimg_4

Es gibt hier ein sehr subtiles, aber wichtiges Detail in diesem letzten Screenshot – WordPress konvertiert („casted“) den ID-Parameter auf einen Integer vor der Ãœbergabe an die Funktion get_post() (1./2. Zeile in der Funktion update_item()!

Dies ist ein Problem aufgrund der Art wie PHP Vergleiche und Konvertierungen durchführt. Folgendes Beispiel würde 123 retournieren wenn eine Konvertierung der Ziffern- u. Zeichenkombination auf Integer durchgeführt wird:

wpimg_5

 

 

Dies führt zu einer wirklich gefährlichen Situation in welcher ein Angreifer eine Anfrage wie Folgende senden könnte: /wp-json/wp/v2/posts/123?id=?id=5811XYZ um den Beitrag mit der ID 5811 zu manipulieren!

Aufgrund dieses Konvertierungsproblems ist es dann möglich, dass ein Angreifer den Inhalt eines Beitrags oder einer Seite ändern kann.

Von dort aus können die Angreifer dann Plugin-spezifische Shortcodes hinzufügen, um Schwachstellen auszunutzen, den Websiteinhalt mit einer SEO-Spam-Kampagne infizieren, oder Anzeigen injizieren, usw.

Abhängig davon welche Plugins auf der Website installiert sind, könnte dadurch sogar PHP Code ausgeführt werden („Remote Code Execution“).

Gegenmaßnahmen

Wenn die WordPress-API nicht verwendet wird, sollten die API-Zugriffe serverseitig deaktiviert werden.

Zugriff auf API verhindern (Nginx)

location /wp-json/wp/v2 {

return 404;

}

Zugriff auf API verhindern (Apache)

# mod_alias

Redirect 404 /wp-json/wp/v2

# mod_rewrite

RedirectMatch 404 /wp-json/wp/v2

Global kann man dies auf einem Webserver auch mit folgender Regel verhindern: (Apache)

<LocationMatch /wp-json/wp/v2>

Order Deny,Allow

Deny from All

</LocationMatch>

Absicherung durch .htaccess

RewriteEngine on

RewriteCond %{REQUEST_URI} ^/wp-json/wp/v2

RewriteRule ^ – [F]

Schlussfolgerung

Wenn Sie bei Ihrem System die automatischen Updates deaktiviert haben, sollten Sie dieses unbedingt auf die Version 4.7.2 updaten.

Es handelt sich hier um eine wirklich schwerwiegende Schwachstelle die auf unterschiedlichste Weise missbraucht werden und schwere Folgen mit sich ziehen kann.

internex hat wie immer proaktiv reagiert und alle Hostingserver sofort geschützt. Wollen auch Sie beruhigt schlafen? Professionelles WordPress-Hosting ab 4,90€.

 

Veröffentlicht am