Sécurité Apache : modsec

Sécurité Apache : modsec jpp

Un serveur Apache est, en lui même, assez sécurisé, mais les applications qu'il héberge peuvent présenter des défauts de sécurité. 
Certains IDS/IPS, par exemple Suricata, peuvent utiliser des règles améliorant la sécurité des applications. Mais, car il y a un "mais", le passage en HTTPS empêche pratiquement l'utilisation de ces règles car le contenu des flux HTTPS ne peut être analysé dans le flux des données réseau. Il faut donc se tourner vers une méthode qui agisse après le traitement HTTPS, il faut donc opérer entre le traitement HTTPS et l'application. 
C'est ainsi que "Modsecurity" (de son petit nom "modsec"), module spécialisé pour Apache, permet d'utiliser des règles sur les données "décodées" et donc d'avoir une analyse fine, comme le fait par exemple Suricata pour le HTTP simple ou les autres protocoles non TLSisés.

Remarques au passage : 
Si vous utilisez "Phpmyadmin" veillez à bien le configurer, à nettoyer les scripts de démarrage et filtrer au maximum l'accès à ses fonctions. Le filtrage par IP en limitant à une IP utilisée pour l'administration est une bonne méthode. En effet une grande partie des "pirates" cherchent un accès par des URL comportant "/phpmyadmin" (éventuellement avec quelques majuscules ou raccourcis), ou d'autres chemins connus "/pma", "/myadmin" .... en ciblant souvent les modules "setup...." ou d'autres réputés présenter une faille. 
De toutes façons il ne me semble pas "sain" d'installer de tels outils sur des machines de production en contact avec Internet afin de limiter au maximum la surface d'attaque. 
Il y a d'autre part intérêt, on ne le répète jamais assez, à mettre rapidement en place les mises à jour de sécurité de tous les logiciels.

Apache modsec : installation

Apache modsec : installation jpp

Afin de me familiariser avec Modsec j'ai commencé par réaliser l'installation dans une VM abritant une copie des sites en exploitation. 
Une petite photo des lieux : 
VM avec Debian 9 un processeur et 1,2Go de mémoire.

Pré-requis : mod_unique_id contenu dans le paquet : libapache-session-perl qui installe en plus les 4 paquets suivants : 
libcgi-fast-perl libcgi-pm-perl libfcgi-perl

Ensuite j'ai juste ajouté le paquet libapache2-mod-security2 qui m'installe le paquet modsecurity-crs. Les premiers test sont OK et les temps de réponse semblent corrects, c'est à dire sans altération preceptible.
Lorsque j'ai tenté d'utiliser "git" pour effectuer la mise à jour des règles Owasp j'ai essuyé un échec. Le paquet est modsecurity-crs est "incorrect" car il ne permet pas la mise à jour par git du contenu du répertoire directement depuis le site OWASP ? 
J'ai donc renommé par sécurité le répertoire "incorrect" /usr/share/modsecutity-crs puis chargé le "bon" par git : 
cd /usr/share 
git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git 
Ceci m'a créé un répertoire owasp-modsecurity-crs ce qui m'a obligé à :

  • - corriger le fichier /etc/apache2/mods-available/security2.conf en remplaçant  
    "IncludeOptional /usr/share/modsecurity-crs/owasp-crs.load"  
    par  
    "IncludeOptional /usr/share/owasp-modsecurity-crs/crs-setup.conf"
  • - dans ce même fichier ajouter : 
    "Include /usr/share/owasp-modsecurity-crs/rules/*.conf"
  • - dans le répertoire "/usr/share/owasp-modsecurity-crs" faire : 
    cp crs-setup.conf.example crs-setup.conf
  • - Pour la mise à jour des règles il suffira ensuite de lancer la commande : 
    /usr/share/owasp-modsecurity-crs/util/upgrade.py --crs 
    ou, pour la mise à jour des informations "geoip" : 
    /usr/share/owasp-modsecurity-crs/util/upgrade.py --geoip 
    Attention il m'a fallu modifier le script "upgrade.py" pour remplacer : 
    "https://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz' 
    par : 
    "https://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.tar.gz"


Avant activation du module :

  • - vérifier que dans /etc/apache2/mods-enabled les liens existent bien, cette action a du être réalisée lors de l'installation initiale :
    •     security2.conf -> ../mods-available/security2.conf
    •     security2.load -> ../mods-available/security2.load
  • Si cela n'est pas fait --> "a2enmod security2"
  • - dans /etc/modsecurity
    • - copier modsecurity.conf-recommended sur modsecurity.conf
    • - activer le module dans "modsecurity.conf" : vérifier que "SecStatusEngine" est bien "on".
  • - relancer apache

Le "error.log" de Apache devrait montrer l'activation de modsecurity. 
Pour mieux "voir" ce qui se passe il est intéressant de mettre la valeur de "SecDebugLogLevel" à 1. 
Par défaut seul le mode "DETECTIONONLY" est activé, il faut donc mettre "SecRuleEngine" à "On" pour activer le mode normal (celui qui bloque les vilaines requêtes ...). 
Je n'ai pas fait d'autres modifications dans ce fichier.

Pour obtenir un log en "JSON" j'ai modifié quelques lignes du fichier "/etc/modsecurity/modsecurity.conf" : 
# DEBUT 
# définitif pour ne voir que "Relevant" 
SecAuditEngine RelevantOnly 
# provisoire pour tout voir 
SecAuditEngine on 
# SecAuditLogRelevantStatus "^(?:5|4(?))" 
SecAuditLogRelevantStatus "^(?:5|4(?!04))" 
# Log everything we know about a transaction. 
# SecAuditLogParts ABDEFHIJZ 
SecAuditLogParts ABFHZ 
SecAuditLogFormat JSON 
SecAuditLogType Serial 
# FIN

Après un "systemctl restart apache2" tout semble fonctionner correctement ... mais l'analyse des fichiers de log de Modsec est assez ardue et je vais essayer de construire quelques outils facilitant la récupération, le stockage, le traitement et l'archivage de ces données. 
Depuis ce test j'ai installé Modsec sur la machine en exploitation et cela repère quelques malins qui tentent des accès douteux réalisés en HTTPS, pour le HTTP Suricata assisté de quelques règles "perso" bloque ou au moins repère la plupart des attaques. 
Le logiciel de gestion des événements générés par Modsec est en cours de réalisation commence à bien fonctionner. 
Ce petit logiciel est constitué d'un module Python qui analyse le fichier d'audit réalisé par modsecurity et inscrit les données dans une base Mysql/MariaDB. 
Quelques progammes en PHP permettent d'afficher et de classifier les événements "repérés" par notre ami modsecurity et de bloquer immédiatement les méchants" à l'aide du pare-feu. 
On peut aussi les "dénoncer", par exemple sur Abuseipdb (AbuseIPDB), pour limiter leur nuisance et intégrer ces IP dans un firewall pour leur bloquer l'accès aux applications maison.

Premières statistiques

Premières statistiques jpp

Après quelques semaines beaucoup d'anomalies ont été interceptées par Modsec, voici un petit tableau statistique des résultats sur le port 443 : 
 
On voit que la majorité des détections sont dues à des "scanners de sites" ou à des "bad bots" qui cherchent inlassablement de nouveaux sites. Un certain nombre de ces "Bad bots" réalisent probablement des actions de reconnaissances pour action ultérieure. 
Remarque : la partie "pirates" ne concerne que le HTTPS, la plupart des attaques exécutées en HTTP sont stoppées par Suricata dans lequel j'ai ajouté un fichier de règles lorsque je rencontre des tentatives non détectées, par exemple il existe des "tests" non détectés au milieu d'une attaque plus vaste. Il est bon d'ajouter la description de ces événements dans une règle Suricata. Ces règles sont souvent plus faciles à écrire que les règles de Modsecurity mais ne peuvent détecter des attaques en HTTPS.