进行这个整理,是因为在XXX项目的时候,发现登录模块的忘记密码功能,在验证用户身份的时候是通过手机验证码验证的。通过修改响应包的返回参数值,可以绕过验证,进入第三步的密码重置。还有最近测试的一个sso登录,也存在验证码问题。

之前的测试中也遇到过类似的验证码绕过的漏洞,所以对验证码绕过方法进行一个总结,以及关于登录模块可能会存在的逻辑漏洞进行一个小整理。

其实,会出现验证码的地方,也就是校验用户身份处,比如,登录、忘记密码、注册、绑定、活动领取、反馈处等。而登录模块中可能存在的逻辑漏洞,无非就是用户枚举、任意用户密码重置,当然认证绕过也是逻辑漏洞,这个我们暂且放在验证码里面。


绕过短信验证码的方法以及例子

通过修改响应包的返回值绕过

这种是用户端根据返回的值,来确定是否进行下一步。比如发送成功返回state的值是success,失败是false,然后客户端根据state的值,来确定下一步的动作。这样,我们可以通过修改响应包,绕过验证。

例1

比如忘记密码处:第二步中,对用户的身份进行短信验证,可通过修改响应包,将error换为ok即可绕过身份验证,到设置密码处。

例2

注册处,验证手机验证码处,通过修改响应包,或替换为自己的手机号,绕过验证码的限制,造成使用他人手机号进行注册。

例3

有些登录也存在类似的问题,随便输入账号密码,拦截返回的响应包,将包替换为A账号正确的登录返回的响应包(前提是,A账号的cookie是有效的),即可登录到A账号。这种也是客户端,根据响应包的值,来决定下一步动作。

服务端未对身份做校验

这种比较少,因为算是功能问题,在验证身份时,未对答案进行校验。就是随便输入,就能进入下一步。

例4

忘记密码处,第二步中,选择其他方式找回,通过密保找回,未对密保答案进行验证,随便输入答案,即可跳转到设置密码处。

验证码置空绕过验证

短信验证码处,随便输入其他,验证码错误,而置空却不校验,则可以通过置空绕过

例5

我的==>登陆==>短信验证码登陆登陆时抓包把code(验证码字段)值置为空,即可登陆任意账户

发送短信时,将手机号替换为自己的手机号获取验证码

当修改别人的信息时,需要短信认证时,在发送短信时,我们可以尝试,将手机号替换为自己的,来获取短信验证码。如果服务端只是检查验证码是否正确,而不是进行手机号和验证码匹配的话,或者只是匹配发送短信手机号和验证码,我们就可以绕过认证。

例6

忘记验证码,验证身份时,在发送短信时,拦截,将手机号替换为我们自己的,发送。然后再输入得到验证码,验证,如果此时只是验证码验证码是否正确,即可绕过。

但是,若验证发送手机号和验证码是否匹配时,我们可以在填好验证码,提交时,拦截,将手机号再次改为我们自己的,即可绕过。

允许一次给多个手机号发送短信,获取验证码

在给手机发送短信验证码时,比如phone=13211111111,我们同时向多个手机号发送短信,用逗号隔开,即phone=13211111111,13233333333,可发送成功。所有手机收到相同的验证码,后面在验证验证码时,如果可以匹配成功的话,即可绕过验证码。另外,这样可以向大量手机号发送,造成费用增加。

例7

注册处,在获取短信验证码时,抓包将mobilePhone的值改为多个手机号,并用逗号分隔,可成功多个手机号发送短信验证码。

短信验证码太短,爆破绕过

有的短信验证码位数太短,采用4为纯数字的短信验证码作为登录认证的凭证,这样若是没有对次数限制或存在图形验证码的话,就很容易采用工具进行爆破验证码登录。

例8

重置密码处根据短信验证码,是否正确来确定是否能修改成功,而且验证码是四位纯数字的,可以进行爆破。code=4935&mobile=18556530793&pwd=123456a

利用接口标记绕过短信限制

注册、忘记密码、修改密码处,均存在发送短信验证,可能会设置参数值的不同,来判断是执行什么样的功能。比如type=1是注册,type=2是忘记密码,type=3是修改密码等。我们可以通过修改参数值,来绕过一分钟内只发送一次限制,达到短信轰炸的目的。

例9

注册页面处,URL/public/getPhoneVerifyCodeWithCheckPicVerCode正常逻辑是验证图片验证码,正确后,再发送手机验证码。将请求修改为/public/getPhoneVerifyCode,从而绕过图片验证码的验证机制。

例10

注册页面处,发送短信验证码处,可以结合上例中的绕过图形验证码的机制,发现smsType的值,不同时,可以绕过180秒限制。可以遍历修改smsType的值,从而造成短信炸弹。

例11

注册,在发送手机验证码或邮箱验证码处,r=2时,连续发送验证码,会提醒“重新输入验证码”,说明验证了图形验证码。但是r=5时,可以发送成功,连续发送时,提醒“一分钟内不允许多次发送”。

仅有一分钟内不允许多次发送验证码限制,但是并未对图形验证码进行校验,可以通过甚至频率,使其,两分钟发送一次,同样可以造成短信/邮箱轰炸。

例12

绑定手机号处,正常的发送短信的URL是sendSMS4Mobile,尝试修改URL,是否存在其他发送接口。经过不断尝试,sendSMS接口同样可以发送短信。

利用空格绕过短信条数限制

通过在参数值的前面加上空格,进行绕过一天内发送次数的限制。比如,mobile=13211111111,一天可以发送10次,超过10次今天将不再发送,第二天才可以继续发送。但是,可以通过在手机号前面或后面加上空格又可以发送10次。比如,mobile= 13211111111,前面加个空格,就可以再次发送成功。

通过修改cookie值绕过短信次数

有些发送短信的次数是根据cookie值进行判断,(此cookie值并不是登录状态下的cookie而不是普通状态下的),利用当前cookie值来验证发送次数的话,很容易被绕过。

例子https://bbs.ichunqiu.com/forum.php?mod=viewthread&tid=27614

之前有个登录账号密码错误三次,就会出现图形验证码。但是当关闭浏览器,重新打开,再登录,又会有三次机会,当时,芦浩分析得出是根据cookie判断的,然后通过,不断获取新的cookie,来绕过三次限制,进而进行账户密码枚举。

http://wiki.iflytek.com/pages/viewpage.action?pageId=128550855

修改IP绕过短信/邮箱轰炸

有些是验证当前IP,如果当前IP短时间内获取短信或邮件频繁或达到一定的次数,会锁定当前IP,这时可以尝试通过修改IP或代理IP来进行绕过限制

利用大小写绕过邮箱轰炸限制

有时候验证码是发送到邮箱的,可以通过修改邮箱后面字母的大小写绕过限制。比如:email=@qq.com,当次数达到限制时,将字母修改为大写:email=@Qq.com,即可绕过。

修复建议:

1、服务端对验证码进行校验,短信验证码应该根据用户存在数据库中的手机号收到的验证码进行匹配验证。

2、增加复杂的图形验证码,且一次性有效

3、限制一天内发送的上限


用户枚举

在验证用户身份的时候,或判断用户是否已注册时,若验证码处理不当、或错误提醒明确,都可能存在用户枚举。

缺乏/未验证的图形验证码,造成用户枚举

例1

忘记密码处,首先验证用户身份,虽然此处有图形验证码,但是,图形验证码不刷新,即不是一次有效,通过拦截请求,发现,并未对验证码进行验证。可以进行用户枚举

例2

手机验证码登录处,在校验手机号是否是已注册的手机号时,绑定的手机号和未绑定的手机号,返回的响应包不同,而且未增加图形验证码校验,可对已绑定的手机号枚举。

例3

忘记密码处,图形验证码参数为imageValidCode,重复放包时,发现,验证码是一次有效的,经过尝试,发现删除imageValidCode参数,可以绕过验证码的验证机制,从而进行用户枚举。爆破已注册的账号。

提醒明确,造成的用户枚举

一些错误,提醒明确,比如登录时,输入账号、密码,均错误的情况下,提醒账号错误;账号正确、密码错误时,提醒密码错误,从而可以进行枚举。

例4

登录处,输入错误的账号,会提醒用户不存在;错误的密码,会提醒密码不正确。可根据提示,进行用户、密码枚举。

例5

关联账户绑定==>切换账户处,根据loginname的值,返回对应账号的绑定的手机、邮箱等个人信息。当loginname为不存在的账号时,响应包为“操作失败”,而且请求包中,仅有loginname这一个参数,可以对其进行用户枚举。

 

例6

在密码修改功能,会验证原始密码和账号的正确性,账号、密码都正确时resCode=00100000,账号错误resCode=00100001,msg为空。账号正确,密码错误时,msg提醒原始密码错误。可以进行枚举其他账号、密码。比如,可以枚举密码为1111的账号。

修复建议:

1、 模糊提醒

2、 增加复杂的图形验证码,对于登录后可能存在的枚举,增加token,且一次性有效

3、 限制请求频率,错误一定次数,锁定账号一段时间


任意用户密码重置

造成任意用户密码重置,主要发生在修改密码、忘记密码处,在逻辑上处理不严谨造成的。比如,忘记密码处,先验证身份,验证通过才允许密码重置,前面验证很严谨,不能绕过,但是第三步不严谨,比如仅根据账号来进行密码重置,那就很可能存在任意用户密码重置。

例1

忘记密码处,最后一步更新新密码处,通过抓包,发现仅是根据账号进行密码修改,那么修改account为任意存在的账号,就可以修改任意账号的密码。

修复建议:

逻辑上要严谨,不能说前面校验现在要重置密码的人是A后,就认为后面的操作都是A的。还是要进行校验确认的。