82 votes

Gérer les attaques HTTP w00tw00t

J'ai un serveur avec apache et j'ai récemment installé mod_security2 parce que je suis souvent attaqué par cela :

Ma version d'apache est apache v2.2.3 et j'utilise mod_security2.c

Voici les entrées du journal des erreurs :

[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:)

Voici les erreurs du journal d'accès :

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 "-" "-" 

J'ai essayé de configurer le mod_security2 comme ceci :

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:\)"

Le problème dans le mod_security2 est que SecFilterSelective ne peut pas être utilisé, cela me donne des erreurs. À la place, j'utilise une règle comme celle-ci :

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:\)"

Même cela ne fonctionne pas. Je ne sais plus quoi faire. Quelqu'un a un conseil à me donner ?

Mise à jour 1

Je vois que personne ne peut résoudre ce problème en utilisant mod_security. Jusqu'à présent, l'utilisation de ip-tables semble être la meilleure solution, mais je pense que le fichier deviendra extrêmement volumineux, car l'adresse IP change plusieurs fois par jour.

J'ai trouvé deux autres solutions. Quelqu'un peut-il me dire si elles sont bonnes ou non ?

  1. La première solution qui me vient à l'esprit est d'exclure ces attaques de mes journaux d'erreurs apache. Cela me permettra de repérer plus facilement d'autres erreurs urgentes au fur et à mesure qu'elles se produisent et de ne pas avoir à cracher dans un long journal.

  2. La deuxième option est meilleure, je pense, et consiste à bloquer les hôtes qui ne sont pas envoyés de la bonne manière. Dans cet exemple, l'attaque w00tw00t est envoyée sans nom d'hôte, donc je pense que je peux bloquer les hôtes qui ne sont pas dans la forme correcte.

Mise à jour 2

Après avoir parcouru les réponses, je suis arrivé aux conclusions suivantes.

  1. Avoir une journalisation personnalisée pour apache consommera des ressources inutiles, et s'il y a vraiment un problème, vous voudrez probablement regarder le journal complet sans rien manquer.

  2. Il est préférable d'ignorer les résultats et de se concentrer sur une meilleure façon d'analyser vos journaux d'erreurs. L'utilisation de filtres pour vos journaux est une bonne approche pour cela.

Dernières réflexions sur le sujet

L'attaque mentionnée ci-dessus n'atteindra pas votre machine si vous disposez au moins d'un système à jour, vous n'avez donc aucun souci à vous faire.

Au bout d'un certain temps, il peut être difficile de distinguer les fausses attaques des vraies, car les journaux d'erreurs et d'accès deviennent extrêmement volumineux.

Empêcher cela de quelque manière que ce soit vous coûtera des ressources et c'est une bonne pratique de ne pas gaspiller vos ressources pour des choses sans importance.

La solution que j'utilise maintenant est Linux logwatch . Il m'envoie des résumés des journaux, qui sont filtrés et regroupés. De cette façon, vous pouvez facilement séparer l'important de l'insignifiant.

Merci à tous pour votre aide, et j'espère que cet article pourra être utile à quelqu'un d'autre.

34voto

Cœur Points 325

D'après votre journal des erreurs, ils envoient une requête HTTP/1.1 sans la partie Host : de la requête. D'après ce que j'ai lu, Apache répond par une erreur 400 (bad request) à cette requête, avant de passer le relais à mod_security. Donc, il ne semble pas que vos règles seront traitées. (Apache s'en occupe avant de devoir passer le relais à mod_security)

Essayez vous-même :

telnet hostname 80
GET /blahblahblah.html HTTP/1.1  (enter)
(enter)

Vous devriez obtenir l'erreur 400 et voir la même erreur dans vos journaux. Il s'agit d'une mauvaise requête et Apache donne la réponse correcte.

Une demande correcte devrait ressembler à ceci :

GET /blahblahblah.html HTTP/1.1
Host: blah.com

Une solution de contournement de ce problème pourrait consister à appliquer un correctif au module mod_uniqueid, afin de générer un identifiant unique, même pour une requête qui a échoué, afin qu'Apache transmette la requête à ses gestionnaires de requêtes. L'URL suivante est une discussion sur ce contournement, et inclut un correctif pour mod_uniqueid que vous pouvez utiliser : http://marc.info/?l=mod-security-users&m=123300133603876&w=2

Je n'ai pas trouvé d'autres solutions à ce problème et je me demande si une solution est vraiment nécessaire.

16voto

Rob Paller Points 4610

Le filtrage des IP n'est pas une bonne idée, à mon avis. Pourquoi ne pas essayer de filtrer la chaîne de caractères que vous connaissez ?

Je veux dire :

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

12voto

Hooman Points 11103

J'ai également commencé à voir ces types de messages dans mes fichiers journaux. Une façon d'éviter ces types d'attaques est de configurer fail2ban( http://www.fail2ban.org/ ) et configurez des filtres spécifiques pour mettre ces adresses IP en liste noire dans vos règles iptables.

Voici un exemple de filtre qui bloquerait l'adresse IP associée à l'envoi de ces messages.

[Tue Aug 16 02:35:23 2011] [error] [client ] Le fichier n'existe pas : /var/www/skraps/w00tw00t.at.blackhats.romanian.anti-sec :) === apache w00t w00t messages jail - regex et filtre === Jail

 [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

Filtre

 # 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 =

3voto

PRW Points 39

W00tw00t.at.blackhats.romanian.anti-sec est une tentative de piratage et utilise des IP usurpées, de sorte que les recherches telles que VisualRoute signaleront la Chine, la Pologne, le Danemark, etc. selon l'IP détachée à ce moment-là. La mise en place d'une IP de refus ou d'un nom d'hôte résoluble est donc pratiquement impossible car elle changera en une heure.

2voto

Xorlev Points 1835

J'ai personnellement écrit un script Python pour ajouter automatiquement des règles IPtables.

Voici une version légèrement abrégée, sans logging et autres cochonneries :

#!/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)

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X