11.4 密码找回
密码找回是出现逻辑问题最多的一个功能,因为它的交互流程最多,目前找回密码的方式比较常见的有邮箱验证码、手机验证码以及密保问题,这个流程通常如图11-10所示。
图 11-10
这个三个大流程中都经常有一些逻辑问题,下面我们来详细看看。
1.输入用户名/邮箱/手机阶段
这里有一个交互过程,即需要输入要重置的账号信息,单击确定的时候,目前大部分的应用会直接从数据库中读取用户邮箱和手机信息,并且发送验证码,还有一部分程序在输入用户名后,会提示使用手机还是邮箱找回密码,并且邮箱和手机号中的一部分会显示在页面上,比如网易账号,如图11-11所示。
提交的时候可以直接抓包修改手机或者邮箱参数,这时候如果后端没有做验证,原本发送给账号A的验证码会发送到被我们篡改的手机或者邮箱上,利用接收到的验证码即可重置密码。
2.填写验证码和新密码阶段
填写验证码和新密码就意味着我们已经拿到了验证码或者重置密码的URL,这里存在的问题主要有:
图 11-11
1)验证凭证较简单,可以被暴力破解 。目前大多数手机短信重置密码的验证码都是4位或者6位数字,如果提交验证码的地方没有对这个验证码进行错误次数限制,则会存在可以爆破的问题,这是目前最常见的一种找回密码漏洞利用方式。
2)验证凭证算法简单,凭证可预测 。部分网站找回密码的Token是根据当前的“用户名+邮箱”或者时间戳进行一次MD5后生成,这就存在一定的预测性,利用自己写的算法去碰撞即可拿到争取到的重置密码凭证。
3)验证凭证直接保存在源码里 。这种目前比较少,不过也存在一定比例,一种是在点击发送验证码的时候就可以直接在源码里看到给当前手机或者邮箱发送过去的验证码,还有一种是在输入验证码的时候,源码里面就直接保存了正确的验证码。
3.发送新密码阶段
凭证未绑定用户 :我们在找回密码的时候,发送到邮箱的链接通常是如下这个样子
http : //www.xxx.com/user.php ? m=repwd&uid= 用户 ID&key= 凭证密钥 &email= 邮箱
当请求这个链接的时候,后端程序根据uid和key对应上了从而判断这个找回密码的链接有效,但是在将新密码提交到服务器的时候,服务器端并没有判断当前这个key是否跟uid或者email匹配,而是直接修改掉了uid或者email指定的用户密码,这样我们只要拦截修改密码的请求包,将里面的用户参数修改成我们要篡改密码的用户账号即可。
基于以上对密码找回的利用方法分析,可以想到的安全风险点应该注意的有:
1)接收验证码的邮箱和手机号不可由用户控制,应该直接从数据库中读取出来。
2)加强验证凭证复杂度,防止被暴力破解。
3)限制验证凭证错误次数,单个用户在半个小时内验证码错误三次,半小时内禁止找回密码。
4)验证凭证设置失效时间。
5)验证凭证不要保存在页面。
6)输入用户邮箱或ID、手机号取验证凭证的地方需要设置验证码防止短信炸弹和批量找回等。
7)验证凭证跟用户名、用户ID、用户邮箱绑定,找回密码时验证当前凭证是否是当前用户的。