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