探测 Microsoft 的自助密码重置(SSPR)端点,以枚举已注册的验证方式,并标记出任何缺少强第二因素的方式。提供用户枚举以及跨 Entra 账户的 MFA 态势近似评估。
[!NOTE] 截至 2026 年 8 月,Microsoft 已从 SSPR 流程中移除旧版 CAPTCHA,并以后端限流和基于行为的滥用检测取而代之(参见 MC1400824)。Microsoft 的立场是,后端控制足以检测并阻止自动化滥用。
# Install pipx if needed
apt install pipx && pipx ensurepath
# From a local clone
git clone https://github.com/mlcsec/ResetSpy.git
cd ResetSpy
pipx install .
python3 -m venv .venv
pip install -r requirements.txt
# Single acc
resetspy [email protected]
# Email file (one per line)
resetspy emails.txt
# Proxy
resetspy emails.txt --proxy http://127.0.0.1:8080
# Export to CSV with increased delay
resetspy emails.txt --csv results.csv --delay 4
# Full HTTP debug — request/response headers and bodies printed to stderr
resetspy [email protected] -v
每次请求之间会在 --delay 的基础上添加随机抖动。
对于 429 响应和网络错误,会应用指数退避(最多 --retries 次尝试)。默认延迟为 2 秒;对于大批量,请增加到
4-6 秒。每次请求都会从 16 个常见 User-Agent 池(Windows、macOS、iOS、Android)中轮换 User-Agent。
Microsoft 的合并安全信息注册体验自 2020 年起默认启用,可在单一流程中为 SSPR 和 MFA 注册身份验证 方法。在实践中,这意味着在大多数现代 Entra ID 租户上,通过 SSPR 可见的方法与保护登录的方法 相同。未注册强 SSPR 方法的账户,很可能就是未注册强 MFA 方法的账户。
参考资料:
SSPR 和 MFA 是独立的注册表。 合并注册使它们在大多数情况下 重叠,但它们并不是同一回事。如果某个方法是在合并注册启用之前注册的,或者管理员将其从 SSPR 策略中排除, 那么它可能存在于 MFA 中,但在此处不可见。
SSPR 不支持 FIDO2 安全密钥和基于证书的身份验证。 Microsoft 从未将这些方法添加到 SSPR 流程中。如果用户唯一注册的因素是 FIDO2 密钥或智能卡,在此处会显示为 没有方法——这是假阴性。在实践中,这对标准用户来说很少见,但在高安全性或无密码环境中更为常见。
参考资料:
逐方法策略不匹配。 管理员可以允许某个方法用于 MFA 登录,但将其从 SSPR 策略中排除,反之亦然。例如,组织可能允许身份验证器推送用于登录,但不允许用于密码 重置。该工具只能看到 SSPR 愿意提供的内容。
SSPR 完全禁用(SSPR_0011)。 如果用户未获得 SSPR 许可或未为其
启用 SSPR,端点会返回 ViewSsprNotEnabledInUserPolicy,并且没有可用的方法信息。该账户存在且很可能已配置 MFA,
但此工具无法确定具体是什么。
访客和联合账户。 外部用户和 B2B 访客通过其主租户进行身份验证。资源租户的 SSPR 端点无法
查看其主租户的 MFA 注册情况,并会返回
ViewFeatureNotAvailable。从此端点无法看到他们的 MFA 态势。
租户范围的方法限制。 如果管理员在 SSPR 策略中禁用了某一方法类别,则无论个人注册情况如何, 都不会向任何用户提供该方法,从而无法区分“方法未注册”和“方法已禁用”。
管理员账户始终启用 SSPR。 Microsoft 的 SSPR 策略 设置仅适用于标准最终用户。无论租户 SSPR 策略如何,管理员账户始终启用自助密码重置, 并且 Microsoft 要求他们注册两种身份验证方法。这是在平台层面强制执行的,租户管理员无法禁用。
参考:SSPR 策略文档
[!IMPORTANT] 这对侦察有一个有用的含义。如果某个租户中为标准用户禁用了 SSPR(返回
ViewSsprNotEnabledInUserPolicy), 那么任何成功进入方法选择屏幕的账户都可能是特权角色的成员。当更广泛的租户策略被禁用时,能够通过 SSPR 干净枚举的账户 会作为可能的管理员账户而显得突出,并且即使标准用户的方法不可见,他们注册的方法也是可见的。 这允许识别高价值目标和特权账户,以便将其单独挑出进行进一步针对性攻击。
CurrentViewName 响应字段被用作结果的基准真相——而不是 HTML 正文匹配Microsoft 的 SSPR 门户(passwordreset.microsoftonline.com)在接受有效用户名后,会显示
联系人方法选择屏幕(MultigateAuthenticationControl)。返回的 HTML 会在 MultigateAuthenticationControl_RadioTable 中将每个已注册的
验证方法列为单选按钮。其 <tr> 行为 display:none 的方法未为该用户注册,
会被跳过。
对于每个目标,该工具执行两个请求。首先,GET 落地页以建立会话并提取 ASP.NET 表单令牌(__VIEWSTATE、
__EVENTVALIDATION、WorkflowConsistencyCheck),这些令牌是服务器接受 POST 所必需的。这些令牌以加密方式绑定到
会话 cookie,无法预测或跨会话重用。其次,POST 提交电子邮件地址以及这些令牌,复现用户点击 Next 时浏览器执行的
异步 UpdatePanel 回发。
ASP.NET 线路响应中的 CurrentViewName 隐藏字段被用作服务器所做决定的
权威信号,而不是对 HTML 正文进行子字符串匹配。
备用电子邮件和安全问题被标记为弱,因为它们可被钓鱼,并且不满足第二因素的意图。仅使用弱方法或完全没有方法的账户会被标记。
[!NOTE] Microsoft 支持软件 OATH 令牌和硬件 OATH 令牌(预览版)用于 SSPR。通过身份验证器应用输入的软件 OATH 令牌很可能通过同一个
AppCodeRadio按钮 呈现,与 TOTP 一样——两者都表现为六位数代码输入——因此它们可能已经涵盖,无需单独的单选 ID。硬件 OATH 令牌(物理 密钥扣)是不同设备类别,但也会生成基于时间的代码;它们可能通过同一个按钮或另一个尚未在此流程测试期间观察到的按钮 呈现。
| 标志 | 默认值 | 描述 |
|---|
--delay SECONDS | 2.0 | 请求之间的基础延迟;会自动添加抖动 |
--retries N | 1 | 遇到瞬时错误时每个账户的最大重试次数 |
--proxy URL | 代理;会自动禁用 SSL 验证 | |
--csv FILE | 将所有结果导出到 CSV | |
-v / --verbose | 将完整的请求/响应头和正文打印到 stderr |
| 能力 | 支持 |
|---|
| 用户枚举(账户是否存在) | 是 |
| SSPR 方法枚举 | 是 |
| MFA 方法推断(通过合并注册) | 近似——对大多数标准租户可靠 |
| FIDO2 / 基于证书的 MFA 检测 | 否 |
| 访客 / 联合账户 MFA | 否 |
| SSPR 被禁用的账户 | 否(已确认账户存在,方法未知) |
| 管理员账户识别 | 部分——管理员始终启用 SSPR,因此当租户 SSPR 在其他情况下被禁用时,他们可能会显得突出 |
| 单选 ID | 方法 | 强度 |
|---|
MultigateAuthenticationControl_AltEmailRadio | 备用电子邮件 OTP | 弱 |
MultigateAuthenticationControl_SecurityQuestionsRadio | 安全问题 | 弱 |
MultigateAuthenticationControl_AppCodeRadio | 身份验证器应用(TOTP) | 足够 |
MultigateAuthenticationControl_MobileAppNotificationRadio | 身份验证器推送通知 | 足够 |
MultigateAuthenticationControl_PhoneRadio | 电话呼叫 / SMS | 足够 |
MultigateAuthenticationControl_OfficePhoneRadio | 办公电话 | 足够 |
| 状态 | 含义 |
|---|
MFA OK | 找到账户;SSPR 中至少注册了一个强第二因素 |
NO MFA | 找到账户;没有强因素(仅弱方法或未注册方法) |
NOT FOUND | 用户名在目录中不存在 |
SSPR DISABLED | 账户存在,但管理员策略阻止 SSPR(例如 SSPR_0011)——方法未知 |
SSPR N/A | SSPR 不支持该账户类型——访客、外部或联合用户 |
CAPTCHA | 服务器显示了 CAPTCHA;需要人工干预 |
ERROR | 意外响应或网络故障 |