Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- import undetected_chromedriver as uc
- from selenium.webdriver.chrome.options import Options
- from colorama import Fore, Style, init as colorama_init
- import websocket
- import ssl
- import threading
- import time
- import json
- import os
- import argparse
- import sys
- import signal
- colorama_init(autoreset=True)
- signal.signal(signal.SIGINT, lambda sig, frame: sys.exit(0))
- # --------------------
- # CONFIGURATION
- # --------------------
- TARGET_URL = "https://hackforums.net/convo.php"
- WS_BASE_URL = "wss://hackforums.net:2096/socket.io/?EIO=3&transport=websocket"
- DUMP_PATH = os.path.expanduser("~/.hf_socket_dump.jsonl")
- # --------------------
- # CLI Argument Parsing
- # --------------------
- parser = argparse.ArgumentParser(description="HackForums dvz mybb shoutbox CLI Chat")
- parser.add_argument("-m", "--message", help="Send a message to a conversation")
- parser.add_argument("-c", "--convo", help="Target conversation ID to send/read from")
- parser.add_argument("-k", "--key", help="Public key for encryption (if applicable)")
- parser.add_argument("-v", "--verbose", action="store_true", help="Enable verbose socket logs")
- parser.add_argument("--dump", help="Specify custom dump path", default=DUMP_PATH)
- parser.add_argument("--read", action="store_true", help="Read messages from a conversation")
- args = parser.parse_args()
- if args.message and not args.convo:
- print(f"{Fore.RED}[!] Conversation ID (-c) required when sending a message (-m).{Style.RESET_ALL}")
- sys.exit(1)
- # --------------------
- # Step 1: Launch stealth browser and fetch cookies
- # --------------------
- def get_cookies():
- print(f"{Fore.YELLOW}[*] Launching stealth browser...{Style.RESET_ALL}")
- chrome_options = Options()
- chrome_options.add_argument("--headless=new")
- chrome_options.add_argument("--disable-blink-features=AutomationControlled")
- chrome_options.add_argument("--no-sandbox")
- chrome_options.add_argument("--disable-dev-shm-usage")
- # Add user-agent string to mimic normal browser
- chrome_options.add_argument(
- "user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
- "(KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
- )
- try:
- driver = uc.Chrome(options=chrome_options)
- driver.get(TARGET_URL)
- print(f"{Fore.YELLOW}[*] Waiting out JS/Captcha firewall (15s)...{Style.RESET_ALL}")
- time.sleep(15) # Allow enough time to pass CF JS challenge & login cookies to settle
- cookies = driver.get_cookies()
- driver.quit()
- print(f"{Fore.GREEN}[+] Browser cookies captured.{Style.RESET_ALL}")
- return "; ".join([f"{c['name']}={c['value']}" for c in cookies])
- except Exception as e:
- print(f"{Fore.RED}[!] Error fetching cookies: {e}{Style.RESET_ALL}")
- sys.exit(1)
- cookie_header = get_cookies()
- # --------------------
- # Step 2: WebSocket URL with timestamp to avoid caching
- # --------------------
- ts = int(time.time() * 1000)
- ws_url = f"{WS_BASE_URL}&t={ts}"
- # Remove old dump file if exists
- if os.path.exists(args.dump):
- os.remove(args.dump)
- # --------------------
- # Utility: Extract session token from cookies
- # --------------------
- def get_session_token():
- for part in cookie_header.split("; "):
- if part.startswith("session="):
- return part.split("=", 1)[1]
- return None
- # --------------------
- # Logging & Dumping
- # --------------------
- def log_event(event_type, data):
- if not data:
- return
- color_map = {
- "debug": Fore.BLUE,
- "convo_message": Fore.CYAN,
- "typing": Fore.MAGENTA,
- "notice": Fore.YELLOW
- }
- color = color_map.get(event_type, Fore.WHITE)
- print(f"{color}[⚡ EVENT] {event_type.upper()}{Style.RESET_ALL}")
- print(json.dumps(data, indent=2))
- with open(args.dump, "a") as f:
- f.write(json.dumps({"event": event_type, "data": data, "ts": int(time.time())}) + "\n")
- def parse_socketio_payload(message):
- if not message.startswith("42"):
- return None
- try:
- payload = json.loads(message[2:])
- return payload[0], payload[1]
- except Exception as e:
- print(f"{Fore.RED}[!] Payload parse error: {e}{Style.RESET_ALL}")
- return None
- # --------------------
- # Socket.IO message wrappers
- # --------------------
- def send_packet(ws, event_name, data):
- payload = [event_name, data]
- packet = "42" + json.dumps(payload)
- ws.send(packet)
- if args.verbose:
- print(f"{Fore.YELLOW}[>] Sent event '{event_name}' with data: {data}{Style.RESET_ALL}")
- def send_message(ws, convo_id, message, pubkey=None):
- # dvz mybb shoutbox send_message payload:
- data = {
- "convo_id": convo_id,
- "message": message,
- "key": pubkey or ""
- }
- send_packet(ws, "send_message", data)
- def request_convo(ws, convo_id):
- send_packet(ws, "fetch_messages", {"convo_id": convo_id})
- def join_convo(ws, convo_id):
- send_packet(ws, "join_conversation", {"convo_id": convo_id})
- def auth_user(ws):
- token = get_session_token()
- data = {"session": token} if token else {}
- send_packet(ws, "auth_user", data)
- print(f"{Fore.GREEN}[+] Sent 'auth_user' with session token.{Style.RESET_ALL}")
- # --------------------
- # WebSocket event handlers
- # --------------------
- def on_message(ws, message):
- if args.verbose:
- print(f"{Fore.LIGHTBLACK_EX}[<] {message}{Style.RESET_ALL}")
- result = parse_socketio_payload(message)
- if result:
- event_type, data = result
- log_event(event_type, data)
- # You can add auto-reply or other logic here
- def on_error(ws, error):
- if error:
- print(f"{Fore.RED}[!] WebSocket error: {error}{Style.RESET_ALL}")
- else:
- print(f"{Fore.RED}[!] WebSocket error occurred with no message.{Style.RESET_ALL}")
- def on_close(ws, code, msg):
- print(f"{Fore.RED}[-] WebSocket closed: Code={code} Message={msg}{Style.RESET_ALL}")
- def on_open(ws):
- print(f"{Fore.GREEN}[+] WebSocket handshake initiated{Style.RESET_ALL}")
- def socketio_handshake():
- try:
- # Standard Socket.IO probe & upgrade handshake
- ws.send("2probe")
- time.sleep(1)
- ws.send("5")
- time.sleep(1)
- ws.send("3")
- time.sleep(1)
- # Authenticate user with session token
- auth_user(ws)
- # Join convo and optionally send/read messages
- if args.convo:
- join_convo(ws, args.convo)
- if args.read:
- request_convo(ws, args.convo)
- if args.message:
- send_message(ws, args.convo, args.message, args.key)
- # Heartbeat loop
- while True:
- time.sleep(15)
- ws.send("2")
- if args.verbose:
- print(f"{Fore.YELLOW}[>] Heartbeat ping sent{Style.RESET_ALL}")
- except Exception as e:
- print(f"{Fore.RED}[X] Handshake thread error: {e}{Style.RESET_ALL}")
- threading.Thread(target=socketio_handshake, daemon=True).start()
- # --------------------
- # Run WebSocket client
- # --------------------
- def start_ws():
- ws = websocket.WebSocketApp(
- ws_url,
- on_open=on_open,
- on_message=on_message,
- on_error=on_error,
- on_close=on_close,
- header=[
- "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
- "Origin: https://hackforums.net",
- f"Referer: {TARGET_URL}",
- f"Cookie: {cookie_header}"
- ]
- )
- print(f"{Fore.YELLOW}[*] Connecting to {ws_url}{Style.RESET_ALL}")
- try:
- ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})
- except KeyboardInterrupt:
- print(f"{Fore.RED}\n[!] Interrupted by user. Closing WebSocket...{Style.RESET_ALL}")
- ws.close()
- sys.exit(0)
- # --------------------
- # Entrypoint
- # --------------------
- if __name__ == "__main__":
- start_ws()
Add Comment
Please, Sign In to add comment