最好的分布式蛮力对策是什么?

时间:2022-03-30 05:02:34

First, a little background: It is no secret that I am implementing an auth+auth system for CodeIgniter, and so far I'm winning (so to speak). But I've run into a pretty non-trivial challenge (one that most auth libraries miss entirely, but I insist on handling it properly): how to deal intelligently with large-scale, distributed, variable-username brute-force attacks.

首先,有一点背景知识:我正在为CodeIgniter实现一个auth+auth系统,这并不是什么秘密,到目前为止,我取得了胜利(可以说)。但我遇到了一个相当重要的挑战(大多数auth库都忽略了这个挑战,但我坚持要正确地处理它):如何智能地处理大规模、分布式、可变用户名的暴力攻击。

I know all the usual tricks:

我知道所有常见的把戏:

  1. Limiting # of failed attempts per IP/host and denying the offenders access (e.g. Fail2Ban) - which no longer works since botnets have grown smarter
  2. 限制每个IP/主机失败尝试的#,并拒绝违规者访问(例如Fail2Ban)——这不再有效,因为僵尸网络已经变得更聪明了
  3. Combining the above with a blacklist of known 'bad' IPs/hosts (e.g. DenyHosts) - which relies on botnets falling for #1, which they increasingly don't
  4. 将上面的内容和一个已知的“坏”ip /主机(例如DenyHosts)的黑名单结合起来——这个黑名单依赖于僵尸网络排在第一位,但他们越来越不这么做了
  5. IP/host whitelists combined with traditional auth (sadly useless with dynamic IP users and the high churn on most web sites)
  6. IP/主机白名单与传统的身份认证(遗憾的是,对于动态IP用户和大多数网站的高流失率来说毫无用处)
  7. Setting a sitewide limit on # of failed attempts within a N minute/hour period, and throttling (suspending) all login attempts after that for a number of minutes/hours (with the problem that DoS attacking you becomes botnet child's play)
  8. 在N分钟/小时内设置一个站点范围内的失败尝试的数量限制,并在之后的几分钟/小时内限制(暂停)所有登录尝试。
  9. Mandatory digital signatures (public-key certificates) or RSA hardware tokens for all users with NO login/password option (without question a rock-solid solution, but only practical for closed, dedicated services)
  10. 对于没有登录/密码选项的所有用户,强制数字签名(公钥证书)或RSA硬件令牌(毫无疑问,这是一个坚如磐石的解决方案,但只适用于封闭的、专用的服务)
  11. Enforced ultra-strong password schemes (e.g. >25 nonsense characters with symbols - again, too impractical for casual users)
  12. 强制的超强密码方案(例如:>25个带有符号的无意义字符——同样,对于普通用户来说太不实用了)
  13. And finally, CAPTCHAs (which could work in most cases, but are annoying for users and virtually useless against a determined, resourceful attacker)
  14. 最后,验证码(在大多数情况下都可以使用,但对用户来说很烦人,对一个有决心、足智多谋的攻击者来说几乎毫无用处)

Now, these are just the theoretically workable ideas. There are plenty of rubbish ideas that blow the site wide open (e.g. to trivial DoS attacks). What I want is something better. And by better, I mean:

这些只是理论上可行的想法。有大量的垃圾想法将网站彻底开放(例如,对琐碎的DoS攻击)。我想要的是更好的东西。更好的说法是:

  • It has to be secure(+) against DoS and brute-force attacks, and not introduce any new vulnerabilities that might allow a slightly sneakier bot to continue operating under the radar

    它必须是安全的(+)对抗DoS和蛮力攻击,并且不引入任何新的漏洞,可能允许一个稍微狡猾的机器人继续在雷达下操作

  • It has to be automated. If it requires a human operator to verify each login or monitor suspicious activity, it's not going to work in a real-world scenario

    它必须是自动化的。如果它需要一个人工操作符来验证每个登录名或监视可疑活动,那么它在真实场景中是无法工作的

  • It has to be feasible for mainstream web use (ie. high churn, high volume, and open registration that can be performed by non-programmers)

    它必须是可行的主流网络使用。高流失率、高容量和开放注册(非程序员可以执行)

  • It can't impede the user experience to the point where casual users will get annoyed or frustrated (and potentially abandon the site)

    它不能阻碍用户体验,以至于普通用户会感到恼怒或沮丧(甚至可能会放弃网站)

  • It can't involve kittens, unless they are really really secure kittens

    它不能涉及小猫,除非它们真的很安全

(+) By 'secure', I mean at least as secure as a paranoid user's ability to keep his password secret

(+)我所说的“安全”,指的是至少和一个偏执的用户保密密码的能力一样安全

So - let's hear it! How would you do it? Do you know of a best-practice that I haven't mentioned (oh please say you do)? I admit I do have an idea of my own (combining ideas from 3 and 4), but I'll let the true experts speak before embarrassing myself ;-)

让我们来听听!你会怎么做?你知道我没有提到的最佳实践吗?我承认我有我自己的想法(结合3和4的想法),但我会让真正的专家在让我自己难堪之前说出来;

17 个解决方案

#1


64  

All right, enough stalling; here's what I've come up with so far

好了,足够的停滞;这是我到目前为止得出的结论

(sorry, long post ahead. Be brave, friend, the journey will be worth it)

(对不起,长文章。勇敢一点,朋友,这段旅程是值得的

Combining methods 3 and 4 from the original post into a kind of 'fuzzy' or dynamic whitelist, and then - and here's the trick - not blocking non-whitelisted IPs, just throttling them to hell and back.

将方法3和4从最初的帖子中组合到一种“模糊”或动态的白名单中,然后——这里有一个技巧——不阻塞非白化的IPs,而是把它们节流到地狱和地狱。

Note that this measure is only meant to thwart this very specific type of attack. In practice, of course, it would work in combination with other best-practices approaches to auth: fixed-username throttling, per-IP throttling, code-enforced strong password policy, unthrottled cookie login, hashing all password equivalents before saving them, never using security questions, etc.

注意,这一措施仅仅是为了挫败这种类型的攻击。当然,在实践中,它可以与其他最佳实践方法结合使用:固定用户名节流、每ip节流、代码强制强密码策略、未节流的cookie登录、保存前对所有密码对等物进行散列处理、从不使用安全问题等等。

Assumptions about the attack scenario

关于攻击场景的假设

If an attacker is targeting variable usernames, our username throttling doesn't fire. If the attacker is using a botnet or has access to a large IP range, our IP throttling is powerless. If the attacker has pre-scraped our userlist (usually possible on open-registration web services), we can't detect an ongoing attack based on number of 'user not found' errors. And if we enforce a restrictive system-wide (all usernames, all IPs) throttling, any such attack will DoS our entire site for the duration of the attack plus the throttling period.

如果攻击者的目标是可变的用户名,我们的用户名调节不会启动。如果攻击者使用的是僵尸网络或者有一个大的IP范围,我们的IP节流是无能为力的。如果攻击者预先剪贴了我们的用户列表(通常可以在开放注册的web服务上使用),我们就无法检测到基于“用户未发现”错误数量的持续攻击。如果我们强制执行系统范围内的限制(所有用户名、所有ip)节流,任何这样的攻击都会在攻击持续时间和节流周期内影响整个站点。

So we need to do something else.

所以我们需要做点别的。

The first part of the countermeasure: Whitelisting

对策的第一部分:白脱。

What we can be fairly sure of, is that the attacker is not able to detect and dynamically spoof the IP addresses of several thousand of our users(+). Which makes whitelisting feasible. In other words: for each user, we store a list of the (hashed) IPs from where the user has previously (recently) logged in.

我们可以相当肯定的是,攻击者无法检测并动态地欺骗我们数千用户的IP地址(+)。这使得白名单的可行性。换句话说:对于每个用户,我们存储用户先前(最近)登录的(散列)ip的列表。

Thus, our whitelisting scheme will function as a locked 'front door', where a user must be connected from one of his recognized 'good' IPs in order to log in at all. A brute-force attack on this 'front door' would be practically impossible(+).

因此,我们的白名单方案将作为一个锁住的“前门”,在这里,用户必须通过一个公认的“好”ip连接,才能登录。对这扇“前门”发动暴力袭击几乎是不可能的(+)。

(+) unless the attacker 'owns' either the server, all our users' boxes, or the connection itself -- and in those cases, we no longer have an 'authentication' issue, we have a genuine franchise-sized pull-the-plug FUBAR situation

(+)除非攻击者“拥有”服务器、我们所有用户的盒子或连接本身——在这些情况下,我们不再有“认证”问题,我们有一个真正的加盟商规模的拔塞式FUBAR模式

The second part of the countermeasure: System-wide throttling of unrecognized IPs

对策的第二部分:系统范围内对未被识别的ip进行节流

In order to make a whitelist work for an open-registration web service, where users switch computers frequently and/or connect from dynamic IP addresses, we need to keep a 'cat door' open for users connecting from unrecognized IPs. The trick is to design that door so botnets get stuck, and so legitimate users get bothered as little as possible.

为了让白名单在开放注册的web服务中工作,用户经常交换计算机和/或通过动态IP地址连接,我们需要为连接不被识别的IP地址的用户打开“猫门”。关键是要设计出这样的门,这样僵尸网络就会被卡住,所以合法的用户会被尽可能少的打扰。

In my scheme, this is achieved by setting a very restrictive maximum number of failed login attempts by unapproved IPs over, say, a 3-hour period (it may be wiser to use a shorter or longer period depending on type of service), and making that restriction global, ie. for all user accounts.

在我的方案中,这是通过在3小时内(根据服务类型的不同,可能更明智地使用更短或更长的时间)设置非常严格的未获批准的ip登录尝试的最大失败次数,并使该限制成为全局的(例如)。对所有用户帐户。

Even a slow (1-2 minutes between attempts) brute force would be detected and thwarted quickly and effectively using this method. Of course, a really slow brute force could still remain unnoticed, but too slow speeds defeat the very purpose of the brute force attack.

即使是缓慢的(在尝试之间1-2分钟),也可以通过这种方法快速有效地检测到暴力。当然,一个真正缓慢的蛮力仍然可以被忽略,但是速度太慢会导致蛮力攻击的目的。

What I am hoping to accomplish with this throttling mechanism is that if the maximum limit is reached, our 'cat door' slams closed for a while, but our front door remains open to legitimate users connecting by usual means:

我希望通过这个节流机制实现的是,如果达到了最大限度,我们的“猫门”会关闭一段时间,但我们的前门仍然对合法用户开放,通过通常的方式进行连接:

  • Either by connecting from one of their recognized IPs
  • 通过连接他们的一个公认的ip。
  • Or by using a persistent login cookie (from anywhere)
  • 或者使用一个持久的登录cookie(来自任何地方)

The only legitimate users who would be affected during an attack - ie. while the throttling was activated - would be users without persistent login cookies who were logging in from an unknown location or with a dynamic IP. Those users would be unable to login until the throttling wore off (which could potentially take a while, if the attacker kept his botnet running despite the throttling).

只有合法的用户才会在攻击中受到影响——即。当节流被激活时——将是没有持久登录cookie的用户,他们从一个未知的位置登录或使用动态IP登录。这些用户将无法登录,直到节流结束(这可能需要一段时间,如果攻击者保持他的僵尸网络运行,尽管节流)。

To allow this small subset of users to squeeze through the otherwise-sealed cat door, even while bots were still hammering away at it, I would employ a 'backup' login form with a CAPTCHA. So that, when you display the "Sorry, but you can't login from this IP address at the moment" message, include a link that says "secure backup login - HUMANS ONLY (bots: no lying)". Joke aside, when they click that link, give them a reCAPTCHA-authenticated login form that bypasses the site-wide throttling. That way, IF they are human AND know the correct login+password (and are able to read CAPTCHAs), they will never be denied service, even if they are connecting from an unknown host and not using the autologin cookie.

为了让这一小部分用户挤过另一个封闭的猫门,即使机器人还在不停地敲打,我将使用带有验证码的“备份”登录表单。因此,当你显示“对不起,但你现在不能从这个IP地址登录”消息时,包括一个链接,上面写着“安全备份登录-只有人类(机器人:不撒谎)”。玩笑归玩笑,当他们点击那个链接时,给他们一个验证过的登录表单,它将绕过站点范围的限制。这样,如果他们是人,并且知道正确的登录+密码(并且能够读取验证码),他们将永远不会被拒绝服务,即使他们正在连接一个未知的主机,并且没有使用autologin cookie。

Oh, and just to clarify: Since I do consider CAPTCHAs to be generally evil, the 'backup' login option would only appear while throttling was active.

哦,我想澄清一下:由于我确实认为验证码通常是有害的,所以“备份”登录选项只会在throttling选项是活动的时候出现。

There is no denying that a sustained attack like that would still constitute a form of DoS attack, but with the described system in place, it would only affect what I suspect to be a tiny subset of users, namely people who don't use the "remember me" cookie AND happen to be logging in while an attack is happening AND aren't logging in from any of their usual IPs AND who can't read CAPTCHAs. Only those who can say no to ALL of those criteria - specifically bots and really unlucky disabled people - will be turned away during a bot attack.

不可否认,这样的持续攻击仍将构成DoS攻击的一种形式,但随着系统描述,它只会影响我怀疑是一个很小的子集的用户,即那些不使用“记住我”饼干和碰巧登录登录而发生的攻击和不从任何平常的ip,谁看不清验证码。只有那些对所有这些标准都说不的人——特别是机器人和不幸的残疾人——会在机器人攻击中被拒之门外。

EDIT: Actully, I thought of a way to let even CAPTCHA-challenged users pass through during a 'lockdown': instead of, or as a supplement to, the backup CAPTCHA login, provide the user with an option to have a single-use, user-specific lockdown code sent to his email, that he can then use to bypass the throttling. This definitely crosses over my 'annoyance' threshold, but since it's only used as a last resort for a tiny subset of users, and since it still beats being locked out of your account, it would be acceptable.

编辑:事实上,我甚至想到一个办法让CAPTCHA-challenged用户通过在“锁定”:相反的,或作为补充,备份验证码登录,为用户提供一个选项来一次性,特定于用户的锁定代码发送给他的邮件,可以使用旁路节流。这显然是跨越了我的“烦恼”门槛,但因为它只是作为一小部分用户的最后手段,而且它仍然比被锁定在你的帐户上,这是可以接受的。

(Also, note that none of this happens if the attack is any less sophisticated than the nasty distributed version I've described here. If the attack is coming from just a few IPs or only hitting a few usernames, it will be thwarted much earlier, and with no site-wide consequences)

(另外,请注意,如果攻击比我在这里描述的糟糕的分布式版本更复杂,那么这些都不会发生。如果攻击仅仅来自几个ip,或者只攻击几个用户名,那么攻击将在更早的时候被挫败,并且不会造成站点范围内的影响)


So, that is the countermeasure I will be implementing in my auth library, once I'm convinced that it's sound and that there isn't a much simpler solution that I've missed. The fact is, there are so many subtle ways to do things wrong in security, and I'm not above making false assumptions or hopelessly flawed logic. So please, any and all feedback, criticism and improvements, subtleties etc. are highly appreciated.

所以,这就是我在我的auth库中要实现的对策,一旦我确信它是可靠的,并且我没有错过任何更简单的解决方案。事实是,在安全方面有很多微妙的方法来做错事,我也不介意做出错误的假设或毫无希望的有缺陷的逻辑。因此,我们非常感谢您的任何反馈、批评和改进、微妙之处等。

#2


16  

A few simple steps:

几个简单的步骤:

Blacklist certain common usernames, and use them as a honeypot. Admin, guest, etc... Don't let anyone create accounts with these names, so if someone does try to log them in you know it's someone doing something they shouldn't.

将一些常见的用户名列入黑名单,并将它们用作蜜罐。管理、客人等……不要让任何人用这些名字创建帐户,所以如果有人尝试登录他们,你知道这是某人做了不该做的事情。

Make sure anyone who has real power on the site has a secure password. Require admins/ moderators to have longer passwords with a mix of letters, numbers and symbols. Reject trivially simple passwords from regular users with an explanation.

确保任何在网站上有实权的人都有安全密码。要求管理员/版主拥有更长的密码,包含字母、数字和符号。拒绝普通用户的简单密码,并进行解释。

One of the simplest things you can do is tell people when someone tried to log into their account, and give them a link to report the incident if it wasn't them. A simple message when they log in like "Someone tried to log into your account at 4:20AM Wednesday blah blah. Click here if this wasn't you." It lets you keep some statistics on attacks. You can step up monitoring and security measures if you see that there's a sudden increase in fraudulent accesses.

你能做的最简单的一件事就是告诉人们什么时候有人试图登录他们的账户,并给他们一个链接,如果不是他们的话,报告事件。当他们登录的时候,一个简单的信息就像“有人试图在周三凌晨4点20分登录你的账户。”如果不是你就点击这里它允许您保存一些攻击的统计数据。如果您发现欺诈访问突然增加,您可以加强监视和安全措施。

#3


11  

If I understand the MO of brute force attacks properly, then one or more usernames are tried continuously.

如果我正确理解了蛮力攻击的MO,那么就会不断尝试一个或多个用户名。

There are two suggestions which I don't think I've seen yet here:

有两个建议我在这里还没有看到:

  • I always thought that the standard practice was to have a short delay (a second or so) after each wrong login for every user. This deters brute-force, but I don't know how long a one second delay would keep a dictionary attack at bay. (dictionary of 10,000 words == 10,000 seconds == about 3 hours. Hmm. Not good enough.)
  • 我一直认为,标准的做法是在每个用户错误登录后,有一个短暂的延迟(大约一秒钟)。这可以阻止蛮力,但我不知道一秒钟的延迟会使字典攻击持续多久。(万字字典=万秒= 3小时左右。嗯。不够好。)
  • instead of a site-wide slow down, why not a user-name throttle. The throttle becomes increasingly harsh with each wrong attempt (up to a limit, I guess so the real user can still login)
  • 与其让整个站点的速度慢下来,不如让用户名节流。由于每次错误的尝试,节流阀变得越来越粗糙(我想这是一个真正的用户仍然可以登录的限制)

Edit: In response to comments on a username throttle: this is a username specific throttle without regard to the source of the attack.

编辑:响应用户名节流阀上的评论:这是一个用户名特定的节流阀,不考虑攻击源。

If the username is throttled, then even a coordinated username attack (multi IP, single guess per IP, same username) would be caught. Individual usernames are protected by the throttle, even if the attackers are free to try another user/pass during the timeout.

如果用户名被禁用,那么即使是一个协调的用户名攻击(多IP、单猜测每个IP、相同的用户名)也会被捕获。每个用户名都受到油门的保护,即使攻击者可以在超时期间尝试另一个用户/传递。

From an attackers point of view, during the timeout you may be able to take a first time guess at 100 passwords, and quickly discover one wrong password per account. You may only be able to make a 50 second guesses for the same time period.

从攻击者的角度来看,在超时期间,您可以首次猜测100个密码,并迅速发现每个帐户的一个错误密码。你可能只能在同一时间段内猜测50次。

From a user account point of view, it still takes the same average number of guesses to break the password, even if the guesses are coming from multiple sources.

从用户帐户的角度来看,破解密码仍然需要相同的平均猜测次数,即使猜测来自多个源。

For the attackers, at best, it will be the same effort to break 100 accounts as it would 1 account, but since you're not throttling on a site wide basis, you can ramp up the throttle quite quickly.

对于攻击者来说,破坏100个帐户的效果与破坏1个帐户的效果是一样的,但是由于您没有在站点范围内进行限制,所以您可以很快地加快速度。

Extra refinements:

额外的改进:

  • detect IPs that are guessing multiple accounts - 408 Request Timeout
  • 检测猜测多个帐户的ip - 408请求超时
  • detect IPs that are guessing the same account - 408 Request Timeout after a large (say 100) number of guesses.
  • 检测猜测同一个帐户的IPs——在大量猜测(比如100次)之后的408请求超时。

UI ideas (may not be suitable in this context), which may also refine the above:

UI思想(可能不适合在此上下文中使用),这也可以细化上面的内容:

  • if you are in control of the password setting, then showing the user how strong their password is encourages them to pick a better one.
  • 如果您控制了密码设置,那么向用户展示他们的密码有多强,这将鼓励他们选择一个更好的密码。
  • if you are in control of the login page, after a small (say 10) number of guesses of a single username, offer a CAPTCHA.
  • 如果您控制登录页面,在一个小的(比方说10)个用户名的猜测数之后,提供一个验证码。

#4


8  

There are three factors of authentication:

认证有三个因素:

  1. A user knows something (ie, a password)
  2. 用户知道一些东西(比如,密码)
  3. A user has something (ie, a key fob)
  4. 用户有一些东西(如钥匙离岸价)
  5. A user is something (ie, retina scan)
  6. 用户是什么东西(比如视网膜扫描)

Usually, websites only enforce policy #1. Even most banks only enforce policy 1. They instead rely on a "knows something else" approach to two-factor authentication. (IE: A user knows their password and their mother's maiden name.) If you are able, a way to add in a second factor of authentication is not too difficult.

通常,网站只执行策略#1。即使是大多数银行也只执行政策1。相反,它们依赖于“知道其他东西”的双因素身份验证方法。(即:用户知道自己的密码和母亲的娘家姓。)如果可以,添加第二个身份验证因素的方法并不太难。

If you can generate around 256 characters of randomness, you could structure that in a 16×16 table, and then ask the user to give you the value in the table of cell A-14, for example. When a user signs up or changes their password, give them the table and tell them to print it off and save it.

如果你能产生大约256个字符的随机性,可以在16×16表结构,然后要求用户给你表中的值细胞14,例如。当用户注册或更改他们的密码时,给他们表格并告诉他们打印并保存。

The difficulty with that approach is that when a user forgets their password, as they will, you can't just offer the standard "answer this question and put in a new password", since that's vulnerable to brute-force as well. Also, you can't reset it and email them a new one, since their email could be compromised as well. (See: Makeuseof.com and their stolen domain.)

这种方法的困难在于,当用户忘记密码时,你不能仅仅提供标准的“回答这个问题并输入一个新密码”,因为这也很容易受到暴力攻击。此外,你不能重置它并给他们发一封新邮件,因为他们的邮件也可能被泄露。(参见:Makeuseof.com及其被盗域名。)

Another idea (which involves kittens), is what BOA calls SiteKey (I believe they trademarked the name). Briefly, you have the user upload an image when they register, and when they attempt to login, ask them to pick their image out of 8 or 15 (or more) random ones. So, if a user uploads a picture of their kitten, theoretically only they know exactly which picture is theirs out of all the other kittens (or flowers or whatever). The only real vunerability this approach has is the man-in-the-middle attack.

另一个想法(涉及小猫)是BOA称之为SiteKey(我相信他们注册了这个名字)。简单地说,当用户注册时,用户上传了一个图像,当他们试图登录时,请他们从8个或15个(或更多)随机选择他们的图像。因此,如果用户上传了小猫的照片,理论上只有他们知道其他小猫(或花或其他)的照片是他们的。这种方法唯一真正具有的不可逾越性是中间人攻击。

One more idea (no kittens though), is to track IPs that users access the system with, and require them to perform additional authentication (captcha , pick a kitty, pick a key from this table) when they log in from an address they haven't before. Also, similar to GMail, allow the user to view where they have logged in from recently.

还有一个想法(没有小猫),就是跟踪用户访问系统的ip,并要求用户在登录之前没有访问过的地址时执行额外的身份验证(captcha,选择一个kitty,从这个表中选择一个密钥)。同样,类似于GMail,允许用户查看最近登录的位置。

Edit, New Idea:

编辑新想法:

Another way of validating login attempts is to check whether or not the user has come from your login page. You can't check referrers, since they can be easily faked. What you need is to set a key in the _SESSION var when the user views the login page, and then check to make sure that key exists when they submit their login information. If bot does not submit from the login page, it will not be able to login. You can also facilitate this by involving javascript in the process, either by using it to set a cookie, or adding some information to the form after it has loaded. Or, you can split the form up into two different submits (ie, the user enters their username, submits, then on a new page enters their password and submit again.)

验证登录尝试的另一种方法是检查用户是否来自您的登录页面。你不能检查推荐人,因为他们很容易造假。您需要的是在用户查看登录页面时在_SESSION var中设置一个键,然后在提交登录信息时检查该键是否存在。如果bot没有从登录页面提交,它将无法登录。还可以通过在过程中使用javascript来设置cookie,或者在表单加载后向表单中添加一些信息来实现这一点。或者,你可以将表单分成两个不同的提交(例如,用户输入用户名,提交,然后在一个新页面上输入他们的密码,然后再次提交)。

The key, in this case, is the most important aspect. A common method of generating them is some combination of the user's data, their IP, and the time it was submitted.

在这种情况下,关键是最重要的方面。生成它们的常用方法是将用户的数据、IP和提交的时间组合起来。

#5


6  

I have to ask whether you've done cost-benefit analysis of this problem; it sounds like you're trying to protect yourself from an attacker who has enough web presence to guess a number of passwords, sending maybe 3-5 requests per IP (since you've dismissed IP throttling). How much (roughly) would that kind of attack cost? Is it more expensive than the value of the accounts you're trying to protect? How many gargantuan botnets want what you've got?

我必须问你是否对这个问题做了成本效益分析;这听起来像是在保护自己不受攻击者的攻击,攻击者有足够的网络存在,可以猜测多个密码,每个IP可能发送3-5个请求(因为您已经排除了IP节流)。这种攻击(粗略地)要花多少钱?它比你试图保护的账户的价值更贵吗?有多少庞大的僵尸网络想要你所拥有的?

The answer might be no -- but if it is, I hope you're getting help from a security professional of some sort; programming skill (and * score) do not correlate strongly to security know-how.

答案可能是否定的——但如果是的话,我希望你能得到某种安全专业人士的帮助;编程技能(和*分数)与安全知识没有很强的相关性。

#6


6  

I had previously answered a very similar question over at How can I throttle user login attempts in PHP. I'll reiterate the proposed solution here as I believe many of you will find it informational and useful to see some actual code. Please bare in mind that using a CAPTCHA might not be the best solution due to the increasingly accurate algorithms being used in CAPTCHA busters nowadays:

我之前曾回答过一个非常类似的问题,即如何限制PHP中的用户登录尝试。我将在这里重申所提出的解决方案,因为我相信许多人会发现它是信息和有用的,可以看到一些实际的代码。请记住,使用验证码可能不是最好的解决方案,因为现在验证码终结者中使用的算法越来越精确:

You cannot simply prevent DoS attacks by chaining throttling down to a single IP or username. Hell, you can't even really prevent rapid-fire login attempts using this method.

您不能简单地通过链接到单个IP或用户名来防止DoS攻击。见鬼,你甚至不能阻止使用这个方法的快速登录尝试。

Why? Because the attack can span multiple IPs and user accounts for the sake of bypassing your throttling attempts.

为什么?因为攻击可以跨越多个ip和用户帐户,从而绕过您的节流尝试。

I have seen posted elsewhere that ideally you should be tracking all failed login attempts across the site and associating them to a timestamp, perhaps:

我在其他地方看到过,理想情况下,你应该跟踪所有失败的登录尝试,并将它们与时间戳联系起来,也许:

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;

Decide on certain delays based on the overall number of failed logins in a given amount of time. You should base this on statistical data pulled from your failed_logins table as it will change over time based on the number of users and how many of them can recall (and type) their password.

根据给定时间内失败登录的总数确定某些延迟。您应该基于从failed_logins表中提取的统计数据,因为随着时间的推移,它将根据用户数量和他们中有多少人可以回忆(并键入)他们的密码而变化。


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

Query the table on every failed login attempt to find the number of failed logins for a given period of time, say 15 minutes:

在每次失败的登录尝试上查询表,以找到给定时间内失败登录的次数,例如15分钟:


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

If the number of attempts over the given period of time is over your limit, either enforce throttling or force all user's to use a captcha (i.e. reCaptcha) until the number of failed attempts over the given time period is less than the threshold.

如果给定时间段内的尝试次数超过了您的限制,要么强制执行节流,要么强制所有用户使用验证码(即再验证码),直到在给定时间段内失败尝试的次数小于阈值。

// 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;
    }
}

Using reCaptcha at a certain threshold would ensure that an attack from multiple fronts would be minimized and normal site users would not experience a significant delay for legitimate failed login attempts. I can't gaurantee prevention, as it's already been expanded upon that CAPTCHA's can be busted. There are alternative solutions, perhaps a variant of "Name this animal", which could work quite well as a substitute.

在某个阈值上使用reCaptcha将确保来自多个方面的攻击最小化,正常的站点用户不会因为合法失败的登录尝试而遇到严重的延迟。我不能保证预防,因为它已经被扩展到验证码上了。还有其他的解决办法,也许是“给这只动物起个名字”的变体,它可以作为替代品很好地发挥作用。

#7


5  

To summarize Jens' scheme into a pseudo state transition diagram/rulebase:

将Jens的方案总结为一个伪状态转换图/规则库:

  1. user + password -> entry
  2. 用户+密码->条目
  3. user + !password -> denied
  4. 用户+ !密码->被拒绝。
  5. user + known_IP(user) -> front door, // never throttle
  6. 用户+ known_IP(用户)->前门,//永不节流。
  7. user + unknown_IP(user) -> catflap
  8. 用户+ unknown_IP(用户)——> catflap
  9. (#denied > n) via catflaps(site) -> throttle catflaps(site) // slow the bots
  10. (#拒绝>n)通过catflaps(site) ->节流阀(site) //减速机器人。
  11. catflap + throttle + password + captcha -> entry // humans still welcome
  12. catflap +油门+密码+ captcha ->入口//人仍然欢迎。
  13. catflap + throttle + password + !captcha -> denied // a correct guess from a bot
  14. catflap +油门+密码+ !captcha ->否认// /一个机器人的正确猜测

Observations:

观察:

  • Never throttle the front door. The Elbonian state police have your computer, in your house, but are unable to interrogate you. Brute force is a viable approach from your computer.
  • 千万不要节流前门。Elbonian州警察在你家里有你的电脑,但是不能审问你。使用蛮力是一种可行的方法。
  • If you provide a "Forgetten your password?" link, then your email account becomes part of the attack surface.
  • 如果你提供了一个“忘记你的密码?”链接,那么你的电子邮件帐户将成为攻击表面的一部分。

These observations cover a different type of attack to the ones you are trying to counter.

这些观察涵盖了不同类型的攻击,而不是你想要对抗的攻击。

#8


4  

Looks like you are trying to defend against slow distributed brute force. Not that much you can do about it. We are using a PKI and no password logins. It helps, but if your clients chance workstations every once in a while, this is not very applicable.

看起来你在试图抵抗缓慢的分布式蛮力。对此你无能为力。我们使用的是PKI,没有密码登录。这是有帮助的,但是如果您的客户每隔一段时间就有机会使用工作站,这并不是很适用。

#9


3  

Disclaimer: I work for a two-factor company, but am not here to plug it. Here're some observations.

免责声明:我在一家双因素公司工作,但我不是来这里为它充电的。这里是一些观察。

Cookies can be stolen with XSS and browser vulns. Users commonly change browsers or clear their cookies.

使用XSS和浏览器vulns可以窃取cookie。用户通常会更改浏览器或清除他们的cookie。

Source IP addresses are simultaneously dynamically variable and spoofable.

源IP地址是动态可变和可欺骗的。

Captcha is useful, but doesn't authenticate a specific human.

验证码是有用的,但是不能验证特定的人。

Multiple methods can be combined successfully, but good taste is certainly in order.

多种方法可以成功地结合在一起,但一定要有好的品味。

Password complexity is good, anything password-based critically depends on passwords having sufficient entropy. IMHO, a strong password written down in a secure physical location is better than a weak password in memory. People know how to evaluate the security of paper documents much better than they know how to figure the effective entropy in their dog's name when used as a password for three different websites. Consider giving users the ability to print out a big or small page full of one-time use pass codes.

密码的复杂性是好的,任何基于密码的关键都取决于密码具有足够的熵。IMHO,在安全的物理位置写下的强密码比内存中的弱密码要好。人们知道如何评估纸质文档的安全性,这比他们知道如何在三个不同网站的密码中使用他们的狗的名字的有效熵值更好。考虑给用户打印满一次性使用密码的大或小页面的能力。

Security questions like "what was your high-school mascot" are mostly another lousy form of "something you know", most of them are easily guessable or outright in the public domain.

诸如“你高中时的吉祥物是什么”之类的安全问题,大多是另一种“你知道的东西”的糟糕形式,它们大多数都很容易被人猜出来,或者直接在公共领域被人猜出来。

As you noted, throttling back failed login attempts is a trade-off between preventing brute-force attacks and ease of DoSing an account. Aggressive lockout policies may reflect a lack of confidence in password entropy.

正如您所注意到的,限制失败的登录尝试是在防止暴力攻击和轻松地给帐户加药之间的权衡。积极的锁定策略可能反映出对密码熵缺乏信心。

I personally don't see the the benefit to enforcing password expiration on a website anyway. Attacker gets your password once, he can change it then and comply with that policy just as easily as you can. Perhaps one benefit is that the user might notice sooner if the attacker changes the account password. Even better would be if the the user were somehow notified before the attacker gained access. Messages like "N failed attempts since last login" are useful in this respect.

我个人并不认为在网站上强制执行密码过期的好处。攻击者一旦获得你的密码,他就可以改变它,并尽可能地遵守该政策。一个好处是,如果攻击者更改帐户密码,用户可能会提前通知。如果在攻击者获得访问权之前以某种方式通知用户,那就更好了。在这方面,像“自上次登录以来的N次失败尝试”这样的消息很有用。

The best security comes from a second factor of authentication which is out-of-band relative to the first. Like you said, hardware tokens in the "something you have" are great, but many (not all) have real admin overhead associated with their distribution. I don't know of any biometric "something you are" solutions good for websites. Some two-factor solutions work with openid providers, some have PHP/Perl/Python SDKs.

最好的安全性来自于第二个身份验证因素,与第一个因素相比,它是带外的。正如您所说,“您拥有的东西”中的硬件令牌非常棒,但是许多(不是全部)都有与它们的发行版相关的真正的管理开销。我不知道任何生物特征的“你是”的解决方案对网站有好处。一些双因素解决方案与openid提供者一起工作,其中一些有PHP/Perl/Python sdk。

#10


1  

No matter how good your system is, it'll fail under a long enough attack. There are some good ideas here, on how to extend a password's duration. (I personally like the idea of exponentially-increasing attempt rate limiting per-user and per-IP address.) But no matter what you go with, you'll need to back it up with some password rules.

无论你的系统有多好,它都会在长时间的攻击下失败。这里有一些好的想法,关于如何扩展密码的持续时间。(我个人喜欢指数增长的尝试速率限制每个用户和每个ip地址的想法。)但是不管你用什么,你都需要用一些密码规则来支持它。

I'd encourage you to figure out how fast a password can be cracked, and have users change them twice as often as that. Hope this helps.

我鼓励你弄清楚密码被破解的速度,让用户修改密码的频率翻倍。希望这个有帮助。

Edit: If you expect a lot of lazy attackers, requiring some CAPTCHA after multiple failed attempts is good: it raises the bar a little. If you're worried about a lot of intelligent attackers, hire a security consultant. ;)

编辑:如果您预期会有很多懒惰的攻击者,在多次失败的尝试之后需要一些验证码是很好的:它会增加一些门槛。如果你担心很多聪明的攻击者,请雇佣一个安全顾问。,)

#11


1  

My highest recommendation is to simply make sure that you keep users informed of bad login attempts to their accounts-- Users will likely take the strength of their password much more seriously if they are presented with evidence that somebody is actually trying to get into their account.

我的最高建议是,只要确保你让用户知道他们的账户登录尝试失败——如果用户看到有人试图进入他们的账户的证据,他们很可能会更加认真地对待自己密码的强度。

I actually caught somebody that hacked into my brother's myspace account because they had tried to get into the gmail account I setup for him and used the 'reset my password by email' feature... which went to my inbox.

我发现有人侵入我哥哥的myspace账户,因为他们试图进入我为他设置的gmail账户,并使用了“通过电子邮件重置我的密码”功能……我的收件箱收到了。

#12


1  

  1. What about requiring a one-time-password before entering their normal password? That would make it very obvious that someone was attacking before they got many opportunities to guess the main password?

    在输入常规密码之前,要求输入一次密码怎么样?这就很明显地表明,有人正在攻击,在他们有很多机会猜测主要密码之前?

  2. Keep a global count/rate of login failures - this is the indicator for an attack - during an attack be stricter about login failures e.g. ban IPs more rapidly.

    保持登录失败的全局计数/速率——这是攻击的指示器——在攻击期间对登录失败要更加严格,例如更快地禁止ip。

#13


0  

I don't believe there is a perfect answer but I would be inclined to approach it on a basis of trying to confound the robots if an attack is sensed.

我不相信有一个完美的答案,但我倾向于在感知到攻击时试图迷惑机器人。

Off the top of my mind:

我突然想到:

Switch to an alternate login screen. It has multiple username and password blanks which really do appear but only one of them is in the right place. The field names are RANDOM--a session key is sent along with the login screen, the server can then find out what fields are what. Succeed or fail it's then discarded so you can't try a replay attack--if you reject the password they get a new session ID.

切换到另一个登录屏幕。它有多个用户名和密码空白,但只有一个出现在正确的位置。字段名是随机的——会话密钥随登录屏幕一起发送,服务器就可以知道哪些字段是什么。成功或失败后,它将被丢弃,因此您不能尝试重播攻击——如果您拒绝密码,它们将获得一个新的会话ID。

Any form that is submitted with data in a wrong field is assumed to be from a robot--the login fails, period, and that IP is throttled. Make sure the random field names never match the legit field names so someone using something that remembers passwords isn't mislead.

任何在错误字段中提交数据的表单都被假定为来自机器人——登录失败、周期和IP被控制。确保随机字段的名称与合法字段的名称不匹配,这样使用能记住密码的东西的人就不会被误导。

Next, how about a different sort of captcha: You have a series of questions that won't cause problems for a human. However, they are NOT random. When the attack starts everyone is given question #1. After an hour question #1 is discarded, never to be used again and everyone gets question #2 and so on.

接下来,我们来看看另一种验证码:你有一系列不会给人类带来麻烦的问题。然而,它们不是随机的。当攻击开始时,每个人都要回答第一个问题。一个小时后,第一个问题被丢弃,再也不会被使用,每个人都会得到第二个问题,以此类推。

The attacker can't probe to download the database to put into his robot because of the disposable nature of the questions. He has to send new instructions out to his botnet within an hour to have any ability to do anything.

由于问题是一次性的,攻击者无法探查将数据库下载到他的机器人中。他必须在一个小时内将新的指令发送到他的僵尸网络上,才能做任何事情。

#14


0  

Since several folks included CAPTCHA as a fallback human mechanism, I'm adding an earlier * question and thread on CAPTCHA's effectiveness.

由于有几个人将CAPTCHA作为回退的人工机制,我在前面添加了关于CAPTCHA有效性的*问题和线程。

Has reCaptcha been cracked / hacked / OCR’d / defeated / broken?

已经破解/破解/破解/破解/破解了吗?

Using CAPTCHA doesn't limit improvements from your throttling and other suggestions, but I think the number of answers that include CAPTCHA as a fallback should consider the human-based methods available to people looking to break security.

使用CAPTCHA并不会限制您的节流和其他建议的改进,但是我认为,包括CAPTCHA作为一种退路的答案的数量应该考虑到那些希望破坏安全性的人可以使用的基于人工的方法。

#15


0  

You could also throttle based on the strength of a users password.

您还可以基于用户密码的强度进行节流。

When a user registers or changes their password you calculate a strength rating for their password, say between 1 and 10.

当用户注册或更改密码时,您将计算其密码的强度等级,比如1到10。

Something like "password" scores a 1 whereas "c6eqapRepe7et*Awr@ch" might score a 9 or 10 and the higher the score the longer it takes for throttling to kick in.

“password”之类的分数为1分,而“c6eqapRepe7et*Awr@ch”可能为9分或10分,分数越高,用于节流的时间就越长。

#16


0  

The first answer I've usually heard when asking this question is to change ports, but forget about that and just disable IPv4. If you only allow clients from IPv6 networks you'r no longer pray for simple network scanning and attackers will resort to DNS lookups. Don't run on the same address as your Apache(AAAA)/Sendmail(MX->AAAA)/what have you given out to everybody(AAAA). Make sure your zone can't be xferd, wait you'r allowing your zone to be downloaded by anybody?

我通常听到的第一个答案是更改端口,但是忘记它,然后禁用IPv4。如果你只允许来自IPv6网络的客户端,你将不再祈求简单的网络扫描,攻击者将求助于DNS查找。不要运行在与您的Apache(AAAA)/Sendmail(MX->AAAA)/您给每个人(AAAA)的内容相同的地址上。确保你的区域不能是xferd,等等,你是否允许任何人下载你的区域?

If the bots find your server setup new hostnames, just prepend some gibberish to your hostnames, and change your address. Leave the old names and even setup **honeypot names for the bot net to timeout on.

如果机器人发现你的服务器设置了新的主机名,只要在你的主机名前加上一些胡言乱语,然后改变你的地址。保留旧的名称,甚至为bot网络设置**蜜罐名称以超时。

** Test your reverse(PTR) records(under ip6.arpa.) to see if they can be used to zero in on /4's that have records VS /4s that don't. I.E. Typically ip6.arpa would have ~32 "."s in an address but trying with the last few missing might elude the network blocks that have records VS others that don't. If you take that further it becomes possible to skip large portions of the address space.

**测试你的反向(PTR)记录(ip6.arpa.下),看看它们是否可以用于记录没有记录的/4。即通常ip6。arpa应该是32 "在一个地址中,但是尝试寻找最后几个丢失的可能会避开有记录的网络块而不是其他没有记录的网络块。如果更进一步,就可以跳过大部分地址空间。

In the worst case users will have to setup an IPv6 tunnel, it's not like they'd have to go as far as VPNing into a DMZ... Though one wonders why that's not the first option.

在最坏的情况下,用户将不得不设置一个IPv6隧道,这并不像他们必须走到VPNing到DMZ……尽管有人想知道为什么这不是第一选择。

Also Kerberos is cool, but IMHO LDAP blows(What's technically wrong with NISPlus? I've read that Sun decided that users wanted LDAP and because of this they dropped NIS+). Kerberos does work fine without LDAP or NIS, just have to manage users on a host by host basis. Using Kerberos gives you an easy to use, if not automated, PKI.

Kerberos也很酷,但是不支持LDAP (NISPlus在技术上有什么问题吗?)我读到过Sun决定用户需要LDAP,因此他们放弃了NIS+)。没有LDAP或NIS, Kerberos可以很好地工作,只需根据主机对用户进行管理。使用Kerberos可以使PKI易于使用(如果不是自动化的话)。

#17


0  

Bit late here but I was thinking, assuming a hard case - the attacker uses a lot of random IPs, random user names and a random password selected from say a list of the 10,000 most popular.

在这里有点晚了,但是我在想,假设一个很困难的情况——攻击者使用了很多随机的ip,随机的用户名和一个随机的密码从一个10000最受欢迎的列表中选择。

One thing you could do, especially if the system seems under attack in that there are a lot of wrong password attempts on the system and especially if the password is low entropy is to ask a secondary question like what are your parents first names, for example. If an attacker hits a million accounts trying the password 'password1' there's a good chance they'll get a lot but their odds of also getting the names right would reduce successes dramatically.

你可以做的一件事是,特别是当系统似乎受到攻击时,因为系统上有很多错误的密码尝试,尤其是当密码熵很低时,你可以问第二个问题,比如你父母的名字是什么。如果一个攻击者点击了100万个密码“password1”,那么他们很有可能得到很多,但是他们获得正确名字的几率会大大降低成功的几率。

#1


64  

All right, enough stalling; here's what I've come up with so far

好了,足够的停滞;这是我到目前为止得出的结论

(sorry, long post ahead. Be brave, friend, the journey will be worth it)

(对不起,长文章。勇敢一点,朋友,这段旅程是值得的

Combining methods 3 and 4 from the original post into a kind of 'fuzzy' or dynamic whitelist, and then - and here's the trick - not blocking non-whitelisted IPs, just throttling them to hell and back.

将方法3和4从最初的帖子中组合到一种“模糊”或动态的白名单中,然后——这里有一个技巧——不阻塞非白化的IPs,而是把它们节流到地狱和地狱。

Note that this measure is only meant to thwart this very specific type of attack. In practice, of course, it would work in combination with other best-practices approaches to auth: fixed-username throttling, per-IP throttling, code-enforced strong password policy, unthrottled cookie login, hashing all password equivalents before saving them, never using security questions, etc.

注意,这一措施仅仅是为了挫败这种类型的攻击。当然,在实践中,它可以与其他最佳实践方法结合使用:固定用户名节流、每ip节流、代码强制强密码策略、未节流的cookie登录、保存前对所有密码对等物进行散列处理、从不使用安全问题等等。

Assumptions about the attack scenario

关于攻击场景的假设

If an attacker is targeting variable usernames, our username throttling doesn't fire. If the attacker is using a botnet or has access to a large IP range, our IP throttling is powerless. If the attacker has pre-scraped our userlist (usually possible on open-registration web services), we can't detect an ongoing attack based on number of 'user not found' errors. And if we enforce a restrictive system-wide (all usernames, all IPs) throttling, any such attack will DoS our entire site for the duration of the attack plus the throttling period.

如果攻击者的目标是可变的用户名,我们的用户名调节不会启动。如果攻击者使用的是僵尸网络或者有一个大的IP范围,我们的IP节流是无能为力的。如果攻击者预先剪贴了我们的用户列表(通常可以在开放注册的web服务上使用),我们就无法检测到基于“用户未发现”错误数量的持续攻击。如果我们强制执行系统范围内的限制(所有用户名、所有ip)节流,任何这样的攻击都会在攻击持续时间和节流周期内影响整个站点。

So we need to do something else.

所以我们需要做点别的。

The first part of the countermeasure: Whitelisting

对策的第一部分:白脱。

What we can be fairly sure of, is that the attacker is not able to detect and dynamically spoof the IP addresses of several thousand of our users(+). Which makes whitelisting feasible. In other words: for each user, we store a list of the (hashed) IPs from where the user has previously (recently) logged in.

我们可以相当肯定的是,攻击者无法检测并动态地欺骗我们数千用户的IP地址(+)。这使得白名单的可行性。换句话说:对于每个用户,我们存储用户先前(最近)登录的(散列)ip的列表。

Thus, our whitelisting scheme will function as a locked 'front door', where a user must be connected from one of his recognized 'good' IPs in order to log in at all. A brute-force attack on this 'front door' would be practically impossible(+).

因此,我们的白名单方案将作为一个锁住的“前门”,在这里,用户必须通过一个公认的“好”ip连接,才能登录。对这扇“前门”发动暴力袭击几乎是不可能的(+)。

(+) unless the attacker 'owns' either the server, all our users' boxes, or the connection itself -- and in those cases, we no longer have an 'authentication' issue, we have a genuine franchise-sized pull-the-plug FUBAR situation

(+)除非攻击者“拥有”服务器、我们所有用户的盒子或连接本身——在这些情况下,我们不再有“认证”问题,我们有一个真正的加盟商规模的拔塞式FUBAR模式

The second part of the countermeasure: System-wide throttling of unrecognized IPs

对策的第二部分:系统范围内对未被识别的ip进行节流

In order to make a whitelist work for an open-registration web service, where users switch computers frequently and/or connect from dynamic IP addresses, we need to keep a 'cat door' open for users connecting from unrecognized IPs. The trick is to design that door so botnets get stuck, and so legitimate users get bothered as little as possible.

为了让白名单在开放注册的web服务中工作,用户经常交换计算机和/或通过动态IP地址连接,我们需要为连接不被识别的IP地址的用户打开“猫门”。关键是要设计出这样的门,这样僵尸网络就会被卡住,所以合法的用户会被尽可能少的打扰。

In my scheme, this is achieved by setting a very restrictive maximum number of failed login attempts by unapproved IPs over, say, a 3-hour period (it may be wiser to use a shorter or longer period depending on type of service), and making that restriction global, ie. for all user accounts.

在我的方案中,这是通过在3小时内(根据服务类型的不同,可能更明智地使用更短或更长的时间)设置非常严格的未获批准的ip登录尝试的最大失败次数,并使该限制成为全局的(例如)。对所有用户帐户。

Even a slow (1-2 minutes between attempts) brute force would be detected and thwarted quickly and effectively using this method. Of course, a really slow brute force could still remain unnoticed, but too slow speeds defeat the very purpose of the brute force attack.

即使是缓慢的(在尝试之间1-2分钟),也可以通过这种方法快速有效地检测到暴力。当然,一个真正缓慢的蛮力仍然可以被忽略,但是速度太慢会导致蛮力攻击的目的。

What I am hoping to accomplish with this throttling mechanism is that if the maximum limit is reached, our 'cat door' slams closed for a while, but our front door remains open to legitimate users connecting by usual means:

我希望通过这个节流机制实现的是,如果达到了最大限度,我们的“猫门”会关闭一段时间,但我们的前门仍然对合法用户开放,通过通常的方式进行连接:

  • Either by connecting from one of their recognized IPs
  • 通过连接他们的一个公认的ip。
  • Or by using a persistent login cookie (from anywhere)
  • 或者使用一个持久的登录cookie(来自任何地方)

The only legitimate users who would be affected during an attack - ie. while the throttling was activated - would be users without persistent login cookies who were logging in from an unknown location or with a dynamic IP. Those users would be unable to login until the throttling wore off (which could potentially take a while, if the attacker kept his botnet running despite the throttling).

只有合法的用户才会在攻击中受到影响——即。当节流被激活时——将是没有持久登录cookie的用户,他们从一个未知的位置登录或使用动态IP登录。这些用户将无法登录,直到节流结束(这可能需要一段时间,如果攻击者保持他的僵尸网络运行,尽管节流)。

To allow this small subset of users to squeeze through the otherwise-sealed cat door, even while bots were still hammering away at it, I would employ a 'backup' login form with a CAPTCHA. So that, when you display the "Sorry, but you can't login from this IP address at the moment" message, include a link that says "secure backup login - HUMANS ONLY (bots: no lying)". Joke aside, when they click that link, give them a reCAPTCHA-authenticated login form that bypasses the site-wide throttling. That way, IF they are human AND know the correct login+password (and are able to read CAPTCHAs), they will never be denied service, even if they are connecting from an unknown host and not using the autologin cookie.

为了让这一小部分用户挤过另一个封闭的猫门,即使机器人还在不停地敲打,我将使用带有验证码的“备份”登录表单。因此,当你显示“对不起,但你现在不能从这个IP地址登录”消息时,包括一个链接,上面写着“安全备份登录-只有人类(机器人:不撒谎)”。玩笑归玩笑,当他们点击那个链接时,给他们一个验证过的登录表单,它将绕过站点范围的限制。这样,如果他们是人,并且知道正确的登录+密码(并且能够读取验证码),他们将永远不会被拒绝服务,即使他们正在连接一个未知的主机,并且没有使用autologin cookie。

Oh, and just to clarify: Since I do consider CAPTCHAs to be generally evil, the 'backup' login option would only appear while throttling was active.

哦,我想澄清一下:由于我确实认为验证码通常是有害的,所以“备份”登录选项只会在throttling选项是活动的时候出现。

There is no denying that a sustained attack like that would still constitute a form of DoS attack, but with the described system in place, it would only affect what I suspect to be a tiny subset of users, namely people who don't use the "remember me" cookie AND happen to be logging in while an attack is happening AND aren't logging in from any of their usual IPs AND who can't read CAPTCHAs. Only those who can say no to ALL of those criteria - specifically bots and really unlucky disabled people - will be turned away during a bot attack.

不可否认,这样的持续攻击仍将构成DoS攻击的一种形式,但随着系统描述,它只会影响我怀疑是一个很小的子集的用户,即那些不使用“记住我”饼干和碰巧登录登录而发生的攻击和不从任何平常的ip,谁看不清验证码。只有那些对所有这些标准都说不的人——特别是机器人和不幸的残疾人——会在机器人攻击中被拒之门外。

EDIT: Actully, I thought of a way to let even CAPTCHA-challenged users pass through during a 'lockdown': instead of, or as a supplement to, the backup CAPTCHA login, provide the user with an option to have a single-use, user-specific lockdown code sent to his email, that he can then use to bypass the throttling. This definitely crosses over my 'annoyance' threshold, but since it's only used as a last resort for a tiny subset of users, and since it still beats being locked out of your account, it would be acceptable.

编辑:事实上,我甚至想到一个办法让CAPTCHA-challenged用户通过在“锁定”:相反的,或作为补充,备份验证码登录,为用户提供一个选项来一次性,特定于用户的锁定代码发送给他的邮件,可以使用旁路节流。这显然是跨越了我的“烦恼”门槛,但因为它只是作为一小部分用户的最后手段,而且它仍然比被锁定在你的帐户上,这是可以接受的。

(Also, note that none of this happens if the attack is any less sophisticated than the nasty distributed version I've described here. If the attack is coming from just a few IPs or only hitting a few usernames, it will be thwarted much earlier, and with no site-wide consequences)

(另外,请注意,如果攻击比我在这里描述的糟糕的分布式版本更复杂,那么这些都不会发生。如果攻击仅仅来自几个ip,或者只攻击几个用户名,那么攻击将在更早的时候被挫败,并且不会造成站点范围内的影响)


So, that is the countermeasure I will be implementing in my auth library, once I'm convinced that it's sound and that there isn't a much simpler solution that I've missed. The fact is, there are so many subtle ways to do things wrong in security, and I'm not above making false assumptions or hopelessly flawed logic. So please, any and all feedback, criticism and improvements, subtleties etc. are highly appreciated.

所以,这就是我在我的auth库中要实现的对策,一旦我确信它是可靠的,并且我没有错过任何更简单的解决方案。事实是,在安全方面有很多微妙的方法来做错事,我也不介意做出错误的假设或毫无希望的有缺陷的逻辑。因此,我们非常感谢您的任何反馈、批评和改进、微妙之处等。

#2


16  

A few simple steps:

几个简单的步骤:

Blacklist certain common usernames, and use them as a honeypot. Admin, guest, etc... Don't let anyone create accounts with these names, so if someone does try to log them in you know it's someone doing something they shouldn't.

将一些常见的用户名列入黑名单,并将它们用作蜜罐。管理、客人等……不要让任何人用这些名字创建帐户,所以如果有人尝试登录他们,你知道这是某人做了不该做的事情。

Make sure anyone who has real power on the site has a secure password. Require admins/ moderators to have longer passwords with a mix of letters, numbers and symbols. Reject trivially simple passwords from regular users with an explanation.

确保任何在网站上有实权的人都有安全密码。要求管理员/版主拥有更长的密码,包含字母、数字和符号。拒绝普通用户的简单密码,并进行解释。

One of the simplest things you can do is tell people when someone tried to log into their account, and give them a link to report the incident if it wasn't them. A simple message when they log in like "Someone tried to log into your account at 4:20AM Wednesday blah blah. Click here if this wasn't you." It lets you keep some statistics on attacks. You can step up monitoring and security measures if you see that there's a sudden increase in fraudulent accesses.

你能做的最简单的一件事就是告诉人们什么时候有人试图登录他们的账户,并给他们一个链接,如果不是他们的话,报告事件。当他们登录的时候,一个简单的信息就像“有人试图在周三凌晨4点20分登录你的账户。”如果不是你就点击这里它允许您保存一些攻击的统计数据。如果您发现欺诈访问突然增加,您可以加强监视和安全措施。

#3


11  

If I understand the MO of brute force attacks properly, then one or more usernames are tried continuously.

如果我正确理解了蛮力攻击的MO,那么就会不断尝试一个或多个用户名。

There are two suggestions which I don't think I've seen yet here:

有两个建议我在这里还没有看到:

  • I always thought that the standard practice was to have a short delay (a second or so) after each wrong login for every user. This deters brute-force, but I don't know how long a one second delay would keep a dictionary attack at bay. (dictionary of 10,000 words == 10,000 seconds == about 3 hours. Hmm. Not good enough.)
  • 我一直认为,标准的做法是在每个用户错误登录后,有一个短暂的延迟(大约一秒钟)。这可以阻止蛮力,但我不知道一秒钟的延迟会使字典攻击持续多久。(万字字典=万秒= 3小时左右。嗯。不够好。)
  • instead of a site-wide slow down, why not a user-name throttle. The throttle becomes increasingly harsh with each wrong attempt (up to a limit, I guess so the real user can still login)
  • 与其让整个站点的速度慢下来,不如让用户名节流。由于每次错误的尝试,节流阀变得越来越粗糙(我想这是一个真正的用户仍然可以登录的限制)

Edit: In response to comments on a username throttle: this is a username specific throttle without regard to the source of the attack.

编辑:响应用户名节流阀上的评论:这是一个用户名特定的节流阀,不考虑攻击源。

If the username is throttled, then even a coordinated username attack (multi IP, single guess per IP, same username) would be caught. Individual usernames are protected by the throttle, even if the attackers are free to try another user/pass during the timeout.

如果用户名被禁用,那么即使是一个协调的用户名攻击(多IP、单猜测每个IP、相同的用户名)也会被捕获。每个用户名都受到油门的保护,即使攻击者可以在超时期间尝试另一个用户/传递。

From an attackers point of view, during the timeout you may be able to take a first time guess at 100 passwords, and quickly discover one wrong password per account. You may only be able to make a 50 second guesses for the same time period.

从攻击者的角度来看,在超时期间,您可以首次猜测100个密码,并迅速发现每个帐户的一个错误密码。你可能只能在同一时间段内猜测50次。

From a user account point of view, it still takes the same average number of guesses to break the password, even if the guesses are coming from multiple sources.

从用户帐户的角度来看,破解密码仍然需要相同的平均猜测次数,即使猜测来自多个源。

For the attackers, at best, it will be the same effort to break 100 accounts as it would 1 account, but since you're not throttling on a site wide basis, you can ramp up the throttle quite quickly.

对于攻击者来说,破坏100个帐户的效果与破坏1个帐户的效果是一样的,但是由于您没有在站点范围内进行限制,所以您可以很快地加快速度。

Extra refinements:

额外的改进:

  • detect IPs that are guessing multiple accounts - 408 Request Timeout
  • 检测猜测多个帐户的ip - 408请求超时
  • detect IPs that are guessing the same account - 408 Request Timeout after a large (say 100) number of guesses.
  • 检测猜测同一个帐户的IPs——在大量猜测(比如100次)之后的408请求超时。

UI ideas (may not be suitable in this context), which may also refine the above:

UI思想(可能不适合在此上下文中使用),这也可以细化上面的内容:

  • if you are in control of the password setting, then showing the user how strong their password is encourages them to pick a better one.
  • 如果您控制了密码设置,那么向用户展示他们的密码有多强,这将鼓励他们选择一个更好的密码。
  • if you are in control of the login page, after a small (say 10) number of guesses of a single username, offer a CAPTCHA.
  • 如果您控制登录页面,在一个小的(比方说10)个用户名的猜测数之后,提供一个验证码。

#4


8  

There are three factors of authentication:

认证有三个因素:

  1. A user knows something (ie, a password)
  2. 用户知道一些东西(比如,密码)
  3. A user has something (ie, a key fob)
  4. 用户有一些东西(如钥匙离岸价)
  5. A user is something (ie, retina scan)
  6. 用户是什么东西(比如视网膜扫描)

Usually, websites only enforce policy #1. Even most banks only enforce policy 1. They instead rely on a "knows something else" approach to two-factor authentication. (IE: A user knows their password and their mother's maiden name.) If you are able, a way to add in a second factor of authentication is not too difficult.

通常,网站只执行策略#1。即使是大多数银行也只执行政策1。相反,它们依赖于“知道其他东西”的双因素身份验证方法。(即:用户知道自己的密码和母亲的娘家姓。)如果可以,添加第二个身份验证因素的方法并不太难。

If you can generate around 256 characters of randomness, you could structure that in a 16×16 table, and then ask the user to give you the value in the table of cell A-14, for example. When a user signs up or changes their password, give them the table and tell them to print it off and save it.

如果你能产生大约256个字符的随机性,可以在16×16表结构,然后要求用户给你表中的值细胞14,例如。当用户注册或更改他们的密码时,给他们表格并告诉他们打印并保存。

The difficulty with that approach is that when a user forgets their password, as they will, you can't just offer the standard "answer this question and put in a new password", since that's vulnerable to brute-force as well. Also, you can't reset it and email them a new one, since their email could be compromised as well. (See: Makeuseof.com and their stolen domain.)

这种方法的困难在于,当用户忘记密码时,你不能仅仅提供标准的“回答这个问题并输入一个新密码”,因为这也很容易受到暴力攻击。此外,你不能重置它并给他们发一封新邮件,因为他们的邮件也可能被泄露。(参见:Makeuseof.com及其被盗域名。)

Another idea (which involves kittens), is what BOA calls SiteKey (I believe they trademarked the name). Briefly, you have the user upload an image when they register, and when they attempt to login, ask them to pick their image out of 8 or 15 (or more) random ones. So, if a user uploads a picture of their kitten, theoretically only they know exactly which picture is theirs out of all the other kittens (or flowers or whatever). The only real vunerability this approach has is the man-in-the-middle attack.

另一个想法(涉及小猫)是BOA称之为SiteKey(我相信他们注册了这个名字)。简单地说,当用户注册时,用户上传了一个图像,当他们试图登录时,请他们从8个或15个(或更多)随机选择他们的图像。因此,如果用户上传了小猫的照片,理论上只有他们知道其他小猫(或花或其他)的照片是他们的。这种方法唯一真正具有的不可逾越性是中间人攻击。

One more idea (no kittens though), is to track IPs that users access the system with, and require them to perform additional authentication (captcha , pick a kitty, pick a key from this table) when they log in from an address they haven't before. Also, similar to GMail, allow the user to view where they have logged in from recently.

还有一个想法(没有小猫),就是跟踪用户访问系统的ip,并要求用户在登录之前没有访问过的地址时执行额外的身份验证(captcha,选择一个kitty,从这个表中选择一个密钥)。同样,类似于GMail,允许用户查看最近登录的位置。

Edit, New Idea:

编辑新想法:

Another way of validating login attempts is to check whether or not the user has come from your login page. You can't check referrers, since they can be easily faked. What you need is to set a key in the _SESSION var when the user views the login page, and then check to make sure that key exists when they submit their login information. If bot does not submit from the login page, it will not be able to login. You can also facilitate this by involving javascript in the process, either by using it to set a cookie, or adding some information to the form after it has loaded. Or, you can split the form up into two different submits (ie, the user enters their username, submits, then on a new page enters their password and submit again.)

验证登录尝试的另一种方法是检查用户是否来自您的登录页面。你不能检查推荐人,因为他们很容易造假。您需要的是在用户查看登录页面时在_SESSION var中设置一个键,然后在提交登录信息时检查该键是否存在。如果bot没有从登录页面提交,它将无法登录。还可以通过在过程中使用javascript来设置cookie,或者在表单加载后向表单中添加一些信息来实现这一点。或者,你可以将表单分成两个不同的提交(例如,用户输入用户名,提交,然后在一个新页面上输入他们的密码,然后再次提交)。

The key, in this case, is the most important aspect. A common method of generating them is some combination of the user's data, their IP, and the time it was submitted.

在这种情况下,关键是最重要的方面。生成它们的常用方法是将用户的数据、IP和提交的时间组合起来。

#5


6  

I have to ask whether you've done cost-benefit analysis of this problem; it sounds like you're trying to protect yourself from an attacker who has enough web presence to guess a number of passwords, sending maybe 3-5 requests per IP (since you've dismissed IP throttling). How much (roughly) would that kind of attack cost? Is it more expensive than the value of the accounts you're trying to protect? How many gargantuan botnets want what you've got?

我必须问你是否对这个问题做了成本效益分析;这听起来像是在保护自己不受攻击者的攻击,攻击者有足够的网络存在,可以猜测多个密码,每个IP可能发送3-5个请求(因为您已经排除了IP节流)。这种攻击(粗略地)要花多少钱?它比你试图保护的账户的价值更贵吗?有多少庞大的僵尸网络想要你所拥有的?

The answer might be no -- but if it is, I hope you're getting help from a security professional of some sort; programming skill (and * score) do not correlate strongly to security know-how.

答案可能是否定的——但如果是的话,我希望你能得到某种安全专业人士的帮助;编程技能(和*分数)与安全知识没有很强的相关性。

#6


6  

I had previously answered a very similar question over at How can I throttle user login attempts in PHP. I'll reiterate the proposed solution here as I believe many of you will find it informational and useful to see some actual code. Please bare in mind that using a CAPTCHA might not be the best solution due to the increasingly accurate algorithms being used in CAPTCHA busters nowadays:

我之前曾回答过一个非常类似的问题,即如何限制PHP中的用户登录尝试。我将在这里重申所提出的解决方案,因为我相信许多人会发现它是信息和有用的,可以看到一些实际的代码。请记住,使用验证码可能不是最好的解决方案,因为现在验证码终结者中使用的算法越来越精确:

You cannot simply prevent DoS attacks by chaining throttling down to a single IP or username. Hell, you can't even really prevent rapid-fire login attempts using this method.

您不能简单地通过链接到单个IP或用户名来防止DoS攻击。见鬼,你甚至不能阻止使用这个方法的快速登录尝试。

Why? Because the attack can span multiple IPs and user accounts for the sake of bypassing your throttling attempts.

为什么?因为攻击可以跨越多个ip和用户帐户,从而绕过您的节流尝试。

I have seen posted elsewhere that ideally you should be tracking all failed login attempts across the site and associating them to a timestamp, perhaps:

我在其他地方看到过,理想情况下,你应该跟踪所有失败的登录尝试,并将它们与时间戳联系起来,也许:

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;

Decide on certain delays based on the overall number of failed logins in a given amount of time. You should base this on statistical data pulled from your failed_logins table as it will change over time based on the number of users and how many of them can recall (and type) their password.

根据给定时间内失败登录的总数确定某些延迟。您应该基于从failed_logins表中提取的统计数据,因为随着时间的推移,它将根据用户数量和他们中有多少人可以回忆(并键入)他们的密码而变化。


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

Query the table on every failed login attempt to find the number of failed logins for a given period of time, say 15 minutes:

在每次失败的登录尝试上查询表,以找到给定时间内失败登录的次数,例如15分钟:


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

If the number of attempts over the given period of time is over your limit, either enforce throttling or force all user's to use a captcha (i.e. reCaptcha) until the number of failed attempts over the given time period is less than the threshold.

如果给定时间段内的尝试次数超过了您的限制,要么强制执行节流,要么强制所有用户使用验证码(即再验证码),直到在给定时间段内失败尝试的次数小于阈值。

// 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;
    }
}

Using reCaptcha at a certain threshold would ensure that an attack from multiple fronts would be minimized and normal site users would not experience a significant delay for legitimate failed login attempts. I can't gaurantee prevention, as it's already been expanded upon that CAPTCHA's can be busted. There are alternative solutions, perhaps a variant of "Name this animal", which could work quite well as a substitute.

在某个阈值上使用reCaptcha将确保来自多个方面的攻击最小化,正常的站点用户不会因为合法失败的登录尝试而遇到严重的延迟。我不能保证预防,因为它已经被扩展到验证码上了。还有其他的解决办法,也许是“给这只动物起个名字”的变体,它可以作为替代品很好地发挥作用。

#7


5  

To summarize Jens' scheme into a pseudo state transition diagram/rulebase:

将Jens的方案总结为一个伪状态转换图/规则库:

  1. user + password -> entry
  2. 用户+密码->条目
  3. user + !password -> denied
  4. 用户+ !密码->被拒绝。
  5. user + known_IP(user) -> front door, // never throttle
  6. 用户+ known_IP(用户)->前门,//永不节流。
  7. user + unknown_IP(user) -> catflap
  8. 用户+ unknown_IP(用户)——> catflap
  9. (#denied > n) via catflaps(site) -> throttle catflaps(site) // slow the bots
  10. (#拒绝>n)通过catflaps(site) ->节流阀(site) //减速机器人。
  11. catflap + throttle + password + captcha -> entry // humans still welcome
  12. catflap +油门+密码+ captcha ->入口//人仍然欢迎。
  13. catflap + throttle + password + !captcha -> denied // a correct guess from a bot
  14. catflap +油门+密码+ !captcha ->否认// /一个机器人的正确猜测

Observations:

观察:

  • Never throttle the front door. The Elbonian state police have your computer, in your house, but are unable to interrogate you. Brute force is a viable approach from your computer.
  • 千万不要节流前门。Elbonian州警察在你家里有你的电脑,但是不能审问你。使用蛮力是一种可行的方法。
  • If you provide a "Forgetten your password?" link, then your email account becomes part of the attack surface.
  • 如果你提供了一个“忘记你的密码?”链接,那么你的电子邮件帐户将成为攻击表面的一部分。

These observations cover a different type of attack to the ones you are trying to counter.

这些观察涵盖了不同类型的攻击,而不是你想要对抗的攻击。

#8


4  

Looks like you are trying to defend against slow distributed brute force. Not that much you can do about it. We are using a PKI and no password logins. It helps, but if your clients chance workstations every once in a while, this is not very applicable.

看起来你在试图抵抗缓慢的分布式蛮力。对此你无能为力。我们使用的是PKI,没有密码登录。这是有帮助的,但是如果您的客户每隔一段时间就有机会使用工作站,这并不是很适用。

#9


3  

Disclaimer: I work for a two-factor company, but am not here to plug it. Here're some observations.

免责声明:我在一家双因素公司工作,但我不是来这里为它充电的。这里是一些观察。

Cookies can be stolen with XSS and browser vulns. Users commonly change browsers or clear their cookies.

使用XSS和浏览器vulns可以窃取cookie。用户通常会更改浏览器或清除他们的cookie。

Source IP addresses are simultaneously dynamically variable and spoofable.

源IP地址是动态可变和可欺骗的。

Captcha is useful, but doesn't authenticate a specific human.

验证码是有用的,但是不能验证特定的人。

Multiple methods can be combined successfully, but good taste is certainly in order.

多种方法可以成功地结合在一起,但一定要有好的品味。

Password complexity is good, anything password-based critically depends on passwords having sufficient entropy. IMHO, a strong password written down in a secure physical location is better than a weak password in memory. People know how to evaluate the security of paper documents much better than they know how to figure the effective entropy in their dog's name when used as a password for three different websites. Consider giving users the ability to print out a big or small page full of one-time use pass codes.

密码的复杂性是好的,任何基于密码的关键都取决于密码具有足够的熵。IMHO,在安全的物理位置写下的强密码比内存中的弱密码要好。人们知道如何评估纸质文档的安全性,这比他们知道如何在三个不同网站的密码中使用他们的狗的名字的有效熵值更好。考虑给用户打印满一次性使用密码的大或小页面的能力。

Security questions like "what was your high-school mascot" are mostly another lousy form of "something you know", most of them are easily guessable or outright in the public domain.

诸如“你高中时的吉祥物是什么”之类的安全问题,大多是另一种“你知道的东西”的糟糕形式,它们大多数都很容易被人猜出来,或者直接在公共领域被人猜出来。

As you noted, throttling back failed login attempts is a trade-off between preventing brute-force attacks and ease of DoSing an account. Aggressive lockout policies may reflect a lack of confidence in password entropy.

正如您所注意到的,限制失败的登录尝试是在防止暴力攻击和轻松地给帐户加药之间的权衡。积极的锁定策略可能反映出对密码熵缺乏信心。

I personally don't see the the benefit to enforcing password expiration on a website anyway. Attacker gets your password once, he can change it then and comply with that policy just as easily as you can. Perhaps one benefit is that the user might notice sooner if the attacker changes the account password. Even better would be if the the user were somehow notified before the attacker gained access. Messages like "N failed attempts since last login" are useful in this respect.

我个人并不认为在网站上强制执行密码过期的好处。攻击者一旦获得你的密码,他就可以改变它,并尽可能地遵守该政策。一个好处是,如果攻击者更改帐户密码,用户可能会提前通知。如果在攻击者获得访问权之前以某种方式通知用户,那就更好了。在这方面,像“自上次登录以来的N次失败尝试”这样的消息很有用。

The best security comes from a second factor of authentication which is out-of-band relative to the first. Like you said, hardware tokens in the "something you have" are great, but many (not all) have real admin overhead associated with their distribution. I don't know of any biometric "something you are" solutions good for websites. Some two-factor solutions work with openid providers, some have PHP/Perl/Python SDKs.

最好的安全性来自于第二个身份验证因素,与第一个因素相比,它是带外的。正如您所说,“您拥有的东西”中的硬件令牌非常棒,但是许多(不是全部)都有与它们的发行版相关的真正的管理开销。我不知道任何生物特征的“你是”的解决方案对网站有好处。一些双因素解决方案与openid提供者一起工作,其中一些有PHP/Perl/Python sdk。

#10


1  

No matter how good your system is, it'll fail under a long enough attack. There are some good ideas here, on how to extend a password's duration. (I personally like the idea of exponentially-increasing attempt rate limiting per-user and per-IP address.) But no matter what you go with, you'll need to back it up with some password rules.

无论你的系统有多好,它都会在长时间的攻击下失败。这里有一些好的想法,关于如何扩展密码的持续时间。(我个人喜欢指数增长的尝试速率限制每个用户和每个ip地址的想法。)但是不管你用什么,你都需要用一些密码规则来支持它。

I'd encourage you to figure out how fast a password can be cracked, and have users change them twice as often as that. Hope this helps.

我鼓励你弄清楚密码被破解的速度,让用户修改密码的频率翻倍。希望这个有帮助。

Edit: If you expect a lot of lazy attackers, requiring some CAPTCHA after multiple failed attempts is good: it raises the bar a little. If you're worried about a lot of intelligent attackers, hire a security consultant. ;)

编辑:如果您预期会有很多懒惰的攻击者,在多次失败的尝试之后需要一些验证码是很好的:它会增加一些门槛。如果你担心很多聪明的攻击者,请雇佣一个安全顾问。,)

#11


1  

My highest recommendation is to simply make sure that you keep users informed of bad login attempts to their accounts-- Users will likely take the strength of their password much more seriously if they are presented with evidence that somebody is actually trying to get into their account.

我的最高建议是,只要确保你让用户知道他们的账户登录尝试失败——如果用户看到有人试图进入他们的账户的证据,他们很可能会更加认真地对待自己密码的强度。

I actually caught somebody that hacked into my brother's myspace account because they had tried to get into the gmail account I setup for him and used the 'reset my password by email' feature... which went to my inbox.

我发现有人侵入我哥哥的myspace账户,因为他们试图进入我为他设置的gmail账户,并使用了“通过电子邮件重置我的密码”功能……我的收件箱收到了。

#12


1  

  1. What about requiring a one-time-password before entering their normal password? That would make it very obvious that someone was attacking before they got many opportunities to guess the main password?

    在输入常规密码之前,要求输入一次密码怎么样?这就很明显地表明,有人正在攻击,在他们有很多机会猜测主要密码之前?

  2. Keep a global count/rate of login failures - this is the indicator for an attack - during an attack be stricter about login failures e.g. ban IPs more rapidly.

    保持登录失败的全局计数/速率——这是攻击的指示器——在攻击期间对登录失败要更加严格,例如更快地禁止ip。

#13


0  

I don't believe there is a perfect answer but I would be inclined to approach it on a basis of trying to confound the robots if an attack is sensed.

我不相信有一个完美的答案,但我倾向于在感知到攻击时试图迷惑机器人。

Off the top of my mind:

我突然想到:

Switch to an alternate login screen. It has multiple username and password blanks which really do appear but only one of them is in the right place. The field names are RANDOM--a session key is sent along with the login screen, the server can then find out what fields are what. Succeed or fail it's then discarded so you can't try a replay attack--if you reject the password they get a new session ID.

切换到另一个登录屏幕。它有多个用户名和密码空白,但只有一个出现在正确的位置。字段名是随机的——会话密钥随登录屏幕一起发送,服务器就可以知道哪些字段是什么。成功或失败后,它将被丢弃,因此您不能尝试重播攻击——如果您拒绝密码,它们将获得一个新的会话ID。

Any form that is submitted with data in a wrong field is assumed to be from a robot--the login fails, period, and that IP is throttled. Make sure the random field names never match the legit field names so someone using something that remembers passwords isn't mislead.

任何在错误字段中提交数据的表单都被假定为来自机器人——登录失败、周期和IP被控制。确保随机字段的名称与合法字段的名称不匹配,这样使用能记住密码的东西的人就不会被误导。

Next, how about a different sort of captcha: You have a series of questions that won't cause problems for a human. However, they are NOT random. When the attack starts everyone is given question #1. After an hour question #1 is discarded, never to be used again and everyone gets question #2 and so on.

接下来,我们来看看另一种验证码:你有一系列不会给人类带来麻烦的问题。然而,它们不是随机的。当攻击开始时,每个人都要回答第一个问题。一个小时后,第一个问题被丢弃,再也不会被使用,每个人都会得到第二个问题,以此类推。

The attacker can't probe to download the database to put into his robot because of the disposable nature of the questions. He has to send new instructions out to his botnet within an hour to have any ability to do anything.

由于问题是一次性的,攻击者无法探查将数据库下载到他的机器人中。他必须在一个小时内将新的指令发送到他的僵尸网络上,才能做任何事情。

#14


0  

Since several folks included CAPTCHA as a fallback human mechanism, I'm adding an earlier * question and thread on CAPTCHA's effectiveness.

由于有几个人将CAPTCHA作为回退的人工机制,我在前面添加了关于CAPTCHA有效性的*问题和线程。

Has reCaptcha been cracked / hacked / OCR’d / defeated / broken?

已经破解/破解/破解/破解/破解了吗?

Using CAPTCHA doesn't limit improvements from your throttling and other suggestions, but I think the number of answers that include CAPTCHA as a fallback should consider the human-based methods available to people looking to break security.

使用CAPTCHA并不会限制您的节流和其他建议的改进,但是我认为,包括CAPTCHA作为一种退路的答案的数量应该考虑到那些希望破坏安全性的人可以使用的基于人工的方法。

#15


0  

You could also throttle based on the strength of a users password.

您还可以基于用户密码的强度进行节流。

When a user registers or changes their password you calculate a strength rating for their password, say between 1 and 10.

当用户注册或更改密码时,您将计算其密码的强度等级,比如1到10。

Something like "password" scores a 1 whereas "c6eqapRepe7et*Awr@ch" might score a 9 or 10 and the higher the score the longer it takes for throttling to kick in.

“password”之类的分数为1分,而“c6eqapRepe7et*Awr@ch”可能为9分或10分,分数越高,用于节流的时间就越长。

#16


0  

The first answer I've usually heard when asking this question is to change ports, but forget about that and just disable IPv4. If you only allow clients from IPv6 networks you'r no longer pray for simple network scanning and attackers will resort to DNS lookups. Don't run on the same address as your Apache(AAAA)/Sendmail(MX->AAAA)/what have you given out to everybody(AAAA). Make sure your zone can't be xferd, wait you'r allowing your zone to be downloaded by anybody?

我通常听到的第一个答案是更改端口,但是忘记它,然后禁用IPv4。如果你只允许来自IPv6网络的客户端,你将不再祈求简单的网络扫描,攻击者将求助于DNS查找。不要运行在与您的Apache(AAAA)/Sendmail(MX->AAAA)/您给每个人(AAAA)的内容相同的地址上。确保你的区域不能是xferd,等等,你是否允许任何人下载你的区域?

If the bots find your server setup new hostnames, just prepend some gibberish to your hostnames, and change your address. Leave the old names and even setup **honeypot names for the bot net to timeout on.

如果机器人发现你的服务器设置了新的主机名,只要在你的主机名前加上一些胡言乱语,然后改变你的地址。保留旧的名称,甚至为bot网络设置**蜜罐名称以超时。

** Test your reverse(PTR) records(under ip6.arpa.) to see if they can be used to zero in on /4's that have records VS /4s that don't. I.E. Typically ip6.arpa would have ~32 "."s in an address but trying with the last few missing might elude the network blocks that have records VS others that don't. If you take that further it becomes possible to skip large portions of the address space.

**测试你的反向(PTR)记录(ip6.arpa.下),看看它们是否可以用于记录没有记录的/4。即通常ip6。arpa应该是32 "在一个地址中,但是尝试寻找最后几个丢失的可能会避开有记录的网络块而不是其他没有记录的网络块。如果更进一步,就可以跳过大部分地址空间。

In the worst case users will have to setup an IPv6 tunnel, it's not like they'd have to go as far as VPNing into a DMZ... Though one wonders why that's not the first option.

在最坏的情况下,用户将不得不设置一个IPv6隧道,这并不像他们必须走到VPNing到DMZ……尽管有人想知道为什么这不是第一选择。

Also Kerberos is cool, but IMHO LDAP blows(What's technically wrong with NISPlus? I've read that Sun decided that users wanted LDAP and because of this they dropped NIS+). Kerberos does work fine without LDAP or NIS, just have to manage users on a host by host basis. Using Kerberos gives you an easy to use, if not automated, PKI.

Kerberos也很酷,但是不支持LDAP (NISPlus在技术上有什么问题吗?)我读到过Sun决定用户需要LDAP,因此他们放弃了NIS+)。没有LDAP或NIS, Kerberos可以很好地工作,只需根据主机对用户进行管理。使用Kerberos可以使PKI易于使用(如果不是自动化的话)。

#17


0  

Bit late here but I was thinking, assuming a hard case - the attacker uses a lot of random IPs, random user names and a random password selected from say a list of the 10,000 most popular.

在这里有点晚了,但是我在想,假设一个很困难的情况——攻击者使用了很多随机的ip,随机的用户名和一个随机的密码从一个10000最受欢迎的列表中选择。

One thing you could do, especially if the system seems under attack in that there are a lot of wrong password attempts on the system and especially if the password is low entropy is to ask a secondary question like what are your parents first names, for example. If an attacker hits a million accounts trying the password 'password1' there's a good chance they'll get a lot but their odds of also getting the names right would reduce successes dramatically.

你可以做的一件事是,特别是当系统似乎受到攻击时,因为系统上有很多错误的密码尝试,尤其是当密码熵很低时,你可以问第二个问题,比如你父母的名字是什么。如果一个攻击者点击了100万个密码“password1”,那么他们很有可能得到很多,但是他们获得正确名字的几率会大大降低成功的几率。