autoreg-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
104
skills/anti-detection-browser/scripts/proxy_forwarder.py
Normal file
104
skills/anti-detection-browser/scripts/proxy_forwarder.py
Normal file
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Local HTTP forward proxy that injects Proxy-Authorization for upstream auth.
|
||||
Use when DrissionPage/Playwright doesn't support authenticated proxies.
|
||||
|
||||
Usage:
|
||||
1. Edit UPSTREAM, AUTH_USER, AUTH_PASS below
|
||||
2. Run: python proxy_forwarder.py
|
||||
3. Set browser_proxy to http://127.0.0.1:9128
|
||||
"""
|
||||
|
||||
import http.server
|
||||
import urllib.request
|
||||
import base64
|
||||
import socket
|
||||
import select
|
||||
|
||||
UPSTREAM = 'residential-x.bpproxy.at:1000'
|
||||
AUTH_USER = b'bpuser-XXX'
|
||||
AUTH_PASS = b'YYYY'
|
||||
AUTH = base64.b64encode(AUTH_USER + b':' + AUTH_PASS).decode()
|
||||
LOCAL = 9128
|
||||
|
||||
|
||||
class Proxy(http.server.BaseHTTPRequestHandler):
|
||||
timeout = 30
|
||||
|
||||
def do_GET(self):
|
||||
self._forward('GET')
|
||||
|
||||
def do_POST(self):
|
||||
self._forward('POST')
|
||||
|
||||
def do_HEAD(self):
|
||||
self._forward('HEAD')
|
||||
|
||||
def do_PUT(self):
|
||||
self._forward('PUT')
|
||||
|
||||
def _forward(self, method):
|
||||
try:
|
||||
url = self.path
|
||||
req = urllib.request.Request(url, method=method)
|
||||
req.add_header('Proxy-Authorization', f'Basic {AUTH}')
|
||||
for h, v in self.headers.items():
|
||||
if h.lower() not in ('host', 'proxy-connection', 'proxy-authorization'):
|
||||
req.add_header(h, v)
|
||||
if method in ('POST', 'PUT'):
|
||||
body = self.rfile.read(int(self.headers.get('Content-Length', 0)))
|
||||
req.data = body
|
||||
req.set_proxy(UPSTREAM, 'http')
|
||||
resp = urllib.request.urlopen(req, timeout=30)
|
||||
self.send_response(resp.status)
|
||||
for h, v in resp.getheaders():
|
||||
self.send_header(h, v)
|
||||
self.end_headers()
|
||||
self.wfile.write(resp.read())
|
||||
except Exception as e:
|
||||
self.send_error(502, str(e))
|
||||
|
||||
def do_CONNECT(self):
|
||||
host, port = self.path.split(':')
|
||||
port = int(port)
|
||||
try:
|
||||
uphost, upport = UPSTREAM.split(':')
|
||||
remote = socket.create_connection((uphost, int(upport)), timeout=10)
|
||||
connect_req = (
|
||||
f'CONNECT {host}:{port} HTTP/1.1\r\n'
|
||||
f'Host: {host}:{port}\r\n'
|
||||
f'Proxy-Authorization: Basic {AUTH}\r\n\r\n'
|
||||
)
|
||||
remote.send(connect_req.encode())
|
||||
resp = b''
|
||||
while b'\r\n\r\n' not in resp:
|
||||
resp += remote.recv(4096)
|
||||
if b'200' not in resp.split(b'\r\n')[0]:
|
||||
self.send_error(502, 'CONNECT failed')
|
||||
remote.close()
|
||||
return
|
||||
self.send_response(200, 'Connection Established')
|
||||
self.end_headers()
|
||||
self.connection.settimeout(30)
|
||||
remote.settimeout(30)
|
||||
socks = [self.connection, remote]
|
||||
while True:
|
||||
r, _, _ = select.select(socks, [], [], 30)
|
||||
if not r:
|
||||
break
|
||||
for s in r:
|
||||
try:
|
||||
d = s.recv(8192)
|
||||
if not d:
|
||||
return
|
||||
dst = remote if s is self.connection else self.connection
|
||||
dst.sendall(d)
|
||||
except Exception:
|
||||
return
|
||||
except Exception as e:
|
||||
self.send_error(502, str(e))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(f'[*] Proxy Forwarder: 127.0.0.1:{LOCAL} -> {UPSTREAM}', flush=True)
|
||||
httpd = http.server.HTTPServer(('127.0.0.1', LOCAL), Proxy)
|
||||
httpd.serve_forever()
|
||||
115
skills/anti-detection-browser/scripts/tcp_forwarder.py
Normal file
115
skills/anti-detection-browser/scripts/tcp_forwarder.py
Normal file
@@ -0,0 +1,115 @@
|
||||
import socket, threading, select, base64, json, re, sys
|
||||
"""TCP proxy forwarder for authenticated upstream proxies.
|
||||
|
||||
Usage: python tcp_forwarder.py [proxy_json_path] [local_port]
|
||||
- proxy_json_path: JSON file with proxy pool (default: C:/Users/User/tmp/bpproxy_live.json)
|
||||
- local_port: local port to listen on (default: 9129)
|
||||
|
||||
The script picks the FIRST proxy from the pool. Edit UPSTREAM_HOST/UPSTREAM_PORT/AUTH
|
||||
directly if you want a specific proxy.
|
||||
|
||||
Why TCP instead of HTTP-based:
|
||||
http.server.HTTPServer + BaseHTTPRequestHandler breaks CONNECT tunnels for Chrome.
|
||||
Chrome gets chrome-error://chromewebdata/ while curl works fine.
|
||||
Raw TCP relay handles CONNECT properly.
|
||||
"""
|
||||
|
||||
# --- CONFIG ---
|
||||
DEFAULT_PROXY_POOL = r"C:\Users\User\tmp\bpproxy_live.json"
|
||||
LOCAL_PORT = int(sys.argv[2]) if len(sys.argv) > 2 else 9129
|
||||
|
||||
# Load proxy from pool
|
||||
pool_path = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_PROXY_POOL
|
||||
pool = json.loads(open(pool_path).read())
|
||||
proxy = pool[0]['url'] if isinstance(pool[0], dict) else pool[0]
|
||||
match = re.match(r'http://([^:]+):([^@]+)@([^:]+):(\d+)', proxy)
|
||||
user, password, host, port = match.groups()
|
||||
|
||||
UPSTREAM_HOST = host
|
||||
UPSTREAM_PORT = int(port)
|
||||
AUTH = base64.b64encode(f'{user}:{password}'.encode()).decode()
|
||||
|
||||
|
||||
def handle_client(client_sock):
|
||||
try:
|
||||
data = b''
|
||||
while b'\r\n\r\n' not in data:
|
||||
chunk = client_sock.recv(4096)
|
||||
if not chunk:
|
||||
return
|
||||
data += chunk
|
||||
|
||||
request = data.decode('latin-1', errors='replace')
|
||||
first_line = request.split('\r\n')[0]
|
||||
method, target, _ = first_line.split(' ', 2)
|
||||
|
||||
if method == 'CONNECT':
|
||||
host, port_str = target.rsplit(':', 1)
|
||||
port = int(port_str)
|
||||
|
||||
remote = socket.create_connection((UPSTREAM_HOST, UPSTREAM_PORT), timeout=10)
|
||||
connect_req = (
|
||||
f'CONNECT {host}:{port} HTTP/1.1\r\n'
|
||||
f'Host: {host}:{port}\r\n'
|
||||
f'Proxy-Authorization: Basic {AUTH}\r\n\r\n'
|
||||
)
|
||||
remote.send(connect_req.encode())
|
||||
|
||||
resp = b''
|
||||
while b'\r\n\r\n' not in resp:
|
||||
resp += remote.recv(4096)
|
||||
|
||||
if b'200' not in resp.split(b'\r\n')[0]:
|
||||
client_sock.send(b'HTTP/1.1 502 Bad Gateway\r\n\r\n')
|
||||
remote.close()
|
||||
return
|
||||
|
||||
client_sock.send(b'HTTP/1.1 200 Connection Established\r\n\r\n')
|
||||
_relay(client_sock, remote)
|
||||
else:
|
||||
remote = socket.create_connection((UPSTREAM_HOST, UPSTREAM_PORT), timeout=10)
|
||||
remote.send(data)
|
||||
_relay(client_sock, remote)
|
||||
except Exception:
|
||||
pass
|
||||
finally:
|
||||
try:
|
||||
client_sock.close()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def _relay(a, b):
|
||||
a.settimeout(30)
|
||||
b.settimeout(30)
|
||||
socks = [a, b]
|
||||
while True:
|
||||
r, _, _ = select.select(socks, [], [], 30)
|
||||
if not r:
|
||||
break
|
||||
for s in r:
|
||||
try:
|
||||
d = s.recv(8192)
|
||||
if not d:
|
||||
return
|
||||
dst = b if s is a else a
|
||||
dst.sendall(d)
|
||||
except Exception:
|
||||
return
|
||||
|
||||
|
||||
def main():
|
||||
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
server.bind(('127.0.0.1', LOCAL_PORT))
|
||||
server.listen(50)
|
||||
print(f'[*] TCP Proxy: 127.0.0.1:{LOCAL_PORT} -> {UPSTREAM_HOST}:{UPSTREAM_PORT}', flush=True)
|
||||
|
||||
while True:
|
||||
client, addr = server.accept()
|
||||
t = threading.Thread(target=handle_client, args=(client,), daemon=True)
|
||||
t.start()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user