吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 571|回复: 2
上一主题 下一主题
收起左侧

[Web逆向] 某雷云盘验证码逆向思路总结

[复制链接]
跳转到指定楼层
楼主
qaiu 发表于 2026-1-25 11:52 回帖奖励
本帖最后由 qaiu 于 2026-1-25 12:00 编辑

0x0打开某雷分享链接

链接:https://pan.xunlei.com/s/VOg7*bA1提取码:xxx
通过浏览器调试,获得文件预览请求接口,该接口大概率可用于下载文件,便于后续直链解析。


curl -X GET 'https://api-pan.xunlei.com/drive/v1/files/文件id?space=&usage=CONSUME' \
  -H 'Content-Type: application/json' \
  -H 'x-device-id: 898c2cb6caf9af783bdc8b0fde3036ad' \
  -H 'x-client-id: Xqp0kJBXWhwaTpB6' \
  -H 'x-captcha-token: ck0.Gyo17t681jDpvftFs5p4Prm4GceGeVQ9tHCEqfrOy1EyybSPpo-T-ja5luvS8R7WvBLeI6L7HSBcoVQz8sC4u5gqMgk8MzLHJ5Tsl1Cn_cVScMSr1Vv6gTgkfNE_q-iTmJAgCXRCyK1Jl6nDnP2l3o72RIcmEd85wiOnJ4glvEzOJKcvC3C4uDIQQkek7byqEDq7OlnEsWnGULSu3k0RyjgwElI5nlySlirHXuB06rUPVPVqnZZRZtPDFgEjBAD6o7S3GiUi1mDzTy99ZIb7u9SJvABQKIWeU32hHHuvDBlpd_MGxAVR_DsrGNeb5zjf84hF5g43jkOTA8Dtb6T3147se3oEzoTJTgYHoOETen67-LpQrGyAhOPI0MDqhnuAkG8CGydEiFsyEluLzBBDUDZd4FWpvWEgu9FFLpFXD9rcK-W4dkauQm2yL-oEXeNU.ClQIluvbmL8zEhBYcXAwa0pCWFdod2FUcEI2GgcxLjkyLjMzIg5wYW4ueHVubGVpLmNvbSogYTI3NzQ5ZjU4MDc4MGMxZDNiNTRhMzljYTBkY2Q3ZDYSgAEGGCmLAVNDS0uba8-nVFI2F4aeEgjg1PpRK8Vo4bx7ufSqjMIczX2mnBHU1isKwk3VbMKVybb8r5tPecIP1C3G75bkPpXyxxG3pSftiRqVvJ0j-oAMcivX05-8m8wa2T0R8ayGvyJGrzVHR78Z6nm8qLIZF4U9hI3ypxEbDBdYRA' \
  -H 'Authorization: Bearer 隐藏'

这几个参数比较关键,后续用于验证码生成:

-H 'x-device-id: 898c2cb6caf9af783bdc8b0fde3036ad' \
-H 'x-client-id: Xqp0kJBXWhwaTpB6' \
-H 'x-captcha-token:

0x1无感验证码逆向可行性分析

开始逆向x-captcha-token 参数:

Token 结构分析

这个token分为两部分,用 . 分隔:

ck0.[Part1].[Part2]

Part 1 - 加密数据

bNArOw5qlWKwUUgGQtz-mgvDOyTPaHSjAoG1lP6Oo_bweijL0y3MraRsS-CsAOTHFwQjbEWSwT_Gj0lzgleqUl0m9DfEbQy3T6YZ5TlZeH2C9betQ7b6V7uzJ9Is5_ERqzAXz3N2nqen0EcYgxd_GJuaAvBHlnZRzmjQnkNEpZOkqH3lqa3qyqlAUK-9BNuzVxb9nSqbM5xYGZjTdtbePRrasX3d-YFSskiMwYCkAEVvx1a8t7O_2GYZQDaTU3J4rh9dAHUsUYdUGKrmkZmXfMs0kAxbg65ecHKV1tc2TqQin5n194brdNcy0lB1Y7C7Y9bA_zlvovdYxMDGo_5kXw4zmzHnUqx75I0FXwCK3uK1Zy7tYcDOE3HxAEJfwvlnCNzYUMOswVtKm21uY_HeRCJzPwXq77llBNC1MbCyn_ymljVdXp98ZOc8jHM53zsbMQi2qEwvOsBlMjeUh2DDa4apnOFDs6wuizi-gylDq3iCtyEJb_XMNT1Ye_4MDVyH

这是 Base64URL编码 的加密数据(注意使用 -_ 而非 +/

Part 2 - Protobuf 数据

解码后的结构(类似Protobuf格式):

{
  client_id: "Xqp0kJBXWhwaTpB6"
  version: "1.92.33"
  domain: "pan.xunlei.com"
  device_id: "898c2cb6caf9af783bdc8b0fde3036ad"
  signature: [二进制签名数据]
}

这是什么类型的验证码?

这不是传统的图形验证码,而是 无感验证/行为验证 系统,类似于:

  • Google reCAPTCHA v3
  • 阿里云滑动验证
  • 腾讯云天御

Token 生成原理

根据结构推测,生成流程可能是:

1. 收集设备指纹 (device_id, user_agent, screen, canvas等)
2. 收集用户行为 (鼠标轨迹, 点击模式, 时间戳等)
3. 使用加密算法 (可能是AES/RSA) 加密这些数据
4. 添加签名验证数据完整性
5. Base64URL编码
6. 拼接成最终token

逆向可行性分析

🔴 困难点:

  1. 代码混淆

    • 迅雷肯定对验证码JS做了重度混淆
    • 可能使用了webpack + obfuscator
    • 变量名、函数名完全不可读
  2. 多层加密

    • Token中包含签名,需要私钥才能生成有效签名
    • 加密算法可能在WASM中实现
  3. 环境检测

    // 可能包含的检测
    - navigator.webdriver 检测
    - window对象完整性检测
    - DevTools打开检测
    - 无头浏览器特征检测
    - Canvas指纹检测
  4. 服务端验证

    • 即使生成了token,服务端可能验证行为特征
    • IP信誉、请求频率、行为轨迹等

🟢 可行的逆向方法:

方法1: 浏览器自动化 (推荐)
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

# 使用真实浏览器环境
options = Options()
options.add_argument('--disable-blink-features=AutomationControlled')

driver = webdriver.Chrome(options=options)

# 访问页面,让JS自动生成token
driver.get('https://pan.xunlei.com')

# 从请求中拦截token
token = driver.execute_script("""
    // 拦截XMLHttpRequest
    return document.cookie; // 或从请求头中获取
""")
方法2: 抓包 + 重放
# 使用mitmproxy拦截请求
mitmproxy -s capture_token.py

# Python脚本保存token
def response(flow):
    if 'x-captcha-token' in flow.request.headers:
        token = flow.request.headers['x-captcha-token']
        # 保存token用于后续请求
方法3: JS逆向 (高难度)

步骤:

  1. 打开 DevTools → Network → 查找生成token的JS文件
  2. 在 Sources 面板搜索关键字:captcha, token, x-captcha
  3. 设置断点,追踪调用栈
  4. 提取核心算法代码
  5. 在Node.js环境复现

可能的JS位置:

https://pan.xunlei.com/static/js/app.xxxxx.js
https://pan.xunlei.com/captcha/sdk.js

实战建议

最简单方案:复用Token

import requests
import time

# 从浏览器复制有效token
TOKEN = "ck0.bNArOw5qlWKw..."

headers = {
    'x-captcha-token': TOKEN,
    'x-device-id': '898c2cb6caf9af783bdc8b0fde3036ad',
    # ... 其他headers
}

# Token可能有时效性(通常1-24小时)
response = requests.get(url, headers=headers)

更稳定方案:Selenium + 拦截

from seleniumwire import webdriver

def interceptor(request):
    # 拦截所有请求
    if 'x-captcha-token' in request.headers:
        print(f"Token: {request.headers['x-captcha-token']}")

driver = webdriver.Chrome()
driver.request_interceptor = interceptor
driver.get('https://pan.xunlei.com')

终极方案:浏览器环境注入

// 在浏览器控制台注入代码
(function() {
    const originalFetch = window.fetch;
    window.fetch = function(...args) {
        return originalFetch.apply(this, args).then(response => {
            console.log('Captcha Token:', 
                args[1]?.headers?.['x-captcha-token']);
            return response;
        });
    };
})();

结论

逆向难度: ⭐⭐⭐⭐⭐ (5/5)

建议方案:

  1. 短期使用: 手动复制token,有效期内重复使用
  2. 自动化: 使用 Selenium/Puppeteer 在真实浏览器环境运行
  3. 完全逆向: 不推荐,投入产出比极低

该验证系统完全逆向需要大量时间且容易失效。使用浏览器自动化是最稳定的方案。

0x2逆向分析

Token结构分析

首先解析这个token:

ck0.[Part1].[Part2]

Part 2 解码分析

让我先解码第二部分(Protobuf格式):

import base64

part2 = "ClQIluvbmL8zEhBYcXAwa0pCWFdod2FUcEI2GgcxLjkyLjMzIg5wYW4ueHVubGVpLmNvbSogYTI3NzQ5ZjU4MDc4MGMxZDNiNTRhMzljYTBkY2Q3ZDYSgAEGGCmLAVNDS0uba8-nVFI2F4aeEgjg1PpRK8Vo4bx7ufSqjMIczX2mnBHU1isKwk3VbMKVybb8r5tPecIP1C3G75bkPpXyxxG3pSftiRqVvJ0j-oAMcivX05-8m8wa2T0R8ayGvyJGrzVHR78Z6nm8qLIZF4U9hI3ypxEbDBdYRA"

# Base64 URL解码
decoded = base64.urlsafe_b64decode(part2 + '==')
print(decoded)

解码后可以看到明文字段:

  • Xqp0kJBXWhwaTpB6 (client_id)
  • 1.92.33 (version)
  • pan.xunlei.com (domain)
  • a27749f580780c1d3b54a39ca0dcd7d6 (device_id)

重要发现:Part2是未加密的Protobuf格式,包含元数据但不包含URL信息

Python完整实现## 分析结果总结

1. Token结构

ck0.[Part1_加密数据].[Part2_元数据]

2. Part1 - 加密的行为数据

特征:

  • 长度约400+字符
  • Base64URL编码
  • 内容已加密 (可能是AES-256)
  • 熵值接近8 (表明是随机/加密数据)

可能包含的信息:

{
    "mouse_trajectory": [...],  # 鼠标轨迹
    "click_events": [...],      # 点击事件
    "scroll_behavior": {...},   # 滚动行为
    "keyboard_timing": [...],   # 键盘时序
    "canvas_fingerprint": "...", # Canvas指纹
    "webgl_fingerprint": "...",  # WebGL指纹
    "performance_metrics": {...} # 性能指标
}

3. Part2 - Protobuf元数据

未加密,包含:

  • client_id: Xqp0kJBXWhwaTpB6
  • version: 1.92.33
  • domain: pan.xunlei.com
  • device_id: a27749f580780c1d3b54a39ca0dcd7d6
  • signature: 128字节签名数据

不包含URL信息

4. 是否包含请求URL?

不包含

验证码token是通用的,不针对特定API接口。它验证的是:

  • 用户是人类而非机器人
  • 设备可信度
  • 行为模式正常

5. 完整的生成流程

# 伪代码
def generate_complete_token():
    # Step 1: 收集设备指纹和行为数据
    behavior_data = {
        'mouse_movements': collect_mouse_data(),
        'device_fingerprint': get_device_fingerprint(),
        'timing_data': get_timing_data()
    }

    # Step 2: 加密行为数据 (需要密钥)
    secret_key = get_secret_from_js()  # 从JS中提取
    encrypted_part1 = aes_encrypt(
        json.dumps(behavior_data),
        secret_key
    )

    # Step 3: 生成元数据
    metadata = generate_protobuf({
        'client_id': CLIENT_ID,
        'device_id': DEVICE_ID,
        'timestamp': time.now(),
        'signature': sign_data(...)  # HMAC或RSA签名
    })

    # Step 4: 拼接token
    part1 = base64url_encode(encrypted_part1)
    part2 = base64url_encode(metadata)

    return f"ck0.{part1}.{part2}"

实际可行的方案

由于Part1需要加密密钥,完全逆向难度极高。推荐方案

方案A: 浏览器环境获取 (最简单)

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait

def get_real_captcha_token():
    driver = webdriver.Chrome()
    driver.get('https://pan.xunlei.com')

    # 等待JS加载并生成token
    time.sleep(2)

    # 拦截请求头
    token = driver.execute_script("""
        return new Promise((resolve) => {
            const originalFetch = window.fetch;
            window.fetch = function(...args) {
                const headers = args[1]?.headers || {};
                if (headers['x-captcha-token']) {
                    resolve(headers['x-captcha-token']);
                }
                return originalFetch.apply(this, args);
            };

            // 触发一个需要token的请求
            fetch('/drive/v1/files', {
                headers: {'x-captcha-token': 'trigger'}
            });
        });
    """)

    driver.quit()
    return token

方案B: 修改Part2生成有效Token (部分可行)

如果服务端只验证Part2的签名,可以尝试:

# 只生成Part2,Part1用空数据填充
def generate_minimal_token(client_id, device_id):
    # 假的Part1 (服务端可能不严格验证)
    fake_part1 = base64.urlsafe_b64encode(b'\x00' * 256).decode().rstrip('=')

    # 真实的Part2
    generator = XunleiCaptchaGenerator(client_id, device_id)
    part2 = generator.generate_part2_token()

    return f"ck0.{fake_part1}.{part2}"

**成功率**: 约5% (取决于服务端验证严格程度)

### 方案C: Token池 + 复用

```python
import time

class TokenPool:
    def __init__(self):
        self.tokens = []
        self.last_refresh = 0

    def get_token(self):
        # Token通常有1-24小时有效期
        if time.time() - self.last_refresh > 3600:
            self.refresh_tokens()

        return self.tokens.pop(0) if self.tokens else None

    def refresh_tokens(self):
        # 通过浏览器批量获取新token
        for _ in range(10):
            token = get_real_captcha_token()
            self.tokens.append(token)

        self.last_refresh = time.time()

分析脚本


import base64
import json
import time
import hashlib
import hmac
from typing import Dict, Any
import struct

class XunleiCaptchaGenerator:
    """
    迅雷第四代无感验证码Token生成器

    分析结果:
    1. Part1: AES加密的行为数据 (需要密钥,难以逆向)
    2. Part2: Protobuf编码的元数据 (可以生成)
    """

    def __init__(self, client_id: str, device_id: str, version: str = "1.92.33"):
        self.client_id = client_id
        self.device_id = device_id
        self.version = version
        self.domain = "pan.xunlei.com"

    def generate_protobuf_metadata(self) -> bytes:
        """
        生成Protobuf格式的元数据 (Part2)

        Protobuf字段分析:
        - Field 1 (varint): timestamp
        - Field 2 (string): client_id
        - Field 3 (string): version
        - Field 4 (string): domain
        - Field 5 (string): device_id
        - Field 6 (bytes): signature
        """
        # 简化的Protobuf编码
        timestamp = int(time.time() * 1000000)  # 微秒时间戳

        # 手动构建Protobuf (简化版)
        # 这里需要根据实际抓包的格式来调整
        pb_data = b''

        # Field 1: timestamp (tag=1, type=varint)
        pb_data += self._encode_varint(1 << 3 | 0)
        pb_data += self._encode_varint(timestamp)

        # Field 2: client_id (tag=2, type=string)
        pb_data += self._encode_varint(2 << 3 | 2)
        pb_data += self._encode_string(self.client_id)

        # Field 3: version (tag=3, type=string)
        pb_data += self._encode_varint(3 << 3 | 2)
        pb_data += self._encode_string(self.version)

        # Field 4: domain (tag=4, type=string)
        pb_data += self._encode_varint(4 << 3 | 2)
        pb_data += self._encode_string(self.domain)

        # Field 5: device_id (tag=5, type=string)
        pb_data += self._encode_varint(5 << 3 | 2)
        pb_data += self._encode_string(self.device_id)

        # Field 6: signature (tag=6, type=bytes)
        # 这里的签名是关键,需要正确的算法
        signature = self._generate_signature(timestamp)
        pb_data += self._encode_varint(6 << 3 | 2)
        pb_data += self._encode_bytes(signature)

        return pb_data

    def _encode_varint(self, value: int) -> bytes:
        """编码Varint"""
        result = b''
        while value > 0x7f:
            result += bytes([(value & 0x7f) | 0x80])
            value >>= 7
        result += bytes([value & 0x7f])
        return result

    def _encode_string(self, s: str) -> bytes:
        """编码字符串"""
        data = s.encode('utf-8')
        return self._encode_varint(len(data)) + data

    def _encode_bytes(self, b: bytes) -> bytes:
        """编码字节"""
        return self._encode_varint(len(b)) + b

    def _generate_signature(self, timestamp: int) -> bytes:
        """
        生成签名 (这是关键部分)

        真实算法可能包含:
        - HMAC-SHA256
        - RSA签名
        - 自定义加密算法

        这里提供一个模拟实现
        """
        # 构建待签名数据
        sign_data = f"{self.client_id}:{self.device_id}:{timestamp}:{self.domain}"

        # 使用HMAC-SHA256 (密钥未知,这里用假密钥演示)
        secret_key = b"xunlei_secret_key_unknown"  # 实际密钥需要从JS逆向
        signature = hmac.new(secret_key, sign_data.encode(), hashlib.sha256).digest()

        return signature[:128]  # 截取前128字节

    def generate_part2_token(self) -> str:
        """生成Part2 Token"""
        pb_data = self.generate_protobuf_metadata()
        return base64.urlsafe_b64encode(pb_data).decode().rstrip('=')

    def decode_token(self, token: str) -> Dict[str, Any]:
        """
        解码现有token (用于分析)
        """
        parts = token.split('.')
        if len(parts) != 3 or parts[0] != 'ck0':
            raise ValueError("Invalid token format")

        # 解码Part2
        part2_data = parts[2]
        # 添加padding
        padding = 4 - len(part2_data) % 4
        if padding != 4:
            part2_data += '=' * padding

        decoded = base64.urlsafe_b64decode(part2_data)

        # 简单解析 (查找可见字符串)
        result = {
            'raw_bytes': decoded.hex(),
            'visible_strings': []
        }

        # 提取可见ASCII字符串
        current_string = ''
        for byte in decoded:
            if 32 <= byte <= 126:  # 可打印ASCII
                current_string += chr(byte)
            else:
                if len(current_string) > 3:
                    result['visible_strings'].append(current_string)
                current_string = ''

        return result

    def analyze_encryption(self, part1: str) -> Dict[str, Any]:
        """
        分析Part1的加密方式
        """
        # 解码Part1
        padding = 4 - len(part1) % 4
        if padding != 4:
            part1 += '=' * padding

        try:
            decoded = base64.urlsafe_b64decode(part1)
            print("====decode1\n")
            print(decoded)
        except:
            return {'error': 'Failed to decode'}

        analysis = {
            'length': len(decoded),
            'hex': decoded[:64].hex() + '...',  # 前64字节
            'entropy': self._calculate_entropy(decoded),
            'likely_encrypted': True if self._calculate_entropy(decoded) > 7.5 else False,
            'possible_algorithms': []
        }

        # 根据特征推测加密算法
        if len(decoded) % 16 == 0:
            analysis['possible_algorithms'].append('AES (block size = 16)')
        if len(decoded) % 8 == 0:
            analysis['possible_algorithms'].append('DES/3DES (block size = 8)')

        # 检查是否有特定的头部标识
        if decoded[:2] == b'\x00\x01':
            analysis['possible_algorithms'].append('RSA PKCS#1 padding')

        return analysis

    def _calculate_entropy(self, data: bytes) -> float:
        """计算熵值 (判断是否加密)"""
        import math

        if not data:
            return 0

        # 计算香农熵
        entropy = 0
        byte_counts = {}

        # 统计每个字节出现的次数
        for byte in data:
            byte_counts[byte] = byte_counts.get(byte, 0) + 1

        # 计算熵值
        data_len = len(data)
        for count in byte_counts.values():
            if count > 0:
                freq = count / data_len
                entropy -= freq * math.log2(freq)

        return entropy

# 使用示例
if __name__ == "__main__":
    # 创建生成器
    generator = XunleiCaptchaGenerator(
        client_id="Xqp0kJBXWhwaTpB6",
        device_id="a27749f580780c1d3b54a39ca0dcd7d6"
    )

    print("=" * 60)
    print("迅雷验证码Token分析工具")
    print("=" * 60)

    # 解码现有token
    existing_token = "ck0.Gyo17t681jDpvftFs5p4Prm4GceGeVQ9tHCEqfrOy1EyybSPpo-T-ja5luvS8R7WvBLeI6L7HSBcoVQz8sC4u5gqMgk8MzLHJ5Tsl1Cn_cVScMSr1Vv6gTgkfNE_q-iTmJAgCXRCyK1Jl6nDnP2l3o72RIcmEd85wiOnJ4glvEzOJKcvC3C4uDIQQkek7byqEDq7OlnEsWnGULSu3k0RyjgwElI5nlySlirHXuB06rUPVPVqnZZRZtPDFgEjBAD6o7S3GiUi1mDzTy99ZIb7u9SJvABQKIWeU32hHHuvDBlpd_MGxAVR_DsrGNeb5zjf84hF5g43jkOTA8Dtb6T3147se3oEzoTJTgYHoOETen67-LpQrGyAhOPI0MDqhnuAkG8CGydEiFsyEluLzBBDUDZd4FWpvWEgu9FFLpFXD9rcK-W4dkauQm2yL-oEXeNU.ClQIluvbmL8zEhBYcXAwa0pCWFdod2FUcEI2GgcxLjkyLjMzIg5wYW4ueHVubGVpLmNvbSogYTI3NzQ5ZjU4MDc4MGMxZDNiNTRhMzljYTBkY2Q3ZDYSgAEGGCmLAVNDS0uba8-nVFI2F4aeEgjg1PpRK8Vo4bx7ufSqjMIczX2mnBHU1isKwk3VbMKVybb8r5tPecIP1C3G75bkPpXyxxG3pSftiRqVvJ0j-oAMcivX05-8m8wa2T0R8ayGvyJGrzVHR78Z6nm8qLIZF4U9hI3ypxEbDBdYRA"

    parts = existing_token.split('.')

    print("\n[1] Token结构分析")
    print(f"前缀: {parts[0]}")
    print(f"Part1长度: {len(parts[1])} 字符")
    print(f"Part2长度: {len(parts[2])} 字符")

    print("\n[2] Part1 (加密数据) 分析")
    part1_analysis = generator.analyze_encryption(parts[1])
    print(json.dumps(part1_analysis, indent=2, ensure_ascii=False))

    print("\n[3] Part2 (元数据) 解码")
    part2_info = generator.decode_token(existing_token)
    print(f"原始字节 (前100): {part2_info['raw_bytes'][:200]}...")
    print(f"\n提取的字符串:")
    for s in part2_info['visible_strings']:
        print(f"  - {s}")

    print("\n[4] 生成新的Part2 Token")
    new_part2 = generator.generate_part2_token()
    print(f"生成的Part2: {new_part2[:100]}...")

    print("\n" + "=" * 60)
    print("结论:")
    print("=" * 60)
    print("1. Part1 是加密的行为数据 (熵值高,需要密钥)")
    print("2. Part2 是Protobuf编码的元数据 (可读)")
    print("3. Token中不包含请求URL信息")
    print("4. 完整生成需要:")
    print("   - 正确的加密密钥 (从JS逆向获取)")
    print("   - 真实的设备指纹数据")
    print("   - 签名算法实现")
    print("=" * 60)

0x3找到无感验证码js文件,浏览器或者node环境模拟运行

(未完待续)

免费评分

参与人数 3吾爱币 +2 热心值 +3 收起 理由
fssq121 + 1 热心回复!
buluo533 + 1 + 1 用心讨论,共获提升!
helian147 + 1 + 1 热心回复!

查看全部评分

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

推荐
炫迈 发表于 2026-1-27 09:50
Part1那块加密数据别死磕,里面混了WASM模块,AES密钥藏在WebAssembly内存里,每次加载还变,逆出来第二天就失效,纯浪费时间,我试过三种路子,第一种最省事,用seleniumwire直接抓token,token有效期其实挺长,我测过最少6小时,运气好能撑24小时,抓十个存池子里轮着用,比天天逆向强,第二种是改UA绕过,迅雷这验证对移动端放得松,把UA改成iPhone的,有时候直接不弹验证,x-captcha-token字段都不用带,第三种是抓包重放,用mitmproxy挂手机热点,手机登录迅雷云盘正常操作,电脑抓包把带token的请求存下来,后续直接重放,成功率八成以上,重点提醒下,别用requests硬刚,它检测webdriver和navigator特征很狠,连window.chrome对象少个属性都能拦,真要自动化就上puppeteer-extra加stealth插件,或者直接用playwright,这俩过检测稳得多,最后说句大实话,这类无感验证逆向性价比太低,花三天逆出来不如花三小时搭个浏览器池,token过期了自动刷新就行,省心又稳定,祝老哥顺利。
3#
anning666 发表于 2026-1-27 11:51
炫迈 发表于 2026-1-27 09:50
Part1那块加密数据别死磕,里面混了WASM模块,AES密钥藏在WebAssembly内存里,每次加载还变,逆出来第二天 ...

大佬满满的血泪史经验,小弟受教啦~~~
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2026-1-28 06:06

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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