可能大家觉得验证码没什么好聊的,验证码的目的、实现方式都简单明了,目的当然是防止恶意提交,密码穷举等,但平时工作中和上网中,的确发现很多因为验证码引发的非常严重的问题,小到验证码形同虚设从而数据被抓取,大到用户密码被破解。
鄙人曾经在工作中发现公司的某系统登录验证码可以轻易被绕过,从而轻易被穷举,而该系统在公司的地位非常核心,幸运的是在我发现前未发生攻击现象,很快修复该漏洞,否则后果不堪设想。
验证码问题看似简单,实则要求开发人员的web基础扎实,对http协议,浏览器的交互行为一定要真正的了解,要知道每一个请求的含义,包括对session、cookie的理解,因此,验证码问题绝对是一个考验web开发者是否真正对web熟悉的好问题。
这里举一个现实中存在验证码安全漏洞实例:火车票余票查询12306.cn(在笔者写该文章时,该漏洞依然存在,用户可以绕过验证码来查询余票信息)
该网站的验证码验证流程如下:
1、加载主页面,这时浏览器会写session来维持会话信息,假设session。
2、验证码的位置动态写入动态url(这里其实动不动态都无所谓),暂且认为是固定的url,该URL的作用是生成验证码图片,暂且叫做B(实际上为http://dynamic.12306.cn/TrainQuery/passCodeAction.do?rand=rrand?0.19811323)
3、请求B的后台逻辑是这样的:随机生成一个验证码图片C,并更新$session中的验证码值,即$session[‘验证码值’]=C。请注意,session[‘验证码’]的值只会在请求B时发生变化,这里是漏洞的关键。
4、用户提交查询信息+验证码,后台会判断$session[‘验证码值’]和提交的验证码是否匹配,来检查验证是否通过,从而返回查询结果,不通过,则重新加载主页面,重复上述步骤。
现在问题基本上显而易见了,上面的流程都是基于浏览器来说的,首先假定了用户都是合法的,都是通过浏览器访问的,而浏览器都是基于http协议,用户完全可以自己写程序来控制请求的流程,比如我想抓取所有的车次的余票信息,可以按如下的操作来绕过验证码:
1、首先请求首页,目的是种下session。
2、再请求B(实际上为http://dynamic.12306.cn/TrainQuery/passCodeAction.do?rand=rrand?0.19811323),这时会得到验证码B,记下。
3、这时就可以开始进行循环了,只要不再请求B,只要session不失效,正确的验证码将永远为B,因此可以写程序不停的用B来验证通过,从而达到目的。
这个问题的解决方案也很简单,就是只要验证码被验证过一次,不管成功还是失败,都需要让验证码失效,这样就避免了攻击。
总之,验证码问题包含者许多的web知识,web学习者可以通过学习验证码的原理来理解web中的一些交互知识,面试者可通过验证码问题来考察应聘者的基础知识。
原文链接:https://www.cnblogs.com/quanwei888/archive/2011/09/09/2172253.html
原创文章,作者:优速盾-小U,如若转载,请注明出处:https://www.cdnb.net/bbs/archives/18734