免责声明

本文章所提到的技术仅用于学习用途,禁止使用本文章的任何技术进行发起网络攻击、非法利用等网络犯罪行为,一切信息禁止用于任何非法用途。若读者利用文章所提到的技术实施违法犯罪行为,其责任一概由读者自行承担,与作者无关。

0x01 前言

滑块验证码是我们在互联网上经常遇见的校验是否人类操作行为的一种检测方式,大概流程就是生成一张图片,然后随机挖去一块,在页面展示被挖去部分的图片,再通过js获取用户滑动距离,以及坐标等信息到后台进行校验。只要用户移动的距离符合,以及移动的轨迹行为检测通过即可视为验证通过。

而大部分开发者做爬虫时经常需要绕过该此类验证码进行下一步的爬虫,本文仅对极验geetest平台下的滑块验证码的图片还原进行分析与研究,试图找到打乱图片到正常图片之间的还原函数以及解析它还原算法的原理。

0x02 截获验证码原图

访问极验geetest滑动模块demo页面后请求验证码图片,并使用浏览器F12开发者工具截获从极验geetest服务器响应回来的图片。

响应回来的一张是原图,另一张是带有拼图缺口的图,但它们均是乱序的,介绍来我们得逐步分析js的源代码是如何将乱序图片恢复至正常图片的。

0x03 找突破口

寻找思路

思路是需要找到还原验证码图片的方法,首先我们得找到验证码被绘制时的方法调用,打开Elements(元素)选项卡,查看页面上验证码图片框内的元素。

显然易见,该图片是使用canvas画出来的,这时候我们第一想到的就是使用事件监听断点,将canvas要被创建时的动作断下来。打开Sources(源代码)选项卡,将右侧Event Listener Breakpoints(事件监听断点)内的Canvas->Create canvas context,勾选上,意为在canvas创建context之时将断点停在该方法上。重新点击刷新验证码图片后,即可捕获到该事件。

捕获CanvasContext创建事件

捕获到canvas创建context事件,由下图不难看出,第280行代码var o = i[$_CJDQ(76)]($_CJDQ(28));以及第282代码var s = e[$_CJET(76)]($_CJET(28));均是创建了一个CanvasRenderingContext2D对象,并分别赋值给了变量o变量s

接下来直接断点至第291行,并放行至该行代码,忽略for循环的运算逻辑以及他的意义,我们需要先梳理被混淆后的js源代码的实际含义是什么。

恢复源代码被混淆前的含义

经过断点后,可以将光标放置在被混淆的掩码上,会自动提示该掩码的真正含义。以下是作者整理出来的含义以及恢复后的源代码。

掩码 实际含义
$_CJDQ(76) "getContext"
$_CJDQ(28) "2d"
$_CJET(12) "drawImage"
$_CJET(72) "height"
$_CJDQ(39) "width"
$_CJET(69) "getImageData"
$_CJET(66) "putImageData"
// slide.7.8.6.js的第280行至第290行代码
var o = i[$_CJDQ(76)]($_CJDQ(28));
o[$_CJET(12)](t, 0, 0);
var s = e[$_CJET(76)]($_CJET(28));
e[$_CJET(72)] = r,
e[$_CJDQ(39)] = 260;
for (var a = r / 2, _ = 0; _ < 52; _ += 1) {
var c = Ut[_] % 26 * 12 + 1,
u = 25 < Ut[_] ? a: 0,
l = o[$_CJET(69)](c, u, 10, a);
s[$_CJET(66)](l, _ % 26 * 10, 25 < _ ? a: 0);
}

经过对掩码的替换,执行含义也非常的清晰。

// 被还原后的代码含义(变量名也经过了修改)
var CRC2D_1 = i.getContext("2d"); //创建一个CanvasRenderingContext2D对象
CRC2D_1.drawImage(t, 0, 0); //将t变量画到CRC2D_1中,该t为验证码乱码原图
var CRC2D_2 = e.getContext("2d"); //创建另一个CanvasRenderingContext2D对象
CRC2D_2.height = r, //设置高度
CRC2D_2.width = 260; //设置宽度
// 该循环必定是还原乱码原图的算法
for (var a = r / 2, _ = 0; _ < 52; _ += 1) {
var c = Ut[_] % 26 * 12 + 1,
u = 25 < Ut[_] ? a: 0,
l = CRC2D_1.getImageData(c, u, 10, a); // 将某个小区块的乱码原图赋值给变量l
CRC2D_2.putImageData(l, _ % 26 * 10, 25 < _ ? a: 0); // 将在乱码原图扣下来的小部分按顺序拼接到CRC2D_2中
}

显然for循环体内的数组Ut[]必定就是该乱码图片还原的关键序列,通过调试可以得出数组Ut[]并不会随着运行次数的改变而改变,它是固定的一个还原序列,通过Console(控制台)选项卡可直接打印数组Ut[]进行还原顺序的查看。

0x04 还原算法的原理

首先需要知道的是乱码图片其实是被分成了上下各26块小图块,并且接收的图片一定被分为上下两大块,原因是还原算法的for循环中,定义了var a = r / 2,意思是a为图片坐标的一半,并且是固定的一半。

var c = Ut[_] % 26 * 12 + 1u = 25 < Ut[_] ? a: 0,这两条for循环体中的语句对应的变量c变量u的含义分别是第Ut[_]个乱图中小方块的左上角xy的像素位置。

经过l = CRC2D_1.getImageData(c, u, 10, a)方法执行,将小图块从(c, u)坐标开始,宽度为10,高度为a(指的就是小图块的高度)扣下来,保存到变量l中。

然后执行CRC2D_2.putImageData(l, _ % 26 * 10, 25 < _ ? a: 0);,将变量l保存的小图块,把它按从左往后,从上往下的顺序,依次写入到对象CRC2D_2中。

由此分析,可得到以下图片的还原顺序。

0x05 作者的一些话

该篇讲述如何使用浏览器F12开发者工具对极验geetest滑动验证码图片的还原函数的定位、寻找思路,以及解析了还原函数的实现原理,作者强烈反对大家使用该技术进行实质性地爬虫以及其他形式的利用。

请时刻牢记:天网恢恢,疏而不漏。

对极验geetest滑块验证码图片还原算法的研究的更多相关文章

  1. Django中使用极验Geetest滑动验证码

    一,环境部署 1.创建一个django测试项目 此处省略... 二,文档部署 1.下载安装python对应的SDK 使用命令从Github导入完整项目:git clone https://github ...

  2. 破解极验(geetest)验证码

      破解极验(geetest)验证码 这是两年前的帖子: http://www.v2ex.com/t/138479 一个月前的破解程序,我没用过 asp.net ,不知道是不是真的破解了, demo ...

  3. Js逆向-滑动验证码图片还原

    本文列举两个例子:某象和某验的滑动验证 一.某验:aHR0cHM6Ly93d3cuZ2VldGVzdC5jb20vZGVtby9zbGlkZS1mbG9hdC5odG1s 未还原图像: 还原后的图: ...

  4. 爬虫进阶教程:极验(GEETEST)验证码破解教程

    摘要 爬虫最大的敌人之一是什么?没错,验证码!Geetest作为提供验证码服务的行家,市场占有率还是蛮高的.遇到Geetest提供的滑动验证码怎么破?授人予鱼不如授人予渔,接下来就为大家呈现本教程的精 ...

  5. 极验(Geetest) Laravel 5 集成开发包,让验证更安全

    简述 在网站开发中使用频率最高的工具之一便是验证码,验证码在此也是多种多样,不过简单的图片验证码已经可以被机器识别,极验验证码提供了一个安全可靠的滑动验证码体系,让网站开发更加安全. 先感受一下这种验 ...

  6. laravel 极验(Geetest) 让验证更安全。

    整理的有些仓促,在9月15号之后会更新更加详细更加全面的文档,供给大家参考,学习! 1.简述 在网站开发中使用频率最高的工具之一便是验证码,验证码在此也是多种多样,不过简单的图片验证码已经可以被机器识 ...

  7. 极验(geetest)验证码

    最近在做项目的时候,需要用到登录验证,在网上看到了一个很不错的验证插件,在此记录一下使用流程. 极限验证码   官网:http://www.geetest.com/,到GitHub下载服务端代码htt ...

  8. 使用Python + Selenium破解滑块验证码

    在前面一篇博客<使用 Python + Selenium 打造浏览器爬虫>中,我介绍了 Selenium 的基本用法和爬虫开发过程中经常使用的一些小技巧,利用这些写出一个浏览器爬虫已经完全 ...

  9. 极验反爬虫防护分析之slide验证方式下图片的处理及滑动轨迹的生成思路

    本文要分享的内容是去年为了抢鞋而分析 极验(GeeTest)反爬虫防护的笔记,由于篇幅较长(为了多混点CB)我会按照我的分析顺序,分成如下四个主题与大家分享: 极验反爬虫防护分析之交互流程分析 极验反 ...

随机推荐

  1. Niushop开源商店渗透测试

    靶机 提取码:le8l 首先连上靶机 先扫一下靶场ip,看看开启了哪些端口 开启了80端口,扫描一下目录 一个shop的界面, 一个admin后台管理界面 其他的目录翻看了一下, 看样子是网站的配置文 ...

  2. 【LeetCode】628. Maximum Product of Three Numbers 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 方法一:排序 日期 题目地址:https://lee ...

  3. Ubuntu安装Git及Git配置

    1.检查Git是否已经安装 使用git version,若不显示版本号则Git未安装,下面是我安装好后显示的版本号 2.安装Git sudo apt-get install git Centos使用y ...

  4. C++输出控制小数点后位数的方法

    以C++输出小数点两位数为例 setprecision(n)使用方法总结 首先要记住写头文件 #include <iomanip> //不要忘了头文件 以下是控制小数位数的三种写法 //t ...

  5. jsp标签 c:when

    Illegal use of <when>-style tag without <choose> as its direct parent 在jsp页面用报错Illegal u ...

  6. IT6516替代方案|CS5212替代IT6516|CapstoneCS5212

    IT6516/IT6516BFN:是一款DP显示端口转VGA转换器的嵌入式MCU单片机. IT6516/IT6516BFN结合DisplayPort接收器和三重DAC,通过转换功能支持DisplayP ...

  7. pod存在,但是deployment和statefulset不存在

    pod存在,但是deployment和statefulset不存在 这样的话,可以看一下是不是ReplicaSet, kubectl get ReplicaSet  -n iot

  8. SpringCloud创建Config读取本地配置

    1.说明 Config Server获取配置支持的方式很多, 包括Git仓库(github/gitee等),任何与JDBC兼容的数据库, Subversion,Hashicorp Vault,Cred ...

  9. Elasticsearch安装X-Pack插件

    Elasticsearch安装X-Pack插件, 基于已经安装好的6.2.2版本的Elasticsearch, 安装6.2.2版本的X-Pack插件. 1.下载x-pack的zip包到本地 https ...

  10. 【17MKH】我在框架中对.Net依赖注入的扩展

    说明 依赖注入(DI)是控制反转(IoC)的一种技术实现,它应该算是.Net中最核心,也是最基本的一个功能.但是官方只是实现了基本的功能和扩展方法,而我呢,在自己的框架 https://github. ...