首先我想讨论一下验证码这玩意儿。
有谁还记得大概几年前突然出现了验证码这东西,许多网站甚至桌面应用程序都陆续实现了验证码技术,主要作用无非就是防止用户利用程序进行自动提交,避免暴力破解,避免服务器遭受恶意攻击。
那么,验证码机制又该如何实现。
目前主流的实现技术主要有session和cookie两种方式,而这两种方式可以说技术是一样的,区别在于将验证码字符串存储在服务器还是客户端。
前者工作流程:服务器发送验证码图片到客户端并在服务器保存验证码字符串到session,用户辨认图片并提交验证码字符串到服务器,服务器将用户提交的验证码字符串与session中保存的字符串进行比较。
后者工作流程:服务器发送验证码图片以及验证码字符串(可能会进行加密)到客户端,客户端将验证码字符串存储到本地cookie,用户辨认图片并提交验证码字符串以及cookie中所存储的字符串到服务器,服务器将用户提交的两个字符串(进行解密后)进行比较。
相对而言,存放在服务器的session更为安全,只不过消耗服务器内存,程序员除了使用模式识别辨认出验证码,没有其他办法。而对于使用cookie方式的验证码,不增加服务器内存消耗,但我们可以通过对传输数据进行分析轻易破解验证码。
这种传统的验证码方式,其框架非常简单。
看上图,我们从大的框架分析问题,这里面说的“提供验证码服务”已经不区分session还是cookie了。
接下来从图中我们可以看出什么了呢,对于有多台服务器的大企业是十分平常的,那么,假如每一个服务程序都使用验证码技术,那么每一个服务程序就需要独自实现验证码服务,这样做不是不可以,只是增加了程序员的负担而已。
好吧,现在我们正式进入今天的主题,也是接着上面的话题,腾讯的验证码框架有何不同。
我们随便进入一个需要验证码的腾讯页面:
http://web2.qq.com
登录webQQ的时候需要输入验证码,我们通过抓包或者看源代码,可以知道点击“换一张”时其实是访问了这个URL:http://captcha.qq.com/getimage,来自tencent http server。多尝试几个需要验证码的页面,发现其验证码依然是是通过访问http://captcha.qq.com/getimage获得。当然也有例外的情况,不过总体看来腾讯的验证码机制的框架与上面讨论的又有些不一样。
看到了吗,在这种框架体系下,验证码成了一个单独的组件,不同服务器不同应用程序都可使用它提供的验证码服务接口。
具体流程
好吧,我们继续进一步研究腾讯验证码的具体流程。
访问http://captcha.qq.com/getimage,看到“zqcu”验证码图片,抓包,查看响应标头:
键 值
响应 HTTP/1.1 200 OK
Server tencent http server
Accept-Ranges bytes
Pragma No-cache
Content-Length 2559
Set-Cookie verifysession=h0052f5e46e7ca7d3f1bbb1cfa3bbb2a9ea86bded65adbf78e575c50e0d361145fcd232015653790eb
4;PATH=/; DOMAIN=qq.com;
Connection close
Content-Type image/jpeg
以上就是HTTP协议中的header内容,请注意其中Set-Cookie的部分,其实这就是验证码“zqcu”字符串经过加密后的密文。当我们提交验证码时,正是将我们输入的“zqcu”和密文同时提交,然后服务器A/B再通过服务器C的验证接口判断是否正确。这时候,一切浮云都是神马了,原来腾讯验证码居然采用cookie方式。
那么,接下来高手通常会有两种做法:
第一,通过模式识别辨认出图片所承载的验证码字符串,然后提交的时候直接发送识别的字符串。
第二,通过解密破译出verifysession的明文。
很抱歉,我不是高手,以上两种方法我都无能为力。所以,以下的内容高手可绕过,到此结束了。
利用cookie欺骗绕过验证码
到这里,有人可能会骂,你这不是标题党么,什么cookie欺骗,什么漏洞,啥都没。
好吧,接下来讲讲我的方法,就是利用cookie欺骗绕过验证码。
刚才我们访问http://captcha.qq.com/getimage的时候已经获得一个验证码图片,利用人眼识别技术,知道它的验证码字符串为“zqcu”,并且截获了其密文verifysession。
于是,我便开始尝试每次提交都提交“zqcu”并且将cookie设为已知的verifysession。嘿嘿,我可以把入哥的介绍信多复印好几份嘛。
如果真的那么简单的话,腾讯也太二了。
第一次提交的时候,我十分惊喜,居然成功欺骗了服务器。
可是当我再次使用这一组验证码及其密文,却返回验证码错误的提示。我的猜想是,某个验证码用过之后,不能马上再次使用,也许要过1分钟或者1个小时之后才能使用,这是一个我称之为过期机制的坎。也就是说,当洪哥问入哥,这是你写的介绍信么,入哥看了看,说是,然后给这封信添了一个标志。
发现了这个坎,那么悲剧了。
现在我能做的事只有:提前获得几组甚至几百几千组验证码(需要人眼识别,人手输入)及其密文。而且所获得的验证码还不能闲置太长时间,入哥可能将同一份介绍信发给两个人,当别人先用了它,那么我要过一段时间才能再用。
注意上面提到了提前两字,但是同样需要人工识别并输入,这到底有什么用呢。
在做什么事情的时候我们是带着这样一个目的的:提前输入好几组验证码,在特定时间连续并快速的提交。
好吧,我不多说了,看看标题,我们开始暴力秒杀吧。
拍拍秒杀流程如下:商品有一个秒杀时间,当到了这个时间,成千上万的玩家开始填写验证码并点击提交,先到先得。
于是,有了cookie欺骗,我可以提前输入验证码,当时间一到,只要提交即可。
今天就讲到这里吧,大家可以畅所欲言,提出疑问或者指出错误的地方。最后附上我做的拍拍秒杀助手,为了图个方便用的c#编程,所以需要.net farmework环境,有兴趣的同学可以将其改写成c++。
PS:修改本地cookie非常简单,但是,腾讯这里的Set-Cookie并不是保存到本地的cookie,它是一个标志为httponly的cookie,只存储在标头。
我提供一个函数:InternetSetCookieEx(),其msdn如下:
http://msdn.microsoft.com/zh-cn/library/aa385108.aspx
附下载链接:http://d.namipan.com/d/efb4375ee41afae5932279334313c00442c995d2ee600800
【编辑推荐】