PHPIDS. За и против

IDS (Intrusion Detection System - Система Обнаружения Вторжений) или система предотвращения вторжений является одним из средств защиты от различных атак. Среди типов IDS можно выделить сетевые и локальные IDS. Сетевая IDS обеспечивает безопасность целой подсети; как правило, она работает на аппаратном уровне, т.е. встроена в маршрутизатор или другие сетевые устройства. Локальная IDS располагается непосредственно на том компьютере, который необходимо защищать от различных атак извне. В этом случае контроль обеспечивается на программном уровне. Многие файрволы и брэндмауэры так или иначе включают в себя модуль IDS, а самой известной системой подобного рода является Snort. Главное назначение IDS - это предотравщение таких атак, как переполнение буфера, сканирование портов, отказ в обслуживании (DoS).

PHPIDS (http://php-ids.org/) в этом отношении выделяется среди традиционных систем обнаружения вторжений, так как проводит контроль на уровне web-приложений и распознает следующие виды атак: XSS, SQL-инъекции, header-инъекции, directory traversal, инклуды и многие другие. Стоит отметить, что благодаря большому набору правил PHPIDS справляется со своей задачей довольно хорошо: провести XSS, даже используя различные методы обхода фильтрации (http://ha.ckers.org/xss.html), вам не удастся, не говоря уже о простейших SQL-инъекциях, основанных на UNION SELECT; в то же время количество ложных срабатаваний практически сведено к нулю. Попробовать обхитирить IDS можно на этой странице. Однако любая IDS - это система, которая прежде всего распознает и фиксирует факт атаки, т.е. проводит проверку данных, но не фильтрацию. Это значит, что обнаружив в одном из параметров запроса строку 0′ OR 1=1/*, сработает правило, в результате которого PHPIDS завершит выполнение скрипта и выдаст предупреждение (при стандартной конфигурации). Безусловно, в данном примере более грамотным подходом была бы фильтрация с помощью функции intval(). Тем не менее, результат в обоих случаях будет одинаков: любые попытки провести какую-либо атаку завершатся неудачей.

Таким образом, я рекомендую данное решение тем, кто использует веб-приложения с открытым исходным кодом и не силен в программировании. Многие опытные веб-разработчики скорее всего откажутся от PHPIDS, так как только сам программист точно знает какие данные должны поступать и как эти данные должны обрабатываться.

Ссылки:

* Скачать PHPIDS (http://php-ids.org/files/phpids-0.5.zip)
* Security-плагин для wordpress, основанный на PHPIDS (http://wpids.googlecode.com/svn/misc/wp-ids.zip)

(с) raz0r.name

Intrusion Detection For PHP Applications With PHPIDS
Установка PHPIDS

Эта статья покажет как настроить PHPIDS. PHPIDS (PHP-Intrusion Detection System) - это легко используемая, хорошо структурированная, быстрая прослойка для анализа безопасности ваших приложений. IDS - не является прослойкой для анализа данных, введенных пользователем, он только распознает, когда пытаются атаковать ваш сайт. на основе набора проверенных и оттестированных правил каждой атаке сопоставлен рейтинг ее опасности. Это позволит легко сохранять статистику по атакам или отсылать уведомления для команды разработчиков.

Предисловие
Примеры для данной статьи делались на Debian Etch LAMP с Apache версии 2 и PHP5, IP - 192.168.0.100.
Пользователь и группа Apache - www-data. Путь к php.ini - /etc/php5/apache2/php.ini. В качестве document root для виртуального хоста использовался /var/www/web1/web

Установка PHPIDS
Из изображений безопасности я установил PHPIDS вне document root, поэтому я создал /var/www/web1/phpids:

Затем я установил PHPIDS (на момент установки последняя версия была 0.4.7).
cd /tmp
wget http://php-ids.org/files/phpids-0.4.7.tar.gz
tar xvfz phpids-0.4.7.tar.gz
cd phpids-0.4.7
mv lib/ /var/www/web1/phpids/
cd /var/www/web1/phpids/lib/IDS
chown -R www-data:www-data tmp/
Далее я переконфигурировал Config.ini:
cd Config/
vi Config.ini
Я использую конфигурацию по умолчанию, и все что надо сделать - это поменять пути
; PHPIDS Config.ini

; General configuration settings

; !!!DO NOT PLACE THIS FILE INSIDE THE WEB-ROOT IF DATABASE CONNECTION DATA WAS ADDED!!!

[General]

filter_type = xml
filter_path = /var/www/web1/phpids/lib/IDS/default_filter.xml
tmp_path = /var/www/web1/phpids/lib/IDS/tmp
scan_keys = false

exceptions[] = __utmz
exceptions[] = __utmc

; If you use the PHPIDS logger you can define specific configuration here

[Logging]

; file logging
path = /var/www/web1/phpids/lib/IDS/tmp/phpids_log.txt

; email logging

; note that enabling safemode you can prevent spam attempts,
; see documentation
recipients[] = test@test.com.invalid
subject = "PHPIDS detected an intrusion attempt!"
header = "From: info@php-ids.org"
safemode = true
allowed_rate = 15

; database logging

wrapper = "mysql:host=localhost;port=3306;dbname=phpids"
user = phpids_user
password = 123456
table = intrusions

; If you would like to use other methods than file caching you can configure them here

[Caching]

; caching: session|file|database|memcached|none
caching = file
expiration_time = 600

; file cache
path = /var/www/web1/phpids/lib/IDS/tmp/default_filter.cache

; database cache
wrapper = "mysql:host=localhost;port=3306;dbname=phpids"
user = phpids_user
password = 123456
table = cache

; memcached
;host = localhost
;port = 11211
;key_prefix = PHPIDS
;tmp_path = /var/www/web1/phpids/lib/IDS/tmp/memcache.timestamp
Использование PHPIDS
Сейчас мы создадим /var/www/web1/web/phpids.php, который будет использовать PHPIDS
set_include_path(
get_include_path()
. PATH_SEPARATOR
. '/var/www/web1/phpids/lib'
);

require_once 'IDS/Init.php';
$request = array(
'REQUEST' => $_REQUEST,
'GET' => $_GET,
'POST' => $_POST,
'COOKIE' => $_COOKIE
);
$init = IDS_Init::init('/var/www/web1/phpids/lib/IDS/Config/Config.ini');
$ids = new IDS_Monitor($request, $init);
$result = $ids->run();

if (!$result->isEmpty()) {
// Take a look at the result object
echo $result;
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);
}
После этого введите в своем браузере _http://192.168.0.100/phpids.php, и вы увидите пустую страницу.
Однако если вы добавите различные параметры, например _http://192.168.0.100/phpids.php?test=%22%3EXXX%3Cscript%3Ealert(1)%3C/script%3E, PHPIDS определит их и напечатает результат в браузер
http://savepic.ru/202863.png
Сейчас мы сделаем так, чтобы PHPIDS тиспользовался в каждом вашем скрипте. Конечно, вам не придется модифицировать каждый файл php в вашей системе. Мы скажем php, чтобы он запускал PHPIDS при каждом старте скрипта. Мы сделаем это используя auto_prepend_file параметр. Для этого сделаем модификацию в php.ini или .htaccess file
auto_prepend_file = /var/www/web1/web/phpids.php
или для .htaccess
php_value auto_prepend_file /var/www/web1/web/phpids.php
Перепустите ваш Apache (для случая с модификацией php.ini)
Создайте файл info.php с содержимым

phpinfo();
Напишите в браузере _http://192.168.0.100/info.php и вы увидите нормальный вывод команды phpinfo()
теперь добавьте параметры, например _http://192.168.0.100/info.php?test=%22%3EXXX%3Cscript%3Ealert(1)%3C/script%3E
и вы увидите
http://savepic.ru/201839.png
PHPIDS запишет эти данные в /var/www/web1/phpids/lib/IDS/tmp/phpids_log.txt
"192.168.0.200",2008-06-04T17:36:08+02:00,54,"xss csrf id rfe lfi","REQUEST.test=%5C%22%3EXXX%3Cscript%3Ealert%2 81%29%3C%2Fscript%3E GET.test=%5C%22%3EXXX%3Cscript%3Ealert%281%29%3C%2 Fscript%3E",
"%2Finfo.php%3Ftest%3D%2522%253EXXX%253Cscript%253 Ealert%281%29%253C%2Fscript%253E"
Теперь, просмотрев записи. вы увидите, что хакер пытался что-то сделать с вашим приложением.

Для добавления другого уровня безопасности для вашего приложения вы можете остановить скрипт, если PHPIDS обнаружил атаку:
мы можем добавить что-то похожее на это
die('
Go away!
');
в секцию if (!$result->isEmpty()) {} в файле /var/www/web1/web/phpids.php script
set_include_path(
get_include_path()
. PATH_SEPARATOR
. '/var/www/web1/phpids/lib'
);

require_once 'IDS/Init.php';
$request = array(
'REQUEST' => $_REQUEST,
'GET' => $_GET,
'POST' => $_POST,
'COOKIE' => $_COOKIE
);
$init = IDS_Init::init('/var/www/web1/phpids/lib/IDS/Config/Config.ini');
$ids = new IDS_Monitor($request, $init);
$result = $ids->run();
Если нет атаки скрипт продолжит выполнение, иначе хакер увидит это
http://savepic.ru/254062.png
коментарий переводчика
Указанные выше примеры можно использовать и на боевых системах. Однако для этого потребуется некое преобразование
$init = IDS_Init::init('/var/www/web1/phpids/lib/IDS/Config/Config.ini');
так как каждый раз незачем загружать файл настроек из файла, а заменить его написанным заранее классом
(c) habrahabr.ru