写在前

如何黑掉一个验证码?很多人第一反应是验证码识别,什么预处理,提取有效信息,分割字符,识别字符,吧啦啦一长串流程……其实有时根本没那么复杂,今天就来讨论些除了验证码识别还可以怎么黑掉一个验证码。

论如何黑掉验证码

使用cookie/session记录登录失败信息
很多时候为了用户体验验证码只有在登录失败一定次数后才会弹出验证码,但是当登录失败次数被记录在cookie或session时,如果攻击者不使用cookie或每次使用新的session验证码弹出机制将被绕过。

验证码使用后不过期
通常验证码与session存在对应关系,当一个验证码验证成功后未做过期处理,攻击者则可反复使用这组验证码和session;当一个验证码验证失败后未做过期处理,则可能会被暴力破解。

验证码使用后过期处理不及时/过期机制可被绕过
如果验证码更新不及时或更新机制可以被绕过将导致攻击者仍旧可以使用用过的验证码。

将验证码的值返回客户端
将验证码的值通过response、cookie等方式返回给客户端将会使验证码失去存在的意义,即使使用md5等方式返回也同样存在这种风险。

验证码可预测
如可根据验证码生产算法预测出验证码的值。

验证码的值域太小
如果验证码的值只有10个,那么攻击者随便尝试一个就有10%的正确率。

无超时/超时时间过长
验证码无超时或超时时间过长可能会给人工打码提供机会,如先收集验证码及对应的session,然后进行人工识别,在需要时再取出人工识别过的验证码和对应的session使用。

绕过验证码
这个属于系统整体设计的问题,如一个功能在PC端有验证码而移动端没有的话,攻击者完全可以利用移动端的接口去实现攻击而没必要再去黑掉验证码。

验证码易识别
想想最后还是不得不讲回验证码识别,一个过于简单的验证码确实还是无法达到防御的目的地。

最后

有些话等过两天再来讲吧……

点击数:628

之前在WooYun知识库上写过一篇《初探验证码识别》,主要介绍了一些基本的验证码识别过程,并且给出了一些设计(改进)验证码时值得考虑的地方。正好最近没事在写Python Web玩时注册、登录等操作需要用到验证码,那么就借着这个机会自己写一个吧~

验证码

“验证码”又名“全自动区分计算机和人类的图灵测试”(英语:Completely Automated Public Turing test to tell Computers and Humans Apart,简称CAPTCHA),最早在2002年由卡内基梅隆大学的路易斯·冯·安、Manuel Blum、Nicholas J.Hopper以及IBM的John Langford所提出,是一种区分用户是计算机或人类的公共全自动程序。

利用其区可分人或计算机的特点,在Web应用中,验证码常被用于注册、登录、发布信息等处,以避免计算机程序恶意进行批量注册、暴力破解用户密码、发布大量打击信息等。

验证码的设计与实现

生成一个简单的验证码

首先,我们使用PIL (Python Imaging Library) 这个库来生成一张验证码图片。这里我们随机选择了4个字符并绘制了一张120*40的白色背景图,然后在相应位置绘制了指定字体和字号的字符。

利用上面的代码便可生成一个简单的验证码了。

5sge

但是从这个验证码字符分隔明显、前背景易区分且无其他干扰,所以它还是比较容易被识别的。因此我们需要在此基础上进一步加工这个验证码。

添加干扰

我们可以在验证码上绘制一些干扰线,ImageDraw.Draw对象的line函数可以很方便的在我们输入的两个点间绘制一条直线:

除了干扰线外我们还可以绘制一些干扰点,因试验发现干扰点较小很容易被降噪处理去掉,而较大又影响验证码的直观体验,所以这里采用了一些较小的字符来对验证码进行干扰:

这里以千分比的方式来控制干扰的强度。

随机字符位置

如果每个字符的位置固定的话,可以很容易的通过位置分隔开每个字符,所以字符位置最好是随机的。另外,通过投影或者连通区域的方法分隔字符的时候可以比较容易的将两个不粘连的字符分开,所以这里在随机范围的设定时,允许存在1/3的字符粘连:

颜色设置

在去干扰时,如果颜色上存在字符和干扰(线、字符等)的分界点的话那么所有干扰就失去了意义,所以在颜色设置方面要尽量使其存在交集,在不影响直观感受的情况下,交集越大越不容易被识别。

其他考虑

字符选择

因部分字体在没有相应辅助信息(如:对齐、拼写环境等)的条件下类似于:1、I、l,0、o、O,2、z、Z这类字符不易辨别,所以在设计验证码时一般会去掉此类字符以降低用户识别难度。

代码

完整代码如下:

 

点击数:6397