PHPIDS - PHP Intrusion Detection System, deixe seu site livre de intrusos!

Este tutorial explica como configurar o PHPIDS em um servidor web com Apache2 e PHP5. PHPIDS (PHP Intrusion Detection System) é simples de usar, bem estruturado, rápido, possui camada de segurança para seu aplicativo web baseado em PHP.

[ Hits: 15.032 ]

Por: Mauro Risonho de Paula Assumpção A.K.A firebits em 09/02/2010


Introdução



Tradução livre de: Intrusion Detection For PHP Applications With PHPIDS

Este tutorial explica como configurar o PHPIDS em um servidor web com Apache2 e PHP5. PHPIDS (PHP Intrusion Detection System) é um IDS simples de usar, bem estruturado, rápido, possui camada de segurança para seu aplicativo web baseado em PHP. O PHPIDS simplesmente reconhece quando um atacante tenta quebrar o seu site e reage exatamente da maneira que você quer. Baseado em um conjunto testado e aprovado de regras de filtragem onde qualquer ataque é atribuído a uma classificação numérica de impacto, que torna mais fácil decidir que tipo de ação deve seguir a tentativa de intrusão.

1. Definições

Eu testei isso em um sistema LAMP Debian Lenny com Apache2 e PHP5 no IP 192.168.0.100. O usuário e grupo do Apache no Debian Lenny é www-data, portanto, se você estiver em uma distribuição diferente, o usuário do Apache e grupo pode ser diferente. A localização do php.ini (/etc/php5/apache2/php.ini no Debian Lenny) pode ser diferente também.

Estou usando uma máquina virtual com o documento raiz /var/www/web1/web neste exemplo.

2. Instalação do PHPIDS

Por razões de segurança eu quero instalar PHPIDS fora da raiz do documento, assim que eu criei o diretório /var/www/web1/phpids:

# mkdir /var/www/web1/phpids

Então vou instalar o PHPIDS (no momento da redação deste artigo a última versão é a 0.4.7). De todo o conteúdo do arquivo PHPIDS-0.4.7.tar.gz, só precisamos do 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 eu vou mudar para o diretório /var/www/web1/phpids/lib/IDS...

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

... e fazer o diretório tmp (que irá conter o arquivo de log PHPIDS) gravável para o usuário e grupo do Apache:

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

Em seguida vamos configurar o arquivo de configuração PHPIDS (Config.ini):

# cd Config/
# vi Config.ini


Estou usando a configuração padrão aqui, tudo que eu fiz foi ajustar os caminhos:

; 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

Agora, quando você chamar o arquivo em um navegador (http://192.168.0.100/phpids.php por exemplo), verá uma página em branco. Mas se você tentar anexar alguns parâmetros maliciosos para a URL (ex. http://192.168.0.100/phpids.php?test=%22%3EXXX%3Cscript%3Ealert(1)%3C/script%3E), PHPIDS irá detectar este ataque e imprimir as suas conclusões no navegador:
Agora temos que encontrar uma maneira de fazer com que nossos scripts PHP se utilizem do PHPIDS. Claro, você não quer modificar todos os seus scripts PHP (pode ter centenas deles ...). Felizmente há uma maneira melhor: podemos dizer ao PHP para preceder um script PHP sempre que um script PHP é chamado. Por exemplo, se nós chamamos o script info.php em um navegador, o PHP executará phpids.php e depois info.php, e nós nem sequer temos que modificar info.php.

Podemos fazer isso usando o parâmetro auto_prepend_file do PHP. Podemos definir isso em nosso php.ini (esta é uma configuração global que é válida para todos os sites PHP no servidor), ou em um arquivo .htaccess (esta é uma configuração válida somente para um site em questão).

O arquivo php.ini

Abra seu php.ini (exemplo /etc/php5/apache2/php.ini) e defina tag auto_prepend_file para var/www/web1/web/phpids.php/:

# vi /etc/php5/apache2/php.ini

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

Reinicie o Apache:

# /etc/init.d/apache2ctl restart

O arquivo .htaccess

Em vez de modificar o php.ini (que é uma mudança global, ou seja, a mudança é válida para todos os sites que usam PHP no servidor), você pode usar um arquivo .htaccess (para a definição seria válida apenas para a web site onde você criar o arquivo .htaccess):

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

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

Por favor, certifique-se que o vhost para seu site em /var/www/web1/web contém algo parecido com isto (caso contrário a linha php_value no arquivo .htaccess será ignorada). Se você tiver que alterar o vhost, por favor, não se esqueça de reiniciar o Apache):


AllowOverride All

Agora vamos criar um arquivo PHP simples, em /var/www/web1/web/info.php:

# vi /var/www/web1/web/info.php

phpinfo();
?>

Chame esse arquivo em um navegador (http://192.168.0.100/info.php) e você deve ver o phpinfo() normalmente.

Agora vamos anexar alguns parâmetros maliciosos para a URL (ex. http://192.168.0.100/info.php?test=%22%3EXXX%3Cscript%3Ealert(1)%3C/script%3E). Você deverá encontrar um relatório PHPIDS antes da saída phpinfo() (porque em /var/www/web1/web/phpids.php foi executado antes do /var/www/web1/web/info.php):
Os logs do PHPIDS vão para /var/www/web1/phpids/lib/IDS/tmp/phpids_log.txt, então você deve ver algo no log a partir de agora:

# cat /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%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"

Agora, observando o log, você sabe o que os hackers estão tentando fazer suas aplicações PHP e você pode tentar endurecer as suas aplicações.

Para adicionar outro nível de segurança, podemos parar a execução de nossos scripts PHP se o PHPIDS achar que eles estão sob ataque. Basta adicionar algo que assuste ou bote os intrusos para correr na seção "if (!$result->isEmpty()) {}" em /var/www/web1/web/phpids.php:

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

 $_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('

Go away!

'); } ?>

Se não houver ataques, os scripts são executados, mas se o PHPIDS encontra um ataque, ele impede que os scripts sejam executados e exibe uma mensagem para os intrusos:
Links para referência:
Bom, é só isso. E não se esqueçam de passar no site do Backtrack Brasil.

Se tiver algum evento ou palestra para ministramos aí na sua cidade, entrem em contato.

Nós vamos até vocês com o Backtrack Brasil.

Até a próxima!

Mauro Risonho de Paula Assumpção
Fundador do BackTrack Brasil (BTB)
Pentester, Analista em Segurança
Desenvolvedor de Software
firebits@backtrack.com.br
http://www.backtrack.com.br
última palestra ministrada: 05-fev-2009 Intel Moblin Day 2008-2009
http://www.intel.com/portugues/pressroom/releases/2009/0205.htm

   

Páginas do artigo
   1. Introdução
Outros artigos deste autor

Teste de vulnerabilidades com OpenVAS 3.0

A vida de quem vive de TI: It Crowd!

Wow! O que esta câmera de segurança está fazendo aí?

Traduzindo plugins do OpenVAS/Nessus para português

Buscar "Teste" no Google

Leitura recomendada

Criando senhas seguras com o mkpasswd

Metasploit Exploitation

Solução de backup para servidores Windows, Linux & BSD’s

Segurança Física (Parte 1)

Introdução ao Anonimato na Web - Web Anonimity

  
Comentários
[1] Comentário enviado por cleysinhonv em 09/02/2010 - 09:35h

Olá Mauro Risonho,

Estou deixando esse comentário em forma de agradecimento pela contribuição, irei implementa-los aqui no trabalho, caso o meu chefe der o aval para usa-lo, eu precisava de uma ferramenta para sugerir para ele, neste momento irei imprimir o artigo e apresentar a ele. Tive uma dúvida no seguinte trecho de código:

# 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/ <---- AQUI (Acho que está faltando um espaço após o lib)

Seria assim:
# mv /lib /var/www/web1/phpids/

Desconsidere caso eu esteja errado, mas se realmente estiver faltando o espaço peça a um dos moderadores modificar.

Um forte abraço

Ótimo artigo!

[2] Comentário enviado por raphaelldf em 09/02/2010 - 09:36h

Que Artigo excelente firebits! tudo que vc contribui aqui tem uma relevância extraordinária no meu desenvolvimento profissional.
te agradeço e add em favoritos!

[3] Comentário enviado por silent-man em 09/02/2010 - 09:54h

Ótimo Artigo! Ótima Ferramenta! Parabéns!

[4] Comentário enviado por qxada07 em 09/02/2010 - 14:01h

Muuuito bom este artigo... Apenas não testei ainda, porém logo mais estarei implementando em meu server....

Parabéns!!!!!!!!!

[5] Comentário enviado por cleysinhonv em 09/02/2010 - 17:41h

Olá Mauro Risonho,

Fiz todos esses procedimentos relatados no artigo, mas não consigo ver os registros de log e também o script sugerido não apresenta nenhum erro. Embora seu artigo tenha sido bem auto explicativo estou com dúvidas nos dois arquivos (info.php e phpids.php), qual a função deles? O info.php foi só usado para fazer o teste?

No aguardo.

um abraço!


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts