Eradiquer les mauvaises herbes : les scanneurs de failles ! Première partie

Première partie : Introduction et filtrage avec Netfilter

Je me lance dans une expérience !

J’ai installé il y a quelques mois un CMS sur un serveur Linux (Debian). Et je constate régulièrement que les logs crachent des messages d’erreurs de tous poils et en continu !!

Deux exemples :

File does not exist: /home/www/wordpress/stat
client sent HTTP/1.1 request without hostname (see RFC2616 section 14.23): /w00tw00t.at.ISC.SANS.DFind:)

Qu’est ce que c’est que ça ?

Ces messages sont principalement dû à des scanner de vulnérabilités.
Les scanneurs envoient aléatoirement des requêtes vers des adresses IP générées arbitrairement à la recherche de failles à exploiter. Ces requêtes sont souvent mal formatées ou composées d’éléments particuliers comme une adresse IP au lieu d’un nom SQDN ou des expressions particulières comme « w00tw00t ».

Comment les éradiquer ?

Je vais mettre en concurrence Netfilter, fail2ban et mod_security pour tenter de bloquer ces scans intempestifs ! Et accessoirement, éviter les tentatives malveillantes qui en découlent !

La principale différence entre ces solutions se situer au niveau de la prise en charge de l’événement à bloquer. Plus tôt il est prise en charge dans son escalade, plus la parade sera efficace. Netfilter sera le premier rempart et probablement le plus efficace car avant que mod_security ou même fail2ban ne puissent le prendre en charge, il y aura déjà pas mal de tentatives et il sera peut-être trop tard ! mod_security est un module Apache, censé analyser les requêtes Web en « temps réel », mais attention aux performances sur une configuration trop fermée. Quant à fail2ban, il fonctionne sur un mécanisme de détection des expressions rationnelles dans les logs puis isole les IP. C’est donc très palliatif. Mais nous constaterons peut-être que la combinaison de ces trois solutions serait finalement le plus efficace…

1/ Avec Netfilter

Je me suis inspiré de http://spamcleaner.org/fr/misc/w00tw00t.html

iptables -I INPUT -d 88.191.122.62 -p tcp --dport 80 -m string --to 70 --algo bm --string 'GET /w00tw00t.at.ISC.SANS.' -j DROP
iptables -I INPUT -d 88.191.122.62 -p tcp --dport 80 -m string --to 700 --algo bm --string 'Host: 88.191.122.62' -j DROP

Après plusieurs heures

pkts bytes target prot opt in out source destination
63 14256 DROP tcp -- * * 0.0.0.0/0 88.191.122.62 tcp dpt:80 STRING match "Host: 88.191.122.62" ALGO name bm TO 700
61 5246 DROP tcp -- * * 0.0.0.0/0 88.191.122.62 tcp dpt:80 STRING match "GET /w00tw00t.at.ISC.SANS." ALGO name bm TO 70

On constate que 14256 bytes ont été dropés pour la premier règle (accès direct sur l’adresse IP du serveur) et que 5246 bytes ont été dropé pour la seconde règle (w00tw00t.at.ISC.SANS.).

Première conclusion : les règles sont utiles mais sont-elles efficaces ?

Si je fais un grep w00tw00t /var/log/apache2/error.log , je constate que je n’ai aucun résultat. Donc, la règle pour le w00tw00t.at.ISC.SANS semble être efficace.

Par contre, qu’en est t il des erreurs du type : « File does not exist: /home/www/wordpress/stat » ?

tail /var/log/apache2/error.log

[Tue Dec 13 07:34:19 2011] [error] [client 65.52.108.148] File does not exist: /home/www/wordpress/photos
[Tue Dec 13 08:27:26 2011] [error] [client 66.249.71.88] File does not exist: /home/www/wordpress/photos
[Wed Dec 14 16:12:10 2011] [error] [client 69.162.119.162] script '/home/www/wordpress/site.php' not found or unable to stat

Donc, bon visiblement la règle « Host: 88.191.122.62 » n’est pas assez efficace.

Alors regardons d’un peu plus près….

cat /var/log/apache2/access.log | grep 69.162.119.162

69.162.119.162 - - [14/Dec/2011:16:12:06 +0100] "GET /awstatstotals/awstatstotals.php?sort=%7b%24%7bpassthru%28chr(105)%2echr(100)%29%7d%7d%7b%24%7bexit%28%29%7d%7d HTTP/1.1" 404 511 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:8.0) Gecko/20100101 Firefox/8.0"
69.162.119.162 - - [14/Dec/2011:16:12:06 +0100] "GET /?file=../../../../../../proc/self/environ%00 HTTP/1.1" 200 8116 "-" ""
69.162.119.162 - - [14/Dec/2011:16:12:07 +0100] "GET /?page=../../../../../../proc/self/environ%00 HTTP/1.1" 200 8114 "-" ""

Premièrement, nous pouvons nous demander pourquoi la règle de filtrage sur l’adresse IP de destination n’a pas fonctionné.

Est ce parce que le nom FQDN a été utilisé ? ou alors est ce parce que le Host à été codé en hexadécimal ?

Au regard des erreurs précédentes, nous n’avons pas assez d’élément pour le déterminer…alors deux possibilités s’offrent à nous :

– Placer une règle pour filtrer le Host en hexadécimal.
– Modifier le format des logs de Apache pour avoir un peu plus d’information.

Donc j’ajoute \\"%{Host}i\\" dans le /etc/apache2/apache2.conf :

LogFormat "%h %l %u %t \\"%r\\" %>s %O \\"%{Referer}i\\" \\"%{User-Agent}i\\" \\"%{Host}i\\"" combined

On aurait pu également ajuster le LogLevel.

Alors quelques heures plus tard :

[Sat Dec 17 07:55:47 2011] [error] [client 207.238.196.3] script '/home/www/wordpress/site.php' not found or unable to stat
[Sat Dec 17 07:55:51 2011] [error] [client 207.238.196.3] File does not exist: /home/www/wordpress/catalog
[Sat Dec 17 07:55:51 2011] [error] [client 207.238.196.3] File does not exist: /home/www/wordpress/shop

Voyons les access.log maintenant :

cat /var/log/apache2/access.log | grep 207.238.196.3

207.238.196.3 - - [17/Dec/2011:07:55:46 +0100] "GET /index.php?option=com_simpledownload&controller=../../../../../../../../../../../../../../../proc/self/environ%00 HTTP/1.1" 301 511 "-" "" "www.pointroot.org"
207.238.196.3 - - [17/Dec/2011:07:55:47 +0100] "GET /site.php?a={%24{passthru%28chr%28105%29.chr%28100%29%29}} HTTP/1.1" 404 504 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:8.0) Gecko/20100101 Firefox/8.0" "www.pointroot.org"

Le dernier élément correspond à l’information Host de l’entête, donc, ici "www.pointroot.org".

En clair, le scanner passe directement avec le FQDN….donc le filtre Netfilter sur l’adresse IP ne fonctionne pas pour ce cas de figure. Il va falloir trouver une autre parade.

Nous allons donc analyser la partie requête (\\ »%r\\ ») pour essayer de déduire une anomalie dont on pourrait se servir pour la bloquer.

Nous pouvons remarquer les expressions suivantes dans les logs :

sort
../
cmd
echo
|
uname
{
}

Une solution serait de mettre ces expressions dans un fichier et demander à Netfilter de vérifier si les requêtes ne contiennent pas les expressions précédentes et ainsi bloquer l’IP à l’origine des requêtes. Mais il sera difficile de tenir cette liste à jour.

Nous avons peut-être atteint les limites de Netfilter pour effectuer ce que nous souhaitons faire….

La suite dans la deuxième partie de l’article….

Annexe

http://blog.nicolargo.com/2010/12/securiser-son-blog-wordpress.html
http://spamcleaner.org/fr/misc/w00tw00t.html
Une extension : WP Security Scan

Cet article Eradiquer les mauvaises herbes : les scanneurs de failles ! Première partie est apparu en premier sur PointRoot.org.

Vus : 1398
Publié par pointroot.org : 17