Ein Vormittag im Leben eines SysAdmins
8:00 Uhr
Ich schaue mir wie immer morgens die Serverstatistik an. Das Programm Cacti bereitet mir vielfältige Daten als Diagramm auf. So zum Beispiel auch die CPU-Last einer Maschine. In CPU-Last-Diagramm eines Servers ist direkt um Mitternacht herum eine extreme Lastspitze zu sehen:

Das ist seltsam.
8:05 Uhr
Ich logge mich per SSH auf den Server ein und nehme mir die Logdateien vor. Gleich in der ersten stoße ich auf eine weitere Spur. In im "Slow-Query"-Log von MySQL sind SQL-Abfragen zu sehen, die nur langsam abgearbeitet werden konnten. Just um Mitternacht wurden einige Abfragen an die Datenbank geschickt, die den MySQL-Befehl "BENCHMARK()" enthalten. Auch das ist seltsam, denn diesen Befehl verwendet man eigentlich nur, um Leistungsdaten des Servers zu ermitteln. Sendet man diesen Befehl exzessiv, könnte man den Server mit einer Denial-of-Service-Attacke außer Gefecht zu setzen.
8:15 Uhr
Zunächst suche ich die Web-Software, die auf dem Server läuft, nach einem Skript ab, das diesen MySQL-Befehl nutzt - Fehlanzeige. Das ist alarmierend, denn zur fraglichen Zeit war niemand auf dem Server eingeloggt. Das bedeutet, dass jemand per SQL-Injection über ein Wordpress-Skript selbst gebaute SQL-Abfragen an die Datenbank schicken kann, was ein großes Sicherheitsrisiko ist, um es noch vorsichtig auszudrücken.
8:25 Uhr
Auf dem Server läuft Wordpress 2.1.3. Die 2.2er-Version läufit nicht, denn ständig auf die neueste Version zu aktualisieren ist ein großer Kostenfaktor, besonders wenn das Weblog gut besucht ist und ständig unter Strom steht. Außerdem sollen die Zweige 2.0 und 2.1 neben der aktuellen Version 2.2 weitergepflegt werden. Auf http://wordpress.org/download/release-archive/ steht:
"... the latest in the 2.0 or 2.1 series ... are both actively maintained."
Kürzlich wurde in der Version 2.2 eine SQL-Injection-Lücke entdeckt. Das betraf aber nur Code, der mit Version 2.2 eingeführt wurde. Sollte es sich um eine neue Lücke in Version 2.1.3 handeln? Ich war zunächst etwas ratlos und recherchierte weiter im Web.
8:40 Uhr
Auf SecurityFocus.com suche ich nach Lücken speziell zu Wordpress 2.1.3. Dort sehe ich unter anderem eine SQL-Injection-Lücke vom Mai 2007. Die Lücke ist also schon über einen Monat alt und es gibt keinen Patch! Ich traue meinen Augen nicht. Die Beschreibung verrät, dass über das Skript /wp-admin/admin-ajax.php JEDER SQL-Abfragen an die Datenbank schicken kann. Man muss nichtmal eingeloggt sein. In der Version 2.2 ist der Fehler behoben. Der Entdecker der Lücke liefert zum Glück ein Beispielskript mit, das die Lücke demonstriert. Ist dieses Exploit-Skript erfolgreich, soll es den Kennwort-Hash des Wordpress-Administrators liefern, was bei einem weiteren Angriff auf den Server eine große Hilfe für Cracker wäre.
8:50 Uhr
Ich lade mir das Skript runter, schaue es mir an und modifiziere es so, dass es läuft. Dabei sehe ich, dass der Angreifer wohl genau dieses Skript für den Angriff auf "meinen" Server genutzt hat, denn der erwähnte "BENCHMARK()"-Befehl ist zu sehen und auch sonst ähneln die erzeuten SQL-Befehle sehr stark denen, die ich im Sloq-Queries-Log gefunden hatte.
9:00 Uhr
Ich lasse den Exploit laufen. Zum Glück ist das Skript nicht erfolgreich. Ich greife meine eigenen Wordpress-Installationen an und schaue, was passiert. Nichts - eine gute Nachricht.
9:30 Uhr
Ich frage mich, was man nun tun kann, um diese Lücke zu schließen. Eine Aktualisierung auf 2.2 kommt eigentlich nicht in Frage. Ich betreue sechs Wordpressen, die teilweise mehrere Millionen Hits pro Tag haben, da kann man nicht mal eben während des Betriebs an der Software herumfummeln. Außerdem werden die Funktionen von Wordpress 2.2 nicht vermisst.
Die Lücke selbst schließen wäre eine Möglichkeit. Ich verwerfe sie allerdings nach einem automatischen Vergleich des 2.1.3-Codes mit der Version 2.2. Die Unterschiede sind zu groß, als dass man eine Art schnellen Backport machen könnte. Möglich wäre das schon. Aber mir ist das Risiko, damit Stunden zu verbringen zu groß und außerdem habe ich keine echte Möglichkeit, die Wirksamkeit des Backport-Patches zu testen, denn der originale Exploit schlug ja schon fehl. Dazu kommt noch, dass die Datei /wp-admin/admin-ajax.php in beiden Versionen gleich ist (oder wars nahezu gleich?), so dass man erstmal herausfinden muss, um welche Stellen man sich überhaupt kümmern muss. Das kommt also auch nicht in Frage.
Eine andere, etwas weniger elegante Möglichkeit wäre es, für das Verzeichnis /wp-admin eine HTTP-Auth-Abfrage per htaccess einzubauen, damit admin-ajax.php nicht von jedem aufgerufen werden kann. Der Nachteil ist dabei, dass alle Wordpress-Autoren sich quasi doppelt einloggen müssen - einmal per HTTP-Auth und einmal in Wordpress selbst. Aber diese Absicherung ist innerhalb weniger Minuten in alle Installationen eingebaut, erledigt den Job und ist schön günstig.
11:00 Uhr
Nachdem alle betroffenen Wordpress-Nutzer informiert und einverstanden sind, baue ich die Abfragen ein. Das lässt alle wieder ruhig schlafen.









