使用Python破解gcaptcha4.js中的w参数加密算法

在这篇文章中,我们将介绍如何使用Python来逆向工程gcaptcha4.js文件,找到并破解w参数的加密算法。这个过程包括观察verify请求,定位加密位置,分析加密算法,最终还原w参数的明文。

一. 观察verify请求
首先,我们需要观察verify请求的发起者。在网络请求中,我们可以看到所有verify请求都来自于gcaptcha4.js文件。因此,这个文件成为我们分析的重点。

我们使用Python的requests库来捕获和分析这些请求。

python

import requests

# 发送一个测试请求,获取响应
response = requests.get('https://example.com/verify')
print(response.text)
通过分析响应内容,可以发现所有的verify请求都指向了gcaptcha4.js文件。

二. 定位w参数加密位置
为了找到w参数的加密位置,我们需要解析gcaptcha4.js文件。我们可以下载并格式化这个文件,然后使用正则表达式搜索关键词:w、.w、'w'或"w"。

python

import re

# 读取gcaptcha4.js文件内容
with open('gcaptcha4.js', 'r') as file:
    js_content = file.read()

# 搜索w参数的位置
matches = re.finditer(r'[\.\'\"]w[\.\'\"]', js_content)
for match in matches:
    print(match.start(), match.end(), match.group())
通过搜索"w",我们找到了相关代码。在第2527行,我们发现了w的值r在第2525行被定义。

三. 分析w参数加密算法
接下来,我们需要简化代码中w的定义。假设我们已经提取了相关的JavaScript代码,我们可以用Python来模拟这个过程。

python

import json
import hashlib
import random

def js_stringify(data):
    return json.dumps(data)

def js_default(data, key):
    return hashlib.md5((data + key).encode()).hexdigest()

# 模拟JavaScript的逗号操作符行为
r = js_default(js_stringify(e), a)
首先,js_stringify(e)相当于对e进行JSON序列化操作。然后,我们分析js_default(js_stringify(e), a)的含义。

python

def a(e, t):
    s = t.get("options", {})
    if not s.get("pt") or s["pt"] == "0":
        return urlsafe_encode(e)

    if s["pt"] == "1":
        n = generate_guid()
        a = encrypt(n)

        while not a or len(a) != 256:
            n = generate_guid()
            a = encrypt(n)

        o = encrypt(e, n)
        return array_to_hex(o) + a
我们可以简化上述Python代码如下:

python

def a(e, t):
    n = generate_guid()
    a = encrypt(n)
    o = encrypt(e, n)
    return array_to_hex(o) + a
从这里可以确定参数t未被使用,参数e就是w的明文。接着我们分析e的组成部分:

python

e = {
    'device_id': 'A8A0',  # 固定值
    'em': { 
        'cp': 0,
        'ek': '11',
        'nt': 0,
        'ph': 0,
        'sc': 0,
        'si': 0,
        'wd': 1,
    },  # 固定值
    'ep': '123',  # 固定值
    'geetest': 'captcha',  # 固定值
    'fq6a': '1925502591',  # 固定值
    'lang': 'zh',  # 固定值
    'lot_number': '7e22264d4f3e4dd8a6ffbf6e82e1122d',  # load请求返回值
    'passtime': 166,  # 通过时间
    'pow_msg': '1|0|md5|2022-03-25T14:23:36.364152+08:00|24f56dc13c40dc4a02fd0318567caef5|7e22264d4f3e4dd8a6ffbf6e82e1122d||29f07cebf938aa4e',  # load请求返回加上某算法返回值
    'pow_sign': '2b47a3a9425dd19dd5abf902c8bb0763',  # pow_msg的md5值
    'setLeft': 88,  # 滑动距离
    'track': [[38, 18, 0], [1, 0, 33]......],  # 轨迹
    'userresponse': 87.47978686742837  # 某算法返回值
}
4.1 分析pow_msg和pow_sign
通过搜索pow_msg,我们找到相关代码并解析如下:

python

def generate_guid():
    return ''.join([format(random.randint(0, 65535), 'x') for _ in range(4)])

u = f"{n}|{a}|{s}|{o}|{t}|{e}|{r}|"
p = generate_guid()
g = u + p
pow_msg = u + p
pow_sign = hashlib.md5(g.encode()).hexdigest()
4.2 分析set_left、track、passtime、userresponse
set_left:滑块移动距离的整数值
track:移动轨迹,从第二步开始,是相对上一步的相对移动距离(x, y, t)
passtime:总移动时间
userresponse:计算公式为set_left / (0.8876 * 340 / 300)
python

set_left = 88
track = [[38, 18, 0], [1, 0, 33]......]
passtime = 166
userresponse = set_left / (0.8876 * 340 / 300)
至此,我们已经完成了w参数的明文解析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值