密码重置功能是 Web 应用中常见且核心的安全环节,一个细微的逻辑缺陷就可能导致整个账户体系沦陷。站在攻击者角度,劫持任意用户密码重置流程的核心思路可概括为:
- 初始化重置:为目标用户(受害者)发起密码重置请求。
- 拦截/篡改凭证:获取或控制用于身份验证的重置凭证(如Token、验证码、USERID等)。
- 接管流程:将本应发送给目标用户的凭证,转发或引导至攻击者控制。
- 完成重置:利用获取到的凭证,最终修改目标用户的密码。
下文将围绕几种常见的密码重置漏洞类型及其挖掘思路展开讨论。
客户端状态校验不全
这是逻辑漏洞的一种常见形式。应用程序错误地将本应由服务器端完全掌控的关键业务状态(如“是否已通过身份验证”)委托给了不可信的客户端(如浏览器)来存储和维护。当客户端将这些状态值返回服务器时,若服务器未进行二次验证,便会引发漏洞。
漏洞利用
进入“忘记密码”页面,输入任意验证码并抓包。尝试修改返回包中的参数状态值,例如将常见的code改为0,或将false改为true等。



接下来正常输入新密码并点击“下一步”抓包,继续修改响应值,即可成功重置密码。
挖掘思路
- 寻找目标场景:关注前台的忘记密码、找回账号等功能。如果前台没有对应功能,可以尝试从前端 JavaScript 代码中提取相关接口进行测试。
- 测试服务端是否缺少校验:通过修改客户端返回的状态值(例如将
“verified”:false 改为 “verified”:true),观察服务器是否仅依据此值来判断步骤是否完成,从而绕过验证。
步骤分离与校验不足
密码重置往往涉及多个步骤(如身份验证、Token验证、设置新密码)。如果步骤间的状态校验不充分,攻击者可能绕过关键验证步骤。
漏洞利用
本地搭建 Dedecms(版本 5.7),创建账户 test1 以及 test2。

登录 test1 账户,随后构建 payload,将其中的 id 参数修改为目标账户的 id。

发送请求获取 key,成功获取 key 值后即可利用此 key 修改目标账户的密码。

挖掘思路
- 测试步骤间状态关联性校验:尝试直接访问重置流程中后续步骤的 URL(例如
/reset/step2、/reset/step3),而不完成其前置步骤。观察系统是否允许直接跳转,并在后续步骤的请求中,是否缺乏对前置步骤已完成的验证(例如缺少一个能证明你已通过第一步验证的Token或Session标识)。
- 操作参数以便越权至其他用户:分析每一步请求中用于标识状态或用户的参数(如
user_id、temp_token、session_id)。检查其是否可预测,并尝试修改这些参数(例如递增或递减user_id),观察是否能切换到其他用户的重置流程。同时,检查这些参数在步骤间是否保持一致,第一步生成的Token或Session标识,是否在后续步骤的请求中被正确校验并与当前用户绑定。
鉴权不严使用简单可预测的用户标识符
许多系统在对用户身份进行认证时,会使用简单的参数作为用户的唯一标识,而这类标识容易被攻击者预测。例如,某些系统直接将 USERID 作为用户密码重置时的标识,攻击者只需枚举其他用户的 USERID 即可重置其密码。
漏洞利用
在对某购物网站进行流量监听时,发现某接口的响应如下:


在响应体中,包含参数:“showResetPassword”:false, “showModifyEmails”:false,其值表示当前用户角色禁用了密码重置和电子邮件修改选项。在 Burp Suite 中拦截该流量包,并修改响应包。

刷新页面后,会发现用户管理界面出现了新的操作选项:

此处,后端接口返回的JSON字段 “showResetPassword”:false 仅用于前端UI决策,未在后端任何鉴权逻辑中进行二次校验。攻击者通过篡改响应包为 “showResetPassword”:true,即可让前端渲染出重置密码按钮。
随后,对所拥有的账户发起密码重置,系统返回 200 状态码并提供了有效的密码重置链接。

访问该链接后,可成功重置密码。

拦截密码重置接口的请求包,发现请求体中仅包含:{“userId”:9438867,“resetAccessKey”:false},没有其他鉴权参数。该端点未检查当前会话是否具备对指定 userId 的操作权限,也未校验当前用户是否有权进行此操作。

重新抓包,将 USERID 修改为另一个账户的 USERID,密码修改成功并可成功登录该账户。

该系统采用了可预测的、单调递增的数字 userld 作为标识符。此时,攻击者只需遍历一个整数区间,即可批量枚举有效用户并重置其密码。
挖掘思路
- 收集令牌样本:通过直接请求,找到应用程序中生成令牌的功能点(如密码重置、邮箱验证),并反复触发。有时应用程序在日志、调试页面或错误信息中也会意外泄露其他用户的令牌。
- 分析模式与结构:观察令牌的字符组成(纯数字、字母数字组合等)、可能的编码方式(如Base64、Hex),并尝试解码。将多个样本放在一起对比,寻找其中固定不变的部分和规律变化的部分。
- 破解生成算法:
- 如果令牌是纯数字且接近当前时间,可能是时间戳或其变换。
- 如果是特定长度的十六进制字符串,可能是哈希值(如MD5、SHA-256),可尝试猜测其原始输入。
- 如果令牌看起来是随机的,但你能获得连续输出,可以尝试推断其内部状态以预测后续值。
- 也可以尝试在前端源码中下断点,分析令牌的生成算法。
账号与校验参数未绑定
密码重置流程通常需要向用户发送验证凭证(如Token、验证码)。如果接收端参数由客户端提供且可篡改,则可能导致凭证被发送至攻击者控制的地址。
漏洞利用
案例一:接收端参数可控
在密码重置页面,输入任意账号,选择邮箱方式找回。在身份验证页面点击获取短信验证码:

拦截请求,发现接收验证码的邮箱为请求包中的一个参数,而此参数可控。直接将其篡改为攻击者的邮箱,此时攻击者成功接收到验证码。

提交验证码后再次抓包,修改其中邮箱为获取验证码的邮箱。此时系统仅校验了验证码是否正确,只要输入正确的验证码即可通过验证。随后正常执行后续步骤即可成功重置该账号的密码。


此处漏洞形成的主要原因是服务器未将实际要重置的账号和验证码进行绑定,导致输入其他用户邮箱所对应的正确验证码也可以重置当前用户的密码。
案例二:验证码转发
在测试任意密码重置功能时,可以尝试在关键参数后面添加额外参数,将验证码转发到攻击者控制的接收端。

攻击者收到验证码后,直接填写即可完成密码重置,修改受害人密码。
案例三:凭证未与用户身份绑定
在密码重置流程中,当使用重置密码凭证执行最终操作时,服务端若没有严格校验和绑定令牌与最初申请者的身份关系,仅校验令牌是否有效,就会导致越权。

当用户已经验证过验证码,在凭证有效期内,攻击者同时进行重置密码操作,即可利用未失效的令牌实现任意密码重置。


输入正确验证码后会触发校验接口,获取重置当前密码的凭证。攻击者利用获取到正确凭证的间隙,在重置密码的请求中,修改控制目标账号的参数为受害人的参数,即可重置其他用户的密码。


挖掘思路
- 还原正常的密码重置流程:记录关键步骤(输入账号、发送验证码、输入验证码、设置新密码)。拦截和分析每一步的HTTP请求,仔细观察请求参数和响应内容。特别注意系统如何确定接收端:是从数据库查询绑定信息,还是通过客户端参数指定。
- 识别接收端参数:在拦截的请求中,寻找可能与接收端相关的参数。
- 直接参数:
phone, mobile, email, to, receiver等。
- 间接参数:
user_id, uid, id, username, account等(系统可能用这些标识去查询绑定的接收端)。
- 测试参数的可篡改性:
- 直接替换:修改直接指定接收端的参数值为攻击者控制的地址。
- 间接关联:修改用户标识参数为另一个账户,看验证码是否发送到该账户的绑定地址。
- 参数污染:尝试添加多个相同的参数,观察系统如何处理。
- 测试步骤间的关联性缺失:测试在不同步骤中,系统是否正确地关联了用户身份。例如,第一步输入目标用户名,第二步发送验证码的请求中尝试修改用户标识,看系统是否会向错误的目标发送验证码。
- 测试验证码与接收端的绑定校验:在提交验证码和设置新密码的阶段,尝试用攻击者收到的验证码去重置目标用户的密码。如果成功,说明系统只验证了验证码的有效性,而未校验其与目标用户的绑定关系。
总结
密码重置逻辑漏洞的挖掘,核心在于理解业务流程并尝试打破其预设的校验逻辑。通过分析请求参数、篡改客户端状态、测试步骤关联性、枚举或预测用户标识等方法,往往能够发现此类安全隐患。这类漏洞通常不涉及复杂的逆向加解密,对于刚入门安全/渗透测试或 SRC 挖掘的安全爱好者而言,是很好的实战切入点。理解并掌握这些思路,能有效提升在渗透测试中发现逻辑缺陷的能力。如果你对更多实战技巧和漏洞分析感兴趣,欢迎在云栈社区交流讨论。

