Web应用程序黑客的方法论(4)--Test the Authentication Mechanism

Posted by D on February 11, 2020

Web应用程序黑客的方法论来自书本 The Web Application Hacker’s Handbook

Testing the authentication mechanism

4.1 理解机制(Understand the Mechanism)

4.1.1
建立使用中的认证技术(例如,表单、认证证书或多因素).

4.1.2
定位所有与身份验证相关的功能(包括登录、注册、帐户恢复等).

4.1.3
如果应用程序没有实现自动自注册机制,请确定是否存在获取多个用户帐户的其他方法.

4.2 测试密码质量(Test Password Quality)

4.2.1
审查应用程序,了解对用户密码实施的最低质量规则的任何描述.

4.2.2
尝试设置各种弱密码,使用任何自注册或密码更改功能来建立实际执行的规则.尝试使用简短的密码、字母字符、单大小写字符、字典单词和当前用户名.

4.2.3
验证凭证不完整的测试.设置一个强而复杂的密码(例如,12个字符,包含大小写混合的字母、数字和印刷字符).尝试使用此密码的不同变体进行登录,方法包括删除最后一个字符、更改字符大小写以及删除任何特殊字符.如果这些登录尝试中的任何一个成功了,那么继续系统地进行试验,以确定实际执行的验证是什么.

4.2.4
在建立了最低密码质量规则和密码验证的范围之后,确定密码猜测攻击需要使用的值的范围,以获得良好的成功概率.尝试定位任何可能不符合标准密码复杂性要求的内置帐户.

4.3 测试用户名枚举(Test for Username Enumeration)

4.3.1
标识提交用户名的各种身份验证函数中的每个位置,包括通过屏幕上的输入字段、隐藏的表单字段或cookie.常见的位置包括主登录、自注册、密码更改、注销和帐户恢复.

4.3.2
对于每个位置,提交两个请求,其中包含一个有效的用户名和一个无效的用户名.查看服务器对每对请求的响应的每个细节,包括HTTP状态代码、任何重定向、屏幕上显示的信息、HTML页面源中隐藏的任何差异以及服务器响应所花费的时间.注意,有些差异可能是细微的(例如,相同的错误消息可能包含细微的排版差异).您可以使用拦截代理的历史记录功能来检查与服务器之间的所有流量.WebScarab有一个比较两个响应的功能,可以快速突出它们之间的差异.

4.3.3
如果您观察到提交了有效用户名和无效用户名的响应之间有任何差异,请使用不同的值对重复测试,确认存在系统差异,可以为自动用户名枚举提供基础.

4.3.4
检查应用程序中可能使您能够编译有效用户名列表的任何其他信息泄漏源.例如,记录功能、注册用户的实际列表,以及在源代码注释中直接提到姓名或电子邮件地址.

4.3.5
找到任何接受用户名的辅助身份验证,并确定它是否可以用于用户名枚举.要特别注意允许用户名特别指定的注册页面.

4.4 测试密码猜测的弹性(Test Resilience to Password Guessing)

4.4.1
标识应用程序中提交用户凭据的每个位置.两个主要实例通常是主登录函数和密码更改函数.后者通常是猜测密码攻击的有效目标,只有在可以提供任意用户名的情况下.

4.4.2
在每个位置,使用您控制的帐户,手动发送包含有效用户名但其他无效凭证的几个请求.监控应用程序的响应以识别任何差异.大约10次登录失败后,如果应用程序没有返回关于帐户锁定的消息,请提交包含有效凭证的请求.如果此请求成功,则帐户锁定策略可能不有效.

4.4.3
如果您没有控制任何帐户,请尝试枚举或猜测一个有效的用户名,并使用此猜测发出几个无效请求,以监视关于帐户锁定的任何错误消息.当然,您应该知道这个测试可能会暂停或禁用属于另一个用户的帐户.

4.5 测试任何帐户恢复功能(Test Any Account Recovery Function)

4.5.1
确定应用程序是否包含任何工具,以便用户在忘记凭据的情况下重新获得对其帐户的控制.这通常是由一个忘记您的密码链接附近的主要登录功能.

4.5.2
通过使用您控制的帐户完成恢复过程的完整演练,确定帐户恢复功能如何工作.

4.5.3
如果该函数使用一个质询(challenge)例如一个秘密问题,请确定用户是否可以在注册期间设置或选择自己的质询(challenge).如果是,请使用枚举或常用用户名的列表来获取challenges列表,并查看任何容易猜测的challenge.

4.5.4
如果该函数使用密码提示,则执行相同的操作来分解密码提示列表,并识别任何看起来容易猜测的提示.

4.5.5
对您在主登录功能中形成的任何帐户恢复challenges执行相同的测试,以评估易受自动猜测攻击的漏洞.

4.5.6
如果该功能涉及向用户发送电子邮件以完成恢复过程,请查找可能使您能够控制其他用户帐户的任何弱点.确定是否可以控制发送电子邮件的地址.如果消息包含惟一的恢复URL,则使用您控制的电子邮件地址获取大量消息,并尝试识别任何可能使您能够预测向其他用户发出的URL的模式.应用步骤 5.3 中描述的方法来识别任何可预测的序列.

4.6 测试任何记住我的功能(Test Any Remember Me Function)

4.6.1
如果主登录函数或它的支持逻辑包含一个Remember Me函数,激活它并检查它的效果.如果这个函数允许用户在以后的场合登录而不需要输入任何凭证,那么您应该仔细检查它是否存在任何漏洞.

4.6.2
仔细检查在激活Remember Me函数时设置的所有持久cookie.查找任何显式标识用户的数据,或包含用户的可预测标识的数据.

4.6.3
即使存储的数据似乎被严重编码或混淆,也要仔细检查,并比较记住几个非常相似的用户名and/or密码的结果,以确定是否有机会对原始数据进行反向工程.应用步骤5.2中描述的方法来识别任何有意义的数据.

4.6.4
根据您的结果,修改您的cookie的内容在适合的方式,试图伪装成其他用户的应用程序.

4.7 测试任何模拟功能(Test Any Impersonation Function)

4.7.1
如果应用程序包含任何允许一个用户模拟另一个用户的显式功能,请仔细检查其中的任何漏洞,这些漏洞可能使您在没有适当授权的情况下模拟任意用户.

4.7.2
查找用于确定模拟目标的任何用户提供的数据.试图操作此操作以模拟其他用户,特别是管理用户,这可能使您能够升级特权.

4.7.3
如果您对其他用户帐户执行任何自动猜测密码的攻击,请查找任何具有多个有效密码的帐户,或具有相同密码的多个帐户.这可能表示存在后门密码,管理员可以使用该密码以任何用户的身份访问应用程序.

4.8 测试用户名唯一性(Test Username Uniqueness)

4.8.1
如果应用程序有一个自注册功能,允许您指定所需的用户名,则尝试用不同的密码注册相同的用户名两次.

4.8.2
如果应用程序阻止了第二次注册尝试,则可以利用此行为枚举已注册的用户名.

4.8.3
如果应用程序注册了两个帐户,则进一步探查以确定当用户名和密码发生冲突时它的行为.尝试更改其中一个帐户的密码以匹配另一个帐户的密码.另外,尝试用相同的用户名和密码注册两个帐户.

4.8.4
如果应用程序在用户名和密码发生冲突时向您发出警告或生成错误,您可能会利用这一点来执行自动猜测攻击,以发现其他用户的密码.以枚举或猜测的用户名为目标,并尝试创建具有此用户名和不同密码的帐户.当应用程序拒绝指定密码时,您可能已经找到了目标帐户的现有密码.

4.8.5
如果应用程序似乎能够容忍用户名和密码的冲突而没有出现错误,则使用冲突凭证登录.确定发生了什么,以及是否可以利用应用程序的行为获得对其他用户帐户的未授权访问.

4.9 测试自动生成凭证的可预测性(Test Predictability of Autogenerated Credentials)

4.9.1
如果应用程序自动生成用户名或密码,请尝试快速连续获取多个值,并识别任何可检测到的序列或模式.

4.9.2
如果以一种可预测的方式生成用户名,则向后推断以获得可能有效的用户名列表.您可以将此作为自动密码猜测和其他攻击的基础.

4.9.3
如果密码是以一种可预测的方式生成的,则推断该模式以获得向其他应用程序用户发出的可能的密码列表.这可以与您获得的任何用户名列表相结合来执行密码猜测攻击.

4.10 检查凭证的不安全传输(Check for Unsafe Transmission of Credentials)

4.10.1
浏览所有与认证有关的功能,包括主要的登录、帐户注册、密码更改,以及任何允许查看或更新用户资料的页面.使用拦截代理监视客户端和服务器之间双向传递的所有流量.

4.10.2
确定凭证在任意方向传输的每个情况.您可以在代理中设置侦听规则来标记包含特定字符串的消息.

4.10.3
如果凭证曾经在URL查询字符串中传输过,那么在浏览器历史记录、屏幕上、服务器日志中,以及在遵循第三方链接时在Referer header中,这些凭证可能很容易被泄露

4.10.4
如果凭据曾经存储在cookie中,那么这些cookie可能容易受到XSS攻击或本地隐私攻击.

4.10.5
如果凭证曾经从服务器传输到客户端,那么这些凭证可能会被会话管理或访问控制中的任何漏洞或XSS攻击所破坏.

4.10.6
如果凭证是通过未加密的连接传输的,那么这些凭证很容易被窃听者截获.

4.10.7
如果凭据是使用HTTPS提交的,而登录表单本身是使用HTTP加载的,则应用程序很容易受到中间人攻击,这种攻击可能用于捕获凭据.

4.11 检查凭证的不安全分发(Check for Unsafe Distribution of Credentials)

4.11.1
如果帐户是通过一些带外通道创建的,或者应用程序有一个自注册功能,它本身并不确定用户的所有初始凭证,那么建立向新用户分发凭证的方法.常见的方法包括将消息发送到电子邮件或邮政地址.

4.11.2
如果应用程序生成了带外分发的帐户激活URLs,请尝试连续注册多个新帐户,并识别接收到的URLs中的任何序列.如果可以确定一个模式,则尝试预测发送给最近和即将到来的用户的URLs,并尝试使用这些URLs获得其帐户的所有权.

4.11.3
尝试多次重用一个激活URL,看看应用程序是否允许这样做.如果没有,请尝试在重用URL之前锁定目标帐户,看看URL是否仍然有效.确定这是否允许您在活动帐户上设置新密码.

4.12 不安全存储测试(Test for Insecure Storage)

4.12.1
如果您访问散列密码,请检查具有相同散列密码值的帐户.尝试使用最常见的散列值的普通密码登录.

4.12.2
使用离线彩虹表的哈希算法来恢复明文值.

4.13 逻辑缺陷检验(Test for Logic Flaws)

4.13.1 测试Fail-Open条件(Test for Fail-Open Conditions)

4.13.1.1
对于应用程序检查用户凭证(包括登录和密码更改功能)的每个函数,使用您控制的帐户以正常方式遍历该过程.注意提交给应用程序的每个请求参数.

4.13.1.2
重复此过程多次,依次以各种意想不到的方式修改每个参数,以干扰应用程序的逻辑.对于每个参数,包括以下更改:

  • 提交一个空字符串作为值
  • 删除name/value
  • 提交非常长和非常短的值
  • 提交字符串而不是数字,反之亦然
  • 多次提交具有相同和不同的值的相同的命名参数

4.13.1.3
仔细检查应用程序对上述请求的响应.如果与基本用例发生任何意外的背离,将此观察反馈到您的进一步测试用例框架中.如果一个修改导致了行为上的变化,尝试将它与其他变化结合起来,将应用程序的逻辑推到极限.

4.13.2 测试任何多级机制(Test Any Multistage Mechanisms)

4.13.2.1
如果任何与身份验证相关的功能涉及到在一系列不同的请求中提交凭据,请确定每个不同阶段的明显目的,并注意在每个阶段提交的参数.

4.13.2.2
重复此过程多次,以干扰应用程序逻辑的方式修改请求序列,包括以下测试:

  • 完成所有阶段,但顺序与预期不同
  • 依次直接进入每个阶段,然后从那里继续正常的顺序
  • 依次跳过每一阶段,并从下一阶段开始继续正常的顺序,这样重复几次
  • 根据您的观察和该机制每个阶段的明显目的,尝试考虑进一步修改序列的方法,并访问开发人员可能没有预料到的不同阶段

4.13.2.3
确定是否在多个阶段提交任何单个信息(例如用户名),因为它从用户那里捕获了多次,或者因为它通过客户端以隐藏的表单字段、cookie或预先设置的查询字符串参数进行传输.如果是这样,尝试在不同的阶段提交不同的值(有效和无效)并观察效果.尝试确定所提交的项是否有时是多余的,或者在某个阶段进行验证,然后在随后进行信任,或者在不同的阶段针对不同的检查进行验证.尝试利用应用程序的行为获得未经授权的访问或降低该机制施加的控制的有效性.

4.13.2.4
查找任何通过客户机传输的数据,这些数据在任何时候都没有从用户那里捕获.如果使用隐藏参数来跨连续阶段跟踪流程的状态,则可能通过以精心设计的方式修改这些参数来干扰应用程序的逻辑.

4.13.2.5
如果过程的任何部分涉及到应用程序提出了一个不断变化的挑战,测试两个常见的缺陷:

  • 如果指定挑战的参数与用户的响应一起提交,请确定是否可以通过修改此值有效地选择自己的challenge.
  • 尝试使用相同的用户名进行多次不同的challenge,并确定是否提出了不同的challenge.如果是的话,你可以通过重复进行这个阶段,直到你想要的challenge出现,来有效地选择你自己的challenge.

4.14 利用任何漏洞获得未经授权的访问(Exploit Any Vulnerabilities to Gain Unauthorized Access)

4.14.1
检查您在各种自动识别功能中发现的任何漏洞,并确定您可以利用的任何漏洞来实现攻击应用程序的目标.这通常涉及到尽可能尝试作为具有管理权限的不同用户进行身份验证.

4.14.2
在进行任何类型的自动攻击之前,请注意您所识别的任何帐户锁定防御.例如,当对登录函数执行用户名枚举时,在每个请求中提交一个通用密码,而不是一个完全任意的值,这样就不会浪费对每个发现的用户名的失败登录尝试.类似地,在宽度优先而不是深度优先的基础上执行任何密码猜测攻击.以最常见的弱密码开始您的单词列表,然后遍历这个列表,对每个枚举的用户名尝试每个条目.

4.14.3
在构造用于任何密码猜测攻击的单词列表时,请考虑密码质量规则和密码验证的完整性,以避免不可能或过于复杂的测试用例.

4.14.4
使用Chapter 14中描述的技术,使尽可能多的工作自动化,并最大化您的攻击的速度和有效性.

Web应用程序黑客的方法论(3)
Web应用程序黑客的方法论(5)

: