Detecção de Intrusos em Aplicações WEB PHP com PHPIDS

Standard

Detecção de Intrusos em Aplicações php com PHPIDS

A dica aqui vai para servidores que rodam com o apache e php5 (sob linux).
O PHPIDs é um sistema de detecção de instrusos, simples, rápido, bem estruturado e de fácil utilização. Isto cria mais uma camada de segurança para a sua aplicação web. Ele não vai filtrar entradas maliciosas, tampouco fazer maravilhas, como se estivesse com inteligência artificial, ele irá detectar o ataque e irá reagir segundo as suas configurações. O interessante é que ele tem o poder de decisão no momento de uma tentativa de invasão. Ele
pode servir para informar ao atacante que está tentando invadir de cuidade, alerta e etc, ou mesmo, notificar ao core de desenvolvimento da aplicação por email a tal tentativa de invasão.

Este how to é beta e nada aqui é GARANTIDO de funcionar, mas deve!

Requerimentos:

Os testes foram realizados na plataforma Gnu/Linux, no sabor Debian Etch, o qual teve ip

setado como 192.168.0.100, tendo por usuário e grupo de usuário do apache www-data.
Nos testes o diretório principal usado é um virtual host -> /var/www/web1/web

Por questões de segurança o diretório do PHPIDs será criado em outro lugar para evitar problemas com a estrutura, tornando-a mais difícil contra vulnerabilidade, no caso:

mkdir /var/www/web1/phpids

Criamos um diretório recursivo, evitando acesso público ao web, que deixaria o script vulnerável.

O arquivo que usamos neste tutorial é phpids-0.4.7.tar.gz, o qual temos apenas a necessidade de uso diretório lib.

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/

Agora mudamos o diretório para /var/www/web1/phpids/lib/IDS:

cd /var/www/web1/phpids/lib/IDS

Agora iremos fazer com que o /tmp permita escrita para o usuário do apache (log do phpids necessitará):

chown -R www-data:www-data tmp/

Agora vamos configurar o PHPIDs em seu arquivo de configuração:

cd Config/
vi Config.ini

As configurações são padrão, todavia iremos alterar o caminho de onde estão os arquivos, sendo o ajuste final idêntico a isto aqui:

; 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: <PHPIDS> 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

Pronto, terminado.

Usando o PHPIDs

Nós iremos criar o arquivo que vai fazer a chamada do PHPIDs (depois iremos ajustar o arquivo para chamar automaticamente os recursos do PHPIDs para todas as contas do servidor):

<?php
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);
}
?>

Se você chamar o arquivo no browser, perceberá que o mesmo ficará em branco, no caso http://192.168.0.100/phpids.php – porém, mas se você tentar usar um suposto ataque, nosso amigo PHPIDs vai entrar em ação, use o exemplo -> http://192.168.0.100/phpids.php?test=%22%3EXXX%3Cscript%3Ealert(1)%3C/script%3E

Pronto, agora iremos ver o caminho para que os scripts usem o PHPIDs, e o interessante aqui, você não precisará alterar todos os seus scripts, isto por que iremos chamar o script automaticamente como recurso do PHP, isto carregará o mesmo “como se fosse um módulo”, e o parâmetro que define isto bacaninha é -> auto_prepend_file, iremos apontar o arquivo no php.ini principal do servidor, isso dará força e velocidade no desenvolvimento usando tal recurso. Isto também pode ser feito em um arquivo .htaccess, desde que apontemos tudo corretamente, haverá de funcionar turbinado.

NO CASO DO PHP.INI

vi /etc/php5/apache2/php.ini

procure pela linha auto_prepend_file, se não achar, insira no meio do arquivo aberto:

auto_prepend_file = /var/www/web1/web/phpids.php

Reinicie o Apache:

/etc/init.d/apache2 restart

NO CASO DO ARQUIVO .HTACCESS

vi /var/www/web1/web/.htaccess

php_value auto_prepend_file /var/www/web1/web/phpids.php

Verifique os confs de vhost, se estão assim:

<Directory /var/www/web1/web/>
AllowOverride All
</Directory>

Caso sim, caso tenha mudado algo no apache e retorne para este padrão acima, reinicie o apache.

Crie um simples arquivo ->

vi /var/www/web1/web/info.php
dentro dele:

<?php
phpinfo();
?>

Faça um acesso simples -> http://192.168.0.100/info.php

Agora, para ver o PHPIDs em ação use http://192.168.0.100/info.php?test=%22%3EXXX%3Cscript%3Ealert(1)%3C/script%3E

Se as mensagens de alerta forem vistas é por que o script de /var/www/web1/web/phpids.php foi chamado automaticamente de dentro de /var/www/web1/web/info.php.

Sobre os logs

Podem ser vistos em /var/www/web1/phpids/lib/IDS/tmp/phpids_log.txt, para ver rapidamente o teste use:

cat /var/www/web1/phpids/lib/IDS/tmp/phpids_log.txt

Algo parecido com os termos abaixo será exibido:

“192.168.0.77”,2008-06-04T17:36:08+02:00,54,”xss csrf id rfe

lfi”,”REQUEST.test=%5C%22%3EXXX%3Cscript%3Ealert%281%29%3C%2Fscript%3E GET.test=%5C%22%3EXXX%3Cscript%3Ealert%281%29%3C%2Fscript%3E”,”%2Finfo.php%3Ftest%3D%2522%253EXXX%253Cscript%253Ealert%281%29%253C%2Fscript%253E”

Isso é bom para quem quer analisar tipos de ataques e quer reaplicar mudanças valiosas na segurança.

Vamos fazer uma mudança no nível de segurança para que seja exibida informação, caso esteja vazio o ataque, prossiga, do contrário será parado o script!

vi /var/www/web1/web/phpids.php

<?php
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);

die(‘<h1>Go away!</h1>’);
}
?>

fonte:

http://www.howtoforge.com/intrusion-detection-for-php-applications-with-phpids