Retrouvez cet article dans : Misc 20
mod_security : validation et filtrage des échanges
mod_security [2] permet de contrôler de manière très fine les échanges entre le client et le serveur : il filtre ces échanges et autorise également une journalisation complète des événements. Nous parlons principalement dans cette section de la version stable (1.8.X) deValidation des requêtes
Avant de procéder au filtrage en soi des URL reçus,- Si le filtre tourne sous Windows, transformation des caractères
\en/. - Transformation de
/./en/. - Optionnellement, validation de l'encodage de l'URL.
- Optionnellement, restriction de la plage de caractères ASCII (table étendue) autorisée.
mod_securityvalide ces caractères selon leur valeur, comprise en décimal entre 0 et 255. - Transformation de
//en/.
GET /index.html HTTP/1.1 Host: www.miscmag.com User-Agent: foobar Referer: www.kernel.com Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 Accept-Language: en-us,en;q=0.5Depuis la version 1.1 de HTTP, les deux premières lignes de notre en-tête HTTP d'exemple sont impératives. Les autres lignes sont indicatives ou servent à la négociation de contenu (préférences en formats multimédias, en termes de langage et autres). Voici une réponse possible du serveur :
HTTP/1.1 200 OK Date: Thu, 05 May 2005 10:13:21 GMT Server: Apache/2.0.54 (Debian GNU/Linux) PHP/4.3.10-12 Content-Length: 305 Content-Type: text/html; charset=iso-8859-1 <html>Bonjour</html>Le serveur confirme qu'il parle HTTP en version 1.1, nous donne un code de succès (200) et spécifie diverses informations, dont la plus importante est le champ Content-Type. Le navigateur utilise en effet ce champ pour interpréter la réponse. Ici, la valeur
 <VirtualHost *:443> ServerName www.foo.com #Mod_security est activé pour ce VirtualHost SecFilterEngine On #Nous filtrons également le contenu complet des requêtes POST SecFilterScanPost On #Seuls les corps de requêtes de l'un de ces deux types sont acceptés (ceci #concerne uniquement les requêtes POST, les autres requêtes n'ont pas de corps SecFilterSelective HTTP_Content_Type "!(^$|application/x-www-form- urlencoded$|^multipart/form-data;)" #Bloquage de l'encodage par morceau des requêtes - utilisé uniquement pour des #attaques - non implémenté par les navigateurs SecFilterSelective HTTP_Transfer-Encoding "!^$" #Vérifions que seuls des encodages valides sont reçus SecFilterCheckURLEncoding On #Vérifions que l'encodage est conforme à Unicode - à utiliser seulement si #notre application web utilise Unicode SecFilterCheckUnicodeEncoding On #Que faire par défaut quand nos filtres correspondent à une requête. Nous #journalisons l'événement et renvoyons une erreur 404 SecFilterDefaultAction "deny,log,status:404" #Vérifions le format des Cookies reçus SecFilterCheckCookieFormat On #Tâchons de corriger les cookies invalides que nous recevons - attention, ceci #peut "casser" certaines applications et est donc à tester avec précautions SecFilterNormalizeCookies On #Les deux directives Apache qui font le "vrai" travail : proxyfier les requêtes ProxyPass / http://192.168.1.0/ #Adresse IP du serveur protégé ProxyPassReverse / http://192.168.1.0/ </VirtualHost>Cet exemple présente une configuration " de base " du module
GET /scripts/..%255c%255c../winnt/system32/cmd.exe?/ c+dir HTTP/1.1Pour Unix :
GET /../../../../bin/sh HTTP/1.1Injection SQL [5] Ce type d'attaque suppose que le serveur web s'appuie sur une base de données et vise à envoyer des données qui seront passées à la base de données pour en extraire des données ou passer outre un test :
GET /identify.php?username=joe&pass=bah'%20OR%20'x'='x HTTP/1.1Dans ce cas trivial (plutôt codé en requête POST en " vrai "), le script PHP " naïf " récupère le nom d'utilisateur et le mot de passe en variables, puis réalise une requête SQL sur la base de données, ce qui dans notre cas donnera par exemple :
SELECT * from users where username='joe' and password='bah' OR 'x'='x';Cross site scripting [6] Plus récente et très différente, cette attaque utilise simplement le fait que le serveur accepte des contenus HTML ou Javascript et les réaffiche. On pourra ainsi injecter du code Javascript malicieux sur un serveur afin de compromettre des utilisateurs légitimes du serveur. Ce type d'attaque ne vise ni ne compromet directement le serveur.Â
Règles de filtrage des requêtes
Bloquons toute tentative d'accès au shell de la machine en ajoutant dans la définition du virtualhost :SecFilter /bin/shIl s'agit de la méthode la plus élémentaire de filtrage, qui fonctionne par mot clé. Le contenu spécifié à la suite de cette directive est comparé à la première ligne de la requête HTTP. Si la requête est une requête de type POST et que nous avons positionné l'option SecFilterScanPost On comme ci-avant, chaque ligne du corps de la requête fait également l'objet de cette comparaison. SecFilter peut également fonctionner de manière plus étendue et accepte comme argument une expression rationnelle :
SecFilter "!(php|asp)"bloque toute requête ne contenant pas le mot
- Contenu de la requête, envoyé par le client : par exemple
REMOTE_USER,POST_PAYLOADouREQUEST_URI - Paramètres liés à la requête, indépendants du client :
SERVER_SOFTWARE,DOCUMENT_ROOT - Paramètres plus ou moins extérieurs à la requête :
TIME_DAY,API_VERSION - Paramètres ajustables à souhait :
HTTP_nom_de_header,ENV_nom_de_variable
SecFilterSelective REQUEST_URI /bin/sh
Filtrage des réponses HTTP
Filtrer les requêtes est une bonne chose, mais nous pouvons faire plus : appliquer certains critères de recherche aux réponses renvoyées par le serveur web. Il suffit pour cela d'utiliser la directive#Nous filtrons les réponses du serveur HTTP au client SecFilterScanOutput On #Filtrons uniquement des mots clés sur les documents dont le type MIME est pertinent #Par exemple, filtrer des mots clés dans une image ou un fichier audio est sans objet SecFilterOutputMimeTypes "(null) text/plain text/html" #Ne laissons pas sortir "information(s) confidentiel(les)" SecFilterSelective OUTPUT "informations* confidentiel*e*s*" #Ne laissons pas le client constater que PHP a renvoyé une erreur fatale, si cela arrive SecFilterSelective OUTPUT "Fatal error:" deny,status:404Comme montré dans le tout dernier exemple, les directives
Les actions utilisables par le filtre
Les actions suivantes peuvent être utilisées dans les directivespass: le contenu poursuit son chemin parmi les filtres à suivre ;allow: le contenu est accepté, sans passer par les autres filtres à suivre ;deny: interruption du traitement de la requête, envoi d'un code d'erreur au client ;status: suivi d'un code d'erreur HTTP, renvoie le code d'erreur spécifié au client ;redirect: redirige le client vers l'URL spécifié ;exec: lance le binaire spécifié, en lui passant toutes les variables d'environnement courantes ;log: journalise la correspondance de la règle dans le fichier d'erreur d'Apache ;nolog: l'inverse de ci-avant ;skipnext: les prochaines règles de filtrage (nombre à spécifier en argument) sont ignorées pour cette requête ;chain: la requête doit correspondre à la présente règle, mais aussi à la suivante, pour que la décision de cette dernière soit appliquée ;pause: attend un certain nombre de millisecondes (spécifié en paramètre) avant de répondre à cette requête. Attention aux performances en utilisant ce paramètre !
SecFilterDefaultAction "deny,log,status:404"comme nous l'avons positionné en début de configuration. Par ailleurs, les actions
SecFilter "credit card" "pass,log"
Fonctionnalités chroot de mod_security
Il est bien sûr possible de chrooter Apache sans utiliserSecChrootDir /repertoire/a/utiliseret le serveur web sera chrooté. Ceci permet d'utiliser
Autres fonctionnalités de mod_security
Voici, brièvement présentées, quelques possibilités (parmi d'autres) proposées parTraitement des fichiers uploadés
Dialogue avec le pare-feu
Comme vu ci-dessus, l'action- Si l'attaquant passe par un serveur mandataire, c'est alors l'adresse du mandataire qui sera listée, bloquant également tous les autres utilisateurs du mandataire.
- Si l'attaquant réussit à usurper l'adresse d'une de nos passerelles, il pourrait nous isoler complètement d'un réseau voire d'Internet.
- Si l'attaquant dispose d'une adresse IP non fixe, il lui suffira de changer d'adresse pour pouvoir nous attaquer de nouveau et nous bloquerons en plus les éventuels accès d'un nouvel utilisateur légitime.
Mesures de performances
Dans la version de développement (1.9) du module, trois variables d'environnement sont créées et visibles par Apache : il s'agit demod_dosevasive
Principe de fonctionnement
Détection des attaques
La détection d'une attaque de type " déni de service " est complexe : chaque requête, prise séparément, pourrait souvent être considérée comme légitime. Il convient donc de distinguer une attaque, par définition de source malveillante, d'un éventuel pic de trafic, qui pourrait résulter d'un référencement sur Slashdot par exemple.- Que la même ressource fait l'objet de requêtes répétées (plusieurs par secondes) depuis la même adresse IP source. Ceci permet d'écarter les consultations régulières puisqu'un utilisateur bienveillant ne récupère normalement pas plusieurs fois par seconde une même ressource.
- Que la même adresse IP réalise plus de N requêtes par seconde sur le même processus enfant d'Apache. Une consultation normale se limite à la récupération de quelques objets à la foi.
- Qu'une adresse déjà en liste noire fait une requête. Cette troisième condition paraît étrange à première vue, mais s'éclaire quand on sait que la liste noire est temporaire : une adresse IP référencée dans cette liste en est retirée après un certain délai configurable si elle ne réalise aucune requête sur le serveur durant ce délai.
Actions entreprises à l'égard des attaquants
Dès lors qu'une adresse IP est positionnée dans la liste noire, toutes ses requêtes feront immédiatement l'objet d'une réponse de type 403, sans que le serveur web ne réalise le traitement normal de la requête. Ceci économise notablement les ressources, en particulier si l'attaquant fait appel à des ressources CGI ou à des contenus dynamiques.Pertinence de la méthode
L'expérience a montré que ce module répond en soi aux besoins de manière très efficace pour des dénis de services petits ou moyens, qu'ils aient pour origine une seule ou plusieurs machines. Réagir à de plus importantes attaques est un problème beaucoup plus avancé : si l'attaquant dispose de suffisamment de ressources réseau pour remplir le tuyau d'entrée du réseau attaqué, il devient beaucoup plus difficile de le contrer.Configuration du module
Les directives suivantes sont proposées par le module :DOSSiteCount: Le nombre maximal de requêtes qu'une adresse IP source peut réaliser sur le même enfant pendant une unité de temps sans être ajoutée à la liste noire.DOSSiteInterval: L'unité de temps (en secondes) évoquée dans la directive DOSSiteCount. La valeur par défaut est d'une seconde.DOSPageCount: Le nombre maximal de requêtes qu'une adresse IP source peut réaliser sur la même ressource (même URL) pendant une unité de temps sans être ajoutée à la liste noire.DOSPageInterval: L'unité de temps évoquée dans la directiveDOSPageCount.DOSBlockingPeriod: Désigne la durée pendant laquelle tous les accès des adresses IP en liste noire seront refusés et recevront une erreur 403. Par défaut, cette durée est de 10 secondes.DOSEmailNotify: Précise une adresse email à laquelle envoyer un courriel lorsqu'une adresse IP est ajoutée en liste noire. (Attention de bien positionner MAILER dans les sources du module pour utiliser cette directive).DOSSystemCommand: Une commande à appeler pour, par exemple, ajouter l'adresse en liste noire sur un routeur.DOSWhiteList: Spécifie une adresse IP à ne jamais positionner en liste noire. Il est courant de positionner cette option à 127.0.0.* pour éviter de bloquer nos éventuels propres accès récursifs ou autres robots de référencement. En production, cette option ne devrait jamais être utilisée pour désigner un réseau d'utilisateurs humains légitimes : les mécanismes internes du module garantissent que le trafic légitime ne sera pas bloqué. Cette directive peut être positionnée plusieurs fois avec divers arguments, ceux-ci seront cumulés dans la configuration.
Conclusion
Voici deux modules présentant des approches très différentes mais largement complémentaires pour améliorer la sécurité de serveurs web. Positionnés en proxy entrant à l'entrée d'un réseau hébergeant quelques sites web, ces deux modules peuvent contribuer à assurer une meilleure sécurité, aussi bien en regard d'attaques applicatives visant à prendre la main sur un serveur, que pour protéger ce dernier d'attaques massives visant à l'empêcher de répondre aux requêtes légitimes. Liens- [1] Sécurisation d'un serveur Apache : Voir Misc 0 ou http://www.miscmag.com/articles/index.php3?page=110
- [2] Site officiel de mod_security : http://www.modsecurity.org/
- [3] Limit et surtout LimitExcept : http://httpd.apache.org/docs-2.0/mod/core.html#limitexcept
- [4] Ivan Ristik, fondateur de la société Thinking Stone : http://www.thinkingstone.com/
- [5] SQL Injection Attacks by Example : http://www.unixwiz.net/techtips/sql-injection.html
- [6] Cross site scripting questions and answers : http://www.cgisecurity.com/articles/xss-faq.shtml
- [7] mod_security stable 1.8 Reference manual : http://www.modsecurity.org/documentation/modsecurity-manual.pdf
- [8] Converted Snort Rules : http://www.modsecurity.org/documentation/converted-snort-rules.html
- [9] Snort : http://www.snort.org/
- [10] Jonathan A. Zdziarski : http://www.nuclearelephant.com/
- [11] mod_dosevasive : http://www.nuclearelephant.com/projects/dosevasive/
 Retrouvez cet article dans : Misc 20





Laissez une réponse
Vous devez avoir ouvert une session pour écrire un commentaire.