Intrusion detector
Getting started with the PHPIDS intrusion detection system
by Daniel Bachfeld
Web applications are regularly threatened by attacks that try to exploit programming weaknesses. The PHP-based, open source PHPIDS solution detects attempted intrusions and raises the alarm when a threat is identified. We're offering some practical installation tips.
PHPIDS helps protect PHP-based applications from Cross-Site-Scripting, SQL-Injection and other attacks. The simplest scenario involves logging attacks to establish whether a site is being targeted and requires further protective measures. Installing PHPIDS is usually only a matter of a few simple steps. This feature shows how to get started by demonstrating the process in several popular content management systems and blogs.
PHPIDS installation and configuration involves three basic steps: unpacking the PHPIDS tarball, adjusting the paths and integrating the IDS into the existing PHP application. The integration step varies a lot with each individual product. The Drupal CMS offers a custom PHPIDS module which greatly simplifies the manual PHPIDS installation process.
Our practical examples are based on version 0.5.4 of PHPIDS under Ubuntu 8.10 with Apache2. The respective PHP applications were located at /var/www/name_of_application
.
General basics
First, unpack the phpids tarball, change the name of the php-0.5.4
directory to phpids
and move the folder into the directory that contains the web application. You can use the example.php
file in the /docs/examples
subdirectory for your first trials, as it is easily adapted. Simply remove any unnecessary items and change the paths in the file so that you're only left with the following:
<?php
set_include_path(
get_include_path()
. PATH_SEPARATOR
. '/var/www/name_of_application/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()
);
}
System admins tend to dislike having all the files of security-critical applications accessible via the web server's root directory, as it potentially gives attackers room to play. PHPIDS can, therefore, also be installed and run outside of the web directory. For this purpose, move the phpids
folder to a directory such as /var/lib
and copy example.php
to /var/lib/phpids
. Adding the snippet
include ('/var/lib/phpids/example.php');
in each PHP application's index.php file integrates the IDS.
Changes are also required in the following lines of example.php
:
. 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/';
In this configuration, the log file is situated at /var/lib/phpids/lib/IDS/tmp
. The web server must have write access to this file (sudo chown www-data:www-data tmp).
The following examples, however, refer to a PHPIDS installation that is contained in the same folder as the web application.
Wordpress
Save example.php in the Wordpress directory and include it behind
require('./wp-blog-header.php');
in index.php by adding
include 'example.php';
. It is important to grant the IDS and web server write access to the phpids/lib/IDS/tmp folder so the filter rules can be stored temporarily and attacks can be written to the phpids_log.txt log file. The best way of doing this is by changing the folder owner:
sudo chown www-data:www-data tmp
Calling http://localhost/wordpress should now display the start page of Wordpress in the browser. However, in our tests with this standard configuration, Wordpress produced an IDS log file entry for every request – even if the request definitely wasn't an attack. Commenting out the REQUEST and COOKIE variables in the request array in example.php
got rid of these false positives. Alternatively you can also define exception variables.
For our first test of the IDS feature, we simulate an SQL-injection attack and attach
?test='%20OR%201=1--
to the URL of our blog, which results in a corresponding entry with an impact of 22 to appear in the IDS file.
A parameter such as
?test=">XXX
, which is typically used for Cross-Site-Scripting tests, results in an impact of 4.
Adding user-defined actions to the PHPIDS allows you to not only detect, but also prevent an attack, for example by blocking the IP address. Further sample actions can be found in the original example.php file in the doc directory. Alternatively, actions can also be integrated via custom tools that continuously monitor the IDS log file.
Next: Serendipity, Joomla, Drupal