|
|
@ -1,4 +1,5 @@ |
|
|
|
import os |
|
|
|
from threading import Thread |
|
|
|
|
|
|
|
from script.obfuscate import BaseObfuscation, NotInstalledError |
|
|
|
import re |
|
|
@ -23,13 +24,25 @@ class GitNotInstalled(Exception): |
|
|
|
|
|
|
|
|
|
|
|
class ShapeShifterBase(BaseObfuscation): |
|
|
|
MODES_SUPPORTED = ["server", "client"] |
|
|
|
ALGORITHMS_SUPPORTED = ["obfs4"] |
|
|
|
|
|
|
|
def __init__(self): |
|
|
|
def __init__(self, mode, algorithm, wireguard_port=None, listen_port=None, client_replicant_port=None, client_options=None): |
|
|
|
super().__init__( |
|
|
|
binary_path=shapeshifter_binary, |
|
|
|
algorithm="obfs4" |
|
|
|
algorithm=algorithm |
|
|
|
) |
|
|
|
|
|
|
|
assert mode in ShapeShifterBase.MODES_SUPPORTED, "%s is not a supported mode. Supported: %s" % ( |
|
|
|
mode, ShapeShifterBase.MODES_SUPPORTED |
|
|
|
) |
|
|
|
|
|
|
|
self._wireguard_port = wireguard_port |
|
|
|
self._listen_port = listen_port |
|
|
|
self._client_replicant_port = client_replicant_port |
|
|
|
self._mode = mode |
|
|
|
self._client_options = client_options |
|
|
|
|
|
|
|
self._go_version_min = (1, 14, 0) |
|
|
|
|
|
|
|
self.ensure_installed() |
|
|
@ -94,6 +107,67 @@ class ShapeShifterBase(BaseObfuscation): |
|
|
|
except FileNotFoundError: |
|
|
|
self._install_shapeshifter() |
|
|
|
|
|
|
|
def start(self): |
|
|
|
|
|
|
|
bind_command = "bindaddr" if self._mode == "server" else "proxylistenaddr" |
|
|
|
bind_port = self._listen_port if self._mode == "server" else self._client_replicant_port |
|
|
|
bind_value = f"127.0.0.1:{bind_port}" # TODO |
|
|
|
if self._mode == "server": |
|
|
|
bind_value = self.algorithm + "-" + bind_value |
|
|
|
connect_command = "orport" if self._mode == "server" else "target" |
|
|
|
connect_port = self._wireguard_port if self._mode == "server" else self._listen_port |
|
|
|
|
|
|
|
cmd = [ |
|
|
|
"-transparent", |
|
|
|
"-udp", |
|
|
|
f"-{self._mode}", |
|
|
|
"-state", f"state", |
|
|
|
f"-{connect_command}", f"127.0.0.1:{connect_port}", |
|
|
|
"-transports", self.algorithm, |
|
|
|
f"-{bind_command}", bind_value |
|
|
|
] |
|
|
|
|
|
|
|
if self._mode == "client": |
|
|
|
cmd.extend([ |
|
|
|
"-options", f"{self._client_options}" |
|
|
|
]) |
|
|
|
|
|
|
|
cmd.extend([ |
|
|
|
"-logLevel", "DEBUG", |
|
|
|
"-enableLogging", |
|
|
|
]) |
|
|
|
print(*cmd) |
|
|
|
output, code = self.execute(*cmd, stream=True, prefix=self._mode) |
|
|
|
print(output, code) |
|
|
|
|
|
|
|
def start_threaded(self): |
|
|
|
t = Thread(target=self.start, args=()) |
|
|
|
t.start() |
|
|
|
return t |
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
x = ShapeShifterBase() |
|
|
|
import time |
|
|
|
x = ShapeShifterBase( |
|
|
|
mode="server", |
|
|
|
algorithm="obfs2", |
|
|
|
wireguard_port=3333, |
|
|
|
listen_port=2222, |
|
|
|
) |
|
|
|
x.start_threaded() |
|
|
|
|
|
|
|
time.sleep(1) |
|
|
|
|
|
|
|
x = ShapeShifterBase( |
|
|
|
mode="client", |
|
|
|
algorithm="obfs2", |
|
|
|
listen_port=2222, |
|
|
|
client_replicant_port=1443, |
|
|
|
client_options='{"cert": "BWvGMVn3C8daXai2Xo+If23XS94eztZE9Kbtykvy9x5ADWc6YCHdGlWQfDh1fzu7AhuTIA", "iat-mode": "0"}' |
|
|
|
) |
|
|
|
x.start_threaded() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while True: |
|
|
|
time.sleep(1) |