【验证码机制原理】
客户端发起请求->服务端响应并创建一个新的SessionID同时生成随机验证码,将验证码和SessionID一并返回给客户端->客户端提交验证码连同SessionID给服务端->服务端验证验证码同时销毁当前会话,返回给客户端结果。
【客户端可能存在的安全问题】
1、有的网站验证码由本地js生成仅仅在本地用js验证。可以在本地禁用js,用burp把验证字段删除。
2、有的网站把验证码输出到客户端html中,送到客户端Cookie或response headers。
3、有些网站默认不显示验证码,而是在输入错误一定数量之后才需要验证验证码,开发人员可能在Cookie中写入一个标记loginErr,用来记录错误数量,则可以不更新Cookie中的loginErr值反复提交,验证码就不会出现。
【服务端可能存在的安全问题】
1、验证码不过期,没有及时销毁会话导致同一验证码反复可用。攻击者可以在Cookie中带固定的sessionID和固定的验证码字符串。
2、没有对验证码进行非空判断,导致可以直接删除验证码参数。
3、产生的验证码问题有限
验证码固定
导致验证码不刷新(固定)的原因是:登录密码错误之后,session中的值没有更新,验证码不变。验证码不刷新通常有以下两种情况:无条件不刷新、有条件不刷新。
无条件不刷新
无条件不刷新是指在某一时间段内,无论登录失败多少次,只要不刷新页面,就可以无限次的使用同一个验证码来对一个或多个用户帐号进行暴力猜解。换句话说,攻击者可以在同一个会话下,在获得第一个验证码后,后面不再主动触发验证码生成页面,并且一直使用第一个验证码就可循环进行后面的表单操作,从而绕过了验证码的屏障作用,对登录进行暴力猜解。
【测试案例 1】测试人员登录并抓取请求包,在不改变验证码的情况下,多次发送请求包,响应包中内容都是“用户名或密码错误”,如下图所示:
【安全建议】建议针对一次请求生成的验证码只能用一次,用完立即过期。每次生成的验证码不允许跨会话和请求使用。
有条件不刷新
有条件不刷新多见于如下情况:登录失败之后,系统会打开一个新页面或者弹出一个新的警告窗口,提示用户登录失败,点击确定后返回登录界面且验证码刷新。这种情况下,只要我们不关闭新窗口或弹窗,配合使用Burpsuite的intruder模块就可以进行暴力破解了。
【测试案例 2】来看下某系统的验证码鉴权流程:
用户输入账户信息+验证码(刷新页面或手动刷新验证码会从服务器获取验证码,但该验证码缓存于session中),服务端接收到账户信息+验证后会先校验验证码是否正确,若不正确则,返回反之与数据库做对比,符合则返回,客户端接收服务端的请求,若成功则跳转,返回根据不同的错误码提示相应信息,并重新获取服务端生成的新验证码,重新缓存。
【问题描述】看完流程可以很容易想到一个问题:验证码此时并不会重置,一切重置验证码的操作都在浏览器,所以在Session不失效的时效内,可以无限重用验证码,这时就可以使用BurpSuite进行暴力破解了,验证码形同虚设。
验证码前端可获取
这种情况在早期的一些网站中比较常见,主要是因为程序员在写代码的时候安全意识不足导致的。验证码通常会被他们隐藏在网站的源码中或者高级一点的隐藏在请求的Cookie中,但这两种情况都可以被攻击者轻松绕过。
验证码隐藏在源码之中
验证这种情况很简单,我们只需要记住验证码,然后右键打开网站源代码,Ctrl+F搜索,输入刚才的验证码,如果可以成功匹配到,那恭喜你,接下来就可以写工具,提取源码中的验证码并将其放入每次请求的报文中,来进行帐号破解,这里推荐使用python。
验证码隐藏在Cookie中
一般来说,我们会把验证码的值用Session存储起来,通过对比用户提交的验证码和Session中的验证码,就可以知道输入是否正确。由于Session会占用服务器资源,有的开发人员会把验证码的值加密后存储在Cookie中。
这种情况,我们可以在提交登录的时候抓包,然后分析一下包中的Cookie字段,看看其中有没有相匹配的验证码,或者是经过了一些简单加密后的验证码。
仅在客户端生成验证码
有的网站验证码由本地js生成仅仅在本地用js验证。
【实际案例】
测试人员抓取登录过程的请求包,如下图所示:
从上面抓取到的数据包可以看出,虽然该系统存在验证码,但是其验证码并没有向服务器传输,而是在本地客户端直接进行验证。我们可以在输入一次正确的验证码(绕过客户端验证)后,使用BurpSuite对用户名和密码同时进行暴力猜测,如下图所示:
返回的数据是“账号不存在”,而不是“验证码错误”,说明此处已不需要输入正确的验证码就能发送登录请求,只要密码字典够大,我们就能进行暴力破解。
计算类型的验证码,如1+8=?,这种类型的验证码严格意义上来说不能叫做验证码,多刷新几次验证码,我们可能会发现系统中的算数题目只有那么几道,这种情况下只要将验证码全部下载下来,生成一个md5库,然后将前端生成的验证码与本地文件进行对比即可。
验证码薄弱
验证码自动识别
有的系统虽然在登录界面带了验证码,但是验证码功能薄弱,可以被工具识别,导致系统面临被爆破登录的风险。
点击F12打开开发者工具,查看前端源码,找到生成验证码的URL。
将URL输入搜索框,验证是否正确。
然后,打开工具PKAV HTTP FUzzer
,开始尝试自动识别验证码。
建议对验证码进行干扰、变形处理!
验证码爆破登录
紧接上面的系统案例,接下来同样借助工具PKAV HTTP FUzzer
,咱们进行带验证码登录页面的暴力破解。
(1)首先,使用Burp Suite抓包
(2)把数据包丢进PKAV工具,分别标记password
、验证码
(username事前知道了,即存在admin的用户,无需用字典猜测,故此处不用标记)。
(3)给标记的变量添加猜测字典。字典可选工具自带的,也可用专门的字典生成工具生成。
或者使用工具生成字典:
(4)添加验证码地址
在登录框找到验证码地址复制到工具,识别范围看情况,这里为数字+字母。
(5)设置参数
切换到重换选项卡设置相关参数,具体设置看情况而定。
(6)识别验证码测试
相关参数设置好之后,点击进行识别测试。
(7)开始爆破
接下来,耐心等待爆破结果。