译文声明
本文是翻译文章,文章原作者Youstin,文章来源:https://youst.in/
原文地址:(Bypassing 2FA using OpenID Misconfiguration (youst.in))
译文仅供参考,具体内容表达以及含义原文为准
两步验证迅速成为所有身份验证系统的一种规范标准,然而错误实现它通常会导致防御机制无用化。
有许多文章会分析过缺少速率限制,不正确的访问控制和令牌泄漏这些漏洞,
但是本文会介绍由OpenID实现中的错误配置引发的一种独特的绕过技巧。
目标是一家拥有50多个全球品牌的公司,其中许多品牌使用该公司的OpenID系统进行身份验证。
该公司的主网站是符合这种情况的,身份提供者和每一个品牌(或网站)都依赖OpenID系统去执行身份验证并配置OpenID流量。
当我们测试一个近期添加到程序范围的网站时,我注意到不同于其他网站,该网站通过Google身份验证器强制执行两步验证。在查看在后台发送的请求,我注意到在单击登录按钮时,会发送与此请求类似的请求:

首当其冲是参数。我以前在查看OpenID流量时没有遇到过它,所以我认为这是一些自定义配置,可以导致一个容易的2FA绕过。
第一个明显的想法是尝试移动该值并仅保留该值。虽然我正确地被重定向到身份提供者的登录页面,但在使用正确的证书登录时,如果该值被移动,我总是会遇到401错误。
acr_values``otp``password``otp
经过进一步的测试,越来越明显的是,这不是一个草率的2FA实现,但它是RFC 8176中说明的一个完善的协议。
通常,每个"amr"值都为一系列密切相关的身份验证方法提供一个标识符。例如,"otp"标识符特意地根据时间和 HMAC(Hashed Message Authentication Code)去覆盖 OTPs(One-Time Passwords)。
许多依赖方会满足于知道除了密码之外还使用了OTP;使用哪种OTP之间的区别对于他们来说不重要。因此,有一个单独的标识符可以满足两种或更多种几乎等效的方式。
基本上,参数将告诉身份提供者客户端请求了哪些身份认证方式。在完成登录流后,客户端网站的回应将包含一个 JWT,如果对其进行解码,将包含如下所示使用的 AMR 值:acr_values
{"alg":"HS256","typ":"JWT"}.{"state":"123456789","auth_time":1234,"amr":["pwd","otp"] ...
先篡改值再以身份提供者登录只是受到一堆401错误的欢迎,所以我很快就放弃了想法。
RFC 8176的第 5 节介绍了实现 AMR 时的以下安全注意事项:
基于特定身份认证方式的依赖可能会导致系统脆弱化,因为某些可能适合于一个特定的认证的认证方式会随着时间的推移而变化。
因此,依赖于 AMR 的 OpenID 配置应确保仅接受受信任和经过验证的身份验证方式。
某些可能适合于一个特定的认证的认证方式会随着时间的推移而变化,这既是由于对现有方式下的攻击的演变,也是由于新身份认证方法的部署。
阅读上文让我想到,可能还有其他一些可用的acr值可以测试。rfc 的第二部分列出了 22 种已定义的身份验证方法,因此我决定测试一些acr值。
不久之后,在将值从 切换为并输入证书时,我看到了下图:acr_values``otp+password``sms+password

这看起来很有希望,所以我使用了一次性的SMS验证服务,并遵循了整个过程。
添加电话号码并确认所有权后,我成功地跳过了Google身份验证器窗口,并且还登录了。
我报告了此问题,并将其作为高危来分类并奖励。团队让我知道这是由于客户端网站同时启用了OTP和SMS,即使没有用于启用SMS作为两步验证方法的UI。
这是一个明显的案例,如何简单地利用AMR协议的错误配置引入意料不到的安全漏洞。