1、验证码设置不合理
缺少对时间和错误次数限制,导致可枚举验证码,一般对4位数字验证码进行枚举;
图片验证码补充:
验证码用过后未失效,得通过用户点击获取新的验证码使其失效,登录操作可直接对密码进行暴力破解;
密码错误后前端向后端重新获取新的验证码,前端拦截获取新的验证码请求,使其旧验证码不过期,可以辅以暴力破解。
2、验证码直接在响应中返回给前端
验证码直接出现在响应中,观察请求验证码请求响应,body体和head信息应一并关注,遇到过开发把验证码放到cookie信息中返回的。
3、验证码未验证用户
服务端只判断了接接收到的验证码和手机号是否匹配,未判断手机号是否和用户匹配,因此修改响应可进行密码重置操作,仅适合网站用户名和手机号分离的设计,如果手机号就是用户名则不存在此类问题;
还有一种可能是重置密码绑定会话信息例如:token或cookie,验证码验证成功则服务端缓存该会话信息,可以替换为其他用户账号进行密码重置。
服务端应校验用户名、手机号、验证码、会话信息一致
4、客户端验证
此业务逻辑适合验证码标识返回给客户端,通过前端js代码判断验证码是否正确,前端的校验都是防用户的,但防不住白帽子。
5、万能验证码或空验证码
万能验证码如888888,开发时为了方便验证上线忘删除或一些特殊业务如记住密码,客户端保存账号和密码,通过拼接万能验证码888888进行拼接调用登陆请求错误的需求实现方式;
空验证就是将验证码code字段置为空或将code验证码整个删掉进行绕过。
6 、绕过校验步骤
目前很多厂商的重置密码都是类似如下图,分步骤进行操作:
通过步骤1可以通过响应提示遍历系统用户;
步骤2一般就是通过注册时的手机号/邮件验证码校验身份,一般绕过身份验证可以通过自己的手机号获取到正确的响应body进行替换绕过,一般前端js通过判断响应code值如1或200、true/false进行下一步跳转,或者通过记住步骤3的url,直接进行url跳转到3;
步骤3是最关键的一步,就算上述两种思路可以绕过步骤2成功到达设置密码的步骤,确认修改密码一般还要回调验证此账户步骤2是否验证通过,如步骤2通过后可能会在响应中添加验证成功的token随机数,进行步骤3操作时,带着步骤2响应的token再去校验,如果验证token,可以用自己的号码正确验证码获取token,去改其他用户的密码类似于3类型,如果不对步骤2回调验证,则可以直接重置成功。
7 、修改请求用户信息
通过修改自己密码,然后替换请求中对应用户的例如:user、id值,即可修改他人密码;
例如请求body ,遍历Userid字段即可批量重置,如果后端校验可尝试替换会话信息如cookie和token进行绕过。
Userid:1&Pwd:123456
8 、弱凭证
如有些业务是通过发送邮件进行密码重置的,可以通过对凭证用户id或时间戳进行枚举凭证重置越权其他人的密码
一种场景知道用户名和用户号就可以对该用户进行密码重置,重置后的密码通过邮件发送,可以通过暴力破解用户名和用户号进行任意密码重置,只是重置后的密码无法得知。
总结:
整理了一些平时学习用到的姿势,要根据不同的场景合理使用,不要仅局限于此,欢迎大佬们进行补充交流。