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

152

Tout d'abord, un peu de contexte: ce n'est un secret pour personne que j'implémente un système auth + auth pour CodeIgniter, et jusqu'à présent, je gagne (pour ainsi dire). Mais j'ai rencontré un défi assez non trivial (un défi que la plupart des bibliothèques d'authentification manquent entièrement, mais j'insiste pour le gérer correctement): comment gérer intelligemment les attaques par force brute à grande échelle, distribuées et à nom d'utilisateur variable .

Je connais toutes les astuces habituelles:

  1. Limiter le nombre de tentatives infructueuses par IP / hôte et refuser l'accès des contrevenants (par exemple Fail2Ban) - ce qui ne fonctionne plus depuis que les botnets sont devenus plus intelligents
  2. Combiner ce qui précède avec une liste noire des adresses IP / hôtes `` mauvaises '' connues (par exemple, DenyHosts) - qui repose sur des botnets tombant pour le n ° 1, ce qu'ils ne font de plus en plus
  3. Listes blanches IP / hôte combinées à l'authentification traditionnelle (malheureusement inutile avec les utilisateurs IP dynamiques et le taux de désabonnement élevé sur la plupart des sites Web)
  4. Définition d'une limite à l'échelle du site sur le nombre de tentatives infructueuses dans une période de N minute / heure, et limitation (suspension) de toutes les tentatives de connexion après cela pendant un certain nombre de minutes / heures (avec le problème que DoS vous attaque devient un jeu d'enfant de botnet)
  5. Signatures numériques obligatoires (certificats à clé publique) ou jetons matériels RSA pour tous les utilisateurs sans option de connexion / mot de passe (sans aucun doute une solution à toute épreuve, mais uniquement pratique pour les services fermés et dédiés)
  6. Enforced systèmes de mot de passe ultra-puissants (par exemple> 25 caractères non - sens avec des symboles - encore une fois, trop peu pratique pour les utilisateurs occasionnels)
  7. Et enfin, les CAPTCHA (qui pourraient fonctionner dans la plupart des cas, mais sont ennuyeux pour les utilisateurs et pratiquement inutiles contre un attaquant déterminé et ingénieux )

Maintenant, ce ne sont que des idées théoriquement réalisables. Il y a beaucoup d'idées idiotes qui font exploser le site (par exemple à des attaques DoS triviales). 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 légèrement plus sournois de continuer à fonctionner sous le radar

  • Il doit être automatisé. Si cela nécessite un opérateur humain pour vérifier chaque connexion ou surveiller une activité suspecte, cela ne fonctionnera pas dans un scénario réel

  • Il doit être faisable pour une utilisation Web grand public (c'est-à-dire un taux de désabonnement élevé, un volume élevé et un enregistrement ouvert pouvant être effectué par des non-programmeurs)

  • Cela ne peut pas entraver l'expérience utilisateur au point où les utilisateurs occasionnels seront ennuyés ou frustrés (et abandonneront potentiellement le site)

  • Cela ne peut pas impliquer des chatons, à moins qu'ils ne soient vraiment des chatons vraiment en sécurité

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

Alors - écoutons-le! Comment feriez-vous cela ? Connaissez-vous une meilleure pratique que je n'ai pas mentionnée (oh, dites-vous que oui)? J'avoue avoir ma propre idée (combinant les idées de 3 et 4), mais je vais laisser les vrais experts parler avant de me mettre dans l'embarras ;-)

Jens Roland
la source

Réponses:

69

Très bien, assez de calage; voici ce que j'ai trouvé jusqu'ici

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

Combiner les méthodes 3 et 4 de la publication d'origine dans une sorte de liste blanche `` floue '' ou dynamique, puis - et voici l'astuce - ne pas bloquer les adresses IP non sur liste blanche, juste les étrangler en enfer et revenir .

Notez que cette mesure vise uniquement à contrecarrer ce type d'attaque très spécifique. En pratique, bien sûr, cela fonctionnerait en combinaison avec d'autres approches de bonnes pratiques d'authentification: limitation du nom d'utilisateur fixe, limitation par IP, stratégie de mot de passe fort appliquée par code, connexion de cookie non limitée, hachage de tous les équivalents de mot de passe avant de les enregistrer, jamais en utilisant des questions de sécurité, etc.

Hypothèses sur le scénario d'attaque

Si un attaquant cible des noms d'utilisateur variables, notre limitation de nom d'utilisateur ne se déclenche pas. Si l'attaquant utilise un botnet ou a accès à une large plage d'adresses IP, notre limitation IP est impuissante. Si l'attaquant a pré-gratté notre liste d'utilisateurs (généralement possible sur les services Web d'enregistrement ouvert), nous ne pouvons pas détecter une attaque en cours basée sur le nombre d'erreurs «utilisateur non trouvé». Et si nous imposons une limitation restrictive à l'échelle du système (tous les noms d'utilisateur, toutes les adresses IP), une telle attaque affectera l'ensemble de notre site pendant la durée de l'attaque plus la période de limitation.

Nous devons donc faire autre chose.

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

Ce dont nous pouvons être assez sûrs, c'est que l'attaquant n'est pas capable de détecter et d'usurper dynamiquement les adresses IP de plusieurs milliers de nos utilisateurs (+). Ce qui rend la liste blanche possible la mise en . En d'autres termes: pour chaque utilisateur, nous stockons une liste des adresses IP (hachées) à partir desquelles l'utilisateur s'est (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 de l'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, toutes les boîtes de nos utilisateurs, soit la connexion elle-même - et dans ces cas, nous n'avons plus de problème `` d'authentification '', nous avons un véritable pull-the de la taille d'une franchise -plug FUBAR situation

La deuxième partie de la contre-mesure: la limitation à l'échelle du système des adresses IP non reconnues

Afin de faire fonctionner une liste blanche pour un service Web d'enregistrement ouvert, où les utilisateurs changent fréquemment d'ordinateur et / ou se connectent à partir d'adresses IP dynamiques, nous devons garder une `` porte de chat '' ouverte pour les utilisateurs se connectant à partir d'adresses 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 le moins dérangés possible .

Dans mon schéma, cela est réalisé en définissant un nombre maximum très restrictif de tentatives de connexion infructueuses par des adresses IP non approuvées sur, par exemple, une période de 3 heures (il peut être plus sage d'utiliser une période plus courte ou plus longue selon le type de service), et rendre cette restriction globale , c.-à-d. pour tous les comptes utilisateurs.

Même une force brute lente (1 à 2 minutes entre les tentatives) serait détectée et contrecarrée rapidement et efficacement en utilisant cette méthode. Bien sûr, une force brute vraiment lente pourrait encore rester inaperçue, mais des vitesses trop lentes vont à l'encontre du but 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 de chat '' se ferme pendant un moment, mais notre porte d'entrée reste ouverte aux utilisateurs légitimes se connectant 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 lors d'une attaque - c'est-à-dire. pendant que la limitation était activée - seraient des utilisateurs sans cookies de connexion persistants qui se connectaient à partir d'un emplacement inconnu ou avec une adresse IP dynamique. Ces utilisateurs seraient incapables de se connecter jusqu'à ce que la limitation se dissipe (ce qui pourrait potentiellement prendre un certain temps, si l'attaquant maintenait son botnet en cours d'exécution malgré la limitation).

Pour permettre à ce petit sous-ensemble d'utilisateurs de se faufiler à travers la porte du chat autrement scellée, même si les robots la martelaient encore, j'utiliserais un formulaire de connexion `` de sauvegarde '' 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", incluez un lien indiquant " Connexion de sauvegarde sécurisée - HUMAINS UNIQUEMENT ( bots: pas de mensonge ) ". Blague à part, quand ils cliquent sur ce lien, donnez-leur un formulaire de connexion authentifié reCAPTCHA qui contourne la limitation à l'échelle du site. De cette façon, S'ils sont humains ET connaissent le bon login + mot de passe (et sont capables de lire les CAPTCHA), ils ne se verront jamais refuser le service, même s'ils se connectent depuis un hôte inconnu et n'utilisent pas le cookie de connexion automatique.

Oh, et juste pour préciser: Comme je ne considère captchas pour être généralement le mal, l'option de connexion « backup » serait seulement apparaît alors que la limitation était actif .

Il est indéniable qu'une attaque soutenue comme celle-ci 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 petit sous-ensemble d'utilisateurs, à savoir les personnes qui n'utilisent pas le "Souviens-toi de moi" et se connecte alors qu'une attaque se produit ET ne se connecte à aucune de leurs adresses IP habituelles ET qui ne peut pas lire les CAPTCHA. Seuls ceux qui peuvent dire non à TOUS ces critères - en particulier les robots et les personnes handicapées vraiment malchanceuses - seront refusés lors d'une attaque de bot.

EDIT: En fait, j'ai pensé à un moyen de laisser passer même les utilisateurs confrontés à CAPTCHA pendant un `` verrouillage '': au lieu ou en complément de la connexion de sauvegarde CAPTCHA, offrez à l'utilisateur la possibilité d'avoir un usage unique , code de verrouillage spécifique à l'utilisateur envoyé à son e-mail, qu'il peut ensuite utiliser pour contourner la limitation. Cela dépasse définitivement mon seuil de `` gêne '', mais comme il n'est utilisé qu'en dernier recours pour un petit sous-ensemble d'utilisateurs, et comme il bat toujours le verrouillage de votre compte, ce serait acceptable.

(Notez également que rien de tout cela ne se produit si l'attaque est moins sophistiquée que la mauvaise version distribuée que j'ai décrite ici. Si l'attaque provient de quelques adresses IP ou ne touche que quelques noms d'utilisateurs, elle sera contrecarrée beaucoup plus tôt , et sans conséquences à l'échelle du site)


Donc, c'est la contre-mesure que je vais mettre en œuvre dans ma bibliothèque d'authentification, une fois que je suis convaincu que c'est sain et qu'il n'y a pas de solution beaucoup plus simple que j'ai 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 de faire de fausses hypothèses ou d'une logique désespérément imparfaite. Alors s'il vous plaît, tous les commentaires, critiques et améliorations, subtilités, etc. sont très appréciés.

Jens Roland
la source
1
Peut-être pourriez-vous générer un mot de passe `` spécial '' pour chaque utilisateur qui pourrait l'utiliser en mode verrouillage (et ils se connectent à partir d'une nouvelle adresse IP, etc.), ce mot de passe spécial étant suffisamment compliqué pour qu'il ne soit pas possible de force brute?
Douglas Leeder
1
Cela pourrait fonctionner, mais seulement si les utilisateurs se souviennent de ces mots de passe même s'ils ne les ont pas utilisés auparavant (ces types d'attaques ne sont pas monnaie courante, et aucun botmaster digne de ce nom ne prendrait la peine d'en garder un longtemps après avoir été étranglé). Le risque est trop grand pour qu'ils ne s'en souviennent tout simplement pas.
Jens Roland
1
Cependant, une méthode qui pourrait certainement fonctionner est de fournir un lien `` envoyez-moi un code de verrouillage '' à ces utilisateurs, leur permettant de recevoir un e-mail contenant un jeton à usage unique et spécifique à l'utilisateur qui leur permettrait de se connecter, en contournant le étranglement.
Jens Roland
1
@Abtin: Bonne idée, sauf que ce serait «entrer dans la course aux armements» - c'est-à-dire. commencer un «qui peut déjouer qui» avec les personnes qui créent des listes de mots de passe pour les attaques par dictionnaire. Je pense qu'une meilleure façon serait d'appliquer une politique de mot de passe forte afin qu'il n'y ait pas de mots de passe faibles
Jens Roland
1
@OrestisP .: Vous manquez le point de l'attaque distribuée - le nombre de tentatives non valides de chaque IP est minime, donc le blocage par IP ne peut pas fonctionner. En outre, la question décrit spécifiquement une attaque par force brute automatisée, donc 1) l'attaquant n'est pas un humain, mais plutôt un botnet de machines zombies (qui ne peuvent pas utiliser la connexion captcha); et 2) la nature de l'attaque par force brute nécessite un très grand nombre de tentatives de connexion pour assurer le succès, ce qui signifie qu'il n'est pas possible de confier la résolution du captcha à un atelier de transpiration quelque part (bien que possible si l'attaquant est bien financé et déterminé assez).
Jens Roland
17

Quelques étapes simples:

Mettez sur liste noire certains noms d'utilisateurs courants et utilisez-les comme pot de miel. Admin, invité, etc ... Ne laissez personne créer des comptes avec ces noms, donc 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 disposant d'un réel pouvoir sur le site dispose d'un mot de passe sécurisé. Exigez que les administrateurs / modérateurs 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 dire aux gens quand 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 quand ils se connectent comme "Quelqu'un a essayé de se connecter à votre compte à 4 h 20 mercredi bla bla. Cliquez ici si ce n'était pas vous." Il vous permet de conserver des statistiques sur les attaques. Vous pouvez intensifier les mesures de surveillance et de sécurité si vous constatez une augmentation soudaine des accès frauduleux.

patros
la source
Belles pensées. J'avais définitivement l'intention de mettre en œuvre une politique de mot de passe automatique qui varie dynamiquement avec le niveau de privilège de l'utilisateur. L'idée du pot de miel peut fonctionner pour certains types d'attaques, mais si l'attaque est distribuée, bloquer les adresses IP qui tombent pour elle ne sera pas efficace.
Jens Roland
En ce qui concerne le `` Heure de la dernière tentative de connexion '', c'est une bonne stratégie pour les utilisateurs expérimentés (ce qui, je parie, c'est pourquoi SO le fait), mais il a deux faiblesses: (a) cela ne résout pas le problème de l'intrusion, il rapporte seulement que cela a pu arriver, et (b), la plupart des utilisateurs ne s'en souviennent tout simplement pas / s'en soucient
Jens Roland
1
Oui, le pot de miel et les rapports des utilisateurs concernent davantage la collecte d'informations. Ils peuvent fournir des métriques précieuses pour vous permettre de savoir si / quand une attaque par force brute lente se produit.
patros
2
Pour le pot de miel, ne serait-il pas préférable de traiter un nom d'utilisateur inexistant comme suspect que d'utiliser simplement une liste fixe de noms d'utilisateurs connus et incorrects? Vous voudriez éviter de verrouiller les utilisateurs qui ont mal tapé leur nom d'utilisateur et n'ont pas remarqué la faute de frappe en réessayant leur mot de passe plusieurs fois, mais je pense toujours qu'il y a des façons dont cela pourrait être utile. Vous pouvez même éviter certains «faux positifs» en créant un filtre de floraison volumineux ou une structure de données similaire avec des variantes de noms d'utilisateur, de prénoms, de noms de famille, d'e-mails, etc. valides à mesure que les utilisateurs sont ajoutés.
R .. GitHub STOP AIDER ICE
11

Si je comprends correctement le MO des attaques par force brute, un ou plusieurs noms d'utilisateur sont essayés en continu.

Il y a deux suggestions que je ne pense pas avoir encore 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 la force brute, mais je ne sais pas combien de temps un délai d'une seconde empêcherait une attaque par dictionnaire. (dictionnaire de 10 000 mots == 10 000 secondes == environ 3 heures. Hum. Pas assez bien.)
  • au lieu d'un ralentissement à l'échelle du site, pourquoi pas une limitation de nom d'utilisateur. L'accélérateur devient de plus en plus dur à chaque mauvaise tentative (jusqu'à une limite, je suppose que l'utilisateur réel peut toujours se connecter)

Edit : En réponse aux commentaires sur un accélérateur de nom d'utilisateur: il s'agit d'un accélérateur spécifique au nom d'utilisateur sans égard à la source de l'attaque.

Si le nom d'utilisateur est limité, alors même une attaque de nom d'utilisateur coordonnée (multi IP, seule estimation par IP, même nom d'utilisateur) serait interceptée. Les noms d'utilisateur individuels sont protégés par la manette des gaz, même si les attaquants sont libres d'essayer un autre utilisateur / pass pendant le délai.

Du point de vue des attaquants, pendant le délai d'expiration, vous pourrez peut-être deviner pour la première fois 100 mots de passe et découvrir rapidement un mot de passe erroné par compte. Vous ne pourrez peut-être faire une estimation de 50 secondes que pour la même période.

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

Pour les attaquants, au mieux, ce sera le même effort pour casser 100 comptes que pour 1 compte, mais comme vous n'êtes pas en train de ralentir à l'échelle du site, vous pouvez accélérer assez rapidement.

Améliorations supplémentaires:

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

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

  • si vous contrôlez la configuration du mot de passe, alors montrer à l'utilisateur la force de son mot de passe l' encourage à en choisir un meilleur.
  • si vous contrôlez la page de connexion , après un petit nombre (disons 10) de suppositions d'un seul nom d'utilisateur, offrez un CAPTCHA.
Jamesh
la source
Un régulateur de nom d'utilisateur et un régulateur IP conviennent parfaitement aux attaques par nom d'utilisateur fixe ou IP fixe, et ils rendent les attaques par dictionnaire traditionnelles irréalisables. Mais si l'attaquant change constamment de nom d'utilisateur, il se faufilera sans déclencher un accélérateur de nom d'utilisateur. C'est ce que je veux contrer
Jens Roland
2
Merci pour la modification, jamesh. Nous parlons maintenant. J'adore l'idée du 408. Cependant, même avec une limitation stricte du nom d'utilisateur, un botnet attaquant plusieurs utilisateurs fonctionnerait toujours. Et vérifier les 5000 meilleurs mots de passe par rapport à un utilisateur a MOINS de chances de réussir que de vérifier LE premier mot de passe sur 5000 utilisateurs
Jens Roland
Rien de tel que le paradoxe de l'anniversaire. Dans un grand groupe, beaucoup utiliseront des mots de passe non sécurisés, et l'un d'entre eux utilisera probablement n'importe quel mot de passe populaire. Il y aura aussi un bon nombre de personnes comme moi qui ne seront pas prises par une telle attaque.
David Thornley
2
En fait, je devrai peut-être revérifier les calculs de ma déclaration précédente. Une fois que vous avez exclu les N mots de passe les plus courants, la probabilité que l'utilisateur ait le mot de passe # (N + 1) peut augmenter suffisamment pour égaliser la différence. Bien que la courbe soit probablement assez raide pour que ce ne soit pas le cas
Jens Roland
9

Il existe trois facteurs d'authentification:

  1. Un utilisateur sait quelque chose (c'est-à-dire 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 scan de la rétine)

Habituellement, les sites Web appliquent uniquement 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 autre chose» de l'authentification à deux facteurs. (IE: Un utilisateur connaît son mot de passe et le nom de jeune fille de sa mère.) Si vous le pouvez, un moyen d'ajouter un deuxième facteur d'authentification n'est pas trop difficile.

Si vous pouvez générer environ 256 caractères aléatoires, vous pouvez 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 modifie son mot de passe, donnez-lui le tableau et dites-lui de l'imprimer et de l'enregistrer.

La difficulté avec cette approche est que lorsqu'un utilisateur oublie son mot de passe, comme il le fera, vous ne pouvez pas simplement proposer le standard "Répondez à cette question et entrez un nouveau mot de passe", car il est également vulnérable à la force brute. En outre, vous ne pouvez pas le réinitialiser et leur envoyer un nouveau courrier électronique, car leur courrier électronique pourrait également être compromis. (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 lors de son inscription, et lorsqu'il tente de se connecter, demandez-lui de choisir son image parmi 8 ou 15 (ou plus) au hasard. Donc, si un utilisateur télécharge une photo de son chaton, théoriquement, il sait exactement quelle image est la sienne parmi tous les autres chatons (ou fleurs ou autre). La seule véritable vulnérabilité de cette approche est l'attaque de l'homme du milieu.

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 chat, choisissez une clé dans ce tableau) lorsqu'ils se connectent à partir d'une adresse qu'ils n'ont pas. pas avant. De même, comme GMail, permet à l'utilisateur de voir où il s'est connecté récemment.

Modifier, nouvelle idée:

Une autre façon de valider les tentatives de connexion est de vérifier si l'utilisateur vient ou non de votre page de connexion. Vous ne pouvez pas vérifier les référents, car ils peuvent être facilement truqués. Ce dont vous avez besoin est de définir une clé dans la variable _SESSION lorsque l'utilisateur affiche la page de connexion, puis de vérifier que cette clé existe lorsqu'il soumet ses informations de connexion. Si le bot ne soumet pas à partir de la page de connexion, il ne pourra pas se connecter. Vous pouvez également faciliter cela 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. Ou, vous pouvez diviser le formulaire en deux soumissions différentes (c'est-à-dire que l'utilisateur entre son nom d'utilisateur, soumet, puis sur une nouvelle page entre 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 adresse IP et de l'heure à laquelle elle a été soumise.

davethegr8
la source
Je suis sûr qu'il y a plus, mais si l'idée de SiteKey est exactement ce que vous avez mentionné, un attaquant n'a pas besoin d'être un MITM, il peut simplement exécuter deux ou trois tentatives de connexion pour cet utilisateur et choisir l'image qui se répète parmi les aléatoires. Même si l'ensemble de 8 à 15 images est statique pour l'utilisateur X,
Jens Roland
(suite) il ne serait probablement pas trop difficile de choisir la bonne, car les gens ont tendance à choisir des types d'images prévisibles (même des images de leurs propres albums Flickr!)
Jens Roland
2
Ouais, j'ai pensé au point que tu as soulevé la nuit dernière après mon retour à la maison. Je pense que le moyen de résoudre ce problème est le suivant: lorsqu'un utilisateur se connecte et fournit un mot de passe correct, affichez son image et un certain nombre d'autres aléatoires. Quand ils ne fournissent pas le mot de passe correct, montrez un certain nombre d'aléatoires
davethegr8
1
images + 1, qui peuvent ou non inclure leur propre image. Aussi, j'ai eu une autre idée, voir l'édition dans le post. Mais oui, ces idées sont un peu difficiles / compliquées.
davethegr8
1
Cela «pourrait» fonctionner, mais je vois quelques problèmes. Que se passe-t-il si le propriétaire de la photo supprime l'image? Comment pouvez-vous être sûr que les images renvoyées ne seront pas offensantes pour votre utilisateur? Comment un utilisateur se souvient-il de l'endroit où il a cliqué? (Il semble difficile d'oublier)
davethegr8
7

J'avais déjà répondu à une question très similaire sur Comment puis-je limiter les tentatives de connexion des utilisateurs en PHP . Je vais réitérer la solution proposée ici car je pense que beaucoup d'entre vous trouveront cela informatif et utile de voir du code réel. Veuillez garder à l'esprit que l'utilisation d'un CAPTCHA n'est peut-être pas la meilleure solution en raison des algorithmes de plus en plus précis utilisés de nos jours dans les busters CAPTCHA:

Vous ne pouvez pas simplement empêcher les attaques DoS en chaînant la limitation à une seule adresse IP ou nom d'utilisateur. Enfer, vous ne pouvez même pas vraiment empêcher les tentatives de connexion rapides en utilisant cette méthode.

Pourquoi? Parce que l'attaque peut s'étendre sur plusieurs adresses IP et comptes d'utilisateurs dans le but de contourner vos tentatives de limitation.

J'ai vu ailleurs que, idéalement, vous devriez suivre toutes les tentatives de connexion infructueuses sur le site et les associer à un horodatage, peut-être:

CREATE TABLE failed_logins(
    id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(16) NOT NULL,
    ip_address INT(11) UNSIGNED NOT NULL,
    attempted DATETIME NOT NULL
) engine=InnoDB charset=UTF8;

Décidez de certains retards en fonction du nombre total d'échecs de connexion dans un laps de temps donné. Vous devez vous baser sur des données statistiques extraites de votre failed_loginstableau, car elles changeront au fil du temps en fonction du nombre d'utilisateurs et du nombre d'entre eux pouvant rappeler (et saisir) leur mot de passe.


10 failed attempts = 1 second
20 failed attempts = 2 seconds
30 failed attempts = reCaptcha

Interrogez le tableau à chaque tentative de connexion échouée pour trouver le nombre d'échecs de connexion pour une période donnée, disons 15 minutes:


SELECT COUNT(1) AS failed FROM failed_logins WHERE attempted > DATE_SUB(NOW(), INTERVAL 15 minute);

Si le nombre de tentatives au cours de la période donnée est supérieur à votre limite, appliquez la limitation ou forcez tous les utilisateurs à utiliser un captcha (c'est-à-dire reCaptcha) jusqu'à ce que le nombre de tentatives infructueuses sur la période donnée soit inférieur au seuil.

// array of throttling
$throttle = array(10 => 1, 20 => 2, 30 => 'recaptcha');

// assume query result of $sql is stored in $row
$sql = 'SELECT MAX(attempted) AS attempted FROM failed_logins';
$latest_attempt = (int) date('U', strtotime($row['attempted']));
// get the number of failed attempts
$sql = 'SELECT COUNT(1) AS failed FROM failed_logins WHERE attempted > DATE_SUB(NOW(), INTERVAL 15 minute)';
// assume the number of failed attempts was stored in $failed_attempts
krsort($throttle);
foreach ($throttle as $attempts => $delay) {
    if ($failed_attempts > $attempts) {
        // we need to throttle based on delay
        if (is_numeric($delay)) {
            $remaining_delay = time() - $latest_attempt - $delay;
            // output remaining delay
            echo 'You must wait ' . $remaining_delay . ' seconds before your next login attempt';
        } else {
            // code to display recaptcha on login form goes here
        }
        break;
    }
}

L'utilisation de reCaptcha à un certain seuil garantirait qu'une attaque provenant de plusieurs fronts serait minimisée et que les utilisateurs normaux du site ne subiraient pas de retard significatif pour les tentatives de connexion échouées légitimes. Je ne peux pas garantir la prévention, car il a déjà été développé sur le fait que les CAPTCHA peuvent être détruits. Il existe des solutions alternatives, peut-être une variante de "Nommez cet animal", qui pourrait très bien fonctionner comme substitut.

Corey Ballou
la source
6

Je dois vous demander si vous avez fait une analyse coûts-avantages de ce problème; on dirait que vous essayez de vous protéger d'un attaquant qui a suffisamment de présence sur le Web pour deviner un certain nombre de mots de passe, en envoyant peut-être 3 à 5 requêtes par IP (depuis que vous avez rejeté la limitation IP). Combien (en gros) ce genre d'attaque coûterait-il? Est-ce plus cher que la valeur des comptes que vous essayez de protéger? Combien de botnets gargantuesques veulent ce que vous avez?

La réponse est peut-être non - mais si c'est le cas, j'espère que vous obtenez l'aide d'un professionnel de la sécurité quelconque; les compétences en programmation (et le score StackOverflow) ne sont pas fortement corrélés au savoir-faire en matière de sécurité.

ojrac
la source
(Vous voulez dire si la réponse est «non» - c'est-à-dire que le coût d'une attaque de botnet n'est PAS trop élevé par rapport aux comptes)
Jens Roland
Mais de toute façon, vous soulevez un point important. Pour mes propres utilisations, je ne m'attends pas à ce qu'un opérateur de botnet s'en soucie le moins du monde, mais je publie le code source pour tous ceux qui souhaitent une sécurité décente pour leur application Web, et je ne peux pas savoir ce que les autres pourraient essayer. protéger, ou qui sont leurs ennemis
Jens Roland
Quoi qu'il en soit, il ne gardera pas les secrets nationaux (les systèmes officiels ont besoin d'une certification spéciale, et je suis à peu près sûr que rien construit sur PHP ne peut être qualifié), mais toutes les applications Web ont besoin d'une authentification sécurisée, donc si je publie ceci, c'est ' Je serais incroyablement irresponsable de ne pas utiliser les meilleures pratiques partout où je peux
Jens Roland
1
Ma réponse courte est donc: je construis ceci parce que 99,9% des sites Web et des applications ont une sécurité effroyable (même dans la cour des grands: AOL, Twitter, Myspace ont tous été compromis auparavant), et dans la plupart des cas parce qu'ils sont en utilisant des bibliothèques d'authentification de mauvaise qualité.
Jens Roland
Lisez également l'article «To Catch A Predator» de Niels Provos et al. extrait de la procédure USENIX 2008 (lien: usenix.org/events/sec08/tech/small.html ) C'est une révélation : 2 mois, un pot de miel: 368 000 attaques depuis près de 30 000 IP distinctes, provenant de plus de 5 600 botnets!
Jens Roland
5

Pour résumer le schéma de Jens en un pseudo diagramme / base de règles de transition d'état:

  1. utilisateur + mot de passe -> entrée
  2. utilisateur +! mot de passe -> refusé
  3. user + known_IP (user) -> porte d'entrée, // never throttle
  4. user + unknown_IP (utilisateur) -> catflap
  5. (#denied> n) via catflaps (site) -> throttle catflaps (site) // slow the bots
  6. catflap + throttle + password + captcha -> entrée // humans still welcome
  7. catflap + throttle + mot de passe +! captcha -> refusé // a correct guess from a bot

Observations:

  • N'étranglez jamais la porte d'entrée. La police d'État d'Elbonian a votre ordinateur chez vous, mais ne peut pas vous interroger. La force brute est une approche viable à partir de votre ordinateur.
  • Si vous fournissez un "Mot de passe oublié?" lien, alors votre compte de messagerie devient une partie de la surface d'attaque.

Ces observations couvrent un type d'attaque différent de ceux que vous essayez de contrer.

Jamesh
la source
Absolument, le compte de messagerie fait partie de la surface d'attaque. J'ai un ensemble d'hypothèses de limite supérieure sur la sécurité que ma stratégie fournira, et la limite la plus basse est la propre sécurité de messagerie de l'utilisateur. Si un attaquant enfreint le courrier électronique d'un utilisateur, tous les paris sont désactivés.
Jens Roland
De plus, je pense que votre diagramme de transition d'état a besoin de quelques détails: # 3 et # 4 devraient inclure un mot de passe; # 1 et # 2 devraient inclure known_IP (utilisateur) car une connexion a toujours une adresse IP connue ou inconnue; et # 6 est `` entrée malgré l'accélérateur ''
Jens Roland
4

On dirait que vous essayez de vous défendre contre la force brute distribuée lentement . Vous ne pouvez pas faire grand-chose à ce sujet. Nous utilisons une PKI et aucune connexion par mot de passe. Cela aide, mais si vos clients ont l'occasion de travailler sur des postes de travail de temps en temps, ce n'est pas très applicable.

Björn Raupach
la source
En fait, force brute aussi rapide. J'espérais être un peu indulgent avec la force brute utilisateur fixe (limitation de seulement 20 secondes), mais sur un site avec 50k utilisateurs, cela rendrait possible la force brute rapide à utilisateur variable (en supposant plus de 20 secondes pour parcourir les utilisateurs). Et ça, comme on dit, serait nul ..
Jens Roland
Eh bien, la force brute rapide d'un seul hôte utilise iptables ou tout autre pare-feu que vous utilisez.
Björn Raupach le
Je faisais référence à la force brute rapide distribuée. C'est rare mais c'est potentiellement très méchant
Jens Roland
3

Avertissement: je travaille pour une entreprise à deux facteurs, mais je ne suis pas là pour la brancher. Voici quelques observations.

Les cookies peuvent être volés avec XSS et les vulns du navigateur. Les utilisateurs changent généralement de navigateur ou effacent leurs cookies.

Les adresses IP source sont simultanément variables dynamiquement et usurpables.

Le captcha est utile, mais n'authentifie pas un humain spécifique.

Plusieurs méthodes peuvent être combinées avec succès, mais le bon goût est certainement de mise.

La complexité du mot de passe est bonne, tout ce qui est basé sur un mot de passe dépend essentiellement de mots de passe ayant une entropie suffisante. À mon humble avis, un mot de passe fort écrit dans un emplacement physique sécurisé vaut mieux qu'un mot de passe faible en mémoire. Les gens savent comment évaluer la sécurité des documents papier beaucoup mieux qu'ils ne savent comment comprendre l'entropie effective du nom de leur chien lorsqu'il est utilisé comme mot de passe pour trois sites Web différents. Envisagez de donner aux utilisateurs la possibilité d'imprimer une grande ou une petite page remplie de codes d'accès à usage unique.

Les questions de sécurité comme "quelle était votre mascotte de lycée" sont pour la plupart une autre forme moche de "quelque chose que vous savez", la plupart d'entre elles sont facilement devinables ou carrément dans le domaine public.

Comme vous l'avez noté, la limitation des tentatives de connexion infructueuses est un compromis entre la prévention des attaques par force brute et la facilité de DoSing d'un compte. Les politiques de verrouillage agressives peuvent refléter un manque de confiance dans l'entropie du mot de passe.

Personnellement, je ne vois pas l'avantage d'appliquer l'expiration du mot de passe sur un site Web de toute façon. L'attaquant obtient votre mot de passe une fois, il peut le modifier ensuite et se conformer à cette politique aussi facilement que vous le pouvez. L'un des avantages est peut-être que l'utilisateur peut le remarquer plus tôt si l'attaquant modifie le mot de passe du compte. Ce serait encore mieux si l'utilisateur était averti d'une manière ou d'une autre avant que l'attaquant n'ait accès. Des messages tels que "N tentatives infructueuses depuis la dernière connexion" sont utiles à cet égard.

La meilleure sécurité vient d'un deuxième facteur d'authentification qui est hors bande par rapport au premier. Comme vous l'avez dit, les jetons matériels dans le "quelque chose que vous avez" sont excellents, mais beaucoup (pas tous) ont de réels frais d'administration associés à leur distribution. Je ne connais aucune solution biométrique «quelque chose que vous êtes» pour les sites Web. Certaines solutions à deux facteurs fonctionnent avec des fournisseurs openid, d'autres ont des SDK PHP / Perl / Python.

Marsh Ray
la source
Tous d'excellents points - je ne pourrais pas être plus d'accord. Le point sur l'insécurité des cookies est très valable, mais sans un deuxième facteur de jetons physiques ou de mots de passe à usage unique (distribués sur une ligne sécurisée), vous ne pouvez vraiment pas vous protéger contre un point de terminaison vulnérable. Si la boîte / navigateur de l'utilisateur est compromis, ses identifiants le sont aussi.
Jens Roland
1

Ma plus haute recommandation est simplement de vous assurer que vous tenez les utilisateurs informés des mauvaises tentatives de connexion à leurs comptes - Les utilisateurs prendront probablement la force de leur mot de passe beaucoup plus au sérieux s'ils se voient présenter des preuves que quelqu'un essaie réellement d'accéder à leur compte. .

J'ai en fait attrapé quelqu'un qui a piraté le compte myspace de mon frère parce qu'il avait essayé d'accéder au compte gmail que j'avais configuré pour lui et avait utilisé la fonction `` réinitialiser mon mot de passe par e-mail '' ... qui est allée dans ma boîte de réception.

nvuono
la source
1
  1. Pourquoi ne pas exiger un mot de passe à usage unique avant d'entrer leur mot de passe normal? Cela rendrait très évident que quelqu'un attaquait avant d'avoir de nombreuses occasions de deviner le mot de passe principal?

  2. Gardez un décompte / taux global des échecs de connexion - c'est l'indicateur d'une attaque - pendant une attaque, soyez plus strict sur les échecs de connexion, par exemple interdire plus rapidement les adresses IP.

Douglas Leeder
la source
1) Comment implémenteriez-vous un mot de passe à usage unique sur une ligne non sécurisée et non authentifiée? En d'autres termes, quand l'utilisateur définit-il ces mots de passe à usage unique? 2) Oui, c'est l'essentiel du n ° 4 sur ma liste, la limite du site sur les tentatives infructueuses. L'inconvénient est l'opportunité DoS qu'il ouvre.
Jens Roland
0

Je ne pense pas qu'il existe une réponse parfaite, mais je serais enclin à l'aborder en essayant de confondre les robots si une attaque est détectée.

Du haut de mon esprit:

Passez à un autre écran de connexion. Il comporte plusieurs espaces vides de nom d'utilisateur et de mot de passe qui apparaissent vraiment, mais un seul d'entre eux est au bon endroit. Les noms de champ sont RANDOM - une clé de session est envoyée avec l'écran de connexion, le serveur peut alors découvrir quels champs sont quoi. Réussir ou échouer, il est ensuite rejeté afin que vous ne puissiez pas essayer une attaque de relecture - si vous rejetez le mot de passe, ils obtiennent un nouvel ID de session.

Tout formulaire soumis avec des données dans un champ incorrect est supposé provenir d'un robot - la connexion échoue, point final et cette adresse IP est limitée. Assurez-vous que les noms de champs aléatoires ne correspondent jamais aux noms de champs légitimes afin que quelqu'un utilisant quelque chose qui se souvient des mots de passe ne soit pas trompeur.

Ensuite, que diriez-vous d'un autre type de captcha: vous avez une série de questions qui ne poseront aucun problème à un humain. Cependant, ils ne sont PAS aléatoires. Lorsque l'attaque commence, tout le monde reçoit la question n ° 1. Après une heure, la question n ° 1 est rejetée, pour ne plus jamais être utilisée et tout le monde reçoit la question n ° 2 et ainsi de suite.

L'attaquant ne peut pas sonder pour télécharger la base de données à mettre dans son robot en raison de la nature jetable des questions. Il doit envoyer de nouvelles instructions à son botnet dans l'heure pour avoir la possibilité de faire quoi que ce soit.

Loren Pechtel
la source
L'écran de connexion alternatif semble confondre davantage les humains que les machines, franchement. Nous supposons bien sûr que l'attaquant aurait vérifié au préalable nos mesures de sécurité. Il aurait pu facilement modifier son grattoir pour trouver les champs correctement placés.
Jens Roland
Les questions de vérification humaine ont déjà été faites et ce n'est pas très efficace. Pour un opérateur de botnet humain, il serait tout à fait possible de répondre à une question par heure (après quoi la nouvelle réponse se propagerait aux bots) lors d'une attaque.
Jens Roland
Vous manquez le point. L'attaquant ne peut pas vérifier à l'avance car il n'affiche les défenses supplémentaires que lorsqu'une attaque se présente.
Loren Pechtel le
Bien sûr, l'humain pouvait voir quelle était la question - mais il doit le communiquer à tous ses robots. C'est un chemin de communication qui facilite la suppression du botnet.
Loren Pechtel le
Je ne pense pas manquer le point. Je ne veux pas dire qu'il aurait lancé une attaque auparavant pour vérifier nos mesures de sécurité, je veux dire qu'il aurait lu ce fil et vérifié le code source (ouvert) pour vérifier les weknesses :)
Jens Roland
0

Étant donné que plusieurs personnes ont inclus CAPTCHA comme mécanisme humain de secours, j'ajoute une question et un fil de discussion StackOverflow sur l'efficacité de CAPTCHA.

ReCaptcha a-t-il été craqué / piraté / OCR'd / vaincu / cassé?

L'utilisation de CAPTCHA ne limite pas les améliorations de votre limitation et d'autres suggestions, mais je pense que le nombre de réponses qui incluent CAPTCHA comme solution de secours devrait prendre en compte les méthodes humaines disponibles pour les personnes qui cherchent à briser la sécurité.

Matthew Glidden
la source
0

Vous pouvez également ralentir en fonction de la force du mot de passe d'un utilisateur.

Lorsqu'un utilisateur enregistre ou modifie son mot de passe, vous calculez une cote de force pour son mot de passe, disons entre 1 et 10.

Quelque chose comme "mot de passe" donne un 1 alors que "c6eqapRepe7et * Awr @ ch" peut obtenir un 9 ou un 10 et plus le score est élevé, plus il faut de temps pour que la limitation intervienne.

Joseph W
la source
2
Je comprends l'idée, mais cela divulguerait indirectement des informations sur le mot de passe, permettant à un attaquant de savoir si un mot de passe vaut la peine d'être piraté ou non. Cela peut sembler un peu théorique, mais de nombreux utilisateurs réutilisent les mots de passe, donc si je veux pénétrer par effraction dans Strong_Throttling_Website.com, je peux simplement attaquer les comptes (privilégiés) au hasard jusqu'à ce que je trouve un utilisateur, 'Freddy', qui a un mot de passe faible (c.-à-d. early throttling), puis accédez à Less_Secure_Website.edu et effectuez une attaque par dictionnaire facile sur le compte de Freddy. C'est un peu compliqué, mais certainement faisable dans la pratique.
Jens Roland
0

La première réponse que j'ai généralement entendue en posant cette question est de changer de port, mais oubliez cela et désactivez simplement IPv4. Si vous n'autorisez que les clients des réseaux IPv6, vous ne priez plus pour une simple analyse du réseau et les attaquants auront recours à des recherches DNS. Ne courez pas sur la même adresse que votre Apache (AAAA) / Sendmail (MX-> AAAA) / ce que vous avez donné à tout le monde (AAAA). Assurez-vous que votre zone ne peut pas être xferd, attendez que vous autorisiez le téléchargement de votre zone par quelqu'un?

Si les bots trouvent de nouveaux noms d'hôte dans la configuration de votre serveur, ajoutez simplement du charabia à vos noms d'hôte et changez votre adresse. Laissez les anciens noms et même configurez ** les noms de pots de miel pour que le bot net expire.

** Testez vos enregistrements inversés (PTR) (sous ip6.arpa.) Pour voir s'ils peuvent être utilisés pour zéro dans les / 4 qui ont des enregistrements VS / 4 qui n'en ont pas. IE Typiquement, ip6.arpa aurait ~ 32 "." Dans une adresse mais essayer avec les derniers manquants pourrait échapper aux blocs réseau qui ont des enregistrements VS d'autres qui n'en ont pas. Si vous allez plus loin, il devient possible de sauter de grandes parties de l'espace d'adressage.

Dans le pire des cas, les utilisateurs devront configurer un tunnel IPv6, ce n'est pas comme s'ils devaient aller jusqu'à VPNing dans une DMZ ... Bien que l'on se demande pourquoi ce n'est pas la première option.

Kerberos est également cool, mais IMHO LDAP souffle (Qu'est-ce qui ne va pas techniquement avec NISPlus? J'ai lu que Sun avait décidé que les utilisateurs voulaient LDAP et à cause de cela, ils ont abandonné NIS +). Kerberos fonctionne bien sans LDAP ou NIS, il suffit de gérer les utilisateurs hôte par hôte. L'utilisation de Kerberos vous offre une PKI facile à utiliser, sinon automatisée.

Mike Mestnik
la source
0

Un peu tard ici mais je pensais, en supposant un cas difficile - l'attaquant utilise beaucoup d'adresses IP aléatoires, des noms d'utilisateurs aléatoires et un mot de passe aléatoire sélectionné, par exemple, dans une liste des 10000 plus populaires.

Une chose que vous pouvez faire, surtout si le système semble attaqué en ce qu'il y a beaucoup de mauvaises tentatives de mot de passe sur le système et surtout si le mot de passe est à faible entropie, c'est de poser une question secondaire comme quels sont les prénoms de vos parents, par exemple . Si un attaquant frappe un million de comptes en essayant le mot de passe 'password1', il y a de fortes chances qu'il en obtienne beaucoup, mais ses chances d'obtenir également les bons noms réduiraient considérablement les succès.

Tim 333
la source