【验证码逆向专栏】某验四代滑块验证码逆向分析

news2024/11/27 4:18:19

00

文章目录

    • 声明
    • 逆向目标
    • 通讯流程
    • 验证码流程分析
    • 逆向分析
      • captcha_id 参数
      • challenge 参数
      • w 参数
    • 结果验证

声明

本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除!

本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请在公众号【K哥爬虫】联系作者立即删除!

逆向目标

  • 目标:某验四代滑块验证码,w 参数逆向
  • 主页:aHR0cHM6Ly9ndDQuZ2VldGVzdC5jb20v
  • 加密算法:RSA、AES

通讯流程

01

验证码流程分析

进入网页后,打开开发者人员工具进行抓包,点击滑动拼图验证,此时还未点击按钮开始验证,抓到了一个名为 load?captcha_id=xxx 的包,Query String Parameters 包含了一些参数:

02

  • captcha_id:验证码 id,固定值,由 adaptive-captcha-demo.js 文件生成,后文分析;
  • challenge:动态变化,由 gtc4.js 文件生成,后文分析;
  • client_type:表示 web 端;
  • risk_type:验证码类型,例如滑块为 slide,无感为 ai;
  • lang:语言;
  • callback:geetest_ + 时间戳,主要作用是防止缓存。

响应预览中返回的关键内容如下,相较于三代,底图未做混淆:

03

  • bg:背景图片地址;
  • captcha_type:验证码类型;
  • gct_path:gct4 文件路径;
  • lot_number:后续生成 pow_msg、w 的关键参数;
  • payload:后续 verify 请求接口需要的参数;
  • datetime:ISO 8601扩展格式的日期,后续生成 pow_msg 的关键参数;
  • process_token:后续 verify 请求接口需要的参数;
  • slice:滑块图片地址。

点击按钮开始验证,弹出滑块验证码,滑动滑块,抓包到 verify?captcha_id=xxxQuery String Parameters 同样包含了一些参数:

04

  • captcha_id:与 load 接口请求头中的 captcha_id 一致;
  • client_type:表示 web 端;
  • lot_number:load 接口返回的;
  • risk_type:与 load 接口中的一致,表示验证码类型;
  • payload:load 接口返回的;
  • process_token:load 接口返回的;
  • w:加密参数,由轨迹、滑动时间、滑动距离、userresponse、device_id、pow_msg 等参数加密得到;
  • callback:geetest_ + 时间戳,主要作用是防止缓存。

响应预览中返回的内容如下,result 值为 fail 即校验失败,success 为校验通过,通过后携带 seccode 下的参数进行后续业务请求:

05

逆向分析

captcha_id 参数

全局搜索 captcha_id,跟进到 gt4.js 文件中:

06

进去后在第 307 行打上断点,刷新页面即会断住,此时 captcha_id 参数的值已经生成,同时 challenge 参数定义在下一行:

07

向上跟栈到 value,即 adaptive-captcha-demo.js 文件中,会发现其是个固定值,实际上这个值是每个网站不一样,是管理员在极验后台申请得到的:

08

challenge 参数

前面提到,challenge 参数定义在 captcha_id 参数的下一行,在 gt4.js 文件的第 309 行打下断点:

09

可以看到,challenge 参数的值由 uuid 函数生成,扣出即可。

w 参数

verify?captcha_id=xxx 接口的堆栈处跟栈进去:

10

打下断点滑动滑块断住后,向上跟栈到 s 处,如果做过某验三代滑块的话,第 6249 行有个很熟悉的东西,"\u0077": r"\u0077" 即字母 w 的 Unicode 值,r 即 w 参数的值:

11

r 参数定义在第 6237 行,e 也是跟三代类似的参数,r 是将 i 参数和转为字符串的 e 参数加密得到的:

12

向上跟栈,找到 e 参数中各部分定义生成的位置,跟到 $_BHIH 中,_ 中先生成了四个键值对:

13

passtimetrack 是熟悉的滑动时间和轨迹,setLeft 为识别出来的缺口距离,userresponse 定义在 19593 行, a 为 setLeft 参数的值,t[$_GDFCG(1909)] 为定值 1.0059466666666665:

a / t[$_GDFCG(1909)] + 2

接着跟到 $_BCFj 中,e 定义在第 6201 行,下面几行定义了 e 中的 device_idlot_numberpow_msgpow_sign

14

device_id 同一个网站是固定值,lot_number 是 load 响应返回的,控制台打印一下 pow_msgpow_sign 的结果:

15

pow_msg 很明显是由几部分组成的,pow_sign 经过加密,向上跟栈到 init 中,分别定义在第 5837 行和第 5838 行,为 d 字典的键,根据键名取值:

16

d 定义在第 5835 行,这部分还原一下就很明显了:

var c = t["toDataURL"]()["replace"]("data:image/png;base64,", "")
	, _ = new w["default"]["MD5"]()["hex"](c);
a["options"]["deviceId"] = _;
var h = a["options"]
	, l = h["powDetail"]
	, p = h["lotNumber"]
	, f = h["captchaId"]
	, d = v["default"](p, f, l["hashfunc"], l["version"], l["bits"], l["datetime"], "")

跟进到 v["default"] 中,函数定义在第 6945 行,于 6978 行打下断点:

17

pow_msg_ + h 得到,_ 定义在第 6960 行:

_ = i + "|" + r + "|" + n + "|" + s + "|" + t + "|" + e + "|" + o + "|";
  • i:l["version"]
  • r:l["bits"]
  • n:l["hashfunc"]
  • s:l["datetime"]
  • t:f, h["captchaId"]
  • e:p, h["lotNumber"]
  • o:""

h 定义在第 6269 行,跟进去是 16 位随机数字符串,pow_sign 为 p,就是 pow_msg 经过 MD5 加密得到的:

18

至此这四个也分析完了,还差以下这部分:

19

em 等定值就不分析了,注意 kqg5:"1557244628",这个参数值和三代滑块中一样,每隔几个小时会改变,向上跟栈到 $_BCFj 中,在第 6207 行打下断点,此时 e 中这个值还未生成:

20

下一行打下断点,下步断点,即执行完 n[$_CBHIE(791)](e); 后,这个参数值就生成了,证明是 n[$_CBHIE(791)] 方法生成的,跟进去:

21

跳转到第 5766 行,在第 5779 行打下断点,此时的 n 中还未生成此参数:

22

执行了 _gct(n) 后即生成:

23

可见其生成位置在 _gct 方法中,跟进去后到 gct4.js 文件,和三代大差不差:

24

可以将值导出,至此 e 就分析完了,接着回到第 6238 行,跟进到加密函数 d[$_CBHHO(84)] 中,定义在第 11669 行,d[$_DIEHS(177)](c) + u 即 r 参数的值,c 为一个大数组,u 明显也经过加密了,所以 r 参数的值就是数组 c 加密后再加上 u 得到的:

25

先跟进到 u,其定义在第 11705 行,解混淆后如下:

u = new l["default"]()["encrypt"](i);

所以 u 是 i 经过加密后得到的,i 定义在第 11702 行:

i = (0,d[$_DIEIq(103)])()

跟进到 d[$_DIEIq(103)] 中,定义在第 852 行,又是熟悉的 16 位随机数:

26

i 是随机数,跟进到加密函数 l[($_DIEHS(84))] 中,在第 12725 行,于 12741 行打下断点,可以看到这里就是个 RSA 加密,扣代码或者直接引库即可:

27

回到 c 参数,c 参数的值为一个大数组,其定义在第 11705 行,解混淆后内容如下:

var c = s[a]["symmetrical"]["encrypt"](e, i);

e 之前分析完了,i 为随机数,两个参数已经分析完了,跟进到加密方法中,在第 12174 行,于 12186 行打下断点,控制台打印一下混淆部分内容,很熟悉的东西,这里就是 AES 加密,iv 为初始向量,加密模式为 CBC,对各类加密算法不熟悉的,可以阅读 K 哥文章 【爬虫知识】爬虫常见加密解密算法:

28

c 参数最后又被 d[$_DIEHS(177)] 函数加密,跟进后,定义在第 547 行,直接扣下来改改即可:

29

结果验证

30

31

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/143278.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

剑指 Offer 27. 二叉树的镜像(Leetcode 226. 翻转二叉树)(二叉树后序遍历)

题目: 链接:剑指 Offer 27. 二叉树的镜像;Leetcode 226. 翻转二叉树 难度:简单 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 示例 1: 输入:root [4,2,7,1,3,…

调用Ishingami Homma解析函数测试PAWN算法(Matlab代码实现)

目录 💥1 概述 📚2 运行结果 🎉3 参考文献 👨‍💻4 Matlab代码 💥1 概述 灵敏度分析分为局部灵敏度分析和全局灵敏度分析;局部灵敏度分析包括:直接求导法、有限差分法、格林函数…

06-07-Alibaba Nacos注册中心源码剖析

Nacos&Ribbon&Feign核心微服务架构图 架构原理 1、微服务系统在启动时将自己注册到服务注册中心,同时外发布 Http 接口供其它系统调用(一般都是基于SpringMVC) 2、服务消费者基于 Feign 调用服务提供者对外发布的接口,先对调用的本地接口加上注…

Github每日精选(第85期):PDF 文档的 React 组件react-pdf-viewer

react-pdf-viewer react-pdf-viewer 用于查看 PDF 文档的 React 组件。它是用 TypeScript 编写的,完全由 React hooks 提供支持。 github 的地址在这里。 使用实例 添加水印 默认情况下,每个页面由画布、文本和注释层构成。在此示例中,我…

RCE(命令执行)总结

文章目录RCE(命令、代码执行)总结1、过滤cat、flag等关键字1.1 常见linux系统命令1.2 使用转义符1.3 使用引号1.4 内联执行绕过1.5 编码绕过1.6 进制绕过1.7 过滤文件名(如: /etc/passwd文件)1.8 使用$*和$,$x,${x}1.9 读取文件命令1.10 查找文件命令(fi…

【观察】汇聚中国开源数据库创新力量,openGauss驶入发展“快车道”

毫无疑问,数据库是“软件产业皇冠上的明珠”,是数字基础设施不可或缺的底座之一。但也要看到,由于数据库难度大,产业投入周期长,迫切需要凝聚产业力量共建基础能力。在此背景之下,作为定位企业级开源数据库…

H264 NALU分析以及提取h264实战

1.H264简介 H.264从1999年开始,到2003年形成草案,最后在2007年定稿有待核实。在ITU的标准⾥称 为H.264,在MPEG的标准⾥是MPEG-4的⼀个组成部分–MPEG-4 Part 10,⼜叫Advanced Video Codec,因此常常称为MPEG-4 AVC或直…

Java学习(22)调试初步——debug入门

程序调试-debug 调试的作用 让程序员能看清程序每一步的效果,在需要查看结果的时候,使用debug查看实际结果是否与预期结果一致。案例 (1) 设置断点 鼠标左键双击设置/取消,或者右键选择Toggle Breakpoint。 (2) 执行调试 Run→\to→Debug&a…

快速了解chrony服务器

目录 一、chrony服务器 二、chrony安装与配置 三、时间服务器 四、配置时间服务器 一、chrony服务器 Chrony是一个开源自由的网络时间协议 NTP 的客户端和服务器软软件。它能让计算机保持系统时钟与时钟服务器(NTP)同步,因此让你的计算机…

操作系统期末复习题-不挂科

写在前面: 本题目由博主收集而成,如有侵权请告知删除! 一、选择题 DMA 控制方式是在( B)之间建立一条直接数据通路。 A. I/O 设备与 CPU B. I/O 设备与主存 C. CPU 与主存 D. I/O 设备之间 以下 I/O 控制方式中&…

javaee之springMVC3

ssm整合说明 ssm整合之搭建环境 现在先去数据里面&#xff0c;创建好库&#xff0c;创建好表 然后在pom.xml中引入各种需要的jar包 pom.xml <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0"…

webpack起步

webpack 1&#xff0c;起步 先安装node.js 再用npm安装webpack全局 运用commonjs模块化语法&#xff0c;用全局命令进行打包来初步了解一下 命令为&#xff1a; webpack 入口main路径 出口bundle路径 很麻烦所以要配置一下webpack入口出口配置。 2&#xff0c;配置 webpa…

SpringCloud Netflix复习之Ribbon

文章目录写作背景SpringCloud Ribbon是什么&#xff0c;干了什么事情Ribbon组件的核心功能Ribbon内置了哪些负载均衡算法上手实战在SpringCloud里Ribbon实战从源码角度看下Ribbon实现原理SpringCloud与Ribbon整合的原理LoadBalancerInterceptor拦截器改变了RestTemplate什么行为…

第三章:OAuth协议流程

应用场景 1、 原生app授权&#xff1a;app登录请求后台接口&#xff0c;为了安全认证&#xff0c;所有请求都带token信息&#xff0c;如果登录验证、 请求后台数据。 2、前后端分离单页面应用&#xff1a;前后端分离框架&#xff0c;前端请求后台数据&#xff0c;需要进行oauth…

Codeforces Round #842 (Div. 2) C. Elemental Decompress

翻译&#xff1a;您将得到一个由&#x1d45b;个整数组成的数组&#x1d44e;。找到两个排列组合&#x1d45d;长度和&#x1d45e;&#x1d45b;这样马克斯(&#x1d45d;&#x1d456;,&#x1d45e;&#x1d456;)&#x1d44e;&#x1d456;所有1≤&#x1d456;≤&#x1…

Spring Boot学习篇(七)

Spring Boot学习篇(七) 1.thymeleaf模板引擎使用篇(一) 1.1 准备工作 1.1.1 在pom.xml中导入所需要的依赖 a thymeleaf模板引擎所需要的依赖 <!--thymeleaf模板引擎,前后端不分离的时候用 普通的html格式--> <dependency><groupId>org.springframework.…

计算机网络实验---Wireshark 实验

数据链路层 实作一/熟悉 Ethernet 帧结构 实作二/了解子网内/外通信时的 MAC 地址 实作三/掌握 ARP 解析过程 网络层 实作一 /熟悉 IP 包结构 实作二 IP 包的分段与重组 实作三 考察 TTL 事件 传输层 实作一 熟悉 TCP 和 UDP 段结构 实作二 分析 TCP 建立和释放连接 应用层 …

数据结构基本介绍

1.what is Data Structure? A data structure is a memory used to store and organize dataIt is also used for processing, retrieving, and storing data 2. what is classification of Data Structure? 2.1 what is Linear data structure? Data structure in which…

你还不懂递归么?不允许你不懂,进来折腾下自己吧

举例数组 const arr [ {id: "1175310929766055936", pid: "", name: "总裁办" },---返回空数组, {id: "1175311213774962688", pid: "", name: "行政部" },---返回空数组, {id: "1175311267684352000&qu…

随想录一刷Day27——回溯算法

文章目录Day27_回溯算法13. 子集 II14. 491.递增子序列15. 全排列全排列 IIDay27_回溯算法 13. 子集 II 90. 子集 II class Solution { private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& nums, int startI…