# modules/sentinel_solver.py """Sentinel 挑战求解器""" import json import uuid from typing import Dict, Optional from core.sentinel.js_executor import JSExecutor from utils.fingerprint import BrowserFingerprint from config import load_config class SentinelSolver: """协调指纹生成和 JS 执行,生成完整的 Sentinel tokens""" def __init__(self, fingerprint: BrowserFingerprint): self.fingerprint = fingerprint self.js_executor = JSExecutor() # 加载配置 config = load_config() self.debug = config.sentinel_debug def generate_requirements_token(self) -> Dict[str, str]: """ 生成 requirements token(初始化时需要) Returns: {'p': 'gAAAAAC...', 'id': 'uuid'} """ if self.debug: print("[Solver] Generating requirements token...") # 生成随机 seed req_seed = str(uuid.uuid4()) # 获取指纹配置 config_array = self.fingerprint.get_config_array() # 调用 JS 求解 answer = self.js_executor.generate_requirements(req_seed, config_array) token = { 'p': f'gAAAAAC{answer}', 'id': self.fingerprint.session_id, } if self.debug: print(f"[Solver] Requirements token: {token['p'][:30]}...") return token def solve_enforcement(self, enforcement_config: Dict) -> str: """ 解决完整的 enforcement 挑战(PoW + Turnstile) Args: enforcement_config: 服务器返回的挑战配置 { 'proofofwork': { 'seed': '...', 'difficulty': '0003a', 'token': '...', # cached token 'turnstile': { 'dx': '...' # VM bytecode } } } Returns: 完整的 Sentinel token (JSON string) """ if self.debug: print("[Solver] Solving enforcement challenge...") pow_data = enforcement_config.get('proofofwork', {}) # 1. 解决 PoW seed = pow_data['seed'] difficulty = pow_data['difficulty'] config_array = self.fingerprint.get_config_array() pow_answer = self.js_executor.solve_pow(seed, difficulty, config_array) # 2. 执行 Turnstile(如果有) turnstile_result = None turnstile_data = pow_data.get('turnstile') if turnstile_data and turnstile_data.get('dx'): dx_bytecode = turnstile_data['dx'] xor_key = self.fingerprint.session_id # 通常用 session ID 作为密钥 turnstile_result = self.js_executor.execute_turnstile(dx_bytecode, xor_key) # 3. 构建最终 token sentinel_token = { # enforcement token 前缀为 gAAAAAB(requirements 为 gAAAAAC) 'p': f'gAAAAAB{pow_answer}', 'id': self.fingerprint.session_id, 'flow': 'username_password_create', } # 添加可选字段 if turnstile_result: sentinel_token['t'] = turnstile_result if pow_data.get('token'): sentinel_token['c'] = pow_data['token'] token_json = json.dumps(sentinel_token) if self.debug: print(f"[Solver] Sentinel token generated: {token_json[:80]}...") return token_json