Filtre des scans d'URL

De EjnTricks

Lors de la mise en ligne d'un serveur, des scans sur des URLs sont réalisés surement afin d'identifier des installations de produits contenant des failles de sécurités. Il apparaît très clairement que ces requêtes ne sont pas destinées à visiter le site, mais à exploiter une faille de sécurité. Dans pareil cas, il est préférable de bannir l'adresse IP dès la première tentative, contrairement au paramétrage sur l'accès SSH standard.

Suite à une mise à jour de Fail2ban, le bannissement sur les URLs a été modifié comme décrit dans l'article suivant. Il est recommandé de plutôt suivre ce dernier.


Hand-icon.png Votre avis

Current user rating: 69/100 (10 votes)

 You need to enable JavaScript to vote


Warning-icon.png Précaution

Cet article a été rédigé sur une version assez ancienne de Fail2ban. Les contenus des fichiers de configurations ne sont plus à jour et doivent être lus avec précaution.

Il sera nécessaire d'adapter avec la structure des versions récentes.


Books-icon.png Analyse

De nombreuses configurations sont déjà disponibles dans le répertoire /etc/fail2ban/filter.d, mais non activées. Cependant, elles fournissent une source d'inspiration pour l'écriture d'une nouvelle règle de filtrage.

Command-icon.png Configuration apache-noscript.conf

# Fail2Ban configuration file
#
# Author: Cyril Jaquier
#
# $Revision: 728 $
#

[Definition]

# Option:  failregex
# Notes.:  regex to match the password failure messages in the logfile. The
#          host must be matched by a group named "host". The tag "<HOST>" can
#          be used for standard IP/hostname matching and is only an alias for
#          (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
# Values:  TEXT
#
failregex = [[]client <HOST>[]] (File does not exist|script not found or unable to stat): /\S*(\.php|\.asp|\.exe|\.pl)
            [[]client <HOST>[]] script '/\S*(\.php|\.asp|\.exe|\.pl)\S*' not found or unable to stat *$

# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
#
ignoreregex =

Cette configuration permet de détecter des accès à des ressources inexistantes sur le serveur Apache, ce qui est le cas pour la configuration à mettre en place. Cependant, le filtre doit s'appliquer sur un ensemble d'URLs bien identifiées. Il parait alors fastidieux de mettre en place chacune des valeurs au niveau de la substitution dans l'expression régulière, au niveau du paramètre failregex.

Robot-icon.png Configuration apache-badbots.conf

# Fail2Ban configuration file
#
# List of bad bots fetched from http://www.user-agents.org
# Generated on Sun Feb 11 01:09:15 EST 2007 by ./badbots.sh
#
# Author: Yaroslav Halchenko
#
# $Revision: 668 $
#

[Definition]

badbotscustom = EmailCollector|WebEMailExtrac|TrackBack/1\.02|sogou music spider
badbots = atSpider/1\.0|autoemailspider|China Local Browse 2\.6|ContentSmartz|DataCha0s/2\.0|DBrowse 1\.4b|DBrowse 1\.4d|Demo Bot DOT 16b|
Demo Bot Z 16b|DSurf15a 01|DSurf15a 71|DSurf15a 81|DSurf15a VA|EBrowse 1\.4b|Educate Search VxB|EmailSiphon|EmailWolf 1\.00|
ESurf15a 15|ExtractorPro|Franklin Locator 1\.8|FSurf15a 01|Full Web Bot 0416B|Full Web Bot 0516B|Full Web Bot 2816B|Industry Program 1\.0\.x|
ISC Systems iRc Search 2\.1|IUPUI Research Bot v 1\.9a|LARBIN-EXPERIMENTAL \(efp@gmx\.net\)|LetsCrawl\.com/1\.0 +http\://letscrawl\.com/|
Lincoln State Web Browser|LWP\:\:Simple/5\.803|Mac Finder 1\.0\.xx|MFC Foundation Class Library 4\.0|
Microsoft URL Control - 6\.00\.8xxx|Missauga Locate 1\.0\.0|Missigua Locator 1\.9|Missouri College Browse|Mizzu Labs 2\.2|
Mo College 1\.9|Mozilla/2\.0 \(compatible; NEWT ActiveX; Win32\)|Mozilla/3\.0 \(compatible; Indy Library\)|
Mozilla/4\.0 \(compatible; Advanced Email Extractor v2\.xx\)|Mozilla/4\.0 \(compatible; Iplexx Spider/1\.0 http\://www\.iplexx\.at\)|
Mozilla/4\.0 \(compatible; MSIE 5\.0; Windows NT; DigExt; DTS Agent|Mozilla/4\.0 efp@gmx\.net|
Mozilla/5\.0 \(Version\: xxxx Type\:xx\)|MVAClient|NASA Search 1\.0|Nsauditor/1\.x|PBrowse 1\.4b|PEval 1\.4b|Poirot|
Port Huron Labs|Production Bot 0116B|Production Bot 2016B|Production Bot DOT 3016B|Program Shareware 1\.0\.2|PSurf15a 11|
PSurf15a 51|PSurf15a VA|psycheclone|RSurf15a 41|RSurf15a 51|RSurf15a 81|searchbot admin@google\.com|sogou spider|sohu agent|
SSurf15a 11 |TSurf15a 11|Under the Rainbow 2\.2|User-Agent\: Mozilla/4\.0 \(compatible; MSIE 6\.0; Windows NT 5\.1\)|
WebVulnCrawl\.blogspot\.com/1\.0 libwww-perl/5\.803|Wells Search II|WEP Search 00

# Option:  failregex
# Notes.:  Regexp to catch known spambots and software alike. Please verify
#          that it is your intent to block IPs which were driven by
#          abovementioned bots.
# Values:  TEXT
#
failregex = ^<HOST> -.*"(GET|POST).*HTTP.*"(?:%(badbots)s|%(badbotscustom)s)"$

# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
#
ignoreregex =

Cette configuration est particulière intéressante car elle donne un exemple de substitution dans les expressions régulière à partir de variables définies dans la section Definition

Icon-Configuration-Settings.png Mise en place

L'objectif est de filtrer un ensemble d'URL et cela dès la première tentative de connexion. Ainsi le trafic est diminué et le serveur Apache n'aura pas à répondre à des accès invalides.

System-Internet-Search-icon.png Configuration apache-scan.conf

Le nouveau fichier apache-scan.conf est créé dans le répertoire /etc/fail2ban/filter.d. Son contenu est un mix des deux configurations étudiées précédement.

# Fail2Ban configuration file
#
# List of URL scanned
#
# Author: Etienne Jouvin
#

[Definition]

scannedurls = admin|db|dbadmin|myadmin|mysql|mysqladmin|typo3|phpadmin|phpMyAdmin|phpmyadmin|phpmyadmin1|phpmyadmin2|pma|
web|xampp|php\-my\-admin|websql|phpmyadmin|phpMyAdmin\-2|php\-my\-admin|phpMyAdmin\-2\.2\.3|phpMyAdmin\-2\.2\.6|phpMyAdmin\-2\.5\.1|
phpMyAdmin\-2\.5\.4|phpMyAdmin\-2\.5\.5\-rc1|phpMyAdmin\-2\.5\.5\-rc2|phpMyAdmin\-2\.5\.5|phpMyAdmin\-2\.5\.5\-pl1|
phpMyAdmin\-2\.5\.6\-rc1|phpMyAdmin\-2\.5\.6\-rc2|phpMyAdmin\-2\.5\.6|phpMyAdmin\-2\.5.7|phpMyAdmin\-2\.5\.7\-pl1|pp
scannedscripts = judge.*\.php|proxyheader\.php

# Option:  failregex
# Notes.:  regex to match the password failure messages in the logfile. The
#          host must be matched by a group named "host". The tag "<HOST>" can
#          be used for standard IP/hostname matching and is only an alias for
#          (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
# Values:  TEXT
#
failregex = [[]client <HOST>[]] (File does not exist|script not found or unable to stat): \/var\/www\/.*(?:%(scannedurls)s).*
            [[]client <HOST>[]] script '\/var\/www\/.*(?:%(scannedscripts)s)' not found or unable to stat

# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
#
ignoreregex =


Deux variables sont mises en place:

  • scannedurls pour référencer les tentatives sur des "applications"
  • scannedscripts pour référencer les tentatives sur des scripts, php par exemple.

Puis deux expressions régulièrement sont mises en place afin d'identifier les messages dans la log.

Add-icon.png Ajout nouvelle règle

Une fois le fichier apache-scan.conf mis en place, il faut le référencer au niveau de la configuration de Fail2ban afin que cette nouvelle surveillance soit active. Comme la surveillance concerne Apache, la définition est injectée au même niveau que celle déjà existante dans le fichier jail.conf dans le répertoire /etc/fail2ban/.

#
# HTTP servers
#

[apache]

enabled  = false
port     = http,https
filter   = apache-auth
logpath  = /var/log/apache*/*error.log
maxretry = 6

# default action is now multiport, so apache-multiport jail was left
# for compatibility with previous (<0.7.6-2) releases
[apache-multiport]

enabled   = false
port      = http,https
filter    = apache-auth
logpath   = /var/log/apache*/*error.log
maxretry  = 6

[apache-noscript]

enabled  = false
port     = http,https
filter   = apache-noscript
logpath  = /var/log/apache*/*error.log
maxretry = 6

[apache-overflows]

enabled  = false
port     = http,https
filter   = apache-overflows
logpath  = /var/log/apache*/*error.log
maxretry = 2

[apache-scan]

enabled  = true
port     = http,https
filter   = apache-scan
logpath  = /var/log/apache*/error*.log
maxretry = 1


Les paramètres mis en place sont:

Paramètre Valeur Description
enabled true Afin d'activer la surveillance
port http,https Indique le type d'accès surveillé. Cette valeur est ensuite utilisée dans la règle Iptables.
filter apache-scan Indique le nom du fichier à prendre en compte pour la définition de la surveillance.
logpath /var/log/apache*/*error.log Toutes les logs de Apache de type error.log sont scrutées.

Cette valeur dépend des configurations des sites mis en place.

maxretry 1 Cette valeur est un peu radicale, mais dès la première tentative l'adresse IP sera bannie.

Comme indiqué dans l'entête du fichier /etc/fail2ban/jail.conf, Il est préférable de créer un fichier jail.local ou jail.d/customisation.local dans lequel les personnalisations sont mises en place. La configuration apache-scan est mise en place dans le fichier /etc/fail2ban/jail.d/customisation.local :

[apache-scan]

enabled  = true
port     = http,https
filter   = apache-scan
logpath  = /var/log/apache*/error*.log
maxretry = 1


Run-icon.png Vérification de la règle

Avant l'activation de la nouvelle configuration, il est possible de la vérifier avec la commande fail2ban-regex.

#sudo fail2ban-regex /var/log/apache2/error.log /etc/fail2ban/filter.d/apache-scan.conf
Running tests
=============

Use regex file : /etc/fail2ban/filter.d/apache-scan.conf
Use log file   : /var/log/apache2/error.log.1


Results
=======

Failregex
|- Regular expressions:
|  [1] [[]client <HOST>[]] (File does not exist|script not found or unable to stat): \/var\/www\/.*(?:admin|db|dbadmin|myadmin|mysql|mysqladmin|typo3|phpadmin|phpMyAdmin|phpmyadmin|phpmyadmin1|phpmyadmin2|pma|web|xampp|php\-my\-admin|websql|phpmyadmin|phpMyAdmin\-2|php\-my\-admin|phpMyAdmin\-2\.2\.3|phpMyAdmin\-2\.2\.6|phpMyAdmin\-2\.5\.1|phpMyAdmin\-2\.5\.4|phpMyAdmin\-2\.5\.5\-rc1|phpMyAdmin\-2\.5\.5\-rc2|phpMyAdmin\-2\.5\.5|phpMyAdmin\-2\.5\.5\-pl1|phpMyAdmin\-2\.5\.6\-rc1|phpMyAdmin\-2\.5\.6\-rc2|phpMyAdmin\-2\.5\.6|phpMyAdmin\-2\.5.7|phpMyAdmin\-2\.5\.7\-pl1|pp).*
|  [2] [[]client <HOST>[]] script '\/var\/www\/.*(?:judge.*\.php|proxyheader\.php)' not found or unable to stat
|
`- Number of matches:
   [1] 197 match(es)
   [2] 13 match(es)

Ignoreregex
|- Regular expressions:
|
`- Number of matches:

Summary
=======

Addresses found:
[1]
    115.181.34.29 (Sun Mar 04 14:10:09 2012)
    115.181.34.29 (Sun Mar 04 14:10:10 2012)
    115.181.34.29 (Sun Mar 04 14:10:10 2012)
    115.181.34.29 (Sun Mar 04 14:10:11 2012)
    202.117.80.215 (Sat Mar 10 19:29:18 2012)
    202.117.80.215 (Sat Mar 10 19:29:19 2012)
    202.117.80.215 (Sat Mar 10 19:29:20 2012)
[2]
    58.218.199.147 (Mon Mar 05 01:00:54 2012)
    58.218.199.147 (Mon Mar 05 16:39:13 2012)
    58.218.199.250 (Mon Mar 05 21:14:17 2012)
    58.218.199.147 (Tue Mar 06 11:40:39 2012)
    58.218.199.147 (Wed Mar 07 11:08:18 2012)
    58.218.199.147 (Thu Mar 08 10:08:11 2012)

Date template hits:
2326 hit(s): MONTH Day Hour:Minute:Second
0 hit(s): WEEKDAY MONTH Day Hour:Minute:Second Year
0 hit(s): WEEKDAY MONTH Day Hour:Minute:Second
0 hit(s): Year/Month/Day Hour:Minute:Second
0 hit(s): Day/Month/Year Hour:Minute:Second
0 hit(s): Day/Month/Year Hour:Minute:Second
0 hit(s): Day/MONTH/Year:Hour:Minute:Second
0 hit(s): Month/Day/Year:Hour:Minute:Second
0 hit(s): Year-Month-Day Hour:Minute:Second
0 hit(s): Day-MONTH-Year Hour:Minute:Second[.Millisecond]
0 hit(s): Day-Month-Year Hour:Minute:Second
0 hit(s): TAI64N
0 hit(s): Epoch
0 hit(s): ISO 8601
0 hit(s): Hour:Minute:Second
0 hit(s): <Month/Day/Year@Hour:Minute:Second>

Success, the total number of match is 210

However, look at the above section 'Running tests' which could contain important information.

Ainsi, il est possible de contrôler la bonne écriture des expressions régulières.

Update icon.png Activation

L'activation s'effectue en relançant le client par la commande:

#sudo fail2ban-client reload

Attention, cela entraîne la suppression des IP précédemment bannie. Cependant, le daemon étant toujours actif, les prochaines tentatives seront de nouveau bannie.


Folder inspection icon.png Impact

Après un petit peu d'attente, les premiers bannis arrivent, se traduisant par le contenu de Iptables:

#sudo  iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
fail2ban-apache-scan  tcp  --  0.0.0.0/0            0.0.0.0/0           multiport dports 80,443
fail2ban-ssh  tcp  --  0.0.0.0/0            0.0.0.0/0           multiport dports 22

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain fail2ban-apache-scan (1 references)
target     prot opt source               destination
DROP       all  --  61.38.186.236        0.0.0.0/0
DROP       all  --  196.217.240.202      0.0.0.0/0
DROP       all  --  58.218.199.147       0.0.0.0/0
DROP       all  --  109.120.141.160      0.0.0.0/0
RETURN     all  --  0.0.0.0/0            0.0.0.0/0

Chain fail2ban-ssh (1 references)
target     prot opt source               destination
DROP       all  --  118.192.41.20        0.0.0.0/0
DROP       all  --  91.230.238.8         0.0.0.0/0
DROP       all  --  14.139.221.4         0.0.0.0/0
DROP       all  --  58.218.185.21        0.0.0.0/0
DROP       all  --  222.174.35.3         0.0.0.0/0
DROP       all  --  59.60.7.111          0.0.0.0/0
DROP       all  --  219.239.227.125      0.0.0.0/0
DROP       all  --  74.221.236.129       0.0.0.0/0
RETURN     all  --  0.0.0.0/0            0.0.0.0/0

Suite à une mise à jour du serveur dans le cadre de cet article, ce n'est plus l'action DROP qui est utilisée mais REJECT, le contenu de Iptables est alors:

#sudo  iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
fail2ban-apache-scan  tcp  --  anywhere            anywhere           multiport dports 80,443
fail2ban-ssh  tcp  --  anywhere            anywhere           multiport dports 22

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain fail2ban-apache-scan (1 references)
target     prot opt source               destination
REJECT     all  --  61.38.186.236        anywhere
REJECT     all  --  196.217.240.202      anywhere
REJECT     all  --  58.218.199.147       anywhere
REJECT     all  --  109.120.141.160      anywhere
RETURN     all  --  anywhere             anywhere

Chain fail2ban-ssh (1 references)
target     prot opt source               destination
REJECT     all  --  118.192.41.20        anywhere
REJECT     all  --  91.230.238.8         anywhere
REJECT     all  --  14.139.221.4         anywhere
REJECT     all  --  58.218.185.21        anywhere
REJECT     all  --  222.174.35.3         anywhere
REJECT     all  --  59.60.7.111          anywhere
REJECT     all  --  219.239.227.125      anywhere
REJECT     all  --  74.221.236.129       anywhere
RETURN     all  --  anywhere             anywhere