页面图片验证码测试思路

  • A+
所属分类:安全文章

页面图片验证码测试思路

前言

网站在进行登录时,一般都存在验证码,用来防止机器大规模注册,机器暴力破解数据密码等危害。但是验证码也并不是绝对安全的,这与验证码的自身复杂度、生成机制、验证机制、传输流程等都有关系。验证码一旦被绕过,那么就完全失去了它的作用,下面总结一下对于验证码测试的思路,其中涉及的示例有的是实际遇到的,有的是自己搭建的环境。

一般验证码的流程

客户端发起请求->服务端响应并创建一个新的SessionID同时生成随机验证码,将验证码和SessionID一并返回给客户端->客户端提交验证码连同SessionID给服务端->服务端验证验证码同时销毁当前会话返回给客户端结果

一种前后端分离的验证码实现方案

  • js生成一个随机数保存在localstorage里。

  • 带上随机数请求服务器

  • 服务器根据客户端信息加密随机数。verify_code = f(rand)

  • 根据加密结果生成验证码,返回base64图片

  • 当用户提交验证码的时候,随机数一起带过来

  • 服务器通过之前的加密规则验证是否正确

根据上面验证码的流程,可以把每个流程分离出来,分别分析各个流程中可能会出现的问题,例如客户端、服务端、验证码自身、传输流程、验证流程。

客户端

前端验证

这种验证码是在前端由JS生成并验证,所以生成和验证过程中不会和服务器进行交互


测试方法

一般这样的验证码不会特别复杂,进行验证时,查看浏览器审查元素中的网络,或者查看抓包软件记录,若其中不存在和服务器交互的数据包,则可以猜测是前端验证,这时候,只需要把JS禁用就可以绕过验证,或者直接在Burp中进行提交数据(因为验证码不是服务端生成所以前端不会向后端发送验证码)


验证码直接输出在前端


这类验证码生成的不是图片,而是直接生成的HTML代码,这就导致了可以直接查看前端代码查看验证码内容,同样可以直接写脚本进行提取,如图(图片来自Wooyun)


页面图片验证码测试思路


服务端

验证码无效

在一些新开发的系统或者不成熟的系统中,开发人员可能为了测试方便,没有配置随机验证码,或者是直接没有写完这个功能,此时输入特定验证码或者任何验证码都可以验证成功。


测试方法

如果在输入验证码时,任意验证都可以验证成功就说明存在验证码无效的问题,另外如果输入了正确验证码却验证失败,可以尝试Fuzz简单的数组或者字母,如8888、1111、123456 这可能是为了方便测试设置的固定验证码。

验证码存在固定有效期

系统在生成一个验证码后,在一段时间内,这个验证码都是有效的,导致可以在一段时间内使用该验证码进行爆破或者其他测试。


测试方法

在输入验证码提价后,验证码没有立即刷新,再次使用相同验证码进行提交时,验证正确。这样的验证码一般会设置5分钟或者其他时间的有效期,过期后验证码失效。

验证码存在固定验证次数

系统生成验证码后,设定一个最大的验证次数,每使用该验证码验证一次,就减1,到0时,重新生成验证码。


测试方法

与上一个类似,在验证后验证码没有立即刷新,验证密码失败固定次数后验证码失效,放在Burp的爆破模块里跑几次就无法验证了

验证码生成结果可控

另外有的系统在请求验证码的字段中,存在验证码字符的范围,例如?range=0123456789,如果存在类似的参数,可以将它设为单个字符或者重复的字符,以此来达到生成固定字符的目的;或者有的流程就像前面前后端分离的验证码实现方案中一样,前端生成随机数,服务端根据随机数生成验证码 如果服务端生成函数存在问题,传入相同随机数时,生成的验证码相同,或者生成的验证码是可被预测的。

验证码自身

验证码易于识别

验证码自身问题主要还是生成的验证码过于简单,导致可以借助OCR软件进行识别,在Burp中也有一些插件可以对这种简单的 二维码进行识别,例如PKAV HTTP Fuzzer、reCAPTCHA。这些插件的实现原理一般都是获取返回的验证码图片,然后调用验证码识别接口或者本地进行识别,所以识别的准确度与验证码自身、训练模型都有关系。


页面图片验证码测试思路

传输流程

生成的验证码使用Cookie传输

服务端会将生成的验证码传输到客户端,其中传输过程中有的系统会直接将验证码放在Cookie中 


页面图片验证码测试思路


获取验证码的响应包存在验证码

这个也是之前经常存在的漏洞,在重新获取验证码时,会发送一个请求包,在响应包中会直接发回验证码,这个时候就可以写一个脚本获取验证码来绕过 或者是同Burp中的Macros功能,自动提取并替换验证码。


页面图片验证码测试思路


返回的验证码图片中存在验证码文本

在返回验证码的时候,会将生成的验证码文本内容放在图片后面返回


页面图片验证码测试思路


验证流程

没有进行非空判断

这种根据不同的系统可能会有很多种测试方法,例如当后台对验证码的参数没有进行严格校验时候,可以将验证码参数值置为空、将参数改为数组或者直接删除这个参数,这些都是有可能绕过验证码的

验证后没有销毁会话

这个问题是验证逻辑的错误,属于验证流程的问题,但是存在于服务端,它是在校验验证码后没有将会话销毁,这样会导致一个验证码能够反复利用,这也是存在最多的一种验证码漏洞,直接的后果就是验证码完全失去了它的作用。


测试方法

直接一直使用同样的包进行发送,查看返回结果,另外可以删除请求包中的某些字段来进行测试,例如Cookie、Session或者请求的其他参数

Burp中Morse的使用

这里是自己写的一个示例,其中存在的问题是在请求验证码时,服务端会将验证码的内容返回回来,因此可以直接将返回包中的验证码输入进行验证。


页面图片验证码测试思路

那么这时候可以自己编写脚本将得到的验证码拿到下一步进行验证,或者使用Burp中的Macros,下面是使用方法。

设置宏

页面图片验证码测试思路


首先设置宏,在图示位置点击添加


页面图片验证码测试思路


添加后会自动弹出历史包,这里选择这两个我们要用到的包,一个是请求验证码,一个是验证验证码的包。


页面图片验证码测试思路


然后选择第一个获取验证码的包(因为是先获取验证码在验证),点击Configure item 进行设置。


页面图片验证码测试思路


页面图片验证码测试思路


之后设置获取字段的名字,这里的名字设置成与验证包里的变量相同的名字然后下面用鼠标选择,它会自动识别前后的内容。


页面图片验证码测试思路


然后回到刚才的地方,设置第二个包,这里它会自动识别提交的参数,只需要选择对应的参数,然后选择数据来源为获取验证码的包,这里第一个包。

设置会话处理规则

接下来设置会话处理规则,刚才设置的只是一个动作,这里的设置是设置在什么时候启用这个宏。


页面图片验证码测试思路


页面图片验证码测试思路


页面图片验证码测试思路

这里选择图示的选项,在后面选择修改包中captcha的内容,之后选择OK


页面图片验证码测试思路


下面设置Scope,其中可以设置动作生效的模块,例如可以只选择爆破模块 中间是URL的范围,最下面是参数的范围,这些都可以根据具体情况进行设定 设定好后OK

然后就可以到Repeater或者爆破模块中进行测试了,这里再爆破模块进行了测试。


页面图片验证码测试思路


可以看到所有的都是验证码正确,注意使用爆破的时候要设置单线程

总结

对于上述的验证码问题,单从验证码方面来说,造成的影响并不是很大,但是验证码一旦失效,可用的地方还是很多的,例如有的后台验证码可重复使用 那么就可以直接对后台的用户或者密码进行爆破,以此来步步深入,或者有的接口验证码失效,那么就可以利用这个接口来遍历或者爆破一些信息。这样的例子还有很多,结合实际情况进行利用,就能加大这个漏洞的影响。

页面图片验证码测试思路

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: