javascript验证码:利用JavaScript破解验证码

="t18">利用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从图像中提取出像素数据后将其送入神经网络通过种简单光学识别技术来推测验证码中到底使用了哪些

  通过阅读源代码我们不仅可以更好地理解其工作原理也可以领会这个验证码究竟是如何实现就像前面看到那样这里使用验证码不是很复杂——每个验证码有 3个组成每个使用种区别颜色并且只使用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;
  }
  }
  }


  然后将画布分成 3个单独像素矩阵每个矩阵包含步实现起来非常容易每个都使用种单独颜色所以通过颜色就可以将其区分开来

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
   (image_data.data[i] colour) {
  image_data.data[i] = 255;
  image_data.data[i+1] = 255;
  image_data.data[i+2] = 255;
  // Everything to black
  } {
  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;
   (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%可能是字母A36%可能是字母B等)

  当对验证码中 3个字母都经过处理以后最终结果也就出来了需要注意该脚本无法达到100%正确性(不知道如果在开始时候不将字母转换成矩形是不是可以提高评分精度)但这已经相当好了至少对于当前用途来说是这样而且所有操作都是在基于标准客户端技术实现浏览器中完成!

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

Tags:  javascript数组 javascript教程 javascript javascript验证码

延伸阅读

最新评论

发表评论