吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4040|回复: 18
收起左侧

[Web逆向] [验证码逆向]关于极验4验证通过却无法登录的问题

  [复制链接]
s1lencee 发表于 2024-1-27 03:29
本帖最后由 s1lencee 于 2024-1-28 10:55 编辑

[验证码逆向]关于极验4验证通过却无法登录的问题

本文内容仅限于安全研究和学习,不公开具体源码。维护网络安全,人人有责。

在这个人手极验4的时代,我就不详细介绍极验的逆向了,但是我曾经遇到过一个问题,感觉挺有意思,便分享一下。

前言

在某个网站登录中,当我使用python生成的极验4验证参数去登录时,却返回验证码错误。起初我以为是登录接口的问题但是我使用网站生成的验证参数去登录却可以成功登录,我就明白是协议代码的问题了。

后来翻遍网上也没发现什么有用的信息,直到我看到极验4发布的一篇博客: https://blog.geetest.com/article/fbb906f609a4dd9773c7609ef48bf664

博客内容

博客内容

其中"异常标记"功能引起我的注意,简单地说就是极验会在js里生成一个固定的键值对,极验服务器会校验该键值对,如果不相同则会返回一个"不正确"的验证参数。

键值对分析

该键值对在生成w值的e变量里。

e变量的值

e变量的值

直觉告诉我就是这个键值对的问题,当我把该键值对塞入代码里,重新登录,不出所料登录成功了。

深入研究发现该键值对与gcaptcha4.js的版本有关。

这是该键值对在gcaptcha4.js中的位置(v1.7.8)

键值对位置

键值对位置

于是我就将版本号和该键值对存在本地,并每次请求load接口都会检查返回的版本,当于本地不相同时获取新的gcaptcha4.js内容,并且用正则来查找该键值对(有条件的可以使用AST,我用正则是为了方便)

load返回的版本号

load返回的版本号

一下是获取键值对的部分代码

import re
# 最新的gcaptcha4.js
gt4_js = ""

# 获取键值对的主要内容
content = re.findall(r"!=typeof global\?global:this(.*?)\(\)", gt4_js)[0]
content = re.findall(r"{(.*?)}", content)[0]

# 获取键
key = re.findall(r"\"(.*?)\"", content)[0]
key = key.encode('utf-8').decode('unicode_escape')

# 获取混淆的值
n = re.findall(r"\(.*?\)", content)[0][1:-1]
# 解混淆函数,其实就是开头的那4个函数中的第3个
value = decrypt(n)
# 构造键值对
data = {key: value}

获取好键值对后可以保存在本地,下次就不需要重新获取了。

关于其他键值对

ep

该值在最近个版本中都是123,当然,如果不放心也可以获取。

def get_ep(gt4_js):
                """获取ep值"""
                # 使用正则表达式查找"\u0065\u0070": $_开头,)结尾的字符串
                js = re.findall(r"\"\\u0065\\u0070\":\$_.*?\)", gt4_js)[0]
                key = int(re.findall(r"\(.*?\)", js)[0][1:-1])
                ep = decrypt(key)
                return ep
biht: "1426265548"

该字符串较为固定,我已经几个月没见它变过了,其实这是在gct.js里生成的并且和ep有关,gct.js也是有版本号的,这个网上已经有人研究过了,我就不过多赘述了。

def get_gct(ep, gct_js) -> dict:
                """在gct.js中获取e值中的随机值键对"""
                function_name = re.findall(r"\)\)\{return (.*?)\(", gct_js)[0]
                break_position = gct_js.find("return function(t){")
                gct_js_new = gct_js[:break_position] + "window.gct=" + function_name + ";" + gct_js[break_position:]
                gct_js_new = "window = global;" + gct_js_new + 'function getGct(){var e = {"lang": "zh", "ep": "' + ep + '"};window.gct(e);delete e["lang"];delete e["ep"];return e;}'
                gct = execjs.compile(gct_js_new).call("getGct")
                return gct

最后的运行结果

结果

结果



免费评分

参与人数 4威望 +1 吾爱币 +23 热心值 +4 收起 理由
jjh4568520 + 1 + 1 用心讨论,共获提升!
涛之雨 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
abilittty + 1 + 1 热心回复!
BonnieRan + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

BonnieRan 发表于 2024-4-23 16:28
JerryGuo 发表于 2024-4-23 15:22
我遇到了与您同样的问题,请问您现在解决了吗,可以给点提示吗,不胜感激!

第二个w有个效验参数: 'xxxx': 'xxxxxxxxxx',长这样
您需要动态地从fullpage.js获取一下,就在文件开头 很长的url编码字符串,解码后和一个长度为6的字符串循环每位异或,解密的值里有这个效验参数,你跟一下用python还原解密, 动态获取 然后请求就可以正常获取到token
BonnieRan 发表于 2024-1-29 19:32
本帖最后由 BonnieRan 于 2024-1-29 21:21 编辑

哇,及时雨啊,太感谢楼主提供思路了~
昨天搞了一晚上MIUI社区的签到验证(geetest_v3 slide),也是通过验证但打死获取不到签到token,想来是以前扣参数的时候,把这个值写死了
我这就去试试~
ky_wei 发表于 2024-1-29 20:22
ky_wei 发表于 2024-1-29 20:51
https://help.aliyun.com/zh/captcha/captcha1-0/user-guide/feature-description-2?spm=a2c4g.11186623.0.i2
 楼主| s1lencee 发表于 2024-1-29 21:19
ky_wei 发表于 2024-1-29 20:22
阿里的人机原理是一样的吗?

阿里的不太清楚,但是我了解到数美的用到了类似技术
Pwaerm 发表于 2024-1-30 11:27
ky_wei 发表于 2024-1-29 20:22
阿里的人机原理是一样的吗?

不一样  那个带行为分析
ky_wei 发表于 2024-1-30 17:47
Pwaerm 发表于 2024-1-30 11:27
不一样  那个带行为分析

有没有办法取到相关参
Pwaerm 发表于 2024-1-31 09:39
ky_wei 发表于 2024-1-30 17:47
有没有办法取到相关参

理论上有破解之法,但是我不会呀。

我目前只知道用Python 模拟鼠标做一些移动或者点击的动作可以过关
ky_wei 发表于 2024-1-31 14:49
Pwaerm 发表于 2024-1-31 09:39
理论上有破解之法,但是我不会呀。

我目前只知道用Python 模拟鼠标做一些移动或者点击的动作可以过关

通过鼠标模拟点击行为确实可以过关,想直接带参获取还是有点难度的,混淆太厉害了
Jason_8840 发表于 2024-2-5 15:50
大佬,极验4的逆向有文章分享吗?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-22 23:59

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表