freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

【验证码逆向专栏】某验四代滑块验证码逆向分析
K哥爬虫 2023-01-19 11:29:11 196727
所属地 湖北省

00

声明

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

本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请在公众号【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

# 逆向 # 逆向工程 # 逆向分析
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 K哥爬虫 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
K哥爬虫逆向专栏
K哥爬虫 LV.7
欢迎关注微信公众号:K哥爬虫,分享 JS/APP/小程序逆向、数据加密解密、高级爬虫进阶知识!
  • 86 文章数
  • 56 关注者
【验证码识别专栏】某盾躲避障碍与某里图像复原验证码识别
2025-04-15
【APP 逆向百例】淘某热点 APP 逆向分析
2025-03-24
【验证码逆向专栏】某盾 v2 滑动验证码逆向分析
2025-03-03
文章目录