最近在挖洞的过程中遇到了这个问题,在后台暴力破解的时候,被验证码的问题卡住了,故才有了这篇文章,来研究一下暴力破解以及后台登录界面的验证码绕过问题。

关于验证码的问题我记得之前面试的时候被问到过,但是并没有特别仔细的写,这篇文章就结合案例来写一下,菜勿喷

验证码机制原理

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

验证码复用

0x01

这种情况在现在基本上不存在了,也就只有pikachu这种入门漏洞靶场有这种情况,还是写一写把

直接进到pikachu暴力破解网站http://localhost/vul/burteforce/bf_server.php 随便输入用户名密码,验证码输入,burp抓包发送到repeat模块

那么问题就出来了,我们直接修改数据包中username和password然后send看一下变化

第一次

修改后

那么问题就很明显了,两次输入的密码不同但是验证码却一样,验证码复用问题就很明显了,直接intruder模块爆破即可,我们也去源代码看看,定位到WWW\vul\burteforce\bf_server.php文件36行左右对验证码进行校验的代码

if (strtolower($_POST['vcode']) != strtolower($_SESSION['vcode'])) {
      $html .= "<p class='notice'>验证码输入错误哦!</p>";
      //应该在验证完成后,销毁该$_SESSION['vcode']
}

在校验验证码后,并没有摧毁生成的验证码,而是并未进行处理,那么问题就出现在这,我们应该在校验结束后将验证码摧毁,然后再重新生成一个

出现这个问题的原因我研究了一下,当你在前端刷新页面或者提交时,验证码会刷新,也就是说验证码的更新是由前端控制的;登录失败以及刷新页面,出现新页面或弹出警告窗口,点击返回后验证码刷新,我们直接发数据包不经有前端提交是不会刷新验证码的

验证码不过期,没有及时销毁会话导致同一验证码反复可用。攻击者可以在Cookie中带固定的sessionID和固定的验证码字符串。

0x02

这里其实还有第二种情况,也是验证码复用的问题,但是跟上面的不太一样,登录失败后验证码会刷新,但是上次验证码一样可以使用的情况

0x03原因

除了上面说到的原因,还有一种可能就是登录密码错误之后,session中的值没有更新,验证码不变。

前端验证码

顾名思义,只在前端产生的验证码,不经过后端调用以及校验;这种情况也几乎不存在了,看来这个靶场确实太老了,只适合入门了http://localhost/vul/burteforce/bf_client.php

F12打开控制台定位到验证码的地方

然后CTRL+F在控制台找这个creatcode(),那么你就发现有意思的地方了,这是前端js生成的验证码,跟后端一点关系都没有

你可以发现burp抓包,不带验证码字段repeat也不会显示验证码为为空的提示,下面直接爆破就ok

验证码没有做非空判断

跟上方前端验证码不同的是,上方的处理结果是直接发数据包后端传输不经由前端通道怕,这种情况是在经由后端代码时并未对验证码进行非空判断导致该安全问题

验证码可获取

这种情况跟前端验证码差不多,也是在前端出现的问题

F12在控制台中搜要输入的验证码,如果在源码中存在的话,将源码中的验证码填写到每次请求的报文中,利用工具进行暴力破解。

或者是有的网站把验证码输出到客户端html中,送到客户端Cookie或response headers中,也是可以直接获取验证码,再来爆破

验证码有规律

类似于时间戳等方法生成的验证码,或者是验证码存在一定的规律,可以直接找到规律后生成字典进行爆破即可

多次错误产生验证码

也是在挖洞过程中发现的一个问题,也是很多网站采用的风格,在你前几次输入username和password的时候,是没有验证码字段的,在你输入多次错误后,才会出现验证码

那么这种情况出现的原因,开发人员可能在Cookie中写入一个标记loginErr,用来记录错误数量,则可以不更新Cookie中的loginErr值反复提交,验证码就不会出现

这只是一种情况,我在挖洞的过程中也特别注意到这一点,但是并没有在cookie中找到一些踪迹,可能是由于加密或者做了其他处理的问题。

其他的情况,例如下面几种情况

0x01基于session

基于cookie中的某一个传参重复错误3次会出现验证码;那么我们只需要在数据包中控制这个参数一致即可使验证码不出现

0x02基于IP

基于X-Forwarded-For判断IP,错误3次出现验证码(User-Agent + IP来判断IP);跟上方一样,直接改数据包将IP每发一次数据包改user-agent即可抑或是直接挂代理池每发一次代理池同步跑也是可以的

0x03基于username

用户输入3次会输验证码,那么用一个用户字典来跑密码

0x04基于密码

密码输入3次会输验证码,那么用一个密码字典来跑用户

其他的验证码

如果都没有前面的问题,也就是说这个网站的验证码还是较为安全的,那么我们就没办法用以西相对简单的爆破方法来进行爆破了,只能借助一些其他方法来绕开验证码,可以借助AI来进行验证码的识别例如pkav,不过pkav好久不维护了,官网也关了

burp也有可以绕过验证码的插件,例如:https://github.com/c0ny1/captcha-killer github中也写的很详细,大家可以去看一下