File size: 3,855 Bytes
c884231
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import os
import sys
import threading
import time
from stem.process import launch_tor_with_config
from websockify import WebSocketProxy

# Try to import the default handler to subclass it. 
# Depending on the websockify version, it might be in different spots.
try:
    from websockify.websocketproxy import ProxyRequestHandler
except ImportError:
    # Fallback: if we can't import it directly, we will grab it 
    # dynamically from the proxy instance later.
    ProxyRequestHandler = None

# Configuration
TOR_SOCKS_PORT = 9050
WEBSOCKET_PORT = 7860
WEBSOCKET_LISTEN_HOST = '0.0.0.0'
TOR_DATA_DIR = os.path.join(os.getcwd(), "tor_data")

def print_status(msg):
    print(f"[*] {msg}")

def start_tor():
    """
    Starts the Tor process.
    """
    print_status("Starting Tor process...")
    if not os.path.exists(TOR_DATA_DIR):
        os.makedirs(TOR_DATA_DIR)

    try:
        config = {
            'SocksPort': str(TOR_SOCKS_PORT),
            'DataDirectory': TOR_DATA_DIR,
        }
        tor_process = launch_tor_with_config(
            config=config,
            init_msg_handler=lambda line: print(f"    [Tor] {line}") if "Bootstrapped" in line else None,
            take_ownership=True,
        )
        print_status(f"Tor is running! SOCKS proxy at 127.0.0.1:{TOR_SOCKS_PORT}")
        return tor_process
    except Exception as e:
        print_status(f"Error starting Tor: {e}")
        sys.exit(1)

def create_custom_handler(base_handler_class):
    """
    Creates a custom handler class inheriting from the provided base.
    This allows us to serve "Hello World" on HTTP GET while keeping
    WebSocket functionality for the proxy.
    """
    class HelloHandler(base_handler_class):
        def do_GET(self):
            # Check if this is a WebSocket upgrade request
            if self.headers.get('Upgrade') and self.headers.get('Upgrade').lower() == 'websocket':
                # Pass it to the standard websockify handler
                super().do_GET()
            else:
                # It's a normal HTTP request (e.g., from a browser)
                self.send_response(200)
                self.send_header("Content-type", "text/plain")
                self.end_headers()
                self.wfile.write(b"Hello World")
    
    return HelloHandler

def start_websockify():
    """
    Starts the Websockify proxy with a Custom Handler.
    """
    print_status(f"Starting Websockify on {WEBSOCKET_LISTEN_HOST}:{WEBSOCKET_PORT}...")
    
    # Initialize the proxy
    proxy = WebSocketProxy(
        listen_host=WEBSOCKET_LISTEN_HOST,
        listen_port=WEBSOCKET_PORT,
        target_host='127.0.0.1',
        target_port=TOR_SOCKS_PORT
    )

    # --- MAGIC HAPPENS HERE ---
    # We get the default handler class the proxy was going to use
    default_handler = proxy.RequestHandlerClass
    
    # We create our custom handler inheriting from the default one
    custom_handler = create_custom_handler(default_handler)
    
    # We tell the proxy to use our new handler instead
    proxy.RequestHandlerClass = custom_handler
    # --------------------------

    try:
        proxy.start_server()
    except OSError as e:
        print_status(f"Error starting Websockify: {e}")
        os._exit(1)

def main():
    tor_process = start_tor()

    ws_thread = threading.Thread(target=start_websockify)
    ws_thread.daemon = True
    ws_thread.start()

    print_status("Setup complete.")
    print_status(f"1. Proxy (WS): ws://<IP>:{WEBSOCKET_PORT}/")
    print_status(f"2. Check (HTTP): http://<IP>:{WEBSOCKET_PORT}/ -> Should say 'Hello World'")
    print_status("Press Ctrl+C to stop.")

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print_status("Stopping...")
        tor_process.terminate()
        sys.exit(0)

if __name__ == "__main__":
    main()