discuz的验证码是怎样被破解的

Author:David | 【转载时请务必以超链接形式标明文章原始出处和作者信息及本声明
URL:

今天改程序,无意中在discuz的注册页面停留了一下,看到他那个验证码,我忽然想到前段时间一个论坛开起了验证码,仍然被spam疯狂注册,一个月被注册了2000多个帐号!
应该说这个验证码已经挺复杂的,主要是字体比较奇怪,如果找不到字体,用简单的模式匹配解码很难。
seccode.png

discuz的验证码只有四位数字,用穷举的方式暴力破解,最多只需要10000次(0000-9999)就可以找到正确的验证码。
问题在于discuz能不能使用暴力破解,于是要自己研究一下。

验证码实现验证的原理是这样的(明白人可以跳过):后台产生一个随机数,存放于服务器session,然后生成一个图片丢给客户端,同时给客户端一个sessionID。客户端输入一个验证码,提交到服务器的验证脚本,脚本根据sessionID去取session,跟提交上来的验证码比较,就可以获得结果。

discuz的注册系统是用ajax实现实时验证的,很方便使用,这也方便了我作测试,输入一个验证码马上会自动发送判断请求,点一下验证码的图片马上会换一个验证码。也因为方便,产生了很大的问题!

暴力破解的原理是:
1.如果程序不是在每次验证之后产生新的验证码的话,hacker就可以不断提交验证码去碰
2.如果服务器每次都更换新的验证码,可以在本地提供一个固定数字,不断向服务器提交验证请求,直到跟本地验证码一致,概率应该是一样的,只不过把产生随机数的过程交给了服务器,这样本地压力更小。

discuz的验证码用上面任何一种破解方式都可以,上面说过,4位的数字,最多只需要10000次就可以得到正确结果,10000此对于机器来说太快了,主要取决于网速。而实际上,验证的过程只需要提交非常小的数据量(小于1K),所以只要服务器响应够快,破解速度就可以足够快。

那么,应该如何防止暴力破解呢?方法其实很简单,一是提高随机数宽度,这种方法不好,验证码位数太长,意味着用户输入更多;二是限制重试次数,比如50次,我想没有那个正常人闲得没事可以反复输错50次,并且重试50次。对于登录来说,这个验证很容易,对于注册来说就不好办,碰上用大量代理暴破的,一点用都没有。不过只要在登录的地方卡死了,注册了也登录不了。

总的来说,现在大部分网站系统的验证码,都跟discuz的这个差不多,很容易暴破,有的甚至用很简单的字体,很固定的排列方式,直接就可以识别,比如我的blog留言那里的那个验证码。我以前曾经写过一个针对网易投票系统的破解程序,有兴趣的可以搜索一下。

其实像一些大的网站那样,比如google、yahoo等,用6位扭曲的英文+数字进行验证已经很强了(36^6=2176782336),关键是不要被识别出来,他们那样的扭曲算法写不出来不要紧,可以直接用多种字体拼凑,每个验证位用一种随机字体,这样就增加了一定的破解难度,当然用传统验证码,总是可以设计出识别算法的,现在流行的用随机问题的方式进行验证,不失为一个好的选择,但是对于大型网站来说要做一个足够大,不容易被人工复制,问题又足够简单的问题库是个很难的事情。

评论:

在老外的网站上注册东西,那个验证码竟然是语音播放,听了好几遍才听明白。另外发现一个免费空间玉米大全,贡献出来[url]http://www.dyingshi.cn[/url]

4位的验证码理论上要9999次吧?不好运的话也要2000次吧

算错了- -
应该是10000次,如果0000也要算上

每次验证出错后应该是生成一个新的验证码吧,这样的概率就不只4*10次了。

难道我写的不明白马?

每次生成一个新的,你认为会有多少概率出现1234这个数?

概率是这么算的
某次猜不中为0.9999 9999次内不中的机会为0.9999^9999=0.36789783622 要达到0.95的概率需要大约29999次

还有如果单次响应时间为0.001,需要30s 半分钟内产生3万个请求一般的机器会挂吧

暴力破验证码不大可行

惭愧,概率没学好 - -

to Dull,问题很简单:每次都用1234,理论上来讲10000次以内应该有一次是对的。

to 楼上的,跟我一样,犯了想当然的错误。

10000次以内有很多次是重复的

Dull说的很对,概率是那样算的,平均需要3w次才能碰到一个验证码。

我觉得还是满难的~

不都OCR吗

不是很难.

你还设置一个自动填写验证码, 真是够狠的.

验证码是一个严重影响用户体验的东西..

发言不用输验证码?说说你的BLOG的验证方法呀

blog现在的验证不好,经常有垃圾进来

垃圾一个试试

(选填)

(必填)

(选填)


Clicki