如今,基于web的应用越来越普及,随之而来的安全威胁也越来越大,近日网上惊现可以破解验证码的JavaScript脚本,可以轻松搞定流行的验证机制CAPTCHA。
<!-- Error -->
近日,网上惊现可以破解验证码的JavaScript脚本——GreaseMonkey!由“Shaun Friedle”开发的这段脚本可以轻松搞定Megaupload站点的CAPTCHA。如果您不相信的话,可以到http://herecomethelizards.co.uk/mu_captcha/亲自尝试一下!
现在,Megaupload站点提供的CAPTCHA在上述代码面前已经败下阵来,说实话,这里的验证码设计的不不太好。但更有趣的是:
1.HTML 5中的Canvas应用程序接口getImageData可以用来从验证码图像中取得像素数据。利用Canvas,我们不仅可以将一个图像嵌入一个画布中,而且之后还可以再从中重新提取出来。
2.上述的脚本中包含一个完全使用JavaScript实现的神经网络。
3.使用Canvas从图像中提取出像素数据后,将其送入神经网络,通过一种简单的光学字符识别技术来推测验证码中到底使用了哪些字符。
通过阅读源代码,我们不仅可以更好地理解其工作原理,也可以领会这个验证码究竟是如何实现的。就像前面看到的那样,这里使用的验证码不是很复杂——每个验证码有三个字符组成,每个字符使用一种不同的颜色,并且只使用26个字母中的字符,而所有字符都使用同一种字体。
第一步的用意很明显,那就是把验证码拷贝到画布上,并且把它转化为灰度图。
function convert_grey(image_data){ for (var x = 0; x < image_data.width; x++){ for (var y = 0; y < image_data.height; y++){ var i = x*4+y*4*image_data.width; var luma = Math.floor(image_data.data[i] * 299/1000 + image_data.data[i+1] * 587/1000 + image_data.data[i+2] * 114/1000); image_data.data[i] = luma; image_data.data[i+1] = luma; image_data.data[i+2] = luma; image_data.data[i+3] = 255; } } } |
然后,将画布分成三个单独的像素矩阵,每个矩阵包含一个字符。这一步实现起来非常容易,因为每个字符都使用一种单独的颜色,所以通过颜色就可以将其区分开来。
filter(image_data[0], 105); filter(image_data[1], 120); filter(image_data[2], 135); function filter(image_data, colour){ for (var x = 0; x < image_data.width; x++){ for (var y = 0; y < image_data.height; y++){ var i = x*4+y*4*image_data.width; // Turn all the pixels of the certain colour to white if (image_data.data[i] == colour) { image_data.data[i] = 255; image_data.data[i+1] = 255; image_data.data[i+2] = 255; // Everything else to black } else { image_data.data[i] = 0; image_data.data[i+1] = 0; image_data.data[i+2] = 0; } } } } |
最终,所有无关的干扰像素都被剔除出去。为此,可以先查找那些前面或者后面被黑色(未匹配的)像素围绕的白色(匹配过的)像素,然后将匹配过的像素删除即可。
var i = x*4+y*4*image_data.width; var above = x*4+(y-1)*4*image_data.width; var below = x*4+(y+1)*4*image_data.width; if (image_data.data[i] == 255 && image_data.data[above] == 0 && image_data.data[below] == 0) { image_data.data[i] = 0; image_data.data[i+1] = 0; image_data.data[i+2] = 0; } |
现在我们已经得到了字符的大约图形,但在将其载入神经网络之前,脚本还会进一步对它进行必要的边缘检测。脚本会寻找图形最左、右、上、下方的像素,并将其转化为一个矩形,接着把矩形重新转换为一个20*25像素的矩阵。
cropped_canvas.getContext("2d").fillRect(0, 0, 20, 25); var edges = find_edges(image_data[i]); cropped_canvas.getContext("2d").drawImage(canvas, edges[0], edges[1], edges[2]-edges[0], edges[3]-edges[1], 0, 0, edges[2]-edges[0], edges[3]-edges[1]); image_data[i] = cropped_canvas.getContext("2d").getImageData(0, 0, cropped_canvas.width, cropped_canvas.height); |
经过上面的处理,我们得到了什么呢? 一个20*25的矩阵,其中包含单个矩形,其中填由黑白色。真是太好了!
然后,会对这个矩形做进一步的简化。我们策略性地从矩阵中提取一些点,作为“光感受器”,这些光感受器将输送到神经网络。举例而言,某个光感受器具体对应的可能是位于9*6位置像素,有像素或者没有像素。脚本会提取一系列这样的状态(远少于对 20*25矩阵整个计算的次数——只提取64种状态),并将这些状态送入神经网络。
您可能要问,为什么不直接对像素进行比较?有必要使用神经网络吗?问题的关键在于,我们要去掉那些模棱两可的情况。如果您试过前面的演示就会发现,直接进行像素比较比通过神经网络比较,更容易出错,尽管出错的时候不多。但我们必须承认,对于大部分用户来说,直接的像素比较应该已经够用了。
下一步就是尝试猜字母了。神经网络中导入了64个布尔值(由其中的一个字符图像获取而来),同时包含一系列预先计算好的数据。神经网络的理念之一,就是我们希望得的结果事先就是知道的,所以我们可以针对结果对神经网络进行相关的训练。脚本作者可以多次运行脚本,并收集了一系列最佳评分,这些评分能帮助倒推出产生它们的那些值,从而帮神经网络猜出答案,除此之外,这些评分没有任何特殊意义。
当神经网络对验证码中一个字母对应的64个布尔值进行计算以后,和一个预先计算好的字母表相比较,然后为和每个字母的匹配都给出一个分数。(最后的结果可能类似:98%的可能是字母A,36%的可能是字母B等。)
当对验证码中的三个字母都经过处理以后,最终的结果也就出来了。需要注意的是,该脚本无法达到100%正确性(不知道如果在开始的时候不将字母转换成矩形,是不是可以提高评分的精度),但这已经相当好了,至少对于当前的用途来说是这样。而且所有的操作都是在基于标准的客户端技术实现的浏览器中完成的!
补充说明一下,这个脚本应该算是一个特例吧,这项技术可能会很好的工作在在其它简陋的验证码上,但对于复杂的验证码来说,就有点鞭长莫及了(尤其是这种基于客户端的分析)。但愿有更多人能从这个项目中受到启发而开发出更奇妙的东西来,因为它的潜力实在是太大了。
分享到:
相关推荐
利用javascript生成验证码,在jsp中可直接使用
javascript 利用ajax获取验证码内容和session值
利用canvas制作一个随机验证码: 1、clearRect:context.clearRect(x,y,width,height);清空给定矩形内的指定像素 2、fillStyle:设置画笔的颜色 3、rotate(deg):旋转角度,以弧度旋转(弧度=degrees*Math.PI/...
jsp中实现中文验证码并利用javascript技术实现验证码无法显示或不清晰时局部刷新验证码...
jk.rUhuman.js 利用拖动条替代图形验证码
验证码JavaScript利用Canvas生成随机验证码
利用jsp和javascript实现的两种彩色验证码,验证码点击可以更新,可直接运行,而且有结果!代码简单,适于初学者。本人已经试验过了,完全可以使用!欢迎评论!
仅用js实现,下载可以直接运行。代码注释清晰明了,可更改验证码长度,背景图和字母随机生成。适合新手研究利用。
实例105 随机产生指定位数的验证码 166 实例106 生成随机字符串 167 3.4 日期与时间 169 实例107 显示长日期格式的系统日期 169 实例108 实时显示系统时间 171 第4章 日期和时间 173 4.1 日期时间显示 174 实例109 ...
5. 机器学习集成:利用机器学习技术对用户输入的验证码进行自动识别,提高用户体验,减少手动输入错误。 6. 安全性:确保系统生成的验证码难以被机器人程序猜测或识别,增强网站安全。 7. 兼容性:确保验证码在...
请给Array本地对象增加一个原型方法,它的用途是删除数组条目中重复的条 目(可能有多个),返回值是一个仅包含被删除的重复条目的新数组。 利用正则表达式,解析形如...利用隐藏控件,设计判断用户输入的验证码。
多语言支持:尽管OpenCV主要使用C++编写,但它提供了丰富的API绑定,支持包括C、Python、Java、MATLAB、JavaScript等多种编程语言,方便不同领域的开发者使用。 开源与免费:OpenCV遵循BSD开源许可证发布,用户...
b) 在Default.aspx文件首部添加脚本: <script language=”javascript”> function VcgReFresh() { var message = ‘tirestay:’; var context = “; <%=CallBack%><br/> } ...
可以用这些代码在网页上实现漂亮的功能.常用js验证码,验证表单——不能超过设置字数,css控制checkbox、select的边框不显示.
第8章 图形图像与多媒体 335 8.1 图片大小 336 实例215 打开自定义大小的图片 336 实例216 图片放大缩小 ...实例315 带验证码的登录页面 500 12.4 其他 501 实例316 使用Script Encoder加密工具加密 501
就我而言,页面上的设计比较灵动的部分,其实不是很多,诸如滑动验证码,图片裁剪等比较好的交互设计。 从刚开始工作的时候,我就想把这些东西了解下,无奈一直没这个需求,乘着今天的空闲,研究了一下午,期间遇到...
本模块利用已有的 来Swift的创建验证码,并提供标记TAG,及验证的功能。 推荐您使用 TAG 针对一个手机号标记不同类型的验证码。(如:用于注册,登录,忘记密码等等。) API init RedisSecurityCode.init(options) ...
多语言支持:尽管OpenCV主要使用C++编写,但它提供了丰富的API绑定,支持包括C、Python、Java、MATLAB、JavaScript等多种编程语言,方便不同领域的开发者使用。 开源与免费:OpenCV遵循BSD开源许可证发布,用户...
WINTR是一个免费且易于使用的网络抓取API,可让您抓取任何网页并解析其HTML内容,而无需处理代理,IP旋转,无头浏览器和验证码。 创建帐户以开始使用 目录 刮擦Javascript呈现的网页,包括外部资产 抓取Javascript...
利用OCR识别验证码, 解决一次实际问题 (Node.js) 用户故事 (User Story) 最近因为牙齿不舒服, 打算通过网上预约挂号, 到附近医院的口腔科就诊. 打开网页注册帐号, 来到预约页面, 预约流程如下: 确定医生和时间段, ...