149 votes

Quelle est la meilleure contre-mesure pour la force brute distribuée ?

Tout d'abord, un peu de contexte : Ce n'est pas un secret que je suis en train d'implémenter un système d'authentification pour CodeIgniter, et jusqu'à présent je suis en train de gagner (pour ainsi dire). Mais je me suis heurté à un défi non trivial (un défi que la plupart des bibliothèques d'authentification manquent complètement, mais j'insiste pour le gérer correctement) : comment traiter intelligemment les données de l'utilisateur ? attaques par force brute à grande échelle, distribuées et à nom d'utilisateur variable. .

Je connais tous les trucs habituels :

  1. Limitation du nombre de tentatives infructueuses par IP/hôte et en refusant l'accès aux délinquants (par exemple, Fail2Ban) - ce qui ne fonctionne plus. depuis que les botnets sont devenus plus intelligents
  2. En combinant ce qui précède avec un liste noire d'adresses IP et d'hôtes connus comme "mauvais". (par exemple DenyHosts) - qui repose sur le fait que les botnets se laissent prendre au #1, ce qui est de moins en moins le cas
  3. Listes blanches d'adresses IP et d'hôtes combiné à l'authentification traditionnelle (malheureusement inutile avec les utilisateurs à IP dynamique et le taux de renouvellement élevé sur la plupart des sites web)
  4. Fixer un limite dans tout le site sur le nombre de tentatives échouées au cours d'une période de N minutes/heures, et l'étranglement (suspension) de toutes les tentatives de connexion après cela pendant un certain nombre de minutes/heures (avec le problème que les attaques DoS deviennent un jeu d'enfant pour les botnets)
  5. Obligatoire signatures numériques (certificats à clé publique) ou des jetons matériels RSA pour tous les utilisateurs sans option de login/mot de passe (sans aucun doute une solution solide comme le roc, mais seulement pratique pour les services fermés et dédiés)
  6. Enforced les systèmes de mots de passe ultra-forts (par exemple, >25 caractères non sensés avec des symboles - là encore, trop peu pratique pour les utilisateurs occasionnels)
  7. Et enfin, CAPTCHAs (qui pourraient fonctionner dans la plupart des cas, mais sont gênants pour les utilisateurs et les pratiquement inutile contre un un attaquant déterminé et plein de ressources )

Il ne s'agit là que d'idées théoriquement réalisables. Il y a abondance d'idées débiles qui font exploser le site (par exemple, pour des attaques DoS insignifiantes). Ce que je veux, c'est quelque chose de mieux. Et par mieux, je veux dire :

  • Il doit être sécurisé(+) contre les attaques DoS et par force brute, et ne pas introduire de nouvelles vulnérabilités qui pourraient permettre à un bot un peu plus sournois de continuer à opérer sous le radar.

  • Il doit être automatisé. S'il faut un opérateur humain pour vérifier chaque connexion ou surveiller les activités suspectes, cela ne fonctionnera pas dans un scénario réel.

  • Il doit pouvoir être utilisé sur le Web de manière générale (c'est-à-dire avec un taux de renouvellement élevé, un volume important et un enregistrement ouvert qui peut être effectué par des non-programmeurs).

  • Il ne doit pas entraver l'expérience de l'utilisateur au point d'irriter ou de frustrer les utilisateurs occasionnels (qui pourraient abandonner le site).

  • Il ne peut pas s'agir de chatons, sauf s'ils sont vraiment très sûr chatons

(+) Par "sûr", j'entends au moins aussi sûr que la capacité d'un utilisateur paranoïaque à garder son mot de passe secret.

Alors, écoutons-les ! Comment le feriez-vous ? ? Connaissez-vous une meilleure pratique que je n'ai pas mentionnée (oh s'il vous plaît, dites que vous en avez une) ? J'admets que j'ai une idée personnelle (combinant les idées des points 3 et 4), mais je vais laisser les vrais experts parler avant de m'embarrasser moi-même ;-)

69voto

Jens Roland Points 19171

Très bien, assez d'hésitation, voici ce que j'ai trouvé jusqu'à présent.

(désolé, long post à venir. Soyez courageux, mon ami, le voyage en vaut la peine)

En combinant les méthodes 3 et 4 de l'article original, on obtient une sorte de liste blanche "floue" ou dynamique, puis - et c'est là que réside l'astuce ne bloque pas les IP qui ne sont pas sur liste blanche, mais les étrangle jusqu'en enfer .

Notez que cette mesure est uniquement destiné à contrecarrer ce type d'attaque très spécifique. En pratique, bien sûr, cela fonctionnerait en combinaison avec d'autres approches de meilleures pratiques d'authentification : étranglement par nom d'utilisateur fixe, étranglement par IP, politique de mot de passe fort renforcée par le code, connexion par cookie non accélérée, hachage de tous les équivalents de mot de passe avant de les enregistrer, ne jamais utiliser de questions de sécurité, etc.

Hypothèses sur le scénario d'attaque

Si un attaquant cible des noms d'utilisateur variables, notre contrôle des noms d'utilisateur ne fonctionne pas. Si l'attaquant utilise un botnet ou a accès à une large plage d'adresses IP, notre étranglement des adresses IP est impuissant. Si l'attaquant a récupéré à l'avance notre liste d'utilisateurs (ce qui est généralement possible avec les services Web d'enregistrement ouvert), nous ne pouvons pas détecter une attaque en cours en nous basant sur le nombre d'erreurs "utilisateur non trouvé". Et si nous appliquons une limitation restrictive à l'échelle du système (tous les noms d'utilisateur, toutes les adresses IP), toute attaque de ce type entraînera un déni de service de l'ensemble de notre site pendant la durée de l'attaque et la période de limitation.

Donc nous devons faire autre chose.

La première partie de la contre-mesure : la mise en liste blanche.

Ce dont nous pouvons être sûrs, c'est que l'attaquant n'est pas en mesure de détecter et d'usurper dynamiquement les adresses IP de plusieurs milliers de nos utilisateurs(+). Ce qui fait que liste blanche faisable. En d'autres termes : pour chaque utilisateur, nous stockons une liste des IP (hachées) à partir desquelles l'utilisateur s'est précédemment (récemment) connecté.

Ainsi, notre système de liste blanche fonctionnera comme une "porte d'entrée" verrouillée, où un utilisateur doit être connecté à partir d'une de ses "bonnes" IP reconnues pour pouvoir se connecter. Une attaque par force brute sur cette "porte d'entrée" serait pratiquement impossible(+).

(+) à moins que l'attaquant ne "possède" soit le serveur, soit toutes les boîtes de nos utilisateurs, soit la connexion elle-même - et dans ce cas, il ne s'agit plus d'un problème d'"authentification", mais d'une véritable situation d'effondrement de la franchise.

La deuxième partie de la contre-mesure : l'étranglement à l'échelle du système. de PI non reconnues

Pour qu'une liste blanche fonctionne dans le cas d'un service web à enregistrement ouvert, où les utilisateurs changent fréquemment d'ordinateur et/ou se connectent à partir d'adresses IP dynamiques, nous devons laisser une "porte de chat" ouverte pour les utilisateurs se connectant à partir d'IP non reconnues. L'astuce consiste à concevoir cette porte de manière à ce que les botnets restent bloqués et que les utilisateurs légitimes soient dérangés. le moins possible .

Dans mon schéma, ceci est réalisé en fixant une valeur de très un nombre maximal restrictif de tentatives de connexion échouées par des IP non approuvées sur une période de 3 heures, par exemple (il peut être plus judicieux d'utiliser une période plus courte ou plus longue en fonction du type de service), et en imposant cette restriction mondial c'est-à-dire pour tous les comptes d'utilisateurs.

Même une force brute lente (1 à 2 minutes entre les tentatives) serait détectée et contrecarrée rapidement et efficacement par cette méthode. Bien entendu, une vraiment lent La force brute pourrait encore passer inaperçue, mais des vitesses trop lentes vont à l'encontre de l'objectif même de l'attaque par force brute.

Ce que j'espère accomplir avec ce mécanisme d'étranglement, c'est que si la limite maximale est atteinte, notre "porte des chats" se ferme pour un moment, mais notre porte d'entrée reste ouverte aux utilisateurs légitimes qui se connectent par les moyens habituels :

  • Soit en se connectant depuis l'une de leurs IP reconnues
  • Ou en utilisant un cookie de connexion persistant (de n'importe où)

Les seuls utilisateurs légitimes qui seraient affectés au cours d'une attaque - c'est-à-dire pendant que l'étranglement est activé - seraient les utilisateurs sans cookies de connexion persistants qui se connectent depuis un lieu inconnu ou avec une IP dynamique. Ces utilisateurs seraient dans l'impossibilité de se connecter jusqu'à ce que l'étranglement se dissipe (ce qui pourrait prendre un certain temps si l'attaquant continuait à faire fonctionner son botnet malgré l'étranglement).

Pour permettre à ce petit sous-ensemble d'utilisateurs de se faufiler par la porte autrement scellée du chat, même si les robots continuent de la marteler, j'utiliserais un formulaire de connexion "de secours" avec un CAPTCHA. Ainsi, lorsque vous affichez le message "Désolé, mais vous ne pouvez pas vous connecter à partir de cette adresse IP pour le moment", vous incluez un lien qui dit " connexion de sauvegarde sécurisée - HUMANS ONLY ( bots : pas de mensonge ) ". Blague à part, lorsqu'ils cliquent sur ce lien, donnez-leur un formulaire de connexion authentifié par reCAPTCHA qui contourne l'étranglement du site. De cette façon, s'ils sont humains et connaissent le bon login+mot de passe (et sont capables de lire les CAPTCHAs), ils pourront jamais se voient refuser le service, même s'ils se connectent depuis un hôte inconnu et n'utilisent pas le cookie d'authentification.

Oh, et juste pour clarifier : puisque je considère que les CAPTCHAs sont généralement maléfiques, l'option de connexion "de secours" serait la suivante uniquement apparaître pendant que l'étranglement était actif .

Il est indéniable qu'une attaque soutenue de ce type constituerait toujours une forme d'attaque DoS, mais avec le système décrit en place, elle n'affecterait que ce que je soupçonne être un minuscule sous-ensemble d'utilisateurs, à savoir les personnes qui n'utilisent pas le cookie "remember me" ET qui se connectent pendant qu'une attaque se produit ET qui ne se connectent pas à partir de leurs IP habituelles ET qui ne peuvent pas lire les CAPTCHAs. Seuls ceux qui peuvent dire non à TOUS ces critères - en particulier les bots et les vraiment malchanceux les personnes handicapées - seront refoulées lors d'une attaque de bot.

EDIT : En fait, j'ai pensé à un moyen de laisser passer même les utilisateurs qui ne sont pas capables d'utiliser le CAPTCHA pendant un "verrouillage" : à la place, ou en complément, de l'ouverture de session CAPTCHA de secours, offrir à l'utilisateur la possibilité d'obtenir un code de verrouillage à usage unique, spécifique à l'utilisateur, envoyé à son courrier électronique, qu'il peut ensuite utiliser pour contourner l'étranglement. Cela dépasse définitivement mon seuil d'ennui, mais puisque ce n'est utilisé qu'en tant qu'outil d'aide à la décision, je pense que c'est une bonne idée. dernier recours pour un minuscule sous-ensemble d'utilisateurs, et puisque c'est toujours mieux que d'être bloqué de son compte, ce serait acceptable.

(Notez également que aucun de cela se produit si l'attaque est moins sophistiquée que la méchante version distribuée que j'ai décrite ici. Si l'attaque ne provient que de quelques adresses IP ou ne touche que quelques noms d'utilisateur, elle sera déjouée beaucoup plus tôt, et ce avec pas de conséquences à l'échelle du site)


C'est donc la contre-mesure que je mettrai en œuvre dans ma bibliothèque d'authentification, une fois que je serai convaincu de son bien-fondé et qu'il n'existe pas de solution beaucoup plus simple que j'aurais manquée. Le fait est qu'il y a tellement de façons subtiles de faire les choses mal en matière de sécurité, et je ne suis pas au-dessus des fausses hypothèses ou des logiques désespérément erronées. Alors, s'il vous plaît, tout retour d'information, toute critique et toute amélioration, toute subtilité, etc. sont très appréciés.

17voto

patros Points 4538

Quelques étapes simples :

Mettez sur liste noire certains noms d'utilisateur courants et utilisez-les comme pot de miel. Admin, guest, etc... Ne laissez personne créer des comptes avec ces noms, ainsi si quelqu'un essaie de se connecter, vous savez que c'est quelqu'un qui fait quelque chose qu'il ne devrait pas.

Assurez-vous que toute personne ayant un pouvoir réel sur le site dispose d'un mot de passe sécurisé. Exigez des administrateurs/modérateurs qu'ils aient des mots de passe plus longs avec un mélange de lettres, de chiffres et de symboles. Rejetez les mots de passe trivialement simples des utilisateurs réguliers avec une explication.

L'une des choses les plus simples que vous puissiez faire est de prévenir les gens lorsque quelqu'un a essayé de se connecter à leur compte, et de leur donner un lien pour signaler l'incident si ce n'était pas eux. Un simple message lorsqu'ils se connectent comme "Quelqu'un a essayé de se connecter à votre compte à 4h20 mercredi bla bla. Cliquez ici si ce n'était pas vous". Cela vous permet de tenir des statistiques sur les attaques. Vous pouvez renforcer la surveillance et les mesures de sécurité si vous constatez une augmentation soudaine des accès frauduleux.

11voto

jamesh Points 9849

Si je comprends bien le mode opératoire des attaques par force brute, un ou plusieurs noms d'utilisateur sont essayés en permanence.

Il y a deux suggestions que je ne pense pas avoir déjà vues ici :

  • J'ai toujours pensé que la pratique standard était d'avoir un court délai (une seconde environ) après chaque mauvaise connexion pour chaque utilisateur. Cela dissuade les attaques par force brute, mais je ne sais pas combien de temps un délai d'une seconde pourrait tenir en échec une attaque par dictionnaire. (dictionnaire de 10.000 mots == 10.000 secondes == environ 3 heures. Hmm. Pas assez bon).
  • au lieu d'un ralentissement à l'échelle du site, pourquoi pas un ralentissement par nom d'utilisateur. L'étranglement devient de plus en plus sévère à chaque tentative erronée (jusqu'à une certaine limite, je suppose pour que le véritable utilisateur puisse toujours se connecter).

Modifier : En réponse aux commentaires sur un étranglement par nom d'utilisateur : il s'agit d'un étranglement spécifique au nom d'utilisateur sans tenir compte de la source de l'attaque.

Si le nom d'utilisateur est limité, même une attaque coordonnée par nom d'utilisateur (plusieurs IP, une seule supposition par IP, même nom d'utilisateur) sera prise en défaut. Les noms d'utilisateur individuels sont protégés par l'étranglement, même si les attaquants sont libres d'essayer un autre utilisateur/passe pendant le délai d'attente.

Du point de vue des attaquants, pendant le délai d'attente, vous pouvez essayer de deviner 100 mots de passe et découvrir rapidement un mauvais mot de passe par compte. Il se peut que vous ne puissiez deviner que 50 fois pendant la même période.

Du point de vue du compte utilisateur, il faut toujours le même nombre moyen de tentatives pour casser le mot de passe, même si les tentatives proviennent de plusieurs sources.

Pour les attaquants, dans le meilleur des cas, il faudra déployer le même effort pour casser 100 comptes qu'un seul, mais comme vous ne pratiquez pas l'étranglement sur l'ensemble du site, vous pouvez augmenter l'étranglement assez rapidement.

Raffinements supplémentaires :

  • détecter les IP qui devinent des comptes multiples - 408 Request Timeout
  • détecter les IP qui devinent le même compte - 408 Request Timeout après un grand nombre (disons 100) de suppositions.

Des idées d'interface utilisateur (qui peuvent ne pas convenir dans ce contexte), qui peuvent également affiner ce qui précède :

  • si vous contrôlez le paramétrage du mot de passe, alors montrer à l'utilisateur la force de leur mot de passe les encourage à en choisir un meilleur.
  • si vous contrôlez la connexion page après un petit nombre (disons 10) de suppositions d'un seul nom d'utilisateur, proposez un CAPTCHA.

9voto

davethegr8 Points 5717

Il existe trois facteurs d'authentification :

  1. Un utilisateur connaît quelque chose (par exemple, un mot de passe)
  2. Un utilisateur a quelque chose (par exemple, un porte-clés)
  3. Un utilisateur est quelque chose (par exemple, un scanner de la rétine)

En général, les sites Web n'appliquent que la politique n° 1. Même la plupart des banques n'appliquent que la politique 1. Elles s'appuient plutôt sur une approche "sait quelque chose d'autre" pour l'authentification à deux facteurs. (Par exemple, un utilisateur connaît son mot de passe et le nom de jeune fille de sa mère.) Si vous en êtes capable, il n'est pas très difficile d'ajouter un deuxième facteur d'authentification.

Si vous pouvez générer environ 256 caractères de caractère aléatoire, vous pourriez structurer cela dans un tableau 16×16, puis demander à l'utilisateur de vous donner la valeur dans le tableau de la cellule A-14, par exemple. Lorsqu'un utilisateur s'inscrit ou change son mot de passe, donnez-lui le tableau et dites-lui de l'imprimer et de le sauvegarder.

La difficulté de cette approche réside dans le fait que lorsqu'un utilisateur oublie son mot de passe, ce qui arrivera, vous ne pouvez pas simplement lui proposer la formule standard "répondez à cette question et saisissez un nouveau mot de passe", car elle est également vulnérable à la force brute. De même, vous ne pouvez pas le réinitialiser et lui envoyer un nouveau mot de passe par courrier électronique, car son adresse électronique pourrait également être compromise. (Voir : Makeuseof.com et leur domaine volé).

Une autre idée (qui implique des chatons), est ce que BOA appelle SiteKey (je crois qu'ils ont déposé le nom). En bref, vous demandez à l'utilisateur de télécharger une image lorsqu'il s'inscrit, et lorsqu'il tente de se connecter, vous lui demandez de choisir son image parmi 8 ou 15 (ou plus) images aléatoires. Ainsi, si un utilisateur télécharge une photo de son chaton, il est théoriquement le seul à savoir exactement quelle photo est la sienne parmi toutes les autres photos de chatons (ou de fleurs ou autres). La seule véritable vulnérabilité de cette approche est l'attaque de type "man-in-the-middle".

Une autre idée (pas de chatons cependant), est de suivre les adresses IP avec lesquelles les utilisateurs accèdent au système, et de leur demander d'effectuer une authentification supplémentaire (captcha, choisissez un chaton, choisissez une clé dans cette table) lorsqu'ils se connectent à partir d'une adresse qu'ils n'ont pas auparavant. De plus, comme pour GMail, il faut permettre à l'utilisateur de voir d'où il s'est connecté récemment.

Edit, New Idea :

Une autre façon de valider les tentatives de connexion consiste à vérifier si l'utilisateur est venu ou non de votre page de connexion. Vous ne pouvez pas vérifier les référents, car ils peuvent être facilement falsifiés. Ce qu'il faut, c'est définir une clé dans la variable _SESSION lorsque l'utilisateur consulte la page de connexion, puis vérifier que cette clé existe lorsqu'il soumet ses informations de connexion. Si le robot ne soumet pas ces informations à partir de la page de connexion, il ne sera pas en mesure de se connecter. Vous pouvez également faciliter cette opération en impliquant javascript dans le processus, soit en l'utilisant pour définir un cookie, soit en ajoutant des informations au formulaire après son chargement. Vous pouvez également diviser le formulaire en deux soumissions différentes (c'est-à-dire que l'utilisateur saisit son nom d'utilisateur, soumet, puis sur une nouvelle page saisit son mot de passe et soumet à nouveau).

La clé, dans ce cas, est l'aspect le plus important. Une méthode courante pour les générer est une combinaison des données de l'utilisateur, de son IP et de l'heure à laquelle il a été soumis.

6voto

ojrac Points 6897

Je dois vous demander si vous avez fait une analyse coût-bénéfice de ce problème ; il semble que vous essayez de vous protéger contre un attaquant qui est suffisamment présent sur le Web pour deviner un certain nombre de mots de passe, en envoyant peut-être 3 à 5 requêtes par IP (puisque vous avez écarté la limitation des IP). Combien (approximativement) coûterait ce type d'attaque ? Est-il plus coûteux que la valeur des comptes que vous essayez de protéger ? Combien de botnets gargantuesques veulent ce que vous avez ?

La réponse peut être négative, mais si c'est le cas, j'espère que vous vous faites aider par un professionnel de la sécurité. Les compétences en programmation (et le score StackOverflow) n'ont pas une forte corrélation avec le savoir-faire en matière de sécurité.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X