/** * ============================================================================ * HCaptcha Bypass Module (Modularized Version) * ============================================================================ * 功能: * 1. 攔截 hCaptcha 的網絡請求 (Fetch & XHR) * 2. 向 hCaptcha HTML 注入自動點擊腳本 * 3. 模擬用戶行為繞過檢測 * 4. 支援配置熱更新 * * 使用方式: * const bypass = new HCaptchaBypassModule(config); * bypass.init(); * ============================================================================ */ class HCaptchaBypassModule { constructor(config = {}) { // 默認配置 this.config = { enabled: true, // 是否啟用繞過 autoClick: true, // 是否自動點擊 clickDelay: 400, // 點擊檢測間隔 (ms) maxAttempts: 200, // 最大嘗試次數 debug: false, // 調試模式 settingsKey: '__HCAPTCHA_BYPASS_SETTINGS__', // 全局配置鍵名 ...config }; // 運行時狀態 this.isInterceptorLoaded = false; this.isInjectorActive = false; this.activeIntervals = []; // 綁定方法上下文 this.checkSettings = this.checkSettings.bind(this); } /** * 初始化模塊 */ init() { this.log('Initializing HCaptcha Bypass Module...'); // 1. 將配置暴露到全局 (供 iframe 內部讀取) this.exposeSettings(); // 2. 啟動攔截器 (劫持網絡請求) this.setupInterceptors(); // 3. 啟動配置熱更新 this.startSettingsWatcher(); // 4. 監聽跨域消息 this.setupMessageListener(); this.log('Module initialized successfully'); } /** * 銷毀模塊 */ destroy() { this.activeIntervals.forEach(id => clearInterval(id)); this.activeIntervals = []; this.log('Module destroyed'); } /** * 暴露配置到全局 */ exposeSettings() { window[this.config.settingsKey] = { autoCaptcha: this.config.autoClick, enabled: this.config.enabled, captchaService: 'hCaptcha' }; // 同時嘗試暴露到父窗口 try { if (window.parent && window.parent !== window) { window.parent[this.config.settingsKey] = window[this.config.settingsKey]; } } catch (e) { // 跨域錯誤忽略 } } /** * 配置熱更新監聽 */ startSettingsWatcher() { const intervalId = setInterval(this.checkSettings, 1000); this.activeIntervals.push(intervalId); } checkSettings() { try { const settings = window[this.config.settingsKey]; if (settings) { this.config.enabled = settings.enabled ?? this.config.enabled; this.config.autoClick = settings.autoCaptcha ?? this.config.autoClick; } } catch (e) { // Ignore } } /** * 跨域消息監聽 */ setupMessageListener() { window.addEventListener('message', (event) => { if (event.data?.type === 'HCAPTCHA_BYPASS_UPDATE_SETTINGS') { Object.assign(this.config, event.data.settings); this.exposeSettings(); this.log('Settings updated via postMessage:', event.data.settings); } if (event.data?.msg === 'hCaptcha Injector Loaded') { this.log('Injector script successfully loaded in iframe'); } }); } /** * ======================================================================== * 攔截器部分:劫持網絡請求並注入腳本 * ======================================================================== */ setupInterceptors() { if (this.isInterceptorLoaded) { this.log('Interceptor already loaded, skipping...'); return; } this.isInterceptorLoaded = true; // 目標 URL 匹配 this.targetUrlPattern = /newassets\.hcaptcha\.com\/captcha\/v1\/[^/]+\/static\/hcaptcha\.html/; // 需要替換的代碼模式 this.replacementPatterns = [ /this\.\$radio\.setAttribute\("aria-checked",\s*!1\)/g, /this\.\$radio\.setAttribute\("aria-checked",\s*false\)/g, /this\.\$radio\.setAttribute\("aria-checked",\s*0\)/g, /setAttribute\("aria-checked",!1\)/g ]; // 注入的 Payload (自動點擊腳本) this.injectedPayload = this.generateInjectorScript(); // Hook Fetch & XHR this.hookFetch(); this.hookXHR(); this.log('Network interceptors installed'); } /** * 生成注入腳本 */ generateInjectorScript() { const config = this.config; // 這裡用模板字符串生成完整的注入代碼 // 將之前的 injector 邏輯封裝成字符串 return ` (function() { 'use strict'; // ===== 配置讀取 ===== let isAutoClickEnabled = false; let settingsKey = '${config.settingsKey}'; function initSettings() { try { if (window.parent && window.parent[settingsKey]) { isAutoClickEnabled = window.parent[settingsKey].autoCaptcha || false; } else if (window.top && window.top[settingsKey]) { isAutoClickEnabled = window.top[settingsKey].autoCaptcha || false; } window.addEventListener('message', (event) => { if (event.data?.type === 'HCAPTCHA_BYPASS_UPDATE_SETTINGS') { isAutoClickEnabled = event.data.settings?.autoClick || false; } }); } catch (err) { isAutoClickEnabled = true; // 跨域限制時默認啟用 } } initSettings(); // ===== 核心點擊邏輯 ===== const CHECKBOX_SELECTOR = '#checkbox'; let attemptCount = 0; let isSolved = false; let clickInterval = null; function attemptClick() { if (attemptCount >= ${config.maxAttempts} || isSolved) { if (clickInterval) clearInterval(clickInterval); return; } const checkbox = document.querySelector(CHECKBOX_SELECTOR); if (!checkbox) { attemptCount++; return; } const isChecked = checkbox.getAttribute('aria-checked'); const isVisible = checkbox.offsetParent !== null; if (isVisible && isChecked === 'false' && isAutoClickEnabled) { try { checkbox.click(); console.log('[HCaptcha Bypass] Checkbox clicked'); setTimeout(() => { const newState = checkbox.getAttribute('aria-checked'); if (newState === 'true') { isSolved = true; if (clickInterval) clearInterval(clickInterval); // 通知父窗口 window.parent.postMessage({ type: 'HCAPTCHA_BYPASS_SOLVED', msg: 'hCaptcha solved successfully' }, '*'); } }, 1000); } catch (e) { console.error('[HCaptcha Bypass] Click failed:', e); } } attemptCount++; } // 啟動點擊循環 clickInterval = setInterval(attemptClick, ${config.clickDelay}); // 冗餘觸發 setTimeout(attemptClick, 500); setTimeout(attemptClick, 1500); setTimeout(attemptClick, 3000); // 通知父窗口注入成功 setTimeout(() => { window.parent.postMessage({ type: 'HCAPTCHA_BYPASS_INJECTOR_LOADED', msg: 'hCaptcha Injector Loaded' }, '*'); }, 2000); })(); `; } /** * Hook Fetch API */ hookFetch() { const originalFetch = window.fetch; const self = this; window.fetch = function(...args) { const url = typeof args[0] === 'string' ? args[0] : args[0]?.url; // 檢查是否為目標 URL const isTarget = url && self.targetUrlPattern.test(url); if (!isTarget || !self.config.enabled) { return originalFetch.apply(this, args); } self.log('Fetch intercepted:', url); // 攔截並修改響應 return originalFetch.apply(this, args).then(response => { return response.text().then(html => { const modifiedHtml = self.injectScript(html); return new Response(modifiedHtml, { status: response.status, statusText: response.statusText, headers: response.headers }); }); }); }; } /** * Hook XMLHttpRequest */ hookXHR() { const originalOpen = XMLHttpRequest.prototype.open; const originalSend = XMLHttpRequest.prototype.send; const self = this; XMLHttpRequest.prototype.open = function(method, url, ...rest) { this._interceptedUrl = url; return originalOpen.apply(this, [method, url, ...rest]); }; XMLHttpRequest.prototype.send = function(...args) { const url = this._interceptedUrl; const isTarget = url && self.targetUrlPattern.test(url); if (!isTarget || !self.config.enabled) { return originalSend.apply(this, args); } self.log('XHR intercepted:', url); const originalOnReadyStateChange = this.onreadystatechange; this.onreadystatechange = function() { if (this.readyState === 4 && this.status === 200) { let html = this.responseText; if (html) { html = self.injectScript(html); Object.defineProperty(this, 'responseText', { get: () => html, configurable: true }); Object.defineProperty(this, 'response', { get: () => html, configurable: true }); } } if (originalOnReadyStateChange) { originalOnReadyStateChange.apply(this, arguments); } }; return originalSend.apply(this, args); }; } /** * 注入腳本到 HTML */ injectScript(html) { let modified = html; // 1. 替換檢測邏輯 (將 false 改為 true) this.replacementPatterns.forEach(pattern => { modified = modified.replace(pattern, match => { return match.replace(/!1|false|0/g, '!0'); // !0 === true }); }); // 2. 注入自動點擊腳本 const scriptTag = ``; if (modified.includes('')) { modified = modified.replace('', scriptTag + ''); } else if (modified.includes('')) { modified = modified.replace('', scriptTag + ''); } else { modified += scriptTag; } this.log('Script injected into hCaptcha HTML'); return modified; } /** * 日誌輸出 */ log(...args) { if (this.config.debug) { console.log('[HCaptcha Bypass Module]', ...args); } } /** * 更新配置 */ updateConfig(newConfig) { Object.assign(this.config, newConfig); this.exposeSettings(); this.log('Config updated:', this.config); } /** * 手動觸發點擊 (從外部調用) */ triggerClick() { const iframes = document.querySelectorAll('iframe[src*="hcaptcha.com"]'); iframes.forEach(iframe => { try { iframe.contentWindow.postMessage({ type: 'HCAPTCHA_BYPASS_TRIGGER_CLICK' }, '*'); } catch (e) { this.log('Cannot access iframe:', e); } }); } } /** * ============================================================================ * 全局 API 暴露 * ============================================================================ */ window.HCaptchaBypassModule = HCaptchaBypassModule; // 自動初始化選項 if (typeof HCAPTCHA_BYPASS_AUTO_INIT !== 'undefined' && HCAPTCHA_BYPASS_AUTO_INIT) { const instance = new HCaptchaBypassModule({ enabled: true, autoClick: true, debug: true }); instance.init(); window.__hcaptchaBypass = instance; }