Lidando com ataques HTTP w00tw00t


82

Eu tenho um servidor com apache e recentemente instalei o mod_security2 porque sou muito atacado por isso:

Minha versão do apache é o apache v2.2.3 e eu uso o mod_security2.c

Estas foram as entradas do log de erros:

[Wed Mar 24 02:35:41 2010] [error] 
[client 88.191.109.38] client sent HTTP/1.1 request without hostname 
(see RFC2616 section 14.23): /w00tw00t.at.ISC.SANS.DFind:)

[Wed Mar 24 02:47:31 2010] [error] 
[client 202.75.211.90] client sent HTTP/1.1 request without hostname 
(see RFC2616 section 14.23): /w00tw00t.at.ISC.SANS.DFind:)

[Wed Mar 24 02:47:49 2010] [error]
[client 95.228.153.177] client sent HTTP/1.1 request without hostname
(see RFC2616 section 14.23): /w00tw00t.at.ISC.SANS.DFind:)

[Wed Mar 24 02:48:03 2010] [error] 
[client 88.191.109.38] client sent HTTP/1.1 request without hostname
(see RFC2616 section 14.23): /w00tw00t.at.ISC.SANS.DFind:)

Aqui estão os erros do access_log:

202.75.211.90 - - 
[29/Mar/2010:10:43:15 +0200] 
"GET /w00tw00t.at.ISC.SANS.DFind:) HTTP/1.1" 400 392 "-" "-"
211.155.228.169 - - 
[29/Mar/2010:11:40:41 +0200] 
"GET /w00tw00t.at.ISC.SANS.DFind:) HTTP/1.1" 400 392 "-" "-"
211.155.228.169 - - 
[29/Mar/2010:12:37:19 +0200] 
"GET /w00tw00t.at.ISC.SANS.DFind:) HTTP/1.1" 400 392 "-" "-" 

Eu tentei configurar mod_security2 assim:

SecFilterSelective REQUEST_URI "w00tw00t\.at\.ISC\.SANS\.DFind"
SecFilterSelective REQUEST_URI "\w00tw00t\.at\.ISC\.SANS"
SecFilterSelective REQUEST_URI "w00tw00t\.at\.ISC\.SANS"
SecFilterSelective REQUEST_URI "w00tw00t\.at\.ISC\.SANS\.DFind:"
SecFilterSelective REQUEST_URI "w00tw00t\.at\.ISC\.SANS\.DFind:\)"

A coisa no mod_security2 é que o SecFilterSelective não pode ser usado, isso me dá erros. Em vez disso, uso uma regra como esta:

SecRule REQUEST_URI "w00tw00t\.at\.ISC\.SANS\.DFind"
SecRule REQUEST_URI "\w00tw00t\.at\.ISC\.SANS"
SecRule REQUEST_URI "w00tw00t\.at\.ISC\.SANS"
SecRule REQUEST_URI "w00tw00t\.at\.ISC\.SANS\.DFind:"
SecRule REQUEST_URI "w00tw00t\.at\.ISC\.SANS\.DFind:\)"

Mesmo isso não funciona. Não sei mais o que fazer. Alguém tem algum conselho?

Atualização 1

Vejo que ninguém pode resolver esse problema usando o mod_security. Até agora, usar tabelas de ip parece ser a melhor opção para fazer isso, mas acho que o arquivo se tornará extremamente grande porque o ip muda de servidor vezes por dia.

Eu vim com duas outras soluções, alguém pode comentar sobre eles ser bom ou não.

  1. A primeira solução que me vem à cabeça é excluir esses ataques dos meus logs de erro do apache. Isso tornará mais fácil para mim detectar outros erros urgentes à medida que ocorrem e não precisar cuspir em um longo registro.

  2. A segunda opção é melhor, eu acho, e isso está bloqueando hosts que não são enviados da maneira correta. Neste exemplo, o ataque w00tw00t é enviado sem o nome do host, então acho que posso bloquear os hosts que não estão na forma correta.

Atualização 2

Após analisar as respostas, cheguei às seguintes conclusões.

  1. Ter um log personalizado para o apache consumirá alguns recursos desnecessários e, se houver realmente um problema, você provavelmente desejará examinar o log completo sem que nada falte.

  2. É melhor simplesmente ignorar as ocorrências e se concentrar em uma maneira melhor de analisar seus logs de erros. Usar filtros para seus logs é uma boa abordagem para isso.

Considerações finais sobre o assunto

O ataque mencionado acima não chegará à sua máquina se você tiver pelo menos um sistema atualizado; portanto, basicamente não há preocupações.

Pode ser difícil filtrar todos os ataques falsos dos reais depois de um tempo, porque os logs de erros e de acesso ficam extremamente grandes.

Impedir que isso aconteça de qualquer maneira custará recursos e é uma boa prática não desperdiçar seus recursos em coisas sem importância.

A solução que eu uso agora é o Linux logwatch . Ele me envia resumos dos logs e eles são filtrados e agrupados. Dessa forma, você pode facilmente separar o importante do sem importância.

Obrigado a todos pela ajuda, e espero que este post também possa ser útil para outra pessoa.

Respostas:


34

No seu log de erros, eles estão enviando uma solicitação HTTP / 1.1 sem a parte Host: da solicitação. Pelo que li, o Apache responde com um erro 400 (solicitação incorreta) a essa solicitação, antes de passar para o mod_security. Portanto, não parece que suas regras serão processadas. (Apache lidando com isso antes de exigir a entrega para mod_security)

Tente você mesmo:

nome do host do telnet 80
GET /blahblahblah.html HTTP / 1.1 (inserir)
(entrar)

Você deve obter o erro 400 e ver o mesmo erro em seus logs. Esta é uma solicitação ruim e o apache está dando a resposta correta.

A solicitação adequada deve se parecer com:

GET /blahblahblah.html HTTP / 1.1
Anfitrião: blah.com

Uma solução alternativa para esse problema pode ser corrigir o mod_uniqueid, gerar um ID exclusivo mesmo para uma solicitação com falha, para que o apache passe a solicitação para seus manipuladores de solicitação. O URL a seguir é uma discussão sobre essa solução alternativa e inclui um patch para o mod_uniqueid que você pode usar: http://marc.info/?l=mod-security-users&m=123300133603876&w=2

Não foi possível encontrar outras soluções para ele e saber se uma solução é realmente necessária.


Eu vejo o problema agora. Você recomenda a solução fornecida no artigo ou acha melhor deixá-la como está. É um scanner para qualquer porta traseira do sistema. Se eu deixar apenas verificando, posso um dia ser atacado.
Saif Bechan 29/03

1
Olá Saif, acho que, desde que você mantenha a instalação do apache atualizada com os patches de segurança das distribuições (ou manuais), você deve ficar bem. Uma solicitação HTTP / 1.1 mal estruturada (como você está vendo) não deve retornar nada além de um erro 400 do apache. Parece que pode ter sido algum tipo de verificação de vulnerabilidade focada nos roteadores DLink. (De acordo com algumas outras fontes)
Imo

Existe pelo menos uma forma de obter esses campos fora da minha error_log apache
Saif Bechan

Talvez você possa fazê-lo via mod_log :: httpd.apache.org/docs/2.2/mod/mod_log_config.html#customlog
Imo

Minha dica extra seria: configure seu host virtual padrão ao lado dos que estão em uso. As tentativas mencionadas acima terminarão nos logs do host virtual padrão .
Koos van den Hout

16

Filtrar IPs não é uma boa ideia. Por que não tente filtrar a string que você conhece?

Quero dizer:

iptables -I INPUT -p tcp --dport 80 -m string --to 60 --algo bm --string 'GET /w00tw00t' -j DROP

spamcleaner.org/en/misc/w00tw00t.html solução semelhante, mas um pouco mais detalhada.
Isaac

Um problema com a filtragem de strings no firewall é que ele é "bastante lento".
Alexis Wilke

@AlexisWilke, você tem evidências para sugerir que a filtragem de strings do iptables é mais lenta que a filtragem no nível do apache?
Jrwren #

@jrwren Na verdade, pode ser bastante lento se, e somente se, você não passar o deslocamento de pacotes para interromper a pesquisa, ou seja, "- a 60" aqui. Por padrão, ele pesquisará todo o pacote, o limite máximo sendo definido em 65.535 bytes, o comprimento máximo do pacote IP: blog.nintechnet.com/… O manual diz claramente "Se não for aprovado, o padrão é o tamanho do pacote".
gouessej

isso é um máximo teórico. um comprimento máximo mais realista da internet é de ~ 1500.
Jrwren

11

Iv também começou a ver esses tipos de mensagens nos meus arquivos de log. Uma maneira de evitar esses tipos de ataques é configurar o fail2ban ( http://www.fail2ban.org/ ) e configurar filtros específicos para colocar na lista negra esses endereços IP nas regras do iptables.

A seguir, um exemplo de filtro que bloquearia o endereço IP associado à criação dessas mensagens

[Ter 16 de agosto 02:35:23 2011] [erro] [cliente] O arquivo não existe: /var/www/skraps/w00tw00t.at.blackhats.romanian.anti-sec :) === apache w00t w00t messages jail - Regex e filtro === Cadeia

 [apache-wootwoot]
 enabled  = true
 filter   = apache-wootwoot
 action   = iptables[name=HTTP, port="80,443", protocol=tcp]
 logpath  = /var/log/apache2/error.log
 maxretry = 1
 bantime  = 864000
 findtime = 3600

Filtro

 # Fail2Ban configuration file
 #
 # Author: Jackie Craig Sparks
 #
 # $Revision: 728 $
 #
 [Definition]
 #Woot woot messages
 failregex = ^\[\w{1,3} \w{1,3} \d{1,2} \d{1,2}:\d{1,2}:\d{1,2} \d{1,4}] \[error] \[client 195.140.144.30] File does not exist: \/.{1,20}\/(w00tw00t|wootwoot|WootWoot|WooTWooT).{1,250}
 ignoreregex =

2
É verdade que você pode bloqueá-los, mas não há necessidade, porque são apenas solicitações ruins. É melhor simplesmente ignorá-los, economizar trabalho e liberar algumas fontes.
Saif Bechan

Certo @ Saif Bechan, se alguém se preocupa com o sucesso dos "ataques de teste", deve corrigir melhor o próprio aplicativo, ao invés de perder tempo para encontrar uma maneira de bloqueá-lo.
Thomas Berger

Deu-lhe +1, obrigado pela resposta.
Saif Bechan

4
@SaifBechan, eu discordo. O w00tw00t é um scanner de vulnerabilidades, e não é possível confiar em uma máquina que está emitindo essas solicitações para tentar outros tipos de solicitações; portanto, se eu sou administrador do sistema e levo 2 minutos para banir esses clientes por dias seguidos, eu faria isso. Eu não basearia toda a minha implementação de segurança nessa abordagem.
Isaac

3

O w00tw00t.at.blackhats.romanian.anti-sec é uma tentativa de hacking e usa IPs falsificados, de modo que pesquisas como o VisualRoute reportem China, Polônia, Dinamarca etc. de acordo com o IP que está sendo destacado naquele momento. Portanto, a configuração de um Negar IP ou um nome de host resolvível é quase impossível, pois será alterada dentro de uma hora.


Essas varreduras de vulnerabilidade não usam endereços IP falsificados. Se o fizessem, o handshake de 3 vias do TCP não seria concluído e o Apache não registraria a solicitação. Para advertências (ISP desonesto, operadores de roteadores etc.), consulte security.stackexchange.com/q/37481/53422
Anthony Geoghegan

2

Eu, pessoalmente, escrevi um script Python para adicionar automaticamente regras de tabelas de IP.

Aqui está uma versão ligeiramente abreviada, sem log e outros itens indesejados:

#!/usr/bin/python
from subprocess import *
import re
import shlex
import sys

def find_dscan():
        p1 = Popen(['tail', '-n', '5000', '/usr/local/apache/logs/error_log'], stdout=PIPE)
        p2 = Popen(['grep', 'w00t'], stdin=p1.stdout, stdout=PIPE)

        output = p2.communicate()[0].split('\n')

        ip_list = []

        for i in output:
                result = re.findall(r"\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b", i)
                if len(result):
                        ip_list.append(result[0])

        return set(ip_list)

for ip in find_dscan():
        input = "iptables -A INPUT -s " + ip + " -j DROP"
        output = "iptables -A OUTPUT -d " + ip + " -j DROP"
        Popen(shlex.split(input))
        Popen(shlex.split(output))

sys.exit(0)

É este para evitar o ataque w00tw00t
Saif Bechan

Sim, eu tenho que verificar os logs de erro do Apache em busca de IPs "w00tw00t" e adicioná-los, se não existirem, embora, por simplicidade, não tenha adicionado a verificação de duplicatas.
Xorlev 24/03/10

Esse script provavelmente deve usar uma tabela, pois adicionar toneladas de regras extras às cadeias do iptables vai atrasar bastante o processamento.
Eric

Ele usa uma tabela. No entanto, simplifiquei muito, pois foi adaptado ao meu sistema.
Xorlev 28/03/10

você acha que isso é uma solução melhor que usar mod_security
Saif Bechan

2

Acredito que a razão pela qual mod_security não está funcionando para você é que o Apache não foi capaz de analisar as solicitações, elas estão fora da especificação. Não tenho certeza se você tem algum problema aqui - o apache está registrando coisas estranhas que estão acontecendo na rede; se não registrá-lo, você nem perceberá que isso está acontecendo. Os recursos necessários para registrar as solicitações provavelmente são mínimos. Entendo que é frustrante que alguém esteja preenchendo seus logs - mas será mais frustrante se você desativar o log apenas para descobrir que realmente precisa dele. Como se alguém invadisse seu servidor da web e você precisasse dos logs para mostrar como eles invadiram.

Uma solução é configurar o ErrorLogging através do syslog e, usando o rsyslog ou o syslog-ng, você pode filtrar e descartar especificamente essas violações de RFC relacionadas ao w00tw00t. Ou então, você pode filtrá-los em um arquivo de log separado, simplesmente para facilitar a leitura do ErrorLog principal. O Rsyslog é incrivelmente poderoso e flexível a esse respeito.

Portanto, no httpd.conf você pode:

ErrorLog syslog:user 

então no rsyslog.conf você pode ter:

:msg, contains, "w00tw00t.at.ISC.SANS.DFind" /var/log/httpd/w00tw00t_attacks.log

Esteja ciente de que esta abordagem realmente utilizará muito mais recursos do que o log originalmente usado diretamente em um arquivo. Se o seu servidor da web estiver muito ocupado, isso pode se tornar um problema.

É uma boa prática enviar todos os logs para um servidor de log remoto o mais rápido possível e isso será benéfico para você, caso seja invadido, pois é muito mais difícil apagar a trilha de auditoria do que foi feito.

O bloqueio de IPTables é uma ideia, mas você pode acabar com uma lista muito grande de bloqueios de iptables, que pode ter implicações de desempenho em si. Existe um padrão nos endereços IP ou é proveniente de uma grande botnet distribuída? Será necessário haver X% de duplicatas antes de você obter um benefício do iptables.


Boa resposta, eu gosto das diferentes abordagens. Pensando nisso, ter um log personalizado criará mais uso de recurso, porque tudo precisa ser verificado primeiro, acho que essa opção também cai. Agora tenho o logwatch ativado. Isso me envia um relatório 2 vezes ao dia com resumos de todos os sistemas. Os logs do apache também são verificados e diz apenas w00tw00t tentativas 300 vezes. Acho que vou deixar a configuração como está por enquanto.
Saif Bechan

1

Você diz na atualização 2:

Problema que ainda permanece O problema que ainda permanece é o seguinte. Esses ataques são de bots que pesquisam determinados arquivos no seu servidor. Esse scanner em particular pesquisa o arquivo /w00tw00t.at.ISC.SANS.DFind :).

Agora você pode simplesmente ignorá-lo, o que é mais recomendado. O problema é que, se você tiver esse arquivo no servidor de alguma forma, um dia, estará com algum problema.

Da minha resposta anterior, concluímos que o Apache está retornando uma mensagem de erro devido a uma consulta HTML 1.1 mal formada. Todos os servidores da Web que suportam HTTP / 1.1 provavelmente devem retornar um erro quando receberem essa mensagem (não verifiquei duas vezes a RFC - talvez a RFC2616 nos diga).

Tendo w00tw00t.at.ISC.SANS.DFind: em seu servidor, em alguns lugares onde não significa misticamente "você está com problemas" ... Se você criar o arquivo w00tw00t.at.ISC.SANS.DFind: no DocumentRoot ou até mesmo DefaultDocumentRoot não importa ... o scanner está enviando uma solicitação HTTP / 1.1 quebrada e o apache está dizendo "não, isso é uma solicitação ruim ... adeus". Os dados no arquivo w00tw00t.at.ISC.SANS.DFind: não serão exibidos.

O uso de mod_security para este caso não é necessário, a menos que você realmente queira (sem motivo?) ... nesse caso, você pode fazer um patch manualmente (link em outra resposta).

Outra coisa que você poderia usar é o recurso RBL no mod_security. Talvez haja um RBL online em algum lugar que forneça IPs w00tw00t (ou outros IPs maliciosos conhecidos). No entanto, isso significa que o mod_security faz uma pesquisa de DNS para cada solicitação.


Eu não acho que o apache os rejeite, apenas gera o erro, mas a pesquisa ainda passa. Eu tenho o mesmo w00tw00t.at.ISC.SANS.DFind no log de acesso. Faz um GET. Portanto, a pesquisa é feita e, se você tiver o arquivo em sua máquina, ele será executado. Posso postar as entradas do log de acesso, mas elas parecem iguais ao log de erros apenas com um GET na frente delas. O Apache lança o erro, mas a solicitação é aprovada. Por isso, perguntei se seria uma boa ideia bloquear essas solicitações sem nomes de host. Mas não quero bloquear usuários normais.
Saif Bechan 31/03

1
Claro, você obtém a mesma entrada no log de acesso, mas olha o código de erro ... 400. Ele não é processado. HTTP / 1.1 (nome do host) é usado para informar ao apache qual host virtual enviar a solicitação para ... sem a parte do nome do host da solicitação HTTP / 1.1 O apache não sabe para onde enviar a solicitação e retorna um erro "400 requisição incorreta" de volta ao cliente.
Imo

Experimente você mesmo ... crie uma página html em seu servidor da web e tente acessá-la manualmente usando "telnet hostname 80" ... as outras etapas estão na minha primeira resposta. Eu colocaria uma grande recompensa nele que você não pode exibir o arquivo html usando HTTP / 1.1 sem o nome do host.
Imo

Ah, sim, sim, por me indicar isso. Eu sempre pensei que o access_log eram entradas que foram passadas pelo log de erros e que realmente entraram na sua máquina. Obrigado por apontar isso para mim e vou editar minha postagem. Eu realmente aprecio sua ajuda.
Saif Bechan

Oi Saif, sem problemas, feliz por ter ajudado. Atenciosamente, Imo
Imo

1

Que tal adicionar uma regra à modsecurity? Algo assim:

   SecRule REQUEST_URI "@rx (?i)\/(php-?My-?Admin[^\/]*|mysqlmanager
   |myadmin|pma2005|pma\/scripts|w00tw00t[^\/]+)\/"
   "severity:alert,id:'0000013',deny,log,status:400,
   msg:'Unacceptable folder.',severity:'2'"

1

Vejo que a maioria das soluções já foi abordada acima, mas gostaria de salientar que nem todos os clientes enviaram solicitações HTTP / 1.1 sem ataques de nome de host , direcionados diretamente ao seu servidor. Existem muitas tentativas diferentes de obter impressões digitais e / ou explorar o sistema de rede que precede o servidor, ou seja, usando:

client sent HTTP/1.1 request without hostname (see RFC2616 section 14.23): /tmUnblock.cgi

para direcionar os roteadores Linksys etc. Então, às vezes, ajuda a ampliar seu foco e dividir seus esforços de defesa entre todos os sistemas com um compartilhamento igual, por exemplo: implementar regras de roteador, implementar regras de firewall (espero que sua rede tenha uma), implementar tabela de firewall / IP do servidor regras e serviços relacionados, isto é, mod_security, fail2ban e assim por diante.


1

que tal agora ?

iptables -I INPUT -p tcp --dport 80 -m string --to 70 --algo bm --string 'GET /w00tw00t.at.ISC.SANS.DFind' -j DROP
iptables -I INPUT -p tcp --dport 80 -m string --to 70 --algo bm --string 'GET /w00tw00t.at.ISC.SANS.DFind' -j LOG --log-level 4 --log-prefix Hacktool.DFind:DROP:

funciona bem para mim.


i recomendado a regra OWASP_CRS / 2.2.5 ou ralador definido para mod_security
Urbach-Webhosting

Isso realmente não é uma boa ideia. Você terminará com muitas conexões suspensas. Além disso, se o seu site tiver alguma discussão sobre essas solicitações, você poderá acabar com falsos positivos.
kasperd

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.