Erste Schritte mit der Einbruchserkennung PHPIDS

Das PHP-basierende, quelloffene PHPIDS erkennt Einbruchsversuche auf Web-Anwendungen und schlägt bei Gefahr Alarm. heise Security gibt praktische Tipps zur Installation.

In Pocket speichern vorlesen Druckansicht
Lesezeit: 9 Min.
Von
  • Daniel Bachfeld
Inhaltsverzeichnis

Das in c't 10/09 vorgestellte PHPIDS soll auf PHP beruhende Anwendungen vor Cross-Site-Scripting-, SQL-Injection und anderen Angriffe schützen. Im einfachsten Einsatzszenario protokolliert man zunächst alle Angriffe mit, um einen Eindruck zu bekommen, ob die eigene Site überhaupt im Brennpunkt steht und weitere Schutzmaßnahmen notwendig sind. Die Installation und Konfiguration von PHPIDS ist in der Regel mit wenigen Handgriffen erledigt. Wir zeigen für erste Tests exemplarisch anhand einiger populärer Content-Management-Systeme und Blogs, wie man dabei vorgeht. Weitere Grundlagen zur Funktion und Hinweise zur Anpassung finden sich im c't-Artikel "Alarmanlage - Angriffe auf Webanwendungen mit PHPIDS erkennen" in c't 10/09 ab Seite 164.

Im Wesentlichen besteht die Installation und Konfiguration des IDS aus drei Schritten: den phpids-Tarball entpacken, die Pfade anpassen und das IDS in die vorhandene PHP-Anwendung einbinden. Insbesondere die Integration in die Anwendung unterscheidet sich von Produkt zu Produkt erheblich. Für das CMS Drupal steht jedoch ein angepasstes PHPIDS-Modul bereit, das zumindest die manuelle Einbindung sehr leicht macht.

Für die Praxisbeispiele haben wir der PHPIDS-Version 0.5.4 unter Ubuntu 8.10 mit Apache2 verwendet, wobei die jeweilige PHP-Anwendung unter /var/www/Name_der_Anwendung installiert war.

Zunächst entpackt man den phpids-Tarball, benennt das Verzeichnis php-0.5.4 in phpids um und verschiebt den Ordner in das Verzeichnis der Webanwendung. Wichtig ist noch, dem IDS respektive dem Webserver Schreibrechte für den Ordner phpids/lib/IDS/tmp zu gewähren, damit dieser dort die Filterregeln temporär ablegen und Attacken in der Log-Datei phpids_log.txt ablegen kann. Dazu ändert man am besten den Besitzer des Ordners via:

sudo chown www-data:www-data tmp

Für erste Tests eignet sich die Beispieldatei example.php im Unterverzeichnis docs/examples, die sich leicht anpassen lässt. Dazu entfernt man allen unnötigen Ballast und passt die dort angebenen Pfade so an, sodass nur folgendes übrig bleibt:

<?php

set_include_path(
get_include_path()
. PATH_SEPARATOR
. '/var/www/Name_der_Anwendung/phpids/lib/'
);

if (!session_id()) {
session_start();
}
require_once 'IDS/Init.php';
try {
$request = array(
'REQUEST' => $_REQUEST,
'GET' => $_GET,
'POST' => $_POST,
'COOKIE' => $_COOKIE
);
$init = IDS_Init::init(dirname(__FILE__) .
'/phpids/lib/IDS/Config/Config.ini');
$init->config['General']['base_path'] = dirname(__FILE__) .
'/phpids/lib/IDS/';
$init->config['General']['use_base_path'] = true;
$init->config['Caching']['caching'] = 'none';
$ids = new IDS_Monitor($request, $init);
$result = $ids->run();
if (!$result->isEmpty()) {
require_once 'IDS/Log/File.php';
require_once 'IDS/Log/Composite.php';
$compositeLog = new IDS_Log_Composite();
$compositeLog->addLogger(IDS_Log_File::getInstance($init));
$compositeLog->execute($result);
} else {
}
} catch (Exception $e) {
printf(
'An error occured: %s',
$e->getMessage()
);
}

Einige Admins stoßen sich vor allem bei sicherheitsrelevanten Anwendungen daran, dass alle Dateien über das Wurzelverzeichnis des Webservers erreichbar sind und Angreifer so Potenzial zum Rumspielen haben. PHPIDS lässt sich alternativ auch außerhalb des Webverzeichnisses installieren und betreiben. Dazu verlegt man den PHPIDS-Ordner beispielsweise nach /var/lib und kopiert die Datei example.php nach /var/lib/phpids. Der Eintrag

include ('/var/lib/phpids/example.php');

in der index.php der jeweiligen PHP-Anwendung bindet das IDS ein.

Darüber hinaus sind in example.php die Zeilen:

     . PATH_SEPARATOR
. '/var/lib/phpids/lib/'
...
$init = IDS_Init::init(dirname(__FILE__) . '/lib/IDS/Config/Config.ini');

...
$init->config['General']['base_path'] = dirname(__FILE__) . '/lib/IDS/';

anzupassen. Die Logdatei findet sich bei dieser Konfiguration in /var/lib/phpids/lib/IDS/tmp. Auch hier muss man dem Webserver via chown Schreibrechte einräumen.

Sofern auf dem System die PHP-Option open_basedir zur Beschränkung der möglichen Pfade für Zugriffe auf das Dateisystem bereits gesetzt ist, muss man den neuen Pfad (/var/lib/phpids) durch einen Doppelpunkt getrennt vom vorhandenen hinzufügen.

Die im folgenden aufgeführten Beispiele beziehen sich jedoch auf eine Installation von PHPIDS im Order der Webanwendung.

Die Datei example.php legt man im Wordpress-Verzeichnis ab und bindet sie in index.php hinter der Zeile

require('./wp-blog-header.php');

mit

include 'example.php';

ein.

Nun sollte ein Aufruf von http://localhost/wordpress im Browser die Startseite von Wordpress zutage fördern. Allerdings produzierte Wordpress in dieser Standardkonfiguration in unseren Tests bei jedem Aufruf einen Eintrag in der IDS-Logdatei – auch wenn es sich definitiv nicht einen Angriff handelte. Durch das Auskommentieren der Variable REQUEST und COOKIE im oben aufgeführten Request-Array traten diese False-Positives nicht mehr auf. Alternativ lassen sich auch Exception-Variablen definieren, mehr dazu im oben erwähnten c't-Artikel.

Hängt man für einen ersten Test der IDS-Funktion als simulierten SQL-Injection-Angriff ein

?test='%20OR%201=1--

an die URL seines Blogs an, so erscheint in der IDS-Datei ein dazugehöriger Eintrag mit einem Impact von 22. Ein typischerweise bei Cross-Site-Scripting-Tests eingesetzter Parameter wie

?test=">XXX

erzeugt einen Eintrag mit einem Impact 4.

Durch das Definieren eigener Aktionen im Rahmen von PHPIDS lässt sich ein Angriff so nicht nur erkennen, sondern auch abwehren, indem man etwa die IP-Adresse sperrt. Beispiele für weitere Aktionen finden sich in der Originaldatei von example.php im doc-Verzeichnis. Alternativ lassen sich Aktionen auch durch eigene Tools realisieren, die kontinuierlich die IDS-Logdatei auswerten.

Bei Serendipity geht man zunächst genauso vor, wie bei Wordpress. Einzige Ausnahme ist der erste Pfad in der Datei example.php, wo der Ordner wordpress gegen serendipity ausgetauscht werden muss (wenn das Blog unter /var/www/serendipity installiert ist). Anschließend inkludiert man example.php in index.php hinter den beiden Zeilen:

header('HTTP/1.0 200');
header('Status: 200 OK');

Alternativ kann man die Datei example.php aber auch automatisch von PHP inkludieren lassen, ohne dass die Originaldateien verändert werden müssen. Dazu genügt es, in /etc/php5/apache3/php.ini die Option

auto_prepend_file = /var/www/serendipity/example.php

zu setzen und den Webserver neu zu starten. Der Vorteil ist, dass nun automatisch jede PHP-Datei mit dem IDS geschützt ist. Dieser schicke Tipp lässt sich aber nicht verallgemeinern. Bei anderen PHP-Anwendungen wie etwa Drupal führte er in unseren Tests zu Problemen, sodass etwa ein Angriff mehrfach im Log auftauchte oder die Anwendung gar nicht mehr funktionierte. Hier muss man selbst probieren.

Auch bei diesem CMS bereitete PHPIDS keine Probleme; in die index.php bindet man als erste PHP-Anweisung die Datei example.php ein. Ansonsten gelten die gleichen Anweisungen wie für Wordpress.

Anwendern des Content-Management-Systems Drupal erleichtert ein speziell für Drupal angepasstes PHPIDS-Modul die Installation und Konfiguration. Für Drupal 6 liegt Drupal.org unter phpids-6.x-1.8-beta2.tar.gz die zum Testzeitpunkt aktuelle Version bereit. Nicht-Standardmodule erwartet Drupal im Verzeichnis sites/all/modules. Dazu muss man das Verzeichnis modules anlegen und den aus dem Tarball extrahierten Ordner dorthin verschieben. Das Modul enthält aber nicht die eigentlichen PHPIDS-Dateien. Diese muss man zusätzlich herunterladen und im Modul-Verzeichnis phpids installieren. Die Drupal-Modul-Dateien sollten dann in sites/all/modules/phpids liegen, unter sites/all/modules/phpids/lib residieren dann wie in den vorherigen Konfigurationen beschrieben die Dateien von PHPIDS.

Im Drupalreport erkennt man einen versuchten Angriff relativ schnell.

Anschließend legt man im temporären Ordner /tmp (Achtung, es ist nicht der Pfad unter lib/IDS/tmp gemeint) das Unterverzeichnis phpids an und gibt dem Webserver Schreibrechte:

sudo chown www-data:www-data /tmp/phpids

Unter dem Drupal-Menüpunkt "/Administer/Site Building/Modules" lässt sich das eben hinzugefügte Modul aktivieren. Unter "/Administer/Site Configuration/Logging and Alerts/PHPIDS Settings" öffnet sich in Drupal nun das PHPIDS-Konfigurationsmenü, in dem man für "PHP-IDS Path" den Pfad /var/www/drupal/sites/all/modules/phpids/lib und für "PHP-IDS Temp Path" /tmp/phpids einträgt. Mit der Definition des "Warning Impact" lassen sich praktischerweise Angriffe nicht nur protokollieren sondern auch abwehren. Angreifer werden dann auf eine Warnseite umgeleitet und der Request verworfen. Die restlichen Felder im Menü füllt man nach Gutdünken oder belässt sie so.

Nach dem Speichern der Einstellungen ist das IDS scharf. Attacken loggt das IDS fortan im Report von Drupal, den man über Administer/Reports/Recent Log Entries erreicht.

Praktisch ist der Einstieg in PHPIDS leicht und schnell erledigt. Ein tiefer Eingriff in die zu überwachende Anwendung ist nicht notwendig, im Zweifel löscht man die Zeile "include ('example.php')" einfach wieder. Am praktischsten ist die Drupal-Lösung, die neben einem übersichtlichen Report auch noch die Möglichkeit zum Abwehren der Angriffe bietet. Bleibt zu hoffen, dass viele Betreiber von PHP-Anwendungen die Lösung einsetzen, um den ausufernden Angriffen auf verwundbare Anwendungen ein wenig Einhalt zu gebieten. (dab)