免责声明

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

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. Table.Skip删除前面N….Skip/RemoveFirstN(Power Query 之 M 语言)

    数据源: "姓名""基数""个人比例""个人缴纳""公司比例""公司缴纳"&qu ...

  2. 网络编程之UDP(1)高效低销

    读书笔记 from here 高效 Linux系统有用户空间(用户态)和内核空间(内核态)之分,内核与用户空间发生切换比较耗时,内核需要保存上下文.执行用户态数据.再恢复到保存的上下文. 实际中,应该 ...

  3. 【LeetCode】839. 相似字符串组 Similar String Groups (Python)

    作者: 负雪明烛 id: fuxuemingzhu 公众号:每日算法题 本文关键词:LeetCode,力扣,算法,算法题,字符串,并查集,刷题群 目录 题目描述 解题思路 并查集 代码 刷题心得 欢迎 ...

  4. 【LeetCode】111. Minimum Depth of Binary Tree 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS BFS 日期 [LeetCode] 题目地址 ...

  5. 【LeetCode】167. Two Sum II - Input array is sorted 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 Java解法 Python解法 日期 题目地址:ht ...

  6. 人脸搜索项目开源了:人脸识别(M:N)-Java版

    ​ 一.人脸检测相关概念 人脸检测(Face Detection)是检测出图像中人脸所在位置的一项技术,是人脸智能分析应用的核心组成部分,也是最基础的部分.人脸检测方法现在多种多样,常用的技术或工具大 ...

  7. HMS Core电商与游戏行业解决方案,全流程赋能开发者创新

    2021年12月29日,"华为云&华为终端云服务创新峰会2022"在北京柏悦酒店成功举办.华为HMS Core电商与游戏行业解决方案亮相本次峰会的线下展区,为行业开发者们解 ...

  8. Attention Is All You Need

    目录 概 主要内容 Positional Encoding auto_regressive 额外的细节 代码 Vaswani A., Shazeer N., Parmar N., Uszkoreit ...

  9. Java高级程序设计笔记 • 【第6章 设计模式】

    全部章节   >>>> 本章目录 6.1 设计模式 6.1.1 设计模式概述和分类 6.1.2 单列模式介绍 6.1.3 单例模式的实现 6.1.4 实践练习 6.2 单例模式 ...

  10. docker学习:docker三要素

    镜像 docker 镜像(image)就是一个只读的模板.镜像可以用来创建docker容器,一个镜像可以创建很多容器 容器 docker 利用容器(Container)独立运行的一个或者一组应用.容器 ...