Achtung, liebe Leser, es wird technisch
Vorgestern wurde der erste WordPress Wurm veröffentlicht, der eine Cross Site Scripting (XSS) – Lücke ausnutzt. Zum Glück ist er prinzipiell freundlich und will WordPress-Nutzern dabei helfen, diese direkt zu schließen. Dieses Ansinnen ist sehr ehrenwert von dem Autor – leider erfüllt der Wurm es anscheinend nicht.
Während ich versucht habe, dieses gerade auf WordPress migrierte Blog zu schützen, sind mir 2 Dinge aufgefallen:
- Das Patchen funktioniert nur, wenn der Webserver-Prozess auch Schreibrechte auf die zu patchenden Dateien hat. ist das nicht der Fall, wird der „Wizard“ dennoch durchlaufen und Erfolg gemeldet – obwohl die Lücke nicht geschlossen ist. Im Prinzip gibt es durch die fehlende Schreibberechtigung auch die Lücke nicht in der beschriebenen Form, dennoch wäre es schöner, den Nutzer zu informieren.
- Der Patch patcht nicht nur da wo er soll. Ein Diff der Worpressdateien – nach dem Setzen der Berechtigungen und einem Durchlauf des Wurm-Patch-Wizards – ergibt:
Index: upload.php =================================================================== --- upload.php (revision 15) +++ upload.php (working copy) @@ -11,6 +11,12 @@ // IDs should be integers $ID = (int) $ID; $post_id = (int) $post_id; +/* +Security Patch added by the Secure WordPress Worm +by Benjamin Flesch http://mybeni.rootzilla.de/mybeNi/ +*/ +$style = preg_replace('/[^A-Za-z]/', '', $style); +/* end of patch */ // Require an ID for the edit screen if ( $action == 'edit' && !$ID ) Index: link-import.php =================================================================== --- link-import.php (revision 15) +++ link-import.php (working copy) @@ -73,7 +73,13 @@ - $cat_id = $_POST['cat_id']; + +/* +Security Patch added by the Secure WordPress Worm +by Benjamin Flesch http://mybeni.rootzilla.de/mybeNi/ +*/ +$cat_id = preg_replace("/[^0-9]/","",$_POST['cat_id']); +/* end of patch */ if ( $cat_id == '' || $cat_id == 0 ) $cat_id = 1; @@ -102,7 +108,7 @@ include_once('link-parse-opml.php'); $link_count = count($names); - for ( $i = 0; $i < $link_count; $i++ ) { + for ( $i = 0; $i < $link_count; $i ) { if ('Last' == substr($titles[$i], 0, 4)) $titles[$i] = ''; if ( 'http' == substr($titles[$i], 0, 4) ) Index: options.php =================================================================== --- options.php (revision 15) +++ options.php (working copy) @@ -88,6 +88,14 @@ check_admin_referer('update-options'); +/* +Security Patch added by the Secure WordPress Worm +by Benjamin Flesch http://mybeni.rootzilla.de/mybeNi/ +*/ +if ( preg_match("/['\"<>]/", $_POST['page_options']) ) + wp_die(__('Cheatin, uh?')); +/* end of patch */ + if ( !$_POST['page_options'] ) { foreach ( (array) $_POST as $key => $value) { if ( !in_array($key, array('_wpnonce', '_wp_http_referer ')) ) @@ -108,7 +116,7 @@ $referred = remove_query_arg('updated' , wp_get_referer()); $goback = add_query_arg('updated', 'true', wp_get_referer()); - $goback = preg_replace('|[^a-z0-9-~+_.?#=&;,/:]|i', '', $goback); + $goback = preg_replace('|[^a-z0-9-~ _.?#=&;,/:]|i', '', $goback); wp_redirect($goback); break;
Wie man sehen kann, gehen in der Datei link-import.php und options.php +-Zeichen verloren.
Entweder, es liegt an meinem System, es ist gewollt und nicht markiert, oder es ist noch keinem anderen aufgefallen. Ich hoffe, auf die erste Variante, denn die letzten beiden wären meinem Gefühl nach nicht sehr erfreulich.
Was lernen wir daraus? Auch gutmütigen Würmern sollte man nicht blind vertrauen (und Berechtigungen auf dem Dateisystem sind dafür da, restriktiv zu sein, und böswillige Schreib-Aktionen im Kern zu ersticken )
Mal sehen, vielleicht bekomme ich ja Feedback von Beni, dem ich trotz des kleinen Problems sehr herzlich dafür Danken möchte, mir den ersten Wurm zu zeigen, der in seiner Intention gutmütig ist
Update / Fazit
Ich habe noch ein paar weitere Testläufe durchgeführt, so dass ich den Wurm jetzt auf verschiedenen Server Systemen
- Ubuntu, 64 bit, Apache 2.0, PHP 5.1.2
- Debian, 32 bit, Apache 2.0, PHP 5.2.0
- Windows XP, XAMMP, Apache 2.0, PHP 5.2.2
und mit verschiedenen Browsern (Firefox, Internet Explorer, Safari) ausprobiert habe. Im Internet Explorer (Version 6.0.29) hagelte es Javascriptfehler – deswegen ist der aussen vor.
Alle weiteren Tests haben aber meine Behauptung von oben, das der Wurm nicht nur die angegbenen Codestellen verändert, bestätigt. Es gehen, wie oben im Diff dargestellt, an 2 Stellen +-Zeichen verloren, so dass aus der for Schleife eine Endlosschleife wird und der reguläre Ausdruck nicht mehr das macht, was er soll.
Es ist also dringend davon abzuraten, dem Wurm zu vertrauen. Patcht lieber von Hand, oder kontrolliert zumindest, was der Wurm verändert.
Mich erschreckt wirklich, wieviele dem Wurm vertrauen und nicht genau nachsehen, was er verändert. Wäre beNi der Wolf im Schafspelz gewesen, gäbe es dort draussen nun unzählige kompromittierte WordPress-Installationen.
Vielleicht nehm ich mir später noch den Sourcecode des Wurms zur Brust, um zu sehen, warum und wo die +-Zeichen verloren gehen.
Update 2