wpsecurity

Em função dos recursos disponíveis e facilidade de gerência, o WordPress é, atualmente, um dos frameworks para gerenciamento de conteúdo mais utilizado na Internet. Infelizmente, tal característica faz dele um dos mais visados para exploração de vulnerabilidades também.

Portanto, é essencial reforçar a configuração do servidor web para dificultar ou inibir diferentes tipos ataques, como força bruta ou scan de vulnerabilidades (WPScan).

Para impedir ataques de força bruta, a utilização do módulo mod_security (no Apache) pode ser de grande valia (extremamente eficiente).

No Ubuntu, a instalação do módulo é simples:

apt-get install libapache2-mod-security2
cd /etc/modsecurity/
mv modsecurity.conf-recommended modsecurity.conf
a2enmod security2
service apache2 restart

Edite o arquivo de configuração /etc/apache2/conf-enabled/security.conf e aplique a seguinte configuração:

ServerTokens Prod
ServerSignature Off
TraceEnable Off

<files readme.html>
        Order allow,deny
        Deny from all
</files>
<files readme.txt>
        Order allow,deny
        Deny from all
</files>
<files license.txt>
        Order allow,deny
        Deny from all
</files>
<files install.php>
        Order allow,deny
        Deny from all
</files>
<files wp-config.php>
        Order allow,deny
        Deny from all
</files>

<IfModule security2_module>
        # This has to be global, cannot exist within a directory or location clause
        #SecAction phase:1,nolog,pass,initcol:ip=%{REMOTE_ADDR},initcol:user=%{REMOTE_ADDR},id:1
        SecAction phase:1,nolog,pass,initcol:ip=%{REQUEST_HEADERS.x-forwarded-for},initcol:user=%{REQUEST_HEADERS.x-forwarded-for},id:1

        <Location /wp-login.php>
                # Setup brute force detection.
 
                # React if block flag has been set.
                SecRule user:bf_block "@gt 0" "deny,status:401,log,msg:'ip address blocked for 60 minutes, more than 15 login attempts in 3 minutes.'
,id:2"
 
                # Setup Tracking. On a successful login, a 302 redirect is performed, a 200 indicates login failed.
                SecRule RESPONSE_STATUS "^302" "phase:5,t:none,log,pass,setvar:ip.bf_counter=0,id:3"
                SecRule RESPONSE_STATUS "^200" "phase:5,chain,t:none,log,pass,setvar:ip.bf_counter=+1,deprecatevar:ip.bf_counter=1/180,id:4"
                SecRule ip:bf_counter "@gt 15" "t:none,setvar:user.bf_block=1,expirevar:user.bf_block=3600,setvar:ip.bf_counter=0"
        </Location>
</IfModule>

As opções ServerTokens e ServerSignature são utilizadas para inibir a obtenção de banners ou assinaturas do servidor Apache. Acredite, a configuração padrão permite isto e é um prato cheio para a identificação do exploit ideal para a execução de determinados ataques.

Também é interessante ocultar a assinatura do php (editando o arquivo php.ini):

expose_php = Off

O bloco seguinte é utilizado para impedir o acesso a arquivos que não devem ser acessados remotamente depois que o ambiente estiver instalado. Também fará com que o scan WPScan não seja capaz de identificar corretamente quais módulos estão instalados e nem a versão utilizada. Parece pouco, mas é uma dificuldade a mais.

O último bloco, com as definições do modsecurity2, é responsável pelo banimento de acesso para tentativas de ataques de força-bruta (quebra de senhas). A configuração ativa, neste exemplo, valida o endereço de origem pelo header x-forwarded-for. É um exemplo válido para configurações com balanceador de carga (forwarded-for ativo). Se não for o seu caso (sem balanceamento, por exemplo), “inverta o comentário da linha SecAction“, removendo o comentário da primeira linha e incluindo na segunda. O endereço IP será bloqueado por 1 hora caso erre a senha 15 vezes no intervalo de 3 minutos.

A lógica de configuração adotada, com modsecurity2, foi extraída do endereço:
http://www.frameloss.org/2011/07/29/stopping-brute-force-logins-against-wordpress/

Este ajuste reforça bastante a segurança do servidor, mas ainda existe um pequeno problema. Por mais que o endereço de origem seja banido, é possível que ainda cause problema com consumo de tráfego intenso que será processado pelo servidor durante o ataque (ataques de força bruta são feitos por ferramentas que realizam centenas de conexões em curto espaço de tempo). Então, é importante evitar que um ataque como este também resulte em DoS.

Neste caso, você pode criar uma assinatura de IPS, como esta (testado no Suricata):

alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"SERVER-WEBAPP WordPress Brute Force Login"; content:"POST"; nocase; depth:5; content:"/wp-login.php"; nocase; content:!"wp-submit"; nocase; detection_filter:track by_src, count 10, seconds 60; flowint:client_packet,+,1; sid:90000000; rev:1;)
drop tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"SERVER-WEBAPP WordPress Brute Force Login"; content:"/wp-login.php"; nocase; flowint:client_packet,isset; flowint:client_packet,>,9; noalert; sid:90000001; rev:1;)