0x01 前言
这篇文章将通过一个实例来讲解验证码的原理,并整理下不合理的设计或使用验证码所引发的安全问题。写这篇文章原因是周末看laravel验证码实现那块发现居然忘记验证码的实现原理了,好记性不如烂笔头,所以要多做笔记~
0x02 Captcha原理
我们先来看下验证码实现原理
1.客户端发起一个请求;
2.服务端响应并创建一个新的SessionID同时生成一个随机验证码;
3.服务端将验证码和SessionID一并返回给客户端;
4.客户端提交验证码连同SessionID给服务端;
5.服务端验证验证码同时销毁当前Session中的验证码,返回给客户端结果。
0x03 Captcha实例
github上https://github.com/HackBraid/Sec-ReinForce
里面有个文件夹Capthca,一个标准、安全的验证码流程的demo,有兴趣可以git下来本地搭建下。
我们本地搭建好后可以测试下这个验证码流程。首先在chrome浏览器设置好burp的代理,然后访问:http://localhost:8081/Capthca/
可以看到burp拦截到的请求包如下:
我们点击Forward按钮,发现服务器的返回包中的Set-Cookie字段会设置sessionID为一个较长的字符串:
我们输入验证码,然后拦截请求,请求包头部会带着sessionID:
然后服务器端会取这个sessionID的验证码与用户提交的验证码进行比对,成功验证后销毁,然后再验证用户名、密码等信息。
|
通过这个验证码的demo我们可以比较清晰的理解其原理了,当然这里session是通过文件来实现的。
0x04 Capthca的安全问题
验证码的设计之初就是为了限制攻击者的撞库、爬虫等攻击,然而不合理的设计或使用验证码就会引发一些安全问题。借用前人的总结,根据验证码的实现流程,其问题可以分为三类:客户端问题、服务端验证问题和验证码可被识别。
客户端问题
1.客户端生成并验证验证码(验证码由客户端js生成并且仅仅在客户端用js验证)
2.验证码输出客户端(验证码直接输出到html、cookie中)
服务端验证问题
1.验证码重用
验证码没有及时销毁导致可重复使用,即如果通过验证,没有销毁当前session里的验证码。这里可以将上面的demo中session.removeAttribute(“CHECK_CODE”); 这行代码注释掉即可复现验证码重用问题。
2.非空判断
很多时候,我们会遗留掉了验证过程中验证码为空的情况,比如去掉cookie中的某些值或者请求中验证码参数,结果就直接通过了验证码验证。
3.其它
像无论输入什么都通过这种不验证的、多个登录入口其中一处未加验证的和请求的url中去掉一些参数即可绕过登录验证码验证的情况也很多。
验证码可被识别
验证码过于简单可以被识别,验证码识别已经有很多现成的工具可以使用了,这里引入随风师傅的一篇文章:
https://www.iswin.org/2016/10/15/Simple-CAPTCHA-Recognition-with-Machine-Learning/
0x05 Capthca的产品
专门做验证码的公司也不少,下面是国内外公司:
国内做的比较优秀的是:极验
国外是被谷歌收购的公司reCAPTCHA。
大家可以自行了解下~
附:
Session的存储方式
最近在学习Laravel,然后发现除了传统的file型Session存储方式外还有以下几种:
database :将Session数据存放到指定数据表中,该数据表由配置项 table 设置
memcached :将Session数据存放到Memcached中
redis :将Session数据存放到Redis中
array :将Session数据存放到数组中,该配置仅用于测试环境
数据库存储方式主要是为了应对大型网络架构中file存储方式的不足。
参考来源:
http://cb.drops.wiki/wooyun/drops/web-5459.html
本文由HackBraid整理总结,原文链接:http://www.cnbraid.com/categories/安全运维/captcha.html,