双因素认证漏洞
滥用"记住我"功能
应用程序可以实现"记住我"功能,以便从同一设备进行的下一次身份验证不需要输入第二因子。为了实现此功能,应用程序可以将长期有效的令牌保存到 cookie 和/或记住 IP 地址。
如果是长期有效的令牌,您可以检查以下几点:
令牌是随机生成的
每个用户和会话(设备)的令牌不同
令牌安全存储,无法从 JavaScript 访问,检查 Cookie 安全
检查是否可以远程撤销记住的设备
如果应用程序记住 IP,检查是否可以使用 HTTP 头部伪造 IP,检查 滥用 IP 白名单
滥用 IP 白名单
应用程序可以"记住"用户进行身份验证的 IP 地址,并在后续登录时不要求第二因子。如果应用程序依赖 HTTP 头部来确定客户端的 IP 地址,请尝试使用以下头部伪造 IP 地址:
使用 OTP 时的常见情况
启用 2FA 不会终止之前创建的会话
启用双因子认证必须撤销所有现有会话。如果这种情况没有发生,受害者将无法管理其账户的安全性。结果,攻击者可以在启用第二因子后很长时间内保持之前创建的活动会话。
忽略 2FA
应用程序在执行可能导致自动登录到用户账户的操作时可能会忽略双因子认证。
滥用半认证会话
应用程序可以在提供凭据后发出具有有限访问权限的会话令牌。尝试在取消注册请求中使用此会话令牌来禁用 2FA(或访问需要身份验证的 API 端点)。您可以通过以下步骤进行检查:
向应用程序提交凭据
从响应中捕获会话令牌
在 2FA 步骤停止身份验证
在取消注册请求(或 API 请求)中使用该令牌
无需 2FA 要求登录账户(访问敏感数据/执行更改)
参考:
跨平台应用程序
应用程序的移动或桌面版本的双因子认证实现可能与 Web 版本不同。双因子认证可能较弱或完全缺失。
禁用 2FA 不需要确认
如果应用程序在禁用双因子认证时不需要额外的确认(当前密码、当前 OTP、来自短信的代码等),这提供了通过 CSRF、XSS 或点击劫持攻击禁用双因子认证的选项。
密码恢复/邮箱确认
应用程序可以在密码恢复/邮箱确认过程完成后自动登录账户,而不需要第二因子。例如,您可以通过以下步骤检查密码恢复:
登录账户。
启用双因子认证。
进行密码恢复。
如果更改密码后无需第二因子就进入账户,则应用程序存在漏洞。
使用第三方账户登录
应用程序在通过第三方账户(如社交网络、Github、Google 等)登录时可能会忽略双因子认证。您可以通过以下步骤进行检查:
登录账户。
启用双因子认证。
链接第三方账户。
如果通过第三方账户登录不需要第二因子,则应用程序存在漏洞。
使用测试环境或旧版 API
如果应用程序的测试版本公开可用,请尝试使用您的凭据登录。在此类环境中,双因子认证可能被禁用。非生产环境可以位于主域的单独域或子域上,例如:
beta.website.com
stage.website.com
beta-website.com
stagewebsite.com
等。
另外检查是否有旧版 API 可用,它们可能不需要第二因子或没有速率限制算法。如果应用程序支持 API 版本控制,版本可以在 URL 或 HTTP 头部中传递,例如:
https://api.website.com/v1/users
https://website.com/api/v1/users
Accept: application/test.data.v1.12+json
等。
参考:
对 2FA 页面的不当访问控制
使用双因子认证时,应用程序可以使用具有预定义参数的 URL 将用户定向到特殊页面。如果此页面可以在没有 cookie 或使用来自另一个会话的 cookie 的情况下访问,您可以检查以下情况:
URL 生成
URL 过期日期
搜索引擎 URL 索引
如果 URL 被猜测到、被搜索引擎索引、具有很长的过期日期,它可以用于无需输入凭据即可登录账户。因此,如果有绕过双因子认证的方法,您可以访问其他用户的账户。
对备份码的不当访问控制
备份码在启用第二因子后立即生成,并且仅在启用后可用。对于每个后续请求,可以重新生成代码或保持不变。
尝试找到可能从对备份码显示端点的请求响应中窃取备份码的漏洞。
不当的速率限制
基于时间的 2FA
长期有效的代码
使用基于时间的代码的应用程序通常维护一个时间间隔,在此期间代码有效,因此人们可以慢慢输入它们。由于新代码以 n
秒为步长生成(通常 n
是 30-60 秒),多个代码同时有效。但是,允许窗口中的每个代码都是用户账户的有效代码。如果代码在一小时内有效,在此窗口内许多代码同时有效。因此,猜测有效代码要容易得多,因为在可能的代码集中有多个有效代码。
例如,如果代码以 30 秒为步长生成,并且这里常见的有效性范围是相对于服务器设置时间的任一方向约 5 分钟,则允许窗口为 [current_time - 5 mins, current_time + 5mins]
,同时有效的代码数量为 10 分钟 * 60 秒 / 30 秒 = 20 个代码
。
参考:
使用旧代码
应用程序可以撤销当前代码,并且不存储最新代码的时间戳以拒绝比当前代码更旧的代码。结果,攻击者能够使用比用户选择输入的代码更旧的代码。您可以通过以下步骤进行检查:
打开两个不同的浏览器并登录
在两个浏览器中都进入 2FA 屏幕
获得有效的 2FA 代码,并将其写下来,暂不使用
等待下一个有效的 2FA 代码,并在一个浏览器中使用它登录
在另一个浏览器中,尝试使用之前写下的旧 2FA 代码登录
如果您可以使用两个会话登录,则应用程序存在漏洞
混合 2FA 模式
应用程序可以提供多种 2FA 模式,如基于 SMS 和基于 TOTP 的 2FA 流程。如果应用程序使用除半认证会话 cookie 之外的每用户唯一参数来引用所需的 2FA 模式,您可以尝试使用您未由受害者使用的 2FA 模式完成身份验证流程。攻击流程的示例可能包含以下步骤:
受害者设置基于 SMS 的 2FA
攻击者使用认证器应用程序(基于 TOTP 的 2FA)注册 2FA 并保存其唯一参数,例如
factor_id
攻击者输入受害者的邮箱地址和密码
如果密码正确,攻击者的浏览器被发送新的身份验证 cookie 并重定向到
/mfa/sms/verification
攻击者不遵循到 SMS 验证表单的重定向。相反,攻击者将其
factor_id
和来自认证器应用程序的代码与受害者的半认证 cookie 一起发送到 TOTP 验证端点:/mfa/totp/verification
端点。
参考:
会话持久性到 2FA 流程
通常,身份验证流程在传递凭据后初始化会话,并等待第二因子完成流程。尝试在此步骤更改密码/禁用 2FA 并完成身份验证流程。如果会话没有超时或者您可以自己续订(例如通过更改身份验证方式)并且应用程序允许您登录,即使在更改密码/禁用 2FA 后,您仍然可以访问用户账户。
攻击的示例如下:
攻击者获得对没有 2FA 的受害者账户的访问权限。
攻击者为受害者账户启用 2FA。
在另一个浏览器中,攻击者在传递凭据后停止,并在此步骤无限期等待。
攻击者为受害者账户禁用 2FA。
受害者重新获得对账户的访问权限并更改密码/重置会话。
攻击者使用 2FA 完成流程并再次获得对账户的访问权限。
参考:
弱共享密钥
大多数基于代码的 2FA 系统依赖于共享密钥。如果此密钥实际上不是加密安全的,或者非常短,攻击者可能能够猜测它。结果,攻击者将能够生成有效的代码。
如果您有源代码访问权限,请确保密钥是使用加密强度生成器生成的。大多数编程语言的默认随机数生成器是可预测的,这意味着攻击者可能能够确定哪些密钥分配给哪些用户。此外,验证共享密钥至少 20 字节长,因为出于安全目的应避免使用较短的密钥。
如果您可以审查源代码,请尝试检查密钥的长度和明显的随机性(使用条形码扫描仪扫描 QR 码以检索密钥)。为同一账户或不同账户生成几个密钥,并尝试回答以下问题:
每个密钥是否不同?
密钥的任何部分是否似乎是顺序的?
密钥的任何部分是否基于账户信息?
其他不安全的情况?
参考
最后更新于