Protokoll der Beseitigung eines WordPress-Hacks (Viagra Spam)

Um über Änderungen von mir betreuter Webseiten informiert zu sein, nutze ich den kostenlosen und empfehlenswerten Dienst changedetection.com. Dieser sendete mir letzten Freitag eine Nachricht über folgende Änderung:

View changes:  2014-09-27 04:17    29 new words, 0 deleted words, 6% change
Anfrage Impressum Poststelle Plastikkarten rite aid viagra price hydrochlorothiazide discount fastest generic viagra shipping generic celexa ingredients good Plastikkarte als Taschenkalender 2014 ... sind Komplettanbieter von Plastikkarten you can try here discount levitra rx generic brand of neurontin viagra cialis order online kompletter Service Datenaufbereitung,

Da weder ich noch meine Kunden im Viagra-Vertrieb tätig sind, deutete dies auf einen erfolgreichen Webseiten-Spam-Angriff hin.

Durch Webseiten-Spam kompromittierte Webseite
Durch Webseiten-Spam kompromittierte Webseite

Der Besuch der Seite brachte für mich zunächst die Überraschung, dass ich dort diesen Spam NICHT sehen konnte. Erst nach dem Abmelden bzw. dem Seitenaufruf im privaten Browsermodus sah ich den Spam auf der Startseite.
Der Spam wird also angemeldeten Administratoren NICHT angezeigt!

Zunächst editierte ich den Artikel um festzustellen, dass der Spamtext sich NICHT im Artikel befindet. Dies bestätigte auch eine Überprüfung des Artikels in der mysql-Datenbank.
Da die Seite Teil einer Multisite-Installation ist, dauerte es nicht lange, bis auch andere Seiten meiner MS-Installation diesen Spam beinhalteten.
Eine Durchsuchung der MySQL-Datenbank führte mich zunächst in die irre. Denn sehr viele Kommentare, beinhalten „VIAGRA“. Allerdings wurden diese alle korrekt von den von mir sehr geschätzten AntispamBee-Plugin als Spam erkannt und NICHT veröffentlicht. Erst als alle Spamkommentare auf allen Seiten gelöscht wurden, wurde eine Durchsuchung der mysql-Datenbank aussagekräftig, brachte aber keine Ergebnisse.

Zum Glück habe ich einen Shell-Zugang zum Webserver und kann so mit Linux-Bordmitteln vorgehen:

zunächst suchte ich mit
grep -rl 'Viagra' /var/www/clients/client7/web5/web/
und stellte fest, dass der ausgegebene Text im Klartext in einigen Dateien zu lesen ist, nämlich in den Cache-Dateien, die das eingesetzte Cachify anlegt. Natürlich ist Cachify völlig unschuldig und tut nur seinen Job, es cacht die Inhalte der ausgelieferten Seiten. Das Löschen des Cache ist folglich keine Lösung des Problems, denn dieser wird in kurzer Zeit wieder mit dem ungewünschten html-Code gefüllt.
Das wäre ja auch zu einfach gewesen.

Anschließend habe ich mit wget die aktuelle deutsche WordPress-Install geholt und in einem tmp-Ordner entpackt.
Danach wurden die installierten Dateien mit der Originalversion verglichen:

diff -rq /var/www/clients/client7/web5/web /var/www/clients/client7/web5/tmp/wordpress | mail -s "Wordpress-Abweichungen der Installation vom Originalpaket" root

Die Sichtung der Vergleichsergebnisse ergab einige Änderungen an den Sprachdateien, die aber offensichtlich einem hinzugekommenen Zeilenumbruch einer zwei Tage neueren Sprachversion geschuldet sind. Geändert wurden auch mehrere index.php-Dateien in Ordnern, die ein Webseitenbesucher nicht einzusehen hat. Dort wurden zwischenzeitlich im WordPress-Code das ?> am Ende entfernt. Darüber hinaus wurden folgende Unterschiede ermittelt:

diff /var/www/clients/client7/web5/web/wp-includes/post-template.php /var/www/clients/client7/web5/tmp/wordpress/wp-includes/post-template.php
223c223
<       $content = str_replace( ']]>', ']]&gt;', $content );@include_once("rss-info.php");
---
>       $content = str_replace( ']]>', ']]&gt;', $content );

Die Datei rss-info.php war base64-coded und enthielt vermutlich ein Schadcodecontainer.

diff /var/www/clients/client7/web5/web/wp-includes/default-constants.php /var/www/clients/client7/web5/tmp/wordpress/wp-includes/default-constants.php
301d300
< @include_once(ABSPATH.WPINC."/js/tinymce/cache.php");

Auch die Datei cache.php ist base64-coded und enthielt vermutlich ein Schadcodecontainer.

Bedingte Weiterleitung

Bemerkenswert und beunruhigend erscheint mir die Tatsache, dass die Weiterleitung auf die verlinkte URL offensichtlich nur dann funktionierte, wenn man von Google kommend auf die Seite verlinkt (Referrer) wurde. Klickt man direkt auf der kompromitierten Seite auf den Link erscheint eine Fehlermeldung, weil die „Unterseite“ nicht existiert. Wird man jedoch von Google auf die kompromitierte Seite mit dem internen Link weitergeleitet, wird man zu der externen Seite verwiesen, welche (vermutlich) Schadcode beinhaltet. Mehr hierzu siehe unten bei den Lektüretipps „Conditional Redirects“. Leider lässt sich dieses Verhalten für mich derzeit nicht mehr exakt nachvollziehen.

Was tun?

Nach der Entfernung der Schadcode-Dateien und der include-Anweisungen bleibt die Frage: Durch welche Sicherheitslücke wurde es möglich Schadcode in  das wp-includes-Verzeichnis einzuschleusen. So lange die Ursache hierfür nicht gefunden und beseitigt ist, bleibt da System gefährdet.

Am besten wäre natürlich die Sicherheitslücke abstellen. Das zweitbeste ist es, eine erneute Kompromittierung frühzeitig zu entdecken.
Das durchsuchen des Webspace nach Dateien, die eine Zeichenfolge „,base64_decode(“ beinhalten ist hierbei hilfreich. Zwar mag es auch gute Gründe geben, dass sich base64 kodierte Inhalte dort befinden, diese Ausnahmen kann man aber überblicken.

Zwei Cronjobs in der Art:
grep -rl ',base64_decode(' /var/www/clients/client7/web5/web/ | mail -s "Liste der Base64 codierten Dateien" root
und ein Vergleich der Originaldateien mit den verwendeten in der Art:
diff -rq /var/www/clients/client7/web5/web /var/www/clients/client7/web5/tmp/wordpress| grep "sind verschieden" | mail -s "modifizierte Dateien bei Multisite-Installation" root
informieren zumindest.

ERGÄNZUNG:

Plugin-Empfehlungen

Zwischenzeitlich ist wieder Ruhe eingekehrt und ich habe zumindest einen Verdacht welches Plugin für den Hack verantwortlich gewesen sein könnte. Die Cronjobs habe ich zwischenzeitlich wieder entfernt und durch eine wesentlich bessere Lösung ersetzt, die im Prinzip ähnlich vorgeht: Das WordPress Plugin Wordfence vergleicht nun täglich die Übereinstimmung der installierten Dateien mit den Originalversionen und blockt automatisch IPs von Angreifern. Darüber hinaus ermöglicht es in einer Live-Ansicht die aktuell erfolgenden Zugriffe zu beobachten und manuell IPs oder Netzwerke zu blockieren. Ein meiner Meinung nach sehr empfehlenswertes Plugin für WordPress-Webmaster.

Google Webmaster Tools versagen auf ganzer Linie

Für mich auch überraschend war die „Dummheit“ der Google-Webmaster Tools. Nachdem Wordfence die Ausgabe der installierten WordPress-Version unterdrückt, erhielt ich eine Warnmeldung von Google Webmaster-Tools, dass ich eine veraltete WordPress-Version einsetze. Der Algorithmus von Google folgert aus der Tatsache, dass es eine WordPress-Installation entdeckt und der Tatsache, dass keine Version angegeben ist, dass es sich um die Version 3.5.1 handelt. Schon viele andere Webmaster haben dieses Fehlverhalten im Google-Forum kritisiert – verbessert wird der Algorithmus nicht, stattdessen wird darauf hingewiesen, dass das Verbergen der WordPress-Version nicht empfohlen wird. Des weiteren überrascht, dass Google allen Ernstes ca. 360 Viagra-Cialis-Links, die der Hack angelegt hatte als ernsthafte Links indiziert und nun, nachdem dieser Müll entfernt ist und Google-Robots massenhaft 404-Fehler erhalten mich warnen, dass viele Seiten nicht mehr erreichbar sind. Die Seiten sind weder intern noch extern verlinkt – doch Google nimmt sie in den Index – und entfernt Sie auch nach einer Woche 404-Fehlern noch nicht. Intelligent ist dieses Verhalten nicht. Nicht erkennen, dass so eindeutig als Webseiten-Spam zu identifizierende Links Spam sind, lässt mich sehr an der Qualität der Google-Algorithmen zweifeln.


Lektüretipps:

Autor: Ralph Lindner

Hier blogge ich zu Themen wie Internet, Technik, Lernen, Städteplanung oder Mobilität.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.