Prévention contre les attaques par Force Brute
Ring
Member
dans Modifications
Voilà une astuce qui m'a évité de créer un plugin trop compliqué pour moi, comprenant notamment la création d'une table IP Bannies.
Il suffit de rajouter un sleep() dans la fonction d'authentification. Ceci permet une pause trop longue dans le reset pour un robot opérant une attaque par Force Brute.
Donc dans le core/admin/auth.php, à la ligne 81 (PluXml 5.5) :
Rajouter le sleep(15) sachant que 15 représente une pause de 15 secondes après le message d'erreur pour représenter un nouveau login. S'il s'agit d'un humain, 15 secondes d'attente ce n'est pas très long. En revanche pour un robot, cela allonge gravement le temps nécessaire à l'attaque, au point de l'abandonner.
De plus, le fait de placer l'instruction APRES l'instruction d'erreur, permet de ne pas attendre ces 15 secondes lorsqu'on ne s'est pas trompé (écrasante majorité des cas) :
Evidemment, je devrai rajouter cette instruction à chaque mise à jour du core. A moins que Stephane ne l'intègre dans la nouvelle version (avec possibilité de mettre le nb de secondes en variable modifiable).
Il suffit de rajouter un sleep() dans la fonction d'authentification. Ceci permet une pause trop longue dans le reset pour un robot opérant une attaque par Force Brute.
Donc dans le core/admin/auth.php, à la ligne 81 (PluXml 5.5) :
[== PHP ==]
# Authentification
if(!empty($_POST['login']) AND !empty($_POST['password'])) {
[...]
if($connected) {
header('Location: '.htmlentities($redirect));
exit;
} else {
$msg = L_ERR_WRONG_PASSWORD;
$error = 'error';
}
}
Rajouter le sleep(15) sachant que 15 représente une pause de 15 secondes après le message d'erreur pour représenter un nouveau login. S'il s'agit d'un humain, 15 secondes d'attente ce n'est pas très long. En revanche pour un robot, cela allonge gravement le temps nécessaire à l'attaque, au point de l'abandonner.
De plus, le fait de placer l'instruction APRES l'instruction d'erreur, permet de ne pas attendre ces 15 secondes lorsqu'on ne s'est pas trompé (écrasante majorité des cas) :
[== PHP ==]
# Authentification
if(!empty($_POST['login']) AND !empty($_POST['password'])) {
[...]
if($connected) {
header('Location: '.htmlentities($redirect));
exit;
} else {
$msg = L_ERR_WRONG_PASSWORD;
$error = 'error';
sleep(15);
}
}
Evidemment, je devrai rajouter cette instruction à chaque mise à jour du core. A moins que Stephane ne l'intègre dans la nouvelle version (avec possibilité de mettre le nb de secondes en variable modifiable).
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Je suis étonné qu'il n'y ait pas encore un captcha sur la page de d'authentification comme pour les commentaires.
J'ai un plugin captchaImage qui comble ce manque sur mon dépôt
A++
Accès à mon dépôt de plugins et thèmes
installe PluXml plus vite que ton ombre avec kzInstall2
Je ne connais pas ton plugin, mais le lien sur le post ne fonctionne pas
merci d'avance,
à plus,
Gzyg
Ben oui mais j'ai eu cette idée en trouvant un script d'attaque par force brute de ce genre en php, sans doute pour les newbies et les "mauvais garçons" dont tu parles ailleurs !
Et puis mon blog ne va pas héberger les adresses et n° de tel de toute la cour d'Angleterre non plus...
Je me suis fait la même remarque en découvrant PluXml. Mais je n'aime pas les captcha image et il est hors de question d'utiliser un captcha propriétaire externe.
Ceci dit, j'ai une bonne idée de captcha ludique et accessible mais je ne sais pas suffisamment programmer en php...
@Gzyg : merci mais tu penses bien que j'ai pillé ce site allègrement ! Merci à Bazooka au passage.
Sinon il existe dans les entrailles de Pluxml un captcha basé uniquement sur des lettres qu'il serait facile de mettre en place.
Si tu as une bonne idée et claire d'un captcha ludique tu peux toujours expliquer. Cela ne devrait pas être difficile à coder en PHP.
Accès à mon dépôt de plugins et thèmes
installe PluXml plus vite que ton ombre avec kzInstall2
le sujet m'intéresse. Je ne veux pas non plus de captcha propriétaire externe.
Les questions auxquelles des humains peuvent répondre mais pas des robots sourds et aveugles, ça marche ou pas dans les cas d'attaque par force brute ?
Quid des sites polyglottes ? Il faudrait des questions adaptées à chaque langue ?
Mise au point d'un futur site sur serveur local MAMP (MacOS)
```Version de PHP : 7.4.2
Apache/2.2.34 (Unix) mod_wsgi/3.5 Python/2.7.13 PHP/7.4.2
mod_ssl/2.2.34 OpenSSL/1.0.2o DAV/2
mod_fastcgi/mod_fastcgi-SNAP-0910052141
mod_perl/2.0.11
Perl/v5.24.0
- du fait du caractère open source desdits CMS, la librairie initiale questions-réponses était connue et facile à programmer sur un robot,
- l'utilisateur pouvait rajouter ses propres questions-réponses à la librairie mais le faible nombre et la pauvreté imaginative de ces éléments rajoutés rendait aussi facile à contrer.
Attention, on parle bien ici d'attaque par Force brute et non de DDOS.
[list=*]
[*]15 secondes entre deux essais[/*]
[*]Une réponse à fournir[/*]
[*]X essais toutes les Y minutes[/*]
[/list]
Qu'en dites-vous ?
Je suis persuadé que la solution est dans la voie ouverte très (trop ?) simplement par Stephane :
- création d'un mot composé de X (aléatoire mais borné) lettres (aléatoire mais alpha minuscule seulement)
- puis choix d'une lettre (aléatoire) dans ce mot en signalant sa position après une petite transformation (rang 1="première", rang 2="deuxième", last="dernière"...).
Jusqu'à maintenant, à part une alerte durant l'été 2015 ou 2014 (je crois l'avoir lu dans le forum) et due certainement à une attaque "humaine" sur les commentaires ("félicitations pour cet article"...), le captcha propriétaire a réussi à tenir face aux attaques des robots jusque là. Il faut prendre en compte la faible diffusion de Pluxml, comparée au plus gros concurrent, et l'intérêt souvent non stratégique des contenus des utilisations, rendant le développement d'un hack insuffisamment rentable.
Pour le rendre encore plus sûr, peut-être qu'il suffirait de :
- étendre les bornes du nombre de lettres du mot aléatoire (5 à 9)
- étendre le champ des caractères choisis (maj, min, chiffres)
- choisir de 2 à plusieurs caractère(s) dans le mot généré (2 à 4)
Dans tous les cas, la méthode choisie devra obligatoirement être accessible et responsive sans l'apport superflu d'une méthode audio toujours faillible (c'est aussi une des raisons de mon éviction de la méthode image générée).
pour l'admin, il y a un plugin déja existant :
Quel dommage que toutes ces ressources (plugin, thèmes) soient éparpillées un peu partout sans même un annuaire pour les recenser - bien qu'il serait meilleur que la communauté regroupe ses ressources sur le site officiel...
Edit : voici la discussion sur le plugin auth : http://forum.pluxml.org/viewtopic.php?id=3050
Mais ce plugin est basé sur un cookie de session donc il est enfantin de contourner le comptage en effaçant le cookie à chaque tentative.
Ça peut venir en complément de la fonction sleep() proposée en haut de topic pour faire une barrière de plus.
Radical mais efficace ^^
Merci Rubén
Mettons on ait drois à trois tentatives, après trois mauvais mots de passe, personne ne peut plus s'identifier.
Pour débloquer la situation, il faut qu'un administrateur supprime le fichier txt où sont compté les tentatives (par FTP par exemple).
Ou sinon aller sur une URL du style www.monsite.com/core/debloquer.php?clef=28f6e29cf70ef8ca38894874f3e950c52457850b qui charge un script qui efface le fichier.
Où la clef serait la même que la clef perso pour le flux RSS privé.
Vous me suivez ?
Alors, si j'ai bien compris, un robot fait 3 tentatives de connexions infructueuses - ou 3 robots, une seule - et le site bloque toute tentative de connexion nouvelle jusqu'à déblocage par l'admin ?
C'est faisable mais (car il y a toujours un mais et ici je me fais l'avocat du diable) si le site fait l'objet d'une attaque ciblée, à quel moment faudrait-il aller le débloquer, sous peine de refaire la manip en permanence ?
D'autre part, le fichier des login manqués devrait être détruit automatiquement de façon régulière. En effet, on ne peut pas considérer que 3 tentatives manquées durant les 6 derniers mois constitue une attaque.
Mais l'idée est bonne à condition, bien sûr, que le fichier du nombre de tentatives ne soit pas lié aux IP (ce que je craignais dans ton idée).
On note l'heure de blocage du site dans un fichier.
Et chaque visite suivante, on regarde si le site a été suffisamment bloqué pendant un certain temps, disons 1 à 2 heures.
Bien sûr on envoie un mail d'alerte à l'admin en début de blocage.
Accès à mon dépôt de plugins et thèmes
installe PluXml plus vite que ton ombre avec kzInstall2
Non je ne pensais pas lier les tentatives avec les adresses IP.
Tu as raison d'indiquer que 3 tentatives en 6 mois et 3 en une minute ce n'est pas pareil.
Il faudrait faire un tableau avec la date de la tentative et nettoyer de temps en temps.
On peut aussi bloquer le site un certain temps, ou accélérer les choses via la méthode dont je parlais.
Très bien aussi l'idée du courriel à l'admin.
On pourrait aussi neutraliser le blocage lorsque l'admin est connecté ou au moins lui lancer une alerte en ligne.
Donc, je récapépète :
* 1ère connexion manquée -> mise en mémoire du numéro de tentative + de la date/heure/min/sec de la tentative. Comparaison de l'heure avec N-2. Si la différence est inférieure à D (durée maxi entre 3 connexions ratées), alors blocage. Dans ce cas 1ère tentative, N-2 n'existant pas ou différence supérieur à D, pas de blocage.
* 2ème connexion manquée -> mise en mémoire du numéro de tentative + de la date/heure/min/sec de la tentative. Comparaison de l'heure avec N-2. Si la différence est inférieure à D (durée maxi entre 3 connexions ratées), alors blocage. Dans ce cas 2ème tentative, N-2 n'existant pas ou différence supérieur à D, pas de blocage.
* 3ème connexion manquée -> mise en mémoire du numéro de tentative + de la date/heure/min/sec de la tentative. Comparaison de l'heure avec N-2 (la 1ère connexion). Suppression des données N-3 devenues inutiles. Si la différence est inférieure à D (durée maxi entre 3 connexions ratées), alors blocage.
- Procédure de blocage : création d'un htaccess ? L'admin est-il connecté ? Oui = alerte, Non = Envoi d'un mail auto à l'admin. Mise en route d'un minuteur (ou cron ?) et comparaison régulière avec la date N-2. Dès que la différence est supérieure à D -> déblocage = nouveau htaccess. Possibilité de déblocage manuel par l'admin à tous moments.
En fait, le fichier ne garderait en permanence que les 3 derniers logs ratés (N° + Date/Heure).
Au départ j'avais une tout autre idée basée sur le concept du captcha. Mais ceci remplacerait carrément le captcha, ce qui serait meilleur.
Qu'en pensez-vous ?
Il n'y a pas que Apache, il y a aussi Nginx qui va mieux. C'est comme Windows ...
On crée un fichier de log dans le dossier de données et on consulte la dernière ligne. En n'oubliant pas de faire un logrotate suivant le temps ou la taille
Tout le monde ne saura pas régler un crontab sur un hébergement mutualisé. Il vaut mieux consulter le fichier de logs à chaque visiteur.
Accès à mon dépôt de plugins et thèmes
installe PluXml plus vite que ton ombre avec kzInstall2