You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

119 lines
3.8 KiB

from pathlib import Path
import requests
import const
from script.obfuscate import BaseObfuscation
import re
import os
import qrcode
import socket
from script.obfuscate.obfs4 import ObfuscateOBFS4
class ObfuscationViaTOR(BaseObfuscation):
def __init__(self, algorithm: BaseObfuscation):
super().__init__(
binary_name="tor"
)
self.algorithm = algorithm
self.tor_data_dir = "/tmp/wg-manager-tor-proxy"
self.tor_config_file = "/tmp/wg-manager-tor-proxy/torrc"
self.tor_fingerprint_file = f"{self.tor_data_dir}/fingerprint"
self.tor_bridge_file = f"{self.tor_data_dir}/pt_state/obfs4_bridgeline.txt"
Path(self.tor_config_file).touch()
os.makedirs(self.tor_data_dir, exist_ok=True)
def __del__(self):
pass
def ensure_installed(self):
super().ensure_installed()
output, code = self.execute("--version")
if re.match(f'Tor version .*', output) and code == 0:
return True
else:
raise RuntimeError(f"Could not verify that {self.binary_name} is installed correctly.")
def start(self):
output, code = self.execute(
"-f", self.tor_config_file,
"--DataDirectory", self.tor_data_dir,
"--RunAsDaemon", "1",
"--ExitPolicy", "reject *:*",
"--ORPort", str(const.OBFUSCATE_SOCKS_TOR_PORT),
"--BridgeRelay", "1",
"--PublishServerDescriptor", "0",
"--ServerTransportPlugin", f"{self.algorithm.algorithm} exec {self.algorithm.binary_path}",
"--ServerTransportListenAddr", f"{self.algorithm.algorithm} 0.0.0.0:{const.OBFUSCATE_TOR_LISTEN_ADDR}",
"--ExtORPort", "auto",
"--ContactInfo", "wg-manager@github.com",
"--Nickname", "wgmanager",
kill_first=True
)
print(output)
def generate_bridge_line(self, local=False):
if local:
ip_address = socket.gethostbyname(socket.gethostname())
else:
ip_address = requests.get("https://api.ipify.org").text
with open(self.tor_fingerprint_file, "r") as f:
fingerprint = f.read().split(" ")
assert len(fingerprint) == 2, "Could not load fingerprint correctly. " \
"Should be a list of 2 items (name, fingerprint)"
fingerprint = fingerprint[1]
with open(self.tor_bridge_file, "r") as f:
bridge_line_raw = f.read()
bridge_line = re.search(r"^Bridge .*", bridge_line_raw, re.MULTILINE).group(0)
bridge_line = bridge_line\
.replace("<IP ADDRESS>", ip_address)\
.replace("<PORT>", str(const.OBFUSCATE_TOR_LISTEN_ADDR))\
.replace("<FINGERPRINT>", fingerprint)\
.replace("Bridge ", "bridge://")\
.replace("\n", "")
#bridge_line = f"bridge://{self.algorithm.algorithm} {ip_address}:{const.OBFUSCATE_SOCKS_TOR_PORT} {fingerprint}"
print(bridge_line)
return bridge_line
def output_qr(self, text, image=False):
qr = qrcode.QRCode(
version=10,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
qr.add_data(text)
qr.make(fit=True)
if image:
img = qr.make_image(fill_color="black", back_color="white")
img.show()
else:
try:
qr.print_tty()
except:
qr.print_ascii()
if __name__ == "__main__":
x = ObfuscationViaTOR(
algorithm=ObfuscateOBFS4()
)
x.ensure_installed()
x.start()
bridge_line = x.generate_bridge_line(local=False)
x.output_qr(bridge_line, image=True)
#x.generate_bridge_line(local=False)