尝试暴力破解平均密码/非侵入性但有意义的限制的次数?

发布于 2024-08-24 12:55:17 字数 1210 浏览 2 评论 0 原文

关于通过应用限制来防止暴力破解 Web 服务的密码,SO 有几个有用的答案。不过,我找不到任何好的数字,而且我在这方面缺乏专业知识,所以问题是:

通常需要多少次尝试才能暴力破解 6 个或更多字符的平均密码(没有其他可能有帮助的知识) ,但考虑到密码可能容易受到字典攻击)并基于此,在不破坏用户体验的情况下,应用于限制算法的有意义的限制是什么?

这是我当前的方案:

  • 登录表单使用随机数,因此攻击者必须等待完整的请求周期完成才能获取登录尝试的结果并检索新令牌。
  • 我允许每个 IP 检索登录表单 50 次,两次请求之间的时间间隔不到一分钟,之后该 IP 将被阻止 1 分钟。这一分钟内的任何新尝试都将重新开始超时。
  • 每次提取尝试次数 / 5 的登录页面时都会应用 sleep ,因此在 5 个请求之后,请求之间的时间间隔不到一分钟,则需要 > 1 秒获取表单,10 次请求后 > 2 秒等。
  • 此外,我只允许每个用户帐户 100 次失败的登录尝试,两次尝试之间的间隔为 2 小时,之后该帐户将被阻止 2 小时。
  • 为了避免频繁的 DoS帐户、IP 可以被列入白名单(无限制)或黑名单(完全忽略任何登录尝试)。

根据迄今为止的答案,我已将其调整为如下工作:

  • 检索登录表单的速度在每个 IP 基础上逐渐减慢。每个新请求都会休眠 # 个请求/2 秒。 10 分钟无登录活动后,计数器将重置。
  • 我为每个 IP 保留登录尝试的 FIFO 堆栈。如果一个IP在2小时内登录失败30次,则该IP被暂停。我还保留了每个 IP 的暂停次数列表,暂停时间的计算方式为 2 ^(暂停次数 + 1)小时。这应该会导致不断违规的 IP 迅速被列入事实上的黑名单。
  • 此外,如果一个帐户在一天内登录失败 20 次,该帐户将被暂停 2 小时。我还不太确定这项措施,因为这意味着帐户很容易受到 DoS 攻击。不过,如果没有大规模的分布式僵尸网络,违规 IP 被列入事实上的黑名单的速度应该比帐户被永久拒绝服务的速度还要快。这也是保护帐户的一种非常有效的措施。

我认为这些限制不应该伤害普通用户,即使是那些经常忘记密码并尝试多次登录的用户。考虑到服务的平均大小,IP 限制也应该适用于经过大量 NAT 处理的用户。有人可以通过一些扎实的数学来证明这是有效还是低效吗? :)

There are several useful answers on SO regarding prevention of brute forcing a password of a web service by applying throttling. I couldn't find any good numbers though and I have little expertise in this area, so the question is:

How many attempts does it usually take to brute-force an average password of 6 or more characters (with no additional knowledge that may help, but taking into account that passwords are probably prone to dictionary attacks) and based on that, what are meaningful limits to apply to the throttling algorithm without disrupting the user experience?

This is my current scheme:

  • The login form uses a nonce, so the attacker has to wait for a complete request cycle to complete to both get the result of the login attempt and retrieve a new token.
  • I allow the login form to be retrieved 50 times per IP with less than a minute between requests, after that the IP will be blocked for 1 minute. Any new attempts within this one minute will restart the timeout.
  • There's a sleep applied for each fetching of the login page of # of attempts / 5, so after 5 requests with less than a minute between requests it'll take > 1 second to fetch the form, after 10 requests > 2 seconds, etc.
  • Additionally, I'm only allowing 100 failed login attempts per user account with 2 hours between attempts, after that the account is blocked for 2 hours.
  • To avoid frequent DoS'ing of accounts, IPs can be whitelisted (no limits applied) or blacklisted (any login attempt ignored completely).

Based on the answers so far, I have tweaked it to work like this:

  • Retrieving the login form is progressively slowed down on a per IP basis. Each new request is slept for # of requests / 2 seconds. The counter is reset after 10 minutes of no login activity.
  • I'm keeping a FIFO stack of login attempts for each IP. If an IP fails to log in 30 times within 2 hours, it's suspended. I'm also keeping a list of number of suspensions per IP, and the suspension time is calculated as 2 ^ (# of suspensions + 1) hours. This should lead to a rapid de facto blacklisting of continually offending IPs.
  • Additionally, if an account failed to log in 20 times within one day it's being suspended for 2 hours. I'm not too sure about this measure yet, since this means accounts can be DoS'd quite easily. Short of a massive distributed botnet though, offending IPs should become de facto blacklisted faster than an account can be permanently DoS'd. It's also quite an effective measure to protect an account.

I think these limits should not harm normal users, even ones that regularly forget their password and try to log in several times. The IP limits should also work okay with heavily NAT'ed users, given the average size of the service. Can somebody prove this to be efficient or inefficient with some solid math? :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

記柔刀 2024-08-31 12:55:17

你有一些很好的控制,但你真的应该加强它。普通用户登录失败的次数不应超过五次。如果他这样做,请向他显示验证码。

请记住,在任何情况下都不应锁定帐户。这称为帐户锁定漏洞。这允许任意用户从服务中注销其他用户(DOS,拒绝服务)。

我已经多次解决过登录限制问题,我喜欢的是在数据库中创建一个包含失败尝试和上次失败尝试日期的字段。每当某人(任何人)无法登录帐户 X 时,您就会增加 X 失败尝试的值并更新上次失败尝试的日期。如果失败的尝试计数超过 Y(例如,五次),则显示特定用户的验证码。因此,您不会有一个巨大的被禁止 IP 数据库来限制登录表单,而是每个用户只有两个字段。由于僵尸网络和代理(合法和非法)的存在,基于 IP 的禁止/限制也没有什么意义。当 IPv6 流行起来时,我想你会更加失败。根据目标帐户进行限制更有意义。因此,当您的帐户 X 成为僵尸网络的目标时,登录表单将受到验证码的限制。这里明显的缺点是,如果您的验证码失败……您的登录限制也会失败。

因此,本质上是这样的:

  • 有人未能登录帐户 X - 增加失败的尝试字段。
  • 如果失败尝试超过5次,并且最后一次失败尝试发生在一小时前,则该帐户似乎受到攻击,请显示验证码。
  • 另一方面,如果最后一次失败的尝试发生在一天多前,则攻击似乎已经结束,降低你的护盾并且不需要验证码。

它基本上是一个盾牌,当针对特定帐户的大规模有针对性的攻击时,它就会打开。这种方法的好处是,即使我在世界各地拥有一个 PC 群也没关系 - 我不能暴力破解单个帐户,因为它是基于帐户的。

这样做的两个坏处是,如果验证码失败,您将一无所有。当然,您也可以通过设置其他保护措施来改善这种情况。第二个问题是,如果我有一个僵尸网络,我可以为每个帐户使用一台电脑,然后很可能在一百万台计算机网络中我至少破解了一个帐户,但这种方法仅适用于非目标攻击。

我希望这能给你一些想法。

You have a couple of good controls there, but you really should tighten it more. A regular user shouldn't fail to log in more than five times. If he does, show him a CAPTCHA.

Remember that under no circumstances should you lock the account. It's called an account lockout vulnerability. This allows an arbitrary user to log out other users from the service (DOS, denial of service).

I've approached this problem of login throttling many times and the one I like is that you create a field of failed attempts and the last failed attempt date in your database. Whenever someone (anyone) fails to log into account X, you increase the value of X's failed attempts and update the last failed attempt date. If the failed attempt count exceeds Y (for example, five), then show a CAPTCHA for the specific user. So, you won't have a huge database of banned IPs to throttle the login form, instead you have just two more fields per user. It also makes little sense to ban/throttle based on IPs, because of botnets and proxies (both legal and illegal ones). When IPv6 comes out in fashion, you will be more doomed I presume. It makes much more sense to throttle based on targeted accounts. So, when your account X is being targeted by a botnet, the login form will be throttled with a CAPTCHA. The obvious drawback here is that if your CAPTCHA fails... so does your login throttling.

So, in the essence it goes like this:

  • Someone failed to log into account X - increase the failed attempts field.
  • If there are more than 5 failed attempts, and the last failed attempt happened one hour ago, it's seems that the account is under attack, show the CAPTCHA.
  • On the other hand, if the last failed attempt occured more than a day ago, it seems that the attack has ended, lower your shields and don't require CAPTCHA.

It's basically a shield that turns on when there's a massive targeted attack against particular accounts. The good thing about this kind of approach is that it won't matter if I own a farm of PCs across the world - I can't brute force a single account because it's account based.

The two bad things about this is that if the CAPTCHA fails you have nothing left. You could of course improve this situation by placing other protections, too. The second problem is that if I had a bot-net, I could use one PC per one account, and then it's likely that with a million computer network I crack at least one account, but this approach works only in non-targeted attacks.

I hope this gave you some thoughts.

梦亿 2024-08-31 12:55:17

从问题来看,他们尝试密码的最快速度是每分钟 50 个。在此基础上并使用随机 6 位密码:

当然,字典攻击会快得多,但我不这么认为没有这方面的数字。

编辑:我试图链接谷歌计算器结果来支持这一点,但 ^ 似乎搞乱了这里的链接。

编辑2:

字典攻击(来自 http://www.outpost9.com/files/WordLists.html< /a>):

  • 所有列出的字词 (75,000):~1 天< /a>
  • 816 个常用密码列表:~16 分钟
  • 非常长的单词列表:~12 天(我查看了我猜它包含了大多数非技术人员的密码)

最后一个很可怕,但 12 天仍然是很长的时间。如果您真的很担心,您可以跟踪每个不正确的密码,直到用户获得正确的密码,然后如果列表超过 100 次不同的尝试,只需禁止该 IP 地址并向用户发送电子邮件即可。

From the question it sounds like the fastest they could possibly try passwords is 50 per minute. Based on that and using random 6 digit passwords:

  • all lower case: 26^6 = 308,915,776 possible passwords = worst case 12 years, 6 years on average
  • lower case and numbers: 36^6 = 82 years max, 41 years on average

Of course, dictionary attacks would be much faster, but I don't have the numbers for that.

EDIT: I tried to link Google calculator results backing this up, but ^ seems to mess up links on here.

EDIT2:

Dictionary attacks (from http://www.outpost9.com/files/WordLists.html):

  • all listed words (75,000): ~1 day
  • list of 816 common passwords: ~16 minutes
  • really long word list: ~12 days (I looked at this and I'm guessing it contains most non-technical people's passwords)

The last one is scary, but 12 days is still a long time. If you're really worried, you could track every incorrect password until the user gets a correct password, then if the list gets to over like 100 different attempts, just ban the IP address and send an email to the user.

独孤求败 2024-08-31 12:55:17

我通常喜欢@Tower的答案,但更喜欢不使用验证码的变体,主要是因为我讨厌它作为用户体验。

除了失败跟踪字段之外,还添加一个带有时间戳的锁定字段。我同意永远锁定用户(或直到手动重置)会带来糟糕的体验,但是 将帐户锁定一个小时(虽然有点痛苦)是一种有效的威慑

更改将是,当失败计数增加超过阈值时,锁定字段将设置为“现在 + 1 小时”。每当执行身份验证时,它都会查看此字段,如果 lockout > 则执行此操作。现在,然后就失败了。

从管理角度手动锁定帐户只需将锁定字段设置为某个遥远的未来值,如 9223372036854775807l(最大 64 位有符号长)。

I generally like @Tower's answer, but prefer a variant that doesn't use CAPTCHA, mostly because I hate it as a user experience.

In addition to his fail tracking fields, also add a lockout field with a timestamp. I agree that locking out a user forever (or until manual reset) makes for a bad experience, but locking out an account for an hour (while mildly painful) is an effective deterrent.

The change would then be that when the fail count is incremented beyond the threshold, the lockout field is set to now + 1 hour. Whenever auth is being performed, it looks at this field and if lockout > now, then it fails.

Manually locking out accounts from an administrative perspective then becomes just a matter of setting the lockout field to some distant future value like 9223372036854775807l (max 64-bit signed long).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文