Plan du site  
pixel
pixel

Articles - Étudiants SUPINFO

Paramétrer mod_security avec Apache

Par Rémi BEAUFILS Publié le 07/01/2017 à 16:59:33 Noter cet article:
(0 votes)
Avis favorable du comité de lecture

Introduction

Le mod_security est un Web Application Firewall (WAF) gratuit, qui fonctionne avec Apache, Nginx et IIS. Il prend en charge un moteur de règles flexible pour effectuer des opérations simples et complexes et est livré avec un jeu de règles de base (CRS) qui contient des règles pour l'injection SQL, les scripts entre sites, les chevaux de Troie, les mauvais agents utilisateurs, le détournement de session et beaucoup d'autres exploits. Pour Apache, c'est un module supplémentaire qui facilite l'installation et la configuration.

Pour compléter ce tutoriel, vous aurez besoin de LAMP installé sur votre serveur afin de réaliser notre installation.

Installation de mod_security

Modsecurity est disponible dans les repos Debian / Ubuntu:

apt-get install libapache2-modsecurity

Vérifiez si le module mod_security a été chargé.

apachectl -M | grep --color security

Vous devriez voir un module nommé "security2_module (shared)" qui indique que le module a été chargé.

L'installation de Modsecurity comprend un fichier de configuration recommandé qui doit être renommé:

mv /etc/modsecurity/modsecurity.conf{-recommended,}
	  		

Recharger Apache

service apache2 reload

Vous trouverez un nouveau fichier de logs pour mod_security dans le répertoire de logs Apache:

[email protected]:~# ls -l /var/log/apache2/modsec_audit.log
-rw-r----- 1 root root 0 Oct 19 08:08 /var/log/apache2/modsec_audit.log

Configurer mod_security

Hors de la machine, modsecurity ne fait rien car il a besoin de règles pour travailler. Le fichier de configuration par défaut est défini sur "DetectionOnly" qui enregistre les requêtes en fonction des correspondances de règles et ne bloque rien. Cela peut être modifié en modifiant le fichier modsecurity.conf:

nano /etc/modsecurity/modsecurity.conf

Trouvez cette ligne :

SecRuleEngine DetectionOnly

Et changez la en :

SecRuleEngine On

Si vous essayez cela sur un serveur de production, modifiez cette directive uniquement après avoir testé toutes vos règles.

Une autre directive à modifier est "SecResponseBodyAccess". Cela configure si les corps de réponse sont mis en mémoire tampon (c'est-à-dire lu par mod_security). Ceci n'est nécessaire que si la détection et la protection des fuites de données sont nécessaires. Par conséquent, en le laissant "On", on utilisera les ressources droplet et augmentera également la taille du fichier de logs.

Trouvez ceci:

SecResponseBodyAccess On

Et changer sa valeur en :

SecResponseBodyAccess Off

Maintenant, nous limiterons le nombre de données maximales pouvant être affichées sur votre application Web. Deux directives les configurent:

SecRequestBodyLimit
SecRequestBodyNoFilesLimit

La directive "SecRequestBodyLimit" spécifie la taille maximale des données de la requête POST. Si quelque chose de plus important est envoyé par un client, le serveur répondra par une erreur "413 Request Entity Too Large". Si votre application Web ne dispose pas d'uploads de fichiers, cette valeur peut être grandement réduite.

La valeur mentionnée dans le fichier de configuration est :

SecRequestBodyLimit 13107200

Ce qui fait 12,5MB.

La directive "SecRequestBodyNoFilesLimit" est similaire à cela. La seule différence est que cette directive limite la taille des données POST moins les téléchargements de fichiers - cette valeur doit être "aussi faible que pratique".

La valeur dans le fichier de configuration est :

SecRequestBodyNoFilesLimit 131072

Ce qui fait 128KB

Avec ces directives, il y en a une autre qui affecte la performance du serveur: "SecRequestBodyInMemoryLimit". Cette directive est assez explicite; Elle spécifie la quantité de données de "request body" (données POSTed) doit être conservée dans la mémoire (RAM), tout ce qui sera placé sur le disque dur (tout comme le swap). Comme les droplets utilisent des disques SSD, ce n'est pas un problème majeur; Cependant, cela peut être défini une valeur décente si vous avez de la RAM en réserve.

SecRequestBodyInMemoryLimit 131072

C'est la valeur (128KB) spécifiée dans le fichier de configuration.

Testons le module avec des injections SQL

Avant d'aller plus loin avec la configuration des règles, nous allons créer un script PHP vulnérable à l'injection SQL et l'essayer. Notez qu'il s'agit simplement d'un script de connexion PHP de base sans gestion de session. Assurez -vous de modifier le mot de passe MySQL dans le script ci-dessous pour qu'il se connecte à la base de données:

/var/www/login.php
<html>
<body>
<?php
    if(isset($_POST['login']))
    {
        $username = $_POST['username'];
        $password = $_POST['password'];
        $con = mysqli_connect('localhost','root','password','sample');
        $result = mysqli_query($con, "SELECT * FROM `users` WHERE username='$username' 
        AND password='$password'");
        if(mysqli_num_rows($result) == 0)
            echo 'Invalid username or password';
        else
            echo '<h1>Logged in</h1><p>A Secret for you....</p>';
    }
    else
    {
?>
        <form action="" method="post">
            Username: <input type="text" name="username"/><br />
            Password: <input type="password" name="password"/><br />
            <input type="submit" name="login" value="Login"/>
        </form>
<?php
    }
?>
</body>
</html>

Ce script affichera un formulaire de connexion. Saisir les bonnes informations d'identification affichera un message "A secret for you."

Nous avons besoin d'informations d'identification dans la base de données. Créez une base de données MySQL et une table, puis insérez des noms d'utilisateur et des mots de passe.

mysql -u root -p

Ceci vous amènera à l'invite de commande "mysql>"

create database sample;
connect sample;
create table users(username VARCHAR(100),password VARCHAR(100));
insert into users values('jesin','pwd');
insert into users values('alice','secret');
quit;
		

Ouvrez votre navigateur, accédez à http://votresite.com/login.php et entrez vos informations d'identification.

Username: jesin
Password: pwd

Vous verrez un message indiquant que votre connexion a réussie. Maintenant revenez et entrez une mauvaise des mauvais logins - vous verrez le message "Invalid username or password."

Nous pouvons confirmer que le script fonctionne correctement. Le prochain travail consiste à tenter une injection SQL pour contourner la page de connexion. Entrez ce qui suit pour le champ d'identifiant:

' or true -- 

Notez qu'il devrait il y avoir un espace après "--" cette injection ne fonctionnera pas sans cet espace. Laissez le champ de mot de passe vide et cliquez sur le bouton de connexion.

Voilà ! Le script affiche le message destiné aux utilisateurs authentifiés.

Paramétrer les règles

Pour vous faciliter la vie, il existe de nombreuses règles déjà installées avec mod_security. Ils sont appelés CRS (Core Rule Set) et sont situés dans :

[email protected]:~# ls -l /usr/share/modsecurity-crs/
total 40
drwxr-xr-x 2 root root  4096 Oct 20 09:45 activated_rules
drwxr-xr-x 2 root root  4096 Oct 20 09:45 base_rules
drwxr-xr-x 2 root root  4096 Oct 20 09:45 experimental_rules
drwxr-xr-x 2 root root  4096 Oct 20 09:45 lua
-rw-r--r-- 1 root root 13544 Jul  2  2012 modsecurity_crs_10_setup.conf
drwxr-xr-x 2 root root  4096 Oct 20 09:45 optional_rules
drwxr-xr-x 3 root root  4096 Oct 20 09:45 util

La documentation est disponible ici :

[email protected]:~# ls -l /usr/share/doc/modsecurity-crs/
total 40
-rw-r--r-- 1 root root   469 Jul  2  2012 changelog.Debian.gz
-rw-r--r-- 1 root root 12387 Jun 18  2012 changelog.gz
-rw-r--r-- 1 root root  1297 Jul  2  2012 copyright
drwxr-xr-x 3 root root  4096 Oct 20 09:45 examples
-rw-r--r-- 1 root root  1138 Mar 16  2012 README.Debian
-rw-r--r-- 1 root root  6495 Mar 16  2012 README.gz

Pour charger ces règles, nous devons indiquer à Apache d'examiner ces répertoires. Modifiez le fichier "modsecurity.conf".

nano /etc/apache2/mods-enabled/modsecurity.conf
		

Ajoutez les directives suivantes à l'intérieur de " <IfModule security2_module> </IfModule> "

Include "/usr/share/modsecurity-crs/*.conf"
Include "/usr/share/modsecurity-crs/activated_rules/*.conf"

Le répertoire "activated_rules" est similaire au répertoire "mods-enabled" d'Apache. Les règles sont disponibles dans les répertoires:

/usr/share/modsecurity-crs/base_rules
/usr/share/modsecurity-crs/optional_rules
/usr/share/modsecurity-crs/experimental_rules

Les liens symboliques doivent être créés à l'intérieur du répertoire "activated_rules" pour les activer. Activez les règles d'injection SQL.

cd /usr/share/modsecurity-crs/activated_rules/
ln -s /usr/share/modsecurity-crs/base_rules/modsecurity_crs_41_sql_injection_attacks.conf
 . 		

Apache doit être rechargé pour que les règles prennent effet.

service apache2 reload

Ouvrez maintenant la page de connexion que nous avons créée plus tôt et essayez d'utiliser la requête d'injection SQL dans le champ Nom d'utilisateur. Si vous avez modifié la directive "SecRuleEngine" sur Activé, vous verrez une erreur "403 - Forbidden". Si elle était laissée à l'option "DetectionOnly", l'injection sera réussie mais la tentative serait enregistrée dans le fichier "modsec_audit.log".

Écrivez vos propres règles sur mod_security

Dans cette section, nous allons créer une chaîne de règles qui bloque la requête si certains mots «indésirables» sont saisis dans un formulaire HTML. Tout d'abord, nous allons créer un script PHP qui obtient l'entrée d'une zone de texte et l'affiche à nouveau à l'utilisateur.

/var/www/form.php
<html>
    <body>
        <?php
            if(isset($_POST['data']))
                echo $_POST['data'];
            else
            {
        ?>
                <form method="post" action="">
                        Enter something here:<textarea name="data"></textarea>
                        <input type="submit"/>
                </form>
        <?php
            }
        ?>
    </body>
</html>

Des règles personnalisées peuvent être ajoutées à l'un des fichiers de configuration ou placées dans les répertoires de mod_security. Nous placerons nos règles dans un nouveau fichier distinct.

nano /etc/modsecurity/modsecurity_custom_rules.conf
		

Ajoutez ces lignes à notre nouveau fichier :

SecRule REQUEST_FILENAME "form.php" "id:'400001',
		chain,deny,log,msg:'Spam detected'"
SecRule REQUEST_METHOD "POST" chain
SecRule REQUEST_BODY "@rx (?i:(pills|insurance|rolex))"

Enregistrez le fichier et rechargez Apache. Ouvrez http://votresite.com/form.php dans le navigateur et saisissez du texte contenant l'un de ces mots: pills, insurance, rolex.

Vous verrez une page 403 et une entrée de log ou seulement une entrée de log basée sur le paramètre "SecRuleEngine". La syntaxe de SecRule est:

SecRule VARIABLES OPERATOR [ACTIONS]

Ici, nous avons utilisé l'action "chain" pour correspondre aux variables "REQUEST_FILENAME" avec form.php, "REQUEST_METHOD" avec POST et "REQUEST_BODY" avec l'expression régulière (@rx) string (pills | insurance | rolex). Le ?i: fait une correspondance insensible à la casse. Lors d'une correspondance réussie de ces trois règles, l'action est de refuser et de se connecter avec le message "Spam détecté." L'action "chain" simule l'opérateur logique "AND" pour correspondre aux trois règles.

Exclure des hôtes et des répertoires

Parfois, il est logique d'exclure un répertoire particulier ou un nom de domaine s'il exécute une application comme phpMyAdmin en tant que mod_security et bloque les requêtes SQL. Il est également préférable d'exclure les backends admin d'applications CMS comme WordPress.

Pour désactiver mod_security pour un VirtualHost complet, entrez ce qui suit dans la partie <VirtualHost>.

<IfModule security2_module>
    SecRuleEngine Off
</IfModule>

Et pour répertoire en particulier :

<Directory "/var/www/wp-admin">
    <IfModule security2_module>
        SecRuleEngine Off
    </IfModule>
</Directory>

Si vous ne souhaitez pas désactiver complètement mod_security, utilisez la directive "SecRuleRemoveById" pour supprimer une règle particulière ou une chaîne de règles en spécifiant son ID.

<LocationMatch "/wp-admin/update.php">
    <IfModule security2_module>
        SecRuleRemoveById 981173
    </IfModule>
</LocationMatch>

Liens

Documentation officielle de mod_security: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual

A propos de SUPINFO | Contacts & adresses | Enseigner à SUPINFO | Presse | Conditions d'utilisation & Copyright | Respect de la vie privée | Investir
Logo de la société Cisco, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société IBM, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Sun-Oracle, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Apple, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Sybase, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Novell, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Intel, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Accenture, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société SAP, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Prometric, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Toeic, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo du IT Academy Program par Microsoft, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management

SUPINFO International University
Ecole d'Informatique - IT School
École Supérieure d'Informatique de Paris, leader en France
La Grande Ecole de l'informatique, du numérique et du management
Fondée en 1965, reconnue par l'État. Titre Bac+5 certifié au niveau I.
SUPINFO International University is globally operated by EDUCINVEST Belgium - Avenue Louise, 534 - 1050 Brussels