In den letzten Tagen wurden verschiedene Projekte auf diesem Server — unter anderem auch dieses Blog — massiv durch einen destruktiven Zeitgenossen angegriffen. Zum Glück ist es mir gelungen, diese Angriffe abzuwehren, ferner habe ich die Vorgehensweise des Angreifers an Hand der Logdateien analysieren können. Dies ermöglicht es mir auch, Empfehlungen für andere Blogger auszusprechen, die WordPress verwenden. Der Text wird etwas länger, aber meines Erachtens für viele Menschen interessant. Ich werde versuchen, die technischen Details so gut wie möglich zu erklären, aber natürlich bin ich wegen meiner im Laufe von einigen Jahrzehnten gewachsenen Kompetenz oft ein bisschen blind für die Probleme gewöhnlicher Anwender — meine eigene Anfängerphase ist inzwischen gründlich verdrängt.
Der Schaden
Vor zwei Tagen, am 18. Juli, bekam ich in der sehr vorgerückten Nacht einen recht heftigen Schreck. Zwei der Projekte — es handelt sich ebenfalls um WordPress-Blogs — die auf diesem Server gelagert sind, waren von einem Cracker mit einem völligen Defacement und ein paar dummen Sprüchen in haarsträubend miserablen Englisch „verziert“ worden. Mein Schreck war so groß, dass ich sogar vergaß, einen Screenshot für die spätere Dokumentation anzufertigen. Ja! Sogar meine heitere Stimmung war für eine gute Minute lang ein wenig getrübt. 😉
Auf diesem Server kann ich mich fast beliebig austoben, es handelt sich eigentlich um den manchmal etwas widerspenstigen Streaming-Server eines Webradios, den ich „nebenbei“ administriere, weil es niemand anders gut kann. Deshalb kann ich mich über ssh
— das ist eine sichere Verbindung, die das Arbeiten an der Kommandozeile gestattet — am Server anmelden und darauf arbeiten. Genau das war auch nach einer kleinen Schrecksekunde meine erste Tat, um den angerichteten Schaden genau in Augenschein nehmen zu können.
Was ich dort sah, entzückte mich nicht besonders. Die Dateien der beiden stark betroffenen Blogs waren teilweise zerstört, hochgeladene Dateien wurden entfernt und in einem dieser Blogs wurde zusätzlich die gesamte Datenbank gelöscht. Andere Projekte waren weniger betroffen, aber völlig unversehrt war keines.
Die folgenden Erläuterungen sollen anderen WordPress-Anwendern helfen, solche Schäden einzugrenzen oder zu verhindern.
Meine Vorsorge
Nun, ich hatte ein wenig Vorsorge gegen diesen schlimmsten anzunehmenden Unfall eines Website-Betreibers getroffen. Jedes unixoide System kennt einen Dienst namens cron
, der es ermöglicht, beliebige Programme automatisch und regelmäßig auszuführen. Wer erfahren möchte, wie man diesen Dienst anwendet, setze einfach ein man crontab
an der Kommandozeile ab. Über diesen Dienst lasse ich in jeder Nacht ein kleines Shellskript ausführen, das mir einen Schnappschuss der verwendeten Datenbanken in einem Verzeichnis auf diesem Server ablegt. Dieses Skript sieht übrigens so aus (Pfade, Datenbanknamen, den Namen des Datenbank-Servers und die Passwörter habe ich hier natürlich geändert, aber dennoch sollte jeder dazu fähig sein, sich so ein Skript an die eigenen Bedürfnisse anzupassen):
#!/bin/sh prefix=/pfad/zum/backup/dir`date +%Y%m%d-%H%M`- dbs="datenbank_1 datenbank_2 datenbank_3" for i in $dbs do mysqldump --add-drop-table \ --comments \ --compress \ --create-options \ --host=mein_hostname \ --user=datenbank_admin_username \ --password=datenbank_admin_password \ --quote-names \ $i | gzip -c >$prefix$i.sql.gz done
(Ja, werter Experte, ich weiß, die Optionen für mysqldump
kann man auch kürzer schreiben. Aber in solchen Skripten werde ich immer ein bisschen „geschwätzig“, da ich im Zweifelsfall auch unter Stress erkennen muss, was im Skript „abgeht“. Erfahrung ist übrigens die Summe von Misserfolgen, aber das ist ein ganz anderes Thema…)
Wichtiger Hinweis: Natürlich sollte man so ein Skript, in dem ein Passwort für den Zugang auf eine Datenbank hinterlegt ist, so ablegen, dass der Zugriff darauf nicht möglich ist. Es hat für niemanden außer seinen Benutzer lesbar, schreibbar oder ausführbar zu sein. Auch das Ausführen muss für andere User unterbunden werden, sonst könnte ein Angreifer dieses Skript ausführen und sich mit einem ps aux
anschauen, wie die Kommandozeile mit dem Passwort aussieht. Und das soll er auf keinen Fall herauskriegen können.
Wegen dieser Vorsorge hatte ich einen Schnappschuss der betroffenen Datenbanken, der weniger als einen Tag alt war. Mit Hilfe dieses Schnappschusses habe ich beim am stärksten betroffenen Projekt auf der Stelle einen Notbetrieb ermöglicht. Dazu habe ich die Datenbank schnell wiederhergestellt, indem ich auf der Kommandozeile…
zcat sicherungsdatei.sql.gz | mysql datenbank_name -u datenbank_admin_username -p
…absetzte, das Passwort des Datenbank-Admins eingab und im Dashboard des betroffenen und so wiederhergestellten Blogs sämliche User (das Blog wird von mehreren Leuten „befüllt“) auf „Registrierter Leser“ setzte und die Kommentarfunktion abschaltete. Ich wusste ja noch nicht, wie dieser Angriff ausgeführt wurde. Damit hatte zwar niemand mehr Schreiberlaubnis, aber die textuellen Inhalte blieben im Internet verfügbar.
Meine Vorsorge war also Gold wert.
Anmerkung für „blutige Laien“: Wenn man solche Sicherungen mit einem automatischen Verfahren macht, sollte man sich in regelmäßigen Abständen davon überzeugen, dass die Sicherung auch wirklich wie gewünscht abläuft und im Krisenfall brauchbar ist. Die einfachste Methode, dies zu tun, ist der Import des SQL-Dumps (so nennt man einen solchen Schnappschuss) in eine leere und unbenutzte Datenbank. Wenn dies ohne Fehlermeldung läuft, ist alles in Ordnung. Im Idealfall setzt man hierzu einen lokalen MySQL-Server auf seinem Arbeitsrechner auf. Für Linuxer ist das kein Problem, sie installieren einfach das entsprechende Paket ihrer Distribution. Wer Windows oder Mac OS benutzt, ist für den Hausgebrauch mit XAMPP bestens bedient.
Als nächstes schnappte ich mir die Logdatei des Webservers (ein Webserver dokumentiert jeden einzelnen Zugriff in einer fortlaufenden Textdatei) und legte mir eine lokale Kopie für die spätere Analyse an. Dann legte ich mich schlafen.
Ein besonderer Dank geht an M., die mir diese ersten Maßnahmen zur Eingrenzung des Schadens über ihre Telefonleitung und ein Modem (!!!) ermöglichte.
Ein weiterer Teil meiner Vorsorge betrifft das Verzeichnis auf dem Server, in dem WordPress läuft. Ich habe die Dateirechte in meinen Projekten alles in allem recht restriktiv vergeben, so dass die WordPress-Dateien nicht mit den Rechten des Webservers überschrieben werden können. Der Nachteil dieser Vorgehensweise ist es natürlich, dass ich niemals einfach aus dem WordPress-Dashboard eine Datei meines Themes editieren kann; der Vorteil ist jedoch, dass auch ein Angreifer das nicht kann. Mit Ausnahme des Upload-Verzeichnisses kann der Webserver auf alle Dateien nur lesend zugreifen. Auch diese Präventention hat sich im Nachhinein als wichtig erwiesen, sie hat nämlich verhindert, dass dieses Blog ebenfalls zerstört wurde. Aber dazu später etwas mehr…
Erste Gedanken und ein zweiter Schreck
Als ich am nächsten Morgen aufwachte, habe ich einen Kaffee getrunken und mir allerhand Gedanken gemacht. Ich setze hier ja eine etwas ältere WordPress-Version ein, ein 2.3.3 — da können natürlich jede Menge Fehler auf einen Menschen warten, der sie sich zunutze macht, um Teile eines Webservers zu übernehmen. Aber. Ich bin dabei auch sorgsam und habe ein Auge auf alle Sicherheitsmeldungen. WordPress 2.3.3 hat viele kleine Schwächen, aber bislang noch keine, die so arg ist, dass mir der Upgrade zu einer nicht funktionierenden Bloatware wie WP 2.5 erforderlich schien.
Nun hatte ich erhebliche Selbstzweifel wegen dieser Entscheidung. Was. Wohl jedem verständlich sein sollte.
Als ich dann beim ersten Blick auf das im Notbetrieb laufende Projekt feststellen musste, dass die Inhalte durch eine weiße Seite ersetzt wurden, wuchsen meine Selbstzweifel ob dieses Schreckes sogar noch an. Ich musste mir ganz schnell anschauen, was da auf dem Server los war. Aber zunächst verfasste ich einen quicken Hinweis an die Leser dieses Blogs, damit sie einen eventuellen Missbrauch durch einen Cracker richtig einschätzen können.
Eine Randnotiz: Es ist übrigens keine Schande, wenn man „gehackt“ wird, und niemand muss sich dafür schämen. Jeder Rechner, der permanent am Internet hängt, ist immer auch ein Opferrechner, der diversen Angriffsversuchen aller Art ausgesetzt ist. Und manchmal wird aus einem solchen Versuch auch ein erfolgreicher Angriff. In einem solchen Fall halte ich es — gerade, wenn man eine große und treue Lesergemeinschaft hat — für besser, offensiv an die Öffentlichkeit zu treten, bevor manipulierte Inhalte auf der Website einen völlig unerwünschten Eindruck hinterlassen können. Wenn immer es irgend möglich ist, sollte ein stummes Abschalten vermieden werden.
Die Analyse
Danach schaute ich mich wieder über ssh
auf dem Server um und analysierte die gesicherten Logdateien. Die Verfahren, die ich bei der Analyse anwandte, sind nicht leicht zu beschreiben und würden einen technischen Laien überfordern. Was aber jeder kann, ist, die Logdatei in einem Texteditor zu öffnen und nach verdächtigen Aktivitäten Ausschau zu halten — die Suchfunktion des Editors kann dabei eine große Hilfe sein.
In meinem Fall stellte ich zwei hoch verdächtige Aktivitäten fest. Zum einen gab es über Stunden hinweg jede Sekunde drei Versuche, sich durch Zugriff auf die Datei wp-login.php
in WordPress einzuloggen. Nachdem diese Aktivität aufhörte, wurden nach einer Pause von ca. 15 Minuten verschiedene PHP-Dateien über die Upload-Schnittstelle (die in der Regel zum Einfügen von Bildern verwendet wird) hochgeladen, die anschließend ausgeführt wurden. Hier hat jemand ein schwaches Passwort und ein vorhandenes Problem in der Konfiguration ausgenutzt und einen Webserver nach allen Regeln der Kunst „geowned“…
Die vielen Login-Versuche deuten darauf hin, dass der Angreifer eine Wörterbuch-Attacke gegen das angegriffene Blog gefahren hat. Tatsächlich wurden von mehreren Autoren die Login-Namen als Anzeigenamen sichtbar, so dass nur noch eine Jagd auf ein schlechtes Passwort erforderlich war, die dann irgendwann auch Erfolg hatte.
Natürlich wurden die IP-Adressen anonymisiert, so dass auch eine Strafanzeige fruchtlos bleiben würde. (Zudem finde ich das Einschalten der Ermittler ein bisschen „unsportlich“.)
So weit, so schlecht.
Die erste hochgeladene Datei trug den Namen c99.php
, über diese Datei wurde der Rest des Angriffes vorgetragen. Dieses c99.php
ist eine recht vollständige, in PHP geschriebene Shell, mit deren Hilfe ein Angreifer ziemlich beliebig im Dateisystem und zusätzlich noch auf einem MySQL-Server rumpfuschen kann. Natürlich läuft diese Shell „nur“ mit den Rechten des Webservers, so dass nicht alles im Dateisystem geht — hier erwiesen sich meine restriktiven Dateirechte als richtig, und jede Schwäche in der Vergabe dieser Rechte wurde vom Angreifer recht erbarmungslos „abgestraft“, indem er über die c99.php
weitere Skripten hochlud, die sich kein Mensch auf einen Webserver wünschen kann, und indem er diese Skripten auch ausführte.
Erläuterung für „normale“ Menschen: Eine „Shell“ ist ein Programm, das zum Start anderer Programme verwendet werden kann und seinem Anwender das Dateisystem eines Rechners zur Verfügung stellt. Der Angreifer konnte mit der hochgeladenen Shell auf diesem Server „arbeiten“, was er auch weidlich tat. Und „Skripten“ sind Programme, die in einer so genannten „Skriptsprache“, das ist eine interpretierte Programmiersprache, verfasst sind. Zum Beispiel ist WordPress eine recht komplexe Sammlung von Skripten.
Eines dieser Skripten war eine weitere Shell, die einen Socket öffnete und auf Verbindungen wartete. Über diese Shell hat der Angreifer weitergemacht, ohne Spuren in der Logdatei des Webservers zu hinterlassen — was es mir erschwerte, die Vorgehensweise des Angriffs zu verfolgen. Deshalb habe ich auch die gelegten Hintertürchen beim ersten Versuch nicht vollständig schließen können.
Noch eine Erläuterung: Ein „Socket“ ist ein TCP-Port, auf dem ein Programm wartet, um dort über das Netzwerk — in diesem Fall das Internet — Verbindungen zu akzeptieren und Eingaben zu verarbeiten. In der Regel wird das Programm auch Aktionen ausführen, das tat auch das kurz beschriebene Skript.
Was ich jedoch sicher weiß, ist, dass der Angreifer mithilfe der c99.php
die Datenbank des angegriffenen Projektes gezogen hat und unter Umständen immer noch als lokale Kopie vorliegen hat. Hierzu hat er sich zunächst die wp-config.php
angeschaut, die ja für den Webserver lesbar sein muss, da WordPress sonst nicht auf die Datenbank zugreifen könnte. Darin stehen unerfreulich klar die Zugangsdaten für die Datenbank, und mit Hilfe dieser Angaben konnte der Angreifer die Datenbank nach Belieben manipulieren.
Wichtige Randnotiz: Die Tatsache, dass sich ein destruktiver Zeitgenosse mit einem bisschen Glück über eine Wörterbuchattacke und einen einfachen Upload die Datenbank eines Blogs abgreifen kann, sollte jedem Blogger klar machen, dass die angegebenen Mailadressen der Kommentatoren in die Hände eines solchen Fieslings geraten können. Wer die Mailadressen seiner Leser nicht einem dahergelaufenen Kriminellen preisgeben möchte, sollte sie auch nicht dauerhaft in der Datenbank speichern. Natürlich funktionieren ohne Speicherung der Mailadressen die Gravatare nicht mehr, aber diese kleinen Bildchen sind wirklich keine unbedingt notwendige Funktion eines Blogs, und es ist mir völlig unverständlich, weshalb dieser gefährliche Anreiz zur unnützen Datenspeicherung zum Bestandteil des Kerns von WordPress 2.5 geworden ist — so etwas gehört meines Erachtens in ein Plugin für jene, die es unbedingt haben müssen. Unter dem Aspekt der Sicherheit gilt die Regel: Weniger ist mehr, und weniger unnütze Funktion ist mehr Sicherheit.
Der Angreifer hat in zäher Handarbeit versucht, weitere Rechte auf diesem Server zu erwerben, da er mit den Rechten des Webservers nicht allzuviel weiteres Unheil anrichten konnte. Zum Glück ist ihm das nicht gelungen. Diese Handarbeit hat ihm Stunden gekostet und war sehr ausdauernd. Das sollte jedem eine Warnung sein, der die Destruktivität mancher Zeitgenossen unterschätzt — als Lohn dieser Mühe wäre nur ein recht unbedeutender gehackter Server übernommen worden, auf dem ein paar recht harmlose und unbedeutende Blogs und ein Internetradio laufen. Sicherheit ist auch bei kleinen und relativ unbekannten Projekten wichtig.
Als der Angreifer die Nutzlosigkeit seines Treibens einsehen musste, hat er aufgegeben. Aber nicht, ohne so viel zu zerstören, wie ihm noch möglich war.
Weitere Klärung des Schadens
Da der Angreifer nur mit den Rechten des Webservers arbeiten konnte, war es relativ einfach, die von ihm angelegten Dateien und damit alle noch vorhandenen Hintertüren aufzuspüren, da sie allesamt dem technischen Benutzer www-data
gehörten. Hierzu reichte es aus, die Dateien mit einem einfachen…
find . -user "www-data" | grep -v "upload/"
…an der Kommandozeile aufzuspüren und unschädlich zu machen. Dabei hat sich gezeigt, dass der Angreifer durchaus gute Ideen hatte, auf welche Weise Dateinamen „unverdächtig“ gemacht werden können. Von den gut 60 Dateien, die sich lustig über verschiedene Projekte verteilten, erhielten viele einen Namen, der in einer WordPress-Installation zunächst plausibel wirkt, zum Beispiel wp-find.php
, wp-search.php
oder wp-text.php
. Ein unerfahrener Anwender hätte keine Chance gehabt, diese überall verteilten Hintertüren an ihren Dateinamen zu erkennen, und selbst ich kenne nicht jede Datei in den Tiefen eines WordPress namentlich.
Wer von einem ähnlichen Angriff betroffen ist und nicht auf der Stelle vesteht, was ich mit der Phrase vom „technischen User www-data
“ meine, sollte besser seine gesamte WordPress-Installation löschen (natürlich mit Ausnahme der Konfiguration und der wirklich eigenen Uploads) und die Dateien neu aufspielen. In jedem Fall im Upload-Verzeichnis nach verdächtigen Dateien mit der Endung .php
, .phtml
, .cgi
, .pl
oder ähnliches suchen und diese Dateien löschen.
Abschließendes
Zunächst bedanke ich mich bei dem teilweise erfolgreichen Angreifer für seine Mühe, mir eine kostenlose Sicherheitsschulung zu geben. 😉 Nach dem Schließen der letzten hinterlegten Hintertür habe ich die ausgenutzten Schwachstellen in den betroffenen Projekten beseitigt, so dass der gleiche Angriff nicht noch einmal möglich ist. Ein wirklich planvoller Mensch, der es darauf anlegt, unentdeckt zu bleiben, hätte über diese Lücken längere Zeit auf diesem Server arbeiten können, ohne dass mir dieser Angriff aufgefallen wäre. Zu meinem Glück strebte der Angreifer nicht danach, eine langfristige Strategie mit Geduld zu verfolgen, es ging ihm „nur“ um Zerstörung.
Natürlich habe ich mir die kleine Mühe gemacht, alle Passwörter zu ändern, die in verschlüsselter Form in der Datenbank enthalten waren. So kann der Angreifer auch mit den spärlichen Informationen, die er sich unterm Nagel gerissen hat, nicht viel anfangen. Die betroffenen Benutzer sind informiert, dass sie gegebenenfalls ihr Passwort auch an anderen Stellen ändern, falls sie dort das gleiche verwenden. Der Angriff war also oberflächlich erfolgreich, immerhin wurde für gut 40 Minuten ein Defacement auf einer Website sichtbar, die nachfolgend noch einmal für ein paar Stündchen verschwand, auch ist die Zerstörung hochgeladener Dateien geglückt; aber diesem „Erfolg“ steht keinerlei ausbeutbare Nachhaltigkeit gegenüber.
Was allerdings einen Menschen bewegt, zehn Stunden Arbeit für ein dermaßen ärmliches und dümmliches „Ergebnis“ zu investieren, gehört einem Seelenleben an, das mir völlig fremd und unverständlich ist.
Im Folgenden gebe ich noch ein paar Hinweise, wie ein solcher Angriff sicher abgewehrt werden kann.
Wie man einen solchen Angriff abwehrt
Sichere Passwörter verwenden
Der Angreifer hat über eine Wörterbuchattacke Gelegenheit gefunden, sich in das Blog einzuloggen. Jedes Passwort, dass aus einem regulären Wort mit ein paar Ziffern oder Sonderzeichen daran besteht, ist gefährlich. Wenn der Angreifer Autorenrechte erhält, kann er schon eine Datei hochladen, was fürchterliche Konsequenzen haben kann.
Login-Namen nicht anzeigen
WordPress hat die angenehme Eigenschaft, dass der angezeigte Benutzername vom Login-Namen abweichen kann. Wenn man davon Gebrauch macht, muss der Angreifer zwei Wörter erraten, was den Aufwand einer Wörterbuchattacke viel größer macht. Es ist sogar möglich, sein Login genau so kryptisch wie ein Passwort zu wählen, ohne dass diese Maßnahme beim Betrachten des Blogs auch nur erahnt werden kann.
Admin-Account löschen
Nach der Installation eines WordPress-Blogs entsteht ein Account mit dem Login-Namen admin
, der volle Verwalter-Rechte im Blog hat. Dieser Account sollte unbedingt gelöscht werden, da dieser Benutzername sehr leicht zu erraten ist. Vor dem Löschen einen normalen Benutzer anlegen, der die erforderlichen administrativen Rechte hat, dann mit diesem Benutzer anmelden und den Standard-Administrator löschen. Das kostet nur eine Minute und kann einem Stunden der Nacharbeit in einem gehackten Blog ersparen.
Restriktive Dateirechte vergeben
Je weniger mit den Rechten des Webservers geschrieben werden kann, desto besser. Nach dem ersten Upload einer Datei wird ein Verzeichnis uploads
unter wp-content
angelegt, dies ist das einzige Verzeichnis, in dem der Webserver Schreibrechte benötigt. Alle anderen Verzeichnisse sollten auf 755
, alle anderen Dateien auf 644
gesetzt werden und nicht dem User gehören, unter dessen Kennung der Webserver läuft. Dieser Funke Prävention hat bei meinem frisch erlebten Angriff viel Schaden verhindert, und alle Schäden tauchten dort auf, wo ich in der Rechtevergabe nachlässig war.
Datenbankerwägungen
Wann immer möglich, sollten sich nicht mehrere Projekte die gleiche Datenbank teilen, um einem erfolgreichen Angreifer nicht allzuviele Informationen preiszugeben. (Das ist in dieser Form nicht bei jedem Hoster möglich.) Für die Datenbank-Anmeldung von WordPress sollte ein eigener Benutzer eingerichtet werden, der nur lokalen Zugriff (Host: localhost
) hat, falls die Datenbank auch extern erreichbar ist. In keinem Fall sollte jemals in der Konfigurationsdatei einer Webanwendung so etwas Wichtiges wie das Passwort des Datenbankadministrators stehen, sonst darf man sich nicht über große Schäden wundern.
Immer muss ein regelmäßiges und funktionierendes Backup von der Datenbank gemacht werden, um einen Verlust der Daten zu verhindern. Wie oft ein Backup angelegt wird, ist eine Frage der Änderungshäufigkeit und Aktualität des Blogs; wer nur einmal in der Woche postet, muss nicht jeden Tag ein Backup anlegen. Die Verfahrensweise beim Backup ist eine Frage der eigenen Vorlieben und des Geschmacks, für viele dürfte es ausreichen, regelmäßig einen Dump mit einem Tool wie PHPMyAdmin zu ziehen, andere werden etwas mehr wollen. Aber das Backup muss sein!
Verzeichniserwägungen
Es kann nicht verhindert werden, dass ein erfolgreicher Angreifer mit einem irgendwie ermittelten Login Dateien hochlädt, wenn er sich mit Autorenrechten anmelden kann. Aber es kann oft verhindert werden, dass PHP-Dateien im Upload-Verzeichnis ausgeführt werden. (Ob dieses Überschreiben der Konfiguration für ein bestimmtes Verzeichnis möglich ist, erfährt man bei seinem Hoster.) Hierzu einfach im Upload-Verzeichnis die folgende Datei .htaccess
hinterlegen…
php_flag engine off AddType text/plain .shtml .php .php3 .phtml .phtm .pl .py .cgi
…und schon ist das Ausführen von Dateien im Upload-Verzeichnis deutlich erschwert. Auch diese Maßnahme gewährt natürlich keine absolute Sicherheit, wenn der Webserver fehlerhaft konfiguriert ist und ausführbare Dateien einfach ausführt, denn die Extension spielt in unixoiden Systemen keine Rolle. In der Regel werden jedoch nur Dateien mit den hier angegebenen Extensions beim Zugriff über den Webserver ausgeführt. Diese relativ einfache Maßnahme könnte große Schäden im Ansatz vermeiden.
Ich würde mir übrigens sehr wünschen, dass zukünftige Versionen von WordPress diese Datei beim Erstellen des Upload-Verzeichnisses automatisch anlegen, wenn ein Überschreiben der Konfiguration möglich ist.
Die Tatsache, dass die Dateien im Upload-Verzeichnis bei einem Angriff gelöscht werden können, zeigt, dass ein regelmäßiger Backup dieses Verzeichnisses ebenso eine Notwendigkeit sein kann wie der Backup der Datenbank, da man sonst leicht viele Stunden Nacharbeit nach einem Angriff hat. Hier war ich ein wenig nachlässig, was dazu führt, dass ich gleich noch ein wenig zu tun habe. Auch hier ist die erforderliche Frequenz des Backups davon abhängig, in welchem Maße Bilder und andere Dateien hochgeladen werden. Wer als typischer Fotoblogger jeden Tag ein Foto hochlädt, sollte regelmäßiger die Daten sichern als jemand, der nur hin und wieder eine Datei an einen Blogbeitrag hängt.
Ich hoffe, dass ich mit diesen Hinweisen ein paar Menschen geholfen habe.
Und nein, es war keine spezifische Schwäche von WordPress 2.3.3, die da von einem destruktiven Zeitgenossen ausgebeutet wurde. So weit ich das absehen kann, wäre ein vergleichbarer Angriff auch gegen ein WordPress 2.5 möglich. Auch der aktivierte „safe-mode“ von PHP war keine große Hilfe, sollte aber dennoch Standard sein. Niemand wiege sich in Sicherheit, nur weil er die aktuelle WordPress-Version verwendet!
💡 Ich habe gerade festgestellt, dass ausgerechnet dieser überlange und wenig erfreuliche Text meine tausendste Veröffentlichung in diesem Blog ist. Dafür hätte ich mir lieber etwas Besseres aufheben sollen. Na ja, manchmal drängt sich ein gewisses Material eben auf…
Trotzdem: 1000 bleibt eine erfreuliche Zahl.
congrats!
Chapeau!
Muss mein System auch mal überprüfen.
Was hat eigentlich die Firewall zu den eröffneten Socket gesagt? Normalerweise sollte da doch alles dicht sein, was nicht explizit erlaubt ist.
Natürlich hat mein Sparringpartner im Vorfeld einen Portscanner verwendet, der aus nahe liegenden Gründen auf dem Server herumliegt, um zu schauen, welche Ports überhaupt nach draußen kommen können. Und ich lasse hier wegen eines Teststreams für neue DJs bei Toxic Apple zwei Ports durch die Firewall, die im Normalbetrieb nicht benutzt werden und deshalb diesen kleinen Zugang gestattet haben. Der hat sich wirklich eine Menge feiner Handarbeit gemacht.
Dass ich den anderen auch noch die Konfiguration eines Paketfilters vor dem Starten des Testservers erläutere, ist einfach ein bisschen zuviel des Guten…
Menno, erst den Kleenen nicht zuende spielen lassen und dann noch über ihn lachen! 😀
Nun, fein jedenfalls, dass Du weiter auf Sendung bist. 🙂
Hallo, dein kleiner Kriminalfall war spannend zu lesen. Aber eine Frage hätt ich noch: wenn eine IP 3 mal pro Sekunde, und das minutenlang, versucht sich einzuloggen, sollte der Angriff an dieser Stelle nicht eigentlich schon aufzuhalten sein? Stichwort „Flood-protection“ bei Webservern. Was sagst du dazu?
MfG, michi
Zu michi (6): Im Prinzip ja. Aber aus der Sicht des Webservers war das ein ganz normaler Seitenabruf bei jedem Login, nichts besonderes. Der Angreifer hat ja auch immer ein bisschen Abstand gehalten. Beim Nachladen von Bildern in einer Website (zum Beispiel die Smilies über diesem Kommentarfeld) kommen sehr viel mehr HTTP-Requests innerhalb einer Sekunde als bei diesem Angriff, und das muss durchgehen. Es kann recht schwierig sein, bei einem nicht gerade strunzdumm durchgeführten Angriff die Parameter für einen solchen Schutz so zu setzen, dass der normale Betrieb davon unbeeinflusst bleibt.
Eigentlich sollte WordPress hier Mechanismen haben, die einer solchen Häufung von gescheiterten Logins von einer Adresse entgegentreten. Wenn nach dem zehnten gescheiterten Login von einer IP für ein Viertelstündchen gar nichts mehr ginge, wenn diese IP einfach nur noch „Temorarily unavailable“ zurückkriegte, denn wäre ein solcher Angriff auch erschwert. Allerdings würde diese wieder eine DoS-Attacke ermöglichen, wenn man einen populären und viel benutzten Proxy für scheiternde Logins verwendet und damit den Benutzern dieses Proxies das Blog einfach wegzieht.
(Über das zweite habe ich nämlich schon kurz nachgedacht, es wäre ein hübsches WP-Plugin.)
Vielen Dank für den gut geschriebenen Artikel, hab ich wieder etwas lernen können und werde mal sehen wie ich das bei mir umsetzen kann.
Und Gratulation zum 1000 Post 🙂
PS. Kann es sein, dass dein Smilieplugin ein Fehler hat? Da werden einige Smilies in der Smilieleiste zwei bis drei mal angezeigt.
Zu Gnafu (8): Na, bei mir sieht die Reihe mit den Smileys so aus, wie sie aussehen soll. Aber wenn da doch noch ein kleiner Bug drin sein sollte, betrifft er wenigstens keine Grundfunktion… 😉
Kannste mir bitte evtl. die PHP-Dateien des Angreifers zur Verfügung stellen?
Zu Christian (11): Mail kommt gleich… 😉