|
|
 | |  |  | Présentation de mod_security2 |  |
by Louis Nyffenegger (11/04/07)
---[ Présentation de mod_security2 ]------------------------------------------
Cet article traite de l'installation et du fonctionnement de mod_security2,
la nouvelle version du célèbre pare feu applicatif.
--[ 1. Introduction ]---------------------------------------------------------
Mod_security2 amène de nombreuses améliorations et une nouvelle syntaxe pour
la création de règles de filtrage, nous allons voir comment installer et
configurer cette nouvelle version de ce firewall applicatif.
À noter que cette version ne fonctionne qu'avec Apache2.
Pour toute information sur le fonctionnement de mod_security et sur la mise en
place de mod_security, je vous conseille la brève de Stéphane Milani :
http://www.hsc.fr/ressources/breves/modsecurity.html .
--[ 2. Différences avec mod_security 1 ]--------------------------------------
Cette nouvelle version de mod_security amène de nombreuses fonctionnalités par
rapport à la version précédente mais ne fonctionne plus avec Apache 1.3. De
plus pour l'instant mod_security2 ne peut pas être compilé comme un module
statique.
Cette nouvelle version apporte le support du format XML, ce qui peut permettre
de mettre en place un firewall XML simple.
La granularité du filtrage a aussi été grandement améliorée et on peut
simplement créer des régles très précises. Là où mod_security ne gère que 2
phases (entrée/sortie), mod_security2 en gère 5.
--[ 3. Installation ]---------------------------------------------------------
Cette nouvelle version étant encore récente, sa distribution n'est pas encore
faite dans toutes les distributions courantes.
Pour l'installer, il faut récupérer la dernière version sur le site de
modsecurity : http://www.modsecurity.org/download/index.html .
Il suffit ensuite de décompresser l'archive :
$ tar -zxvf modsecurity-apache_$version.tar.gz
Puis, il faut faire quelques modifications dans le Makefile :
$ cd modsecurity-$version/apache2/
Il suffit ensuite de modifier les variables top_dir et INCLUDES (exemple pour
Gentoo):
top_dir = /usr/lib/apache2
INCLUDES = -I /usr/include/apache2/ -I /usr/include/libxml2
L'utilisation ou non de la libxml2 peut être décidée grâce à la ligne :
DEFS = -DWITH_LIBXML2
Pour le filtrage d'un WebService, la bibliothèque XML2 est nécessaire.
Enfin, on peut lancer la compilation et l'installation de mod_security2 :
$ make
$ sudo make install
Il ne reste plus qu'à créer le fichier de configuration minimale pour indiquer
à Apache de charger mod_security2 et pour tester son fonctionnement (extrait du
fichier /etc/apache2/modules.d/99_mod_sec2.conf) :
LoadFile /usr/lib/libxml2.so
LoadModule security2_module modules/mod_security2.so
LoadModule unique_id_module modules/mod_unique_id.so
SecRuleEngine On
SecRequestBodyAccess Off
SecResponseBodyAccess Off
SecServerSignature "HSC"
SecDebugLog modsec2_debug.log
SecDebugLogLevel 3
SecRule REQUEST_FILENAME "testhsc" log,deny,status:403,msg:'testhsc'
La ligne SecServerSignature "HSC" permet de changer la bannière du serveur.
La ligne SecRule REQUEST_FILENAME "testhsc" log,deny,status:403,msg:'testhsc'
va permettre de faire un simple test du bon fonctionnement de mod_security2 en
bloquant l'accès au fichier testhsc, toute tentative d'accès renverra une
erreur 403 et sera journalisée avec le message 'testhsc'.
Après rechargement du serveur Apache :
$ sudo /etc/init.d/apache2 restart
il est possible de tester le bon fonctionnement de mod_security2 :
$ telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET / HTTP/1.0
HTTP/1.1 200 OK
Date: Tue, 10 Apr 2007 15:28:54 GMT
Server: HSC
[...]
La nouvelle bannière du serveur est maintenant visible.
L'accès au fichier testhsc est maintenant interdit :
$ telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET /testhsc HTTP/1.0
HTTP/1.1 403 Forbidden
Date: Tue, 10 Apr 2007 15:31:05 GMT
Server: HSC
[...]
Le résultat est visible dans les journaux de mod_security :
$ sudo tail /var/log/apache2/modsec2_debug.log
[...]
[10/Apr/2007:17:31:05 +0200] [kinkakuji/sid#817abe0][rid#82439a0]
[/testhsc][1] Access denied with code 403 (phase 2). Pattern match
"testhsc" at REQUEST_FILENAME. [msg "testhsc"]
--[ 4. Configuration ]--------------------------------------------------------
Voici un petit tour des options qui peuvent s'avérer utiles :
* SecServerSignature permet de modifier la bannière du serveur.
* SecRequestBodyLimit limite la taille du corps des requêtes.
* SecRuleEngine permet d'activer le moteur de règles qui peut
prendre 3 valeurs : On, Off, DetectionOnly.
* SecRule pour la création de règle.
Les règles peuvent être appliquées à 5 instants lors du traitement d'une
requête :
* après la réception de l'en-tête de la requête, le corps de la
requête n'est pas encore disponible, les règles mises en place durant
cette phase ne tiennent pas compte de la gestion des requêtes faite
par Apache. Si une requête est bloquée durant cette phase, le serveur
HTTP ne verra même pas la requête.
* après la réception du corps de la requête, durant cette phase, la
totalité des arguments envoyés à l'application est connue.
* avant l'envoi de l'en-tête de la réponse.
* avant l'envoi du corps de la réponse qui permet de modifier le corps
de la réponse avant son envoi.
* durant la phase de journalisation.
Mod_security2 met à disposition des variables sur lesquelles ont peu simplement
mettre en place des règles :
* ARGS pour traiter l'ensemble des arguments, ou accéder à un argument
en particulier, ou à tous les arguments sauf un, ...
* AUTH_TYPE pour accéder au type d'authentification
* HTTP_REFERER pour l'accès au Referer
* REMOTE_ADDR et REMOTE_HOST pour connaître l'adresse IP ou le reverse
DNS du client
* le corps d'une requête grâce à REQUEST_BODY
* l'en-tête d'une requête avec REQUEST_HEADERS
* la méthode HTTP utilisée avec REQUEST_METHOD
* l'ensemble de la réponse en combinant RESPONSE_BODY et
RESPONSE_HEADERS
Il est ainsi possible d'accéder à l'intégralité des données transférées lors
d'une requête HTTP au moment de la requête et de la réponse.
Mod_security donne aussi accès à des fonctions permettant d'encoder ou de
décoder l'ensemble des variables que nous venons de voir. Il est ainsi possible
de décoder en base64, d'enlever les espaces, de calculer une empreinte md5 ou
sha1, de décoder une url, ...
La validation d'une règle permet de spécifier une ou plusieurs actions,
plusieurs actions sont ainsi disponibles :
* auditlog pour journaliser l'action dans le fichier d'audit
* capture permet de sauvegarder la transaction, 10 captures sont
possibles
* chain pour enchaîner plusieurs règles
* ctl pour mettre à jour les règles de filtrage
* deny : bloque la requête et l'interprétation des autres règles.
* drop pour couper la connexion au niveau TCP
* exec pour lancer un script externe (pour bloquer une adresse par
exemple)
* log pour journaliser la transaction
* pass pour donner la main à la prochaine règle
* phase pour spécifier la phase durant laquelle la règle sera mise
en place
* proxy pour relayer la requête vers un autre serveur (si mod_proxy
est installé)
* redirect pour rediriger le client
* plusieurs actions de nettoyage sanitiseArg, sanitiseMatched,
sanitiseRequestHeader.
* severity pour spécifier le niveau d'une alerte
* status pour spécifier la réponse HTTP : 403, 404, ...
* ...
--[ 4. Les règles génériques ]------------------------------------------------
Il est toujours possible d'utiliser les règles génériques fournies avec
mod_security2, mais il est préférable de mettre en place un filtrage adapté à
l'application hébergée. Les règles génériques risquent de prendre beaucoup
plus de ressources que des règles spécialement mise en place pour une
application donnée.
Les règles génériques sont présentes dans l'archive contenant le code de
mod_security2. Plusieurs fichiers sont disponibles, pour les utiliser il
suffit d'utiliser la directive Apache "Include".
Les jeux de règles suivants sont présents :
* modsecurity_crs_10_config.conf qui est un fichier minimal
d'installation de mod_security est décrit les fonctions de base.
* modsecurity_crs_20_protocol_violations.conf qui permet de vérifier
que les requêtes suivent bien le correctement le protocole HTTP et
permet de détecter certaines anomalies : méthode GET ou HEAD avec un
corps de message, méthode POST sans corps de message, blocage des
requêtes utilisant Apache comme un relais.
* modsecurity_crs_21_protocol_anomalies.conf permet de détecter des
anomalies dans les requêtes comme l'absence d'un User-Agent ou
l'absence de clause Accept.
* modsecurity_crs_30_http_policy.conf permet de n'accepter que les
méthodes GET, HEAD, POST et OPTIONS, de n'accepter que les requêtes
dont le protocole est HTTP 0.9, 1.0 ou 1.1.
* modsecurity_crs_35_bad_robots.conf bloque l'accès aux robots tel que
le scanner nessus, bacunetix, ou des programmes en perl, ceci en se
basant sur le User-Agent principalement.
* modsecurity_crs_40_generic_attacks.conf permet de bloquer les
injections SQL, les injections de fichiers, l'accès à des fichiers
sensibles, l'injection de commande et les XSS. Ce filtrage se fait sur
la base d'une suite d'expression régulières complexes (et donc
consommatrice de ressources).
* modsecurity_crs_45_trojans.conf qui tente de bloquer l'upload de
chevaux de Troie connus sur la machine.
* modsecurity_crs_50_outbound.conf remplace les messages d'erreurs d'une
application par des réponses HTTP 501. Ceci permet de cacher les
informations sensibles contenues dans les messages d'erreurs. Pour
limiter la consommation de ces règles, il est important de n'utiliser
que les règles correspondants aux technologies présentes sur le serveur.
* modsecurity_crs_55_marketing.conf permet de journaliser le passage des
robots d'indexation de Google, Yahoo et Microsoft.
--[ 5. Protection d'une Application Web ]-------------------------------------
Il est possible, comme avec la version précédente de protéger une application
Web.
Par exemple, une application présentant une injection SQL sur le champs id :
http://www.hsc.fr/monapplication/index.php?id=3
Il est possible grâce à mod_security2 de faire une liste blanche des valeurs
possibles pour la variable id. La variable id ne doit pouvoir qu'une valeur
entière.
On peut facilement vérifier que la valeur est un entier grâce à la régle :
SecRule ARGS:id "!(^[0-9]*$)" log,deny,status:403
Après un rechargement d'Apache2, la page index.php renvoie un erreur 403 si
id n'est pas un entier.
NB: L'utilisation des directives plus petit que, plus grand que ne permet en
rien de vérifier que la variable est un entier, si la variable n'est pas un
entier, la régle ne sera pas appliquée.
Un autre exemple, les vulnérabilités de type include :
http://www.hsc.fr/monapplication/index.php?file=home.php
On peut facilement vérifier que la valeur fait partie d'une liste blanche,
grâce à la régle suivante (ici avec home et liens):
SecRule ARGS:file "!(^(home|liens)\.php$)" log,deny,status:403
Mod_security permet ainsi de bloquer la plupart des attaques de façon simple
mais pour autant ne remplacera jamais de bonnes pratiques de développement.
--[ 6. Protection d'un Webservice ]-------------------------------------------
Cette nouvelle version amène la possibilité de filtrer des services Web sur
HTTP. Nous allons voir comment on peut simplement faire une liste blanche sur
les entrées provenant d'un utilisateur.
Pour cela nous allons utiliser un serveur Tomcat avec Jax-WS 2 pour la partie
Webservice et le serveur Apache avec mod_security2 servira de connecteur HTTP.
Une base de données Mysql est utilisée pour le stockage.
________ ________________________ __________________
| | | | | |
| Client |------| Apache + mod_security2 |------| Tomcat+ Jax-WS 2 |
|________| |________________________| |__________________|
|
_____|____
| |
| Mysql |
|__________|
Ce webservice permet pour un numéro de département donné de récupérer le nom
d'un département (stocké dans la base de données MySQL) à partir de son numéro.
Tout d'abord, si la génération de code n'est pas réalisée dynamiquement à
partir du wsdl du webservice. Il est possible de bloquer cette accès à partir
de mod_security2. Pour cela, la règle suivante :
SecRule REQUEST_URI "\?wsdl$" log,deny,status:403
permet de bloquer l'accès aux wsdl. Un intrus n'ayant pas connaissance du
fonctionnement du webservice aura déjà beaucoup plus de mal à s'y attaquer.
Le webservice présenté contient une injection SQL. Le message envoyé lors
d'une interrogation classique du webservice ressemble à cela :
<?xml version="1.0" ?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ns1="http://host.hsc.fr/">
<soapenv:Body>
<ns1:getDptFromString>
<dpt>76</dpt>
</ns1:getDptFromString>
</soapenv:Body>
</soapenv:Envelope>
L'objectif de ce filtre n'est d'accepter qu'un numéro de département, il faut
donc que la valeur du champs dpt soit au maximum de 3 chiffres.
SecRule REQUEST_HEADERS:Content-Type "text/xml" \
phase:1,pass,ctl:requestBodyProcessor=XML,\
ctl:requestBodyAccess=On
SecRule XML://dpt "!(^[0-9]{2,3}$)" phase:2,deny
Cette commande permet ainsi de s'assurer de la conformité des données avec
l'utilisation classique du webservice. La commande "XML://dpt" correspond à
une requête XPath
Pour l'instant, il n'est pas possible de réaliser des requêtes XPath plus
complexe sur les messages SOAP car la gestion des namespaces ne fonctionnent
pas encore (msre_action_xmlns_validate dans re_actions.c).
--[ 7. Conclusion ]-----------------------------------------------------------
Cette brève vous a présenté le fonctionnement de mod_security2 et comment il est
simplement possible de mettre en place un filtrage en amont d'une application
Web ou d'un Webservice ayant des problèmes de sécurité.
Cependant, il ne faut pas oublier que la meilleure solution est tout de même
d'adopter une politique de développement sécurisé dés la création de l'
application en définissant clairement les types de données attendues en entrée
et en pratiquant la programmation défensive.
-- Louis Nyffenegger < Louis.Nyffenegger@hsc.fr > --
--[ 8. Références ]-----------------------------------------------------------
- Le site du projet mod_security :
http://www.modsecurity.org/
- La documentation de mod_security2 :
http://www.modsecurity.org/documentation/modsecurity-apache/2.1.0/
- Brève de Stéphane Milani sur mod_security :
http://www.hsc.fr/ressources/breves/modsecurity.html
- Le site du projet Tomcat
http://tomcat.apache.org/
- Le site du projet Apache :
http://httpd.apache.org/
- Xpath :
http://xmlfr.org/w3c/TR/xpath/
|