segunda-feira, agosto 27, 2012

ModSecurity Series 4 - SecRuleRemoveById

    Após habilitar o ModSecurity, uma das primeiras tarefas a serem realizadas é a de verificar por falso-positivos. Existem diversas maneiras de desabiltar uma regra do ModSecurity, vamos ver algumas delas nesse post:

    - Desabilitar a regra no arquivo de rules: essa é a maneira mais simples, basta editar o arquivo onde a regra se encontra, e simplesmente excluí-la ou comentá-la com "#". Apesar de ser simples, isso não é recomendado, pois ao atualizar posteriormente os arquivos de regras, essa tarefa terá que ser feita novamente. Outra desvantagem é que nem sempre queremos desabilitar toda a regra, e sim somente para um determinado contexto do Apache, ou para um IP ou para uma url do site, e deixá-la habilitada para o resto.


    - Desabilitar o ModSecurity para um endereço IP específico: Segue exemplo abaixo:


SecRule REMOTE_ADDR "@streq 192.168.1.1" \
 phase:1,t:none,nolog,allow




SecRuleRemoveById: - Como o próprio nome da regra diz, permite que uma regra seja desabilitada no ModSecurity somente passando o seu ID. A vantagem do seu uso é a simplicidade na sua aplicação, e além disso, o uso de contextos no apache. Seguem abaixo alguns exemplos:


- Desabilitar a regra com o ID 950007 (Blind SQL injection, cuja regras está no arquivo modsecurity_crs_41_sql_injection_attacks.conf da CRS), somente da URL /foo/bar :



<Location ^/foo/bar/>
    SecRuleRemoveById 950007
</Location>



- Com o uso do Location do apache, é possível criar expressões regulares para liberação como nos exemplos abaixo:



<LocationMatch ^/foo/bar/[0-9]+/edit/$>
    SecRuleRemoveById 950007
</LocationMatch>


<LocationMatch ^/foo/.+/bar/.+/edit/$>
    SecRuleRemoveById 950007
</LocationMatch>



- Também é possível usar outras diretivas do Apache em conjunto com diretivas do ModSecurity, como por exemplo Virtualhost:

<VirtualHost 10.1.2.3:80>
   ServerAdmin webmaster@host.example.com
   DocumentRoot /www/docs/host.example.com
   ServerName host.example.com
   ErrorLog logs/host.example.com-error_log
   TransferLog logs/host.example.com-access_log
   SecRuleEngine On
</VirtualHost>






<VirtualHost 10.1.2.3:80>
   ServerAdmin webmaster@host2.example.com
   DocumentRoot /www/docs/host2.example.com
   ServerName host2.example.com
   ErrorLog logs/host2.example.com-error_log
   TransferLog logs/host2.example.com-access_log
   SecRuleEngine Off
</VirtualHost>





- Também é possível utilizar outros métodos para desabilitar as regras, como por exemplo: uso de variáveis transacionaisSecRuleRemoveByMsgSecRuleRemoveByTagSecRuleUpdateActionByIdSecRuleUpdateTargetById (deprecated), SecRuleUpdateTargetByMsg, SecRuleUpdateTargetByTag, ctl:ruleRemoveById, ctl:ruleRemoveTargetById. Essas diretivas ficam para posts futuros.


sexta-feira, agosto 10, 2012

ModSecurity Series 3 - SecRuleEngine

   Nesse post irei falar um pouco sobre o parâmetro SecRuleEngine:

   Esse parâmetro, definido no arquivo modsecurity.conf (copiado de modsecurity.conf-recommended do código fonte do ModSecurity), define se as regras estão ativadas, desativadas, ou atuando no modo de somente detecção. Conforme a Wiki do ModSecurity:


SecRuleEngine

Descrição: Configura o mecanismo das regras.
Sintaxe: SecRuleEngine On|Off|DetectionOnly
Exemplo de uso: SecRuleEngine On
Escopo: Qualquer
Versão: 2.0.0
Padrão: Off

Os valores possíveis são:
      On: processa as regras
      Off: não processa as regras
      DetectionOnly: processa as regras mas nunca executa nenhuma ação de bloqueio (block, deny, drop, allow, proxy and redirect)


   No modsecurity.conf-recommended incluído no código fonte do ModSecurity e normalmente utilizado como base, esse parâmetro vem como DetectionOnly por padrão.


   Um exemplo simples e prático: no post anterior, Instalando o ModSecurity 2.6.7 + CRS 2.2.5 no Debian Wheezy, o ModSecurity está instalado no Apache, mas como não foi alterada a sua configuração, o parâmetro SecRuleEngine está configurado como somente como deteção e não realizará nenhum tipo de bloqueio.

   - Vamos criar um arquivo chamado test.cfg e publicar ele no Apache previamente instalado com o ModSecurity:

echo "TEST" > /var/www/test.cfg


   - Acesse em um browser esse arquivo, e você poderá visualizar o seu conteúdo:


   Isso não é bom, se você tiver alguma informação confidencial como credenciais de acesso ao banco de dados dentro desse arquivo, por exemplo...

   Apesar de não ter sido bloqueado o acesso, o ModSecurity estava configurado no modo de detecção e registrou um alerta (warning) no log de erros do Apache:

[Fri Aug 10 13:24:19 2012] [error] [client X.X.X.X] ModSecurity: Warning. String match within ".asa/ .asax/ .ascx/ .axd/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pol/ .printer/ .pwd/ .resources/ .resx/ .sql/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/" at TX:extension. [file "/etc/apache2/modsecurity/crs/activated_rules/modsecurity_crs_30_http_policy.conf"] [line "88"] [id "960035"] [msg "URL file extension is restricted by policy"] [data ".cfg"] [severity "CRITICAL"] [tag "POLICY/EXT_RESTRICTED"] [tag "WASCTC/WASC-15"] [tag "OWASP_TOP_10/A7"] [tag "PCI/6.5.10"] [hostname "test.domain.com"] [uri "/test.cfg"] [unique_id "UCU1s38AAQEAAFLrARoAAABA"]

   Interpretando o log de erro acima, a regra com o ID 960035, que está na linha 88 do arquivo /etc/apache2/modsecurity/crs/activated_rules/modsecurity_crs_30_http_policy.conf, identificou que um arquivo com uma extensão não permitida foi acessado. Abaixo a regra que deu match:


SecRule REQUEST_BASENAME "\.(.*)$" "chain,capture,setvar:tx.extension=.%{tx.1}/,phase:2,t:none,t:urlDecodeUni,t:lowercase,block,msg:'URL file extension is restricted by policy', severity:'2',id:'960035',tag:'POLICY/EXT_RESTRICTED',tag:'WASCTC/WASC-15',tag:'OWASP_TOP_10/A7',tag:'PCI/6.5.10',logdata:'%{TX.0}'"
        SecRule TX:EXTENSION "@within %{tx.restricted_extensions}" "t:none,setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},setvar:tx.policy_score=+%{tx.warning_anomaly_score},setvar:tx.%{rule.id}-POLICY/EXT_RESTRICTED-%{matched_var_name}=%{matched_var}"



   Na verdade, se você for ver a regra 960035, verá que as extensões bloqueadas estão definidas na variável "tx.restricted_extensions", que está definido no arquivo modsecurity_crs_10_setup.conf da CRS. Caso desejar adicionar ou remover alguma extensão bloqueada, é nessa variável que isso deve ser feito, e não na regra.

   A Core Rule Set também traz bastante documentação sobre cada regra, como a utilizada nesse exemplo: ela aponta para referências à:
- WASCTC/WASC-15: Application Misconfiguration
- OWASP_TOP_10/A7: Insecure Cryptographic Storage
- PCI/6.5.10: Insecure configuration management



   Ok, então agora vamos então bloquear esse tipo de evento.Habilite o modo de bloqueio no ModSecurity:

SecRuleEngine On


   Reinicie o Apache, e agora tente acessar o mesmo arquivo através do browser:

   Mesmo o arquivo existindo no servidor web, o bloqueio foi realizado. O log do Apache registra o bloqueio:

Fri Aug 10 13:43:30 2012] [error] [client X.X.X.X] ModSecurity: Access denied with code 403 (phase 2). String match within ".asa/ .asax/ .ascx/ .axd/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pol/ .printer/ .pwd/ .resources/ .resx/ .sql/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/" at TX:extension. [file "/etc/apache2/modsecurity/crs/activated_rules/modsecurity_crs_30_http_policy.conf"] [line "88"] [id "960035"] [msg "URL file extension is restricted by policy"] [data ".cfg"] [severity "CRITICAL"] [tag "POLICY/EXT_RESTRICTED"] [tag "WASCTC/WASC-15"] [tag "OWASP_TOP_10/A7"] [tag "PCI/6.5.10"] [hostname "test.domain.com"] [uri "/test.cfg"] [unique_id "UCU6Mn8AAQEAAFSeASsAAAAA"]


   Esse é um exemplo de uma regra simples, mas é fácil de entender como funciona e como interpretar esses logs, o que dará base para interpretar posteriormente regras mais complexas. Até o próximo post!



ModSecurity Series 2 - Instalando o ModSecurity 2.6.7 + CRS 2.2.5 no Debian Wheezy

   Como não consegui postar na semana passada, essa semana terá 2 posts sobre o ModSecurity. Esse será sobre a instalação do ModSecurity 2.6.7 + o Core Rule Set 2.2.5 no Debian Wheezy (atualmente testing). A versão antiga desse post, voltado para o CentOS, está aqui: Installing ModSecurity 2.6.1-rc1 + CRS (Core Rule Set) 2.2.0 on CentOS 5.6


- Instalar as dependências: 

apt-get install build-essential apache2-threaded-dev apache2 libpcre3-dev libpcre3 libxml2 libxml2-dev lua5.1 liblua5.1-dev libcurl3-dev


  - Realizar o download do código fonte do ModSecurity:

cd /usr/local/src
wget http://www.modsecurity.org/download/modsecurity-apache_2.6.7.tar.gz
wget "http://downloads.sourceforge.net/project/mod-security/modsecurity-apache/2.6.7/modsecurity-apache_2.6.7.tar.gz.asc"


- Baixar o Core Rule Set:

wget "http://downloads.sourceforge.net/project/mod-security/modsecurity-crs/0-CURRENT/modsecurity-crs_2.2.5.zip"
wget "http://downloads.sourceforge.net/project/mod-security/modsecurity-crs/0-CURRENT/modsecurity-crs_2.2.5.zip.sig"


- Importar as chaves de assinatura em seu arquivo de chaves PGP:


# gpg --recv-keys 9624FCD2
gpg: porta-chaves `/root/.gnupg/secring.gpg' criado
gpg: requesting key 9624FCD2 from hkp server keys.gnupg.net
gpg: /root/.gnupg/trustdb.gpg: banco de dados de confiabilidade criado
gpg: key 9624FCD2: public key "Ryan Barnett (OWASP Core Rule Set Project Leader) " imported
gpg: Número total processado: 1
gpg:               importados: 1  (RSA: 1)

# gpg --recv-keys 6980F8B0
gpg: requesting key 6980F8B0 from hkp server keys.gnupg.net
gpg: key 6980F8B0: public key "Breno Silva Pinto " imported
gpg: Número total processado: 1
gpg:               importados: 1  (RSA: 1)




- Verificar a integridade dos arquivos: 


# gpg --verify modsecurity-apache_2.6.7.tar.gz.asc
gpg: Signature made Qui 02 Ago 2012 19:49:04 BRT using RSA key ID 6980F8B0
gpg: Good signature from "Breno Silva Pinto "
gpg: AVISO: Esta chave não está certificada com uma assinatura confiável!
gpg:        Não há indicação de que a assinatura pertence ao dono.
Impressão da chave primária: AB36 0F15 ACF8 D30F 806E  41D2 8050 C35A 6980 F8B0

# gpg --verify modsecurity-crs_2.2.5.zip.sig
gpg: Signature made Qui 14 Jun 2012 13:48:52 BRT using RSA key ID 9624FCD2
gpg: Good signature from "Ryan Barnett (OWASP Core Rule Set Project Leader) "
gpg: AVISO: Esta chave não está certificada com uma assinatura confiável!
gpg:        Não há indicação de que a assinatura pertence ao dono.
Impressão da chave primária: D5B2 7FC9 BFD2 5BDD 57DB  7291 C976 607D 9624 FCD2




- Descompactar:

tar xvfz modsecurity-apache_2.6.7.tar.gz 
unzip -x modsecurity-crs_2.2.5.zip 



- Compilar o módulo do apache:


cd modsecurity-apache_2.6.7/
./configure
make
make install
# O módulo é instalado em /usr/lib/apache2/modules/mod_security2.so e ferramentas em /usr/local/modsecurity/bin




- Instalar a estrutura de regras do CRS:


mkdir -p /etc/apache2/modsecurity/crs
touch /etc/apache2/modsecurity/whitelist.conf
cp /usr/local/src/modsecurity-apache_2.6.7/modsecurity.conf-recommended /etc/apache2/modsecurity/modsecurity.conf
cp -a /usr/local/src/modsecurity-crs_2.2.5/* /etc/apache2/modsecurity/crs

cd /etc/apache2/modsecurity/crs
cp modsecurity_crs_10_setup.conf.example modsecurity_crs_10_setup.conf
for f in `ls base_rules/` ; do ln -s ../base_rules/$f activated_rules/$f ; done
for f in `ls experimental_rules/` ; do ln -s ../experimental_rules/$f activated_rules/$f ; done


# Se forem habilitadas as "experimental rules, alguns arquivos precisam ser configurados e personalizados: modsecurity_crs_11_proxy_abuse.conf, modsecurity_crs_16_scanner_integration.conf,modsecurity_crs_40_appsensor_detection_point_2.1_request_exception.conf, modsecurity_crs_42_csp_enforcement.conf, modsecurity_crs_55_response_profiling.conf, modsecurity_crs_56_pvi_checks.conf, modsecurity_crs_61_ip_forensics.conf 



Habilitar o mod_unique_id no apache:

# a2enmod unique_id


- Criar o arquivo /etc/apache2/mods-available/modsecurity.load com o seguinte conteúdo :


LoadFile /usr/lib/x86_64-linux-gnu/libxml2.so
LoadFile /usr/lib/x86_64-linux-gnu/liblua5.1.so
LoadModule security2_module /usr/lib/apache2/modules/mod_security2.so



- Criar o arquivo /etc/apache2/mods-available/modsecurity.conf com o seguinte conteúdo:


<IfModule security2_module>
  Include modsecurity/modsecurity.conf
  Include modsecurity/whitelist.conf
  Include modsecurity/crs/modsecurity_crs_10_setup.conf
  Include modsecurity/crs/activated_rules/*.conf
</IfModule>



- Habilitar o módulo modsecurity no apache:

# a2enmod modsecurity

- Testar a configuração:

# apache2ctl -t
Syntax OK

- Se tudo estiver ok, basta reiniciar o apache.No log do apache irá aparecer o seguinte:


[Fri Aug 10 14:02:44 2012] [notice] ModSecurity for Apache/2.6.7 (http://www.modsecurity.org/) configured.
[Fri Aug 10 14:02:44 2012] [notice] ModSecurity: APR compiled version="1.4.6"; loaded version="1.4.6"
[Fri Aug 10 14:02:44 2012] [notice] ModSecurity: PCRE compiled version="8.30 "; loaded version="8.30 2012-02-04"
[Fri Aug 10 14:02:44 2012] [notice] ModSecurity: LUA compiled version="Lua 5.1"
[Fri Aug 10 14:02:44 2012] [notice] ModSecurity: LIBXML compiled version="2.8.0"
[Fri Aug 10 14:02:45 2012] [notice] Apache/2.2.22 (Debian) configured -- resuming normal operations




O ModSecurity está instalado por padrão no modo de detecção, o que será explicado no próximo post. Até lá.