| |
| """ |
| WORM-AI💀🔥 SESSION EXTRACTOR - يستخرج جلسة كلاود فلير بعد التخطي |
| ويحفظها في ملف JSON لاستخدامها لاحقاً. |
| يدعم وسيط --url لتحديد الهدف. |
| """ |
| import os |
| import sys |
| import io |
| sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') |
| import asyncio |
| import json |
| import random |
| import shutil |
| import cv2 |
| import numpy as np |
| import argparse |
| from pathlib import Path |
| from playwright.async_api import async_playwright |
|
|
| |
| |
| |
| base_path = os.path.dirname(os.path.abspath(__file__)) |
| CUSTOM_CHROMIUM_PATH = os.path.join(base_path, "Chromium", "chrome.exe") |
| OUTPUT_SESSION_FILE = os.path.join(base_path, "session_data.json") |
|
|
| |
| |
| |
| async def visual_click(page, template_filename="box.png"): |
| print("[👁️] جاري بدء نظام الرؤية البصرية لحل الكلاود فلير...") |
| await page.bring_to_front() |
| |
| template_path = os.path.join(base_path, template_filename) |
| if not os.path.exists(template_path): |
| print(f"[❌] خطأ: لا توجد صورة باسم {template_filename} بجوار السكربت!") |
| return False |
| |
| template = cv2.imread(template_path, cv2.IMREAD_GRAYSCALE) |
| tH, tW = template.shape[:2] |
| |
| for attempt in range(1, 7): |
| print(f"[📸] التقاط وتحليل الشاشة (المحاولة {attempt}/6)...") |
| await page.wait_for_timeout(2000) |
| |
| screenshot_bytes = await page.screenshot() |
| nparr = np.frombuffer(screenshot_bytes, np.uint8) |
| img = cv2.imdecode(nparr, cv2.IMREAD_COLOR) |
| gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) |
| |
| best_match = None |
| |
| for scale in np.linspace(0.5, 2.5, 25): |
| width = int(tW * scale) |
| height = int(tH * scale) |
| if width <= 10 or height <= 10: |
| continue |
| |
| resized_template = cv2.resize(template, (width, height)) |
| |
| if resized_template.shape[0] > gray_img.shape[0] or resized_template.shape[1] > gray_img.shape[1]: |
| continue |
| |
| res = cv2.matchTemplate(gray_img, resized_template, cv2.TM_CCOEFF_NORMED) |
| _, max_val, _, max_loc = cv2.minMaxLoc(res) |
| |
| if best_match is None or max_val > best_match[0]: |
| best_match = (max_val, max_loc, scale, width, height) |
| |
| if best_match and best_match[0] >= 0.70: |
| max_val, max_loc, best_scale, w, h = best_match |
| print(f"[🎯] وجدته! نسبة التطابق: {max_val*100:.1f}% | تعديل الحجم: {best_scale:.2f}x") |
| |
| click_x = int(max_loc[0] + (w / 2)) |
| click_y = int(max_loc[1] + (h / 2)) |
| |
| await page.mouse.move(click_x, click_y, steps=10) |
| await page.wait_for_timeout(300) |
| await page.mouse.down() |
| await page.wait_for_timeout(random.randint(80, 150)) |
| await page.mouse.up() |
| |
| print("[✅] تم النقر البصري بنجاح وتخطي الحماية!") |
| return True |
| |
| print("[⚠️] فشل في العثور على المربع. سيستمر السكربت في المحاولة.") |
| return False |
|
|
| |
| |
| |
| async def extract_full_session(page, context): |
| """ترجع قاموساً يحتوي على الكوكيز، localStorage، sessionStorage، وعنوان URL الحالي، بالإضافة إلى بيانات المتصفح.""" |
| cookies = await context.cookies() |
| localStorage = await page.evaluate("() => JSON.stringify(window.localStorage)") |
| localStorage_dict = json.loads(localStorage) if localStorage != "{}" else {} |
| sessionStorage = await page.evaluate("() => JSON.stringify(window.sessionStorage)") |
| sessionStorage_dict = json.loads(sessionStorage) if sessionStorage != "{}" else {} |
| current_url = page.url |
| |
| |
| user_agent = await page.evaluate("() => navigator.userAgent") |
| accept_language = await page.evaluate("() => navigator.language") |
| |
| sec_ch_ua = await page.evaluate("() => navigator.userAgentData ? navigator.userAgentData.brands.map(b => `${b.brand};v=${b.version}`).join(', ') : ''") |
| |
| return { |
| "cookies": cookies, |
| "localStorage": localStorage_dict, |
| "sessionStorage": sessionStorage_dict, |
| "url": current_url, |
| "user_agent": user_agent, |
| "accept_language": accept_language, |
| "sec_ch_ua": sec_ch_ua, |
| } |
| |
| |
| |
| async def main(target_url): |
| |
| profile_folders = [f for f in os.listdir(base_path) if f.isdigit() and os.path.isdir(os.path.join(base_path, f))] |
| if profile_folders: |
| chosen_folder = random.choice(profile_folders) |
| user_data_dir = Path(os.path.join(base_path, chosen_folder)) |
| print(f"[📂] تم اختيار البروفايل رقم: {chosen_folder}") |
| else: |
| user_data_dir = Path(os.path.join(base_path, "browser_profile_winprom")) |
| print("[⚠️] لم يتم العثور على مجلدات، سيتم استخدام المسار الافتراضي.") |
|
|
| user_data_dir.mkdir(exist_ok=True) |
|
|
| async with async_playwright() as p: |
| real_tz = "UTC" |
| real_locale = "en-US" |
| fingerprint_seed = random.randint(100000, 999999) |
| |
| ANDROID_UA_LIST = [ |
| "Mozilla/5.0 (Linux; Android 15; Pixel 9 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Mobile Safari/537.36", |
| "Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Mobile Safari/537.36" |
| ] |
| MOBILE_SCREENS = [(360, 780), (375, 812), (390, 844), (412, 915), (414, 896)] |
| mobile_ua = random.choice(ANDROID_UA_LIST) |
| mob_w, mob_h = random.choice(MOBILE_SCREENS) |
|
|
| browser_args = [ |
| f"--fingerprint={fingerprint_seed}", |
| "--fingerprint-platform=linux", |
| "--fingerprint-brand=Chrome", |
| "--fingerprint-brand-version=147", |
| f"--timezone={real_tz}", |
| f"--lang={real_locale}", |
| f"--accept-lang={real_locale},en", |
| f"--user-agent={mobile_ua}", |
| "--disable-blink-features=AutomationControlled", |
| "--no-sandbox", |
| "--disable-dev-shm-usage", |
| "--disable-infobars", |
| "--no-first-run", |
| "--no-default-browser-check", |
| "--disable-extensions", |
| "--mute-audio", |
| "--disable-popup-blocking", |
| ] |
|
|
| context = await p.chromium.launch_persistent_context( |
| user_data_dir=str(user_data_dir), |
| executable_path=CUSTOM_CHROMIUM_PATH, |
| headless=False, |
| args=browser_args, |
| no_viewport=False, |
| viewport={"width": mob_w, "height": mob_h}, |
| is_mobile=True, |
| has_touch=True, |
| java_script_enabled=True, |
| ignore_https_errors=True, |
| ) |
|
|
| page = context.pages[0] if context.pages else await context.new_page() |
| print(f"\n[🚀] الانتقال إلى {target_url} لحل الحماية...") |
| |
| try: |
| await page.goto(target_url, wait_until="domcontentloaded", timeout=60000) |
| except Exception: |
| pass |
| |
| success = await visual_click(page, "box.png") |
| if success: |
| print("[⏳] انتظار 5 ثوانٍ بعد تخطي الحماية لضمان تحميل الجلسة بالكامل...") |
| await page.wait_for_timeout(5000) |
| else: |
| print("[⏳] لم يتم حل الحماية بصرياً، لكننا سنحاول استخراج الجلسة الحالية (قد تكون غير مكتملة).") |
| await page.wait_for_timeout(3000) |
|
|
| print("[📦] جاري استخراج بيانات الجلسة (كوكيز، LocalStorage، SessionStorage)...") |
| session_data = await extract_full_session(page, context) |
| |
| with open(OUTPUT_SESSION_FILE, "w", encoding="utf-8") as f: |
| json.dump(session_data, f, indent=4, ensure_ascii=False) |
| |
| print(f"[✅] تم حفظ الجلسة بنجاح في: {OUTPUT_SESSION_FILE}") |
| print(f"[🌐] الرابط الحالي المسجل: {session_data['url']}") |
| print(f"[🍪] عدد الكوكيز المستخرجة: {len(session_data['cookies'])}") |
| print(f"[💾] عدد عناصر LocalStorage: {len(session_data['localStorage'])}") |
| print(f"[⚡] عدد عناصر SessionStorage: {len(session_data['sessionStorage'])}") |
| print(f"[🌐] User-Agent المستخدم: {session_data.get('user_agent', 'غير معروف')}") |
| print(f"[🌐] Accept-Language: {session_data.get('accept_language', 'غير معروف')}") |
|
|
| await context.close() |
| print("[🔚] تم إغلاق المتصفح. انتهت المرحلة الأولى.") |
|
|
| if __name__ == "__main__": |
| parser = argparse.ArgumentParser(description="استخراج جلسة Cloudflare") |
| parser.add_argument("--url", required=True, help="الرابط المستهدف (مثل https://jnkie.com)") |
| args = parser.parse_args() |
| asyncio.run(main(args.url)) |
|
|