利用JavaScript破解验证码

  近日,网上惊现可以破解验证码的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%正确性(不知道如果在开始的时候不将字母转换成矩形,是不是可以提高评分的精度),但这已经相当好了,至少对于当前的用途来说是这样。而且所有的操作都是在基于标准的客户端技术实现的浏览器中完成的!

  补充说明一下,这个脚本应该算是一个特例吧,这项技术可能会很好的工作在在其它简陋的验证码上,但对于复杂的验证码来说,就有点鞭长莫及了(尤其是这种基于客户端的分析)。但愿有更多人能从这个项目中受到启发而开发出更奇妙的东西来,因为它的潜力实在是太大了。

时间: 2024-09-21 17:08:14

利用JavaScript破解验证码的相关文章

利用Python破解验证码实例详解_python

一.前言 本实验将通过一个简单的例子来讲解破解验证码的原理,将学习和实践以下知识点:       Python基本知识       PIL模块的使用 二.实例详解 安装 pillow(PIL)库: $ sudo apt-get update $ sudo apt-get install python-dev $ sudo apt-get install libtiff5-dev libjpeg8-dev zlib1g-dev \ libfreetype6-dev liblcms2-dev lib

利用javaScript实现点击输入框弹出窗体选择信息

 这篇文章主要是对利用javaScript实现点击输入框弹出窗体选择信息进的实例行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助 在这里奉上源代码,没有做样式处理,不过功能是可以的,希望大家可以和我交流交流!   代码如下: <html>  <head>   <title>点击弹出DIV选择信息</title>      <meta http-equiv="keywords" content="keyword1

利用JavaScript创建功能强大的GUI

javascript|创建 大多数的计算机用户都非常熟悉Windows的图形用户界面(GUI),都通过使用Word或微软的电子邮件客户端软件了解了按钮.工具条.标签,但与客户端软件都拥有几乎一致的界面截然不同的是,我们可以发现,每个网站的界面都各不相同.用户需要学会如何使用每一种互联网应用程序.尽管大多数的互联网应用程序都不是太复杂,但一个用户需要不断地去学习应用程序界面,时时感觉自己象个新手,这对于用户而言,毕竟不是一件令人愉快的事. 通过利用javascript和CSS建立互联网应用程序或网

Javascript实例教程(8) 利用Javascript基于浏览器类型的重定向

javascript|教程|浏览器 利用javascript基于浏览器类型的重定向 基于浏览器类型的重定向的实现可以通过使用javascript函数来检查navigator.userAgent的字符串"MSIE",它将告诉你用户是否使用Microsoft Internet Explorer(微软的IE浏览器).通过修改windows.location函数可以重定向到正确的URL(同意资源定位器).下面是详细的代码: <HTML> <HEAD> <SCRIP

Javascript实例教程(7) 利用Javascript进行密码保护

javascript|教程 利用javascript进行密码保护 随着互联网的飞速发展,地球变得越来越小,人们可以跨越时间和空间得界限进行交流于合作.但是随之也产生了一些肆意搞破坏的黑客,这就使得程序设计人员在编制应用程序中要考虑到黑客袭击这个问题,所以自然而然地就会想到保护.本节教程将教你怎样利用javascript进行密码保护.利用javascript来对网页进行密码保护有几种方法.最早的一种方法是依耐于用户而不知道目标文件名,代码如下: <SCRIPT LANGUAGE="javas

利用javascript来转换GB2312到UNICONDE -- &amp;#形式

javascript|转换 利用javascript来转换 <style>BODY {FONT-SIZE: 9pt; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px;}input {FONT-SIZE: 9pt; height: 13pt;}</style> <script language="JavaScript1.2">/*This foll

利用javascript来转换GB2312到UNICONDE

javascript|转换 利用javascript来转换 <style>BODY {FONT-SIZE: 9pt; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px;}input {FONT-SIZE: 9pt; height: 13pt;}</style> <script language="JavaScript1.2">/*This foll

利用JavaScript和CSS制作浮动menu

css|javascript|浮动 随着INTERNET的高速发展,越来越多的人拥有了个人主页,但以往的静态HTML语言,已经不能满足人们的要求.javascript和多层模式表单(Cascading Style Sheet, CSS)的出现使网页更加生动活泼,从而可以获得令人满意的效果.本文以javascript和CSS制作一种浮动菜单的方法为例,来说明其灵活性,同时也是抛砖引玉希望和广大网友共同切磋技术,制作出更好的家页(homepage).当我们浏览一个超过屏幕显示范围的一个页面时,为了回

Javascript实例教程(6) 利用Javascript进行密码保护

随着互联网的飞速发展,地球变得越来越小,人们可以跨越时间和空间得界限进行交流于合作.但是随之也产生了一些肆意搞破坏的黑客,这就使得程序设计人员在编制应用程序中要考虑到黑客袭击这个问题,所以自然而然地就会想到保护.本节教程将教你怎样利用Javascript进行密码保护.利用JavaScript来对网页进行密码保护有几种方法.最早的一种方法是依耐于用户而不知道目标文件名,代码如下: <SCRIPT LANGUAGE="JavaScript"><!-- function g