• 4 heures
  • Facile

L'attaque par force brute

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Cette partie est une peu différente des autres dans la mesure où nous apprendrons à nous protéger contre les attaques par force brute (plus couramment appelées "bruteforce"). Le but n'est donc pas de se protéger contre une faille, mais de rendre ce type d'attaque inefficace.

Attaque par force brute ?

L'attaque par force brute est une technique relativement courante, mais qui nécessite beaucoup de temps d'exécution. Comme son nom l'indique, c'est une technique très... barbare ! Le principe est simple :  le hacker crée un formulaire identique à celui de votre site, puis avec un script il essaye toutes les combinaisons de mots de passe possibles et imaginables. Il existe une autre technique de bruteforce où le hacker se base sur d'énormes dictionnaires contenant des millions voire milliards de mots de passe régulièrement utilisés. Pas très fin, mais redoutablement efficace ! Surtout si l'utilisateur s'est inscrit avec un mot de passe simple.

Bon relativisons : pour un mot de passe contenant 7 caractères (en supposant qu'il contienne chiffres, lettres minuscules et lettres majuscules), il n'existe pas moins de 3 521 614 606 208 combinaisons différentes. Un mot de passe de cette longueur résisterait plusieurs mois avant d'être découvert. Et encore, on est dans le cas où le hacker connaît la longueur du mot de passe. Si on prend en compte la longueur moyenne d'un mot de passe :

Source

Les mots de passe "lambda" ont donc une longueur moyenne comprise entre 6 et 8 (voir 9). Calculons donc le nombre de possibilités :

$\[p = 62^6 + 62^7 + 62^8 = 2.22*10^{14} = 221 \hspace{0.2cm} 918 \hspace{0.2cm} 520 \hspace{0.2cm} 426 \hspace{0.2cm} 688\]$

  

Ce qui est, somme toute, relativement beaucoup. Quoi que très long et fastidieux, il reste malgré tout possible de casser un mot de passe de cette longueur. Je vais donc vous montrer plusieurs techniques pour rendre la tache encore plus difficile (voire même impossible) au méchant hacker. :p

Ralentir le processus

Cette première technique ne rend pas impossible l'attaque par force brute, mais elle va considérablement la ralentir. Tellement la ralentir qu'il faudrait des milliers d'années avant de trouver un mot de passe basique. Elle a également l'avantage d'être très facile à mettre en place. Le principe est simple. Comme indiqué dans le titre, il suffit de "ralentir" l'exécution du formulaire de connexion en ajoutant une pause de 1 seconde. Un utilisateur normal ne verra presque pas la différence, mais le pirate sera drôlement embêté !

<html>
    <form method="post" action="connexion.php">
    <input type="text" name="pseudo">
    <input type="password" name="password">
    <input type="submit" value="connexion">
    </form>
</html>

<?php 

if(isset($_POST['pseudo']) AND isset($_POST['password'])) {
    
    sleep(1); // Une pause de 1 sec
    
    if... // Vérification des identifiants/password etc..

?>

Un rapide calcul pour voir concrètement ce qu'une petite pause de 1 seconde apporte en sécurité :

$\[2.22*10^{14} \hspace{0.2cm} Sec \hspace{0.1cm} = \hspace{0.1cm} 2.57*10^{9} \hspace{0.1cm}Jours = 7 \hspace{0.2cm} 041 \hspace{0.2cm} 095 \hspace{0.1cm} Ans\]$

 Voilà autant vous dire que c'est assez pour en décourager plus d'un ! ;)

Après soyons francs, il est possible d'exécuter plusieurs formulaires à la fois et le pirate pourra se servir d'un réseau botnet. Et là notre technique s'avère beaucoup moins efficace que prévue. C'est donc une bonne technique, mais elle ne vaut pas grand choses si elle est utilisée seule. De plus, elle comporte certains inconvénients sur le plan technique. Bien qu'il ne s'agisse que d'une petit seconde, cela va monopoliser un thread d'apache pendant une seconde. Sur un site qui possède un faible trafic, cela ne posera pas trop de problème. Mais si le serveur doit gérer simultanément plusieurs centaines de connexion, vous comprendrez alors à quel point cette technique ruine les performances du serveur.

Le bannissement d'IP

Cette technique est plus complexe, mais beaucoup plus efficace. Elle consiste à limiter le nombre de tentatives par personne et par jour. Bien évidemment, il ne faut pas bloquer le compte visé par l'attaque, mais empêcher le hacker de continuer à brutaliser notre formulaire. L'astuce consiste donc à créer une table qu'on appellera connexion et dans laquelle on enregistrera toutes les tentatives ratées de connexions au site. On y enregistrera simplement l'IP de la personne.  Au-delà d'un certain nombre de tentatives, l'accès au compte avec cet IP devient impossible pendant un certain temps.

Faisons un exemple simple :  Au-delà de 10 tentatives, l'IP est bannie jusqu'au lendemain. Pour cela, il faut tout d'abord créer notre script PHP qui enregistre les tentatives de connexion ratées.

<?php

// Pour simplifier voilà le password
$password = "zero";

 // On se connecte à la bdd
try { $bdd = new PDO('mysql:host=localhost;dbname=bdd','root',''); }
catch (Exeption $e) { die('Erreur : ' .$e->getMessage())  or die(print_r($bdd->errorInfo())); }

// On récupère l'IP du visiteur
$ip = $_SERVER['REMOTE_ADDR'];
    
// On regarde s'il est autorisé à se connecter
$recherche = $bdd->prepare('SELECT * FROM connexion WHERE ip = ?');
$recherche->execute(array($ip));
$count = $recherche->rowCount();

// Si l'ip a essayé de se connecter moins de 10 fois ce jour là
if ($count < 10)
    
        // Vérification classique du password
        if ($_POST['password'] == $password) {
          echo "Bravo vous êtes connecté";
         }
    
        else {
		
		    // On enregistre la tentative échouée pour cette ip
			$req = $bdd->prepare('INSERT INTO connexion(ip) VALUES(:ip)');
			$req->execute(array('ip' => $ip));
			
            echo "Mot de passe incorrecte";
         }

// Si la personne a déja essayé de se connecter 10 fois ce jour là
else {
    echo "Désolé vous êtes banni jusqu'à demain";
}

?>

Mais ce n'est pas tout ! Comme vous l'avez remarqué, je n'ai pas mis de champ qui compte le temps. En effet cette solution est possible, mais elle sous-entend que vous avez une table qui contient toutes les connexions à votre site pendant plusieurs jours/mois/années. Ce qui est tout à fait inutile. Personnellement je préconise d'utiliser un cron.

Un cron ? C'est quoi encore ce plan...

Rien de bien compliqué je vous rassure ! Un cron c'est tout simplement un petit programme qui se situe côté serveur et qui peut (par exemple) exécuter des actions à des heures précises. Il suffit donc dans notre cas de créer un cron qui vide notre table connexion tous les jours à 0h00 (ou à 14h23 si ça vous amuse ^^). Voilà un tuto qui devrait vous permettre de créer votre cron sans trop de difficultés. Une fois le cron mis en place, vous lui ordonnez d'exécuter un fichier PHP chargé de vider notre table tous les soirs à 0h00. Un petit exemple :

<?php

 // On se connecte à la bdd
try { $bdd = new PDO('mysql:host=localhost;dbname=bdd','root',''); }
catch (Exeption $e) { die('Erreur : ' .$e->getMessage())  or die(print_r($bdd->errorInfo())); }

// On fait un peu de ménage
$nettoyage = $bdd->exec('DELETE FROM connexion');
$nettoyage->closeCursor();

?>

Ah c'est sympa ! Mais je n'ai pas mon propre serveur, je suis hébergé chez [NomD'unHébergeur] je peux le faire quand même ?

Le cron est un outil très utile, mais si le serveur ne vous appartient pas et/ou que vous êtes en mutualisé, son utilisation peut s'avérer plus complexe.  Pour en savoir plus, il vous suffit de faire une petite recherche sur votre hébergeur et les services qu'il propose. Si la mise en place d'un cron n'est pas autorisée chez votre hébergeur, il y a malgré tout d'autres techniques pour vider périodiquement notre table. À partir de la version 5.1.6 de MySql, il est possible de mettre en place un programmateur d'évènements. Je ne peux pas m'attarder là dessus, mais voilà un très bon site qui explique tout sur le programmateur d'évènements MySQL.

Bon comme je vous l'avais dit, ce système est un peu plus compliqué. Mais soyons franc, il reste tout de même réalisable pour peu qu'on prenne le temps de s'y mettre. Et puis, si ça peut éviter de se faire attaquer, ça en vaut la peine ! ;)

Fail2ban

Je ne pouvais évidement pas terminer cette partie sur le bannissement d'IP sans vous parler de la solution fail2ban. Voilà un résumé explicatif très concis fournis par la documentation officielle

Fail2ban lit des fichiers de log comme /var/log/pwdfail ou /var/log/apache/error_log et bannit les adresses IP qui ont obtenu un trop grand nombre d'échecs lors de l'authentification. Il met à jour les règles du pare-feu pour rejeter cette adresse IP. Ces règles peuvent êtres définies par l'utilisateur. Fail2ban peut lire plusieurs fichiers de log comme ceux de sshd ou du serveur Apache.

Comme vous l'aurez probablement compris, ce service permet de bannir définitivement les IP qui ont obtenu un trop grand nombre d'échec. Bien que ça soit un peu radical, cette solution est très efficace. N'hésitez pas à la mettre en place, quitte à ajouter un service de récupération pour les utilisateur vraiment étourdis (avec une vérification humaine, pas un script).

Voilà, je ne détaillerai pas la façon dont il s'installe, c'est vraiment enfantin et tout est parfaitement bien expliqué dans la documentation officielle.

La vérification par captcha

Cette dernière technique est très simple. Elle consiste à insérer un captcha de vérification dans vos formulaires. Et c'est très efficace ! C'est presque imparable pour être certain qu'on a à faire à un humain et non à un script.

Un captcha ? Jamais entendu parler

Vous ne les connaissez peut être pas de nom, mais vous les avez forcément rencontrés quelque part sur le web. Ce sont ces petites cases avec des lettrse déformées que vous devez recopier pour confirmer que vous êtes un humain. Vous ne voyez toujours pas ? Ok une image devrait vous rafraichir la mémoire :

Ahhhhh oui c'était donc ça ! Mais c'est un peu moche, je sais pas comment ça s'installe...

En effet ce n'est pas forcément très esthétique, quoique la nouvelle version de recptcha proposée par Google est vraiment acceptable niveau design. De plus, cette protection est tellement efficace qu'il faudra peut-être faire quelques sacrifices. Mieux vaut un site sécurisé que faillible et beau (bien que l'idéal soit d'allier les deux) !

Pour ce qui est de la mise en place, je vous renvoie à la partie 2 de ce cours qui explique comment mettre en place toutes ces protections.

Exemple de certificat de réussite
Exemple de certificat de réussite