http://mdsec.net/auth/16/
http://mdsec.net/auth/32/
http://mdsec.net/auth/46/
http://mdsec.net/auth/49/
一个典型的登录表单要求用户输入两组信息(用户名和密码),而另外一些应用程序则需要更多信息(如出生日期、纪念地或PIN号码)。
如果登录尝试失败,当然可以得出结论:至少有一组信息出错。但是,如果应用程序通知是哪一组信息无效,就可以利用它显著降低登录机制的防御效能。
在最简单的情况下,如果只需要用户名和密码登录,应用程序可能会通过指出失败的原因(用户名无效或密码错误)来响应失败的登录尝试,如图6-3所示。
图6-3 详细的登录失败消息指出已猜测出有效的用户名
在这种情况下,攻击者可以发动一次自动化攻击,遍历大量常见的用户名,确定哪些有效。当然,用户名一般并非秘密(例如,登录时并不隐藏用户名)。但是,如果攻击者能够轻易确定有效的用户名,就更可能在有限的时间内、运用一定的技能、付出一定的精力攻破应用程序,并将枚举出的用户名列表作为随后各种攻击的基础,包括密码猜测、攻击用户数据或会话,或者社会工程 [1] 。
除主要的登录功能外,还可以对验证机制的其他组件进行用户名枚举。理论上,需要提交真实或潜在用户名的任何功能都可用于这一目的。例如,通常都可以对用户注册功能进行用户名枚举。如果应用程序允许新用户注册并指定他们自己的用户名,由于应用程序需要防止注册重复用户名,在这种情况下,几乎不可能阻止用户名枚举攻击。如本章后面部分所述,有时也可以对密码修改或忘记密码功能进行用户名枚举。
注解
许多验证机制以隐含或明确的方式提示用户名。根据设计常识,Web邮件账户的用户名通常为电子邮件地址。许多其他站点在应用程序中透露用户名,或者允许使用可轻易猜测出的用户名(如user1842,User1843等),并未考虑攻击者会对其加以利用的情况。
在更复杂的登录机制中,应用程序要求用户提交几组信息,或者完成几个步骤。这时,详细的失败消息或差异点可帮助攻击者轮流针对登录过程的每个阶段发动攻击,提高其获得未授权访问的可能性。
注解
这种漏洞可能会以更隐含的形式出现。即使响应有效和无效用户名的错误消息表面看来完全相同,它们之间仍然存在细微的差别,可用于枚举有效的用户名。例如,如果应用程序中的多条代码路径返回“相同的”失败消息,这些消息之间仍然可能存在细小的排版差异。有些时候,应用程序响应在屏幕上显示的内容完全相同,但其HTML源代码可能隐藏着细微的区别,如注释或布局方面的不同。如果无法轻易枚举出有效的用户名,应当仔细比较应用程序对有效和无效用户名作出的响应。
可以使用Burp Suite中的“比较”(Comparer)工具自动分析并突出显示两个应用程序响应之间的差异,如图6-4所示。这有助于迅速确定有效的用户名是否会导致应用程序的响应出现任何系统性的差异。
图6-4 使用Burp Suite确定应用程序响应的细微差别