From f1791b207bebbdd787fb645a9d3febbf86420060 Mon Sep 17 00:00:00 2001 From: Per-Arne Andersen Date: Tue, 21 Jul 2020 22:23:02 +0200 Subject: [PATCH] * Work on shapeshifter.py #19 --- .../script/obfuscate/__init__.py | 11 ++- .../script/obfuscate/shapeshifter.py | 99 +++++++++++++++++++ 2 files changed, 106 insertions(+), 4 deletions(-) create mode 100644 wg_dashboard_backend/script/obfuscate/shapeshifter.py diff --git a/wg_dashboard_backend/script/obfuscate/__init__.py b/wg_dashboard_backend/script/obfuscate/__init__.py index 9db98d6..5debc81 100644 --- a/wg_dashboard_backend/script/obfuscate/__init__.py +++ b/wg_dashboard_backend/script/obfuscate/__init__.py @@ -1,7 +1,10 @@ import abc from pathlib import Path import subprocess -import shlex + + +class NotInstalledError(Exception): + pass class BaseObfuscation(abc.ABC): @@ -9,7 +12,7 @@ class BaseObfuscation(abc.ABC): def __init__(self, binary_name=None, binary_path=None, algorithm=None): assert binary_name is not None or binary_path is not None - self.binary_name = binary_name if binary_name is not None else Path(self.binary_path).name + self.binary_name = binary_name if binary_name is not None else Path(binary_path).name self.binary_path = binary_path if binary_path else "" self.algorithm = algorithm @@ -23,7 +26,7 @@ class BaseObfuscation(abc.ABC): data = [x.decode().strip() for x in proc_which.communicate() if x != b''][0] if proc_which.returncode != 0: - raise RuntimeError("Could not find binary '%s'" % data) + raise NotInstalledError("Could not find binary '%s'" % data) self.binary_path = data @@ -38,7 +41,7 @@ class BaseObfuscation(abc.ABC): #kill_output, kill_code = self.execute(*[pattern], override_command="pkill") command = override_command if override_command is not None else self.binary_path - print(shlex.join([command] + list(args))) + proc_which = subprocess.Popen([command] + list(args), stdout=subprocess.PIPE, stderr=subprocess.PIPE) raw_data = proc_which.communicate() diff --git a/wg_dashboard_backend/script/obfuscate/shapeshifter.py b/wg_dashboard_backend/script/obfuscate/shapeshifter.py new file mode 100644 index 0000000..cd10951 --- /dev/null +++ b/wg_dashboard_backend/script/obfuscate/shapeshifter.py @@ -0,0 +1,99 @@ +import os + +from script.obfuscate import BaseObfuscation, NotInstalledError +import re +import pathlib +import shutil + +current_dir = pathlib.Path(__file__).parent.absolute() +shapeshifter_path = current_dir.joinpath("binary/shapeshifter-dispatcher") +shapeshifter_binary = shapeshifter_path.joinpath("shapeshifter-dispatcher") + + +class GoNotFound(Exception): + pass + + +class GoVersionIncompatible(Exception): + pass + + +class GitNotInstalled(Exception): + pass + + +class ShapeShifterBase(BaseObfuscation): + + def __init__(self): + super().__init__( + binary_path=shapeshifter_binary, + algorithm="obfs4" + ) + + self._go_version_min = (1, 14, 0) + + self.ensure_installed() + + def _verify_go_installed(self): + output, code = self.execute("version", override_command="go") + + try: + match = re.findall("go([0-9]+.[0-9]+.[0-9]+)", output) + match = match[0] + except IndexError: + raise GoNotFound("Go was not found on the system.") + + major, minor, patch = match.split(".") + + if int(major) < self._go_version_min[0] or int(minor) < self._go_version_min[1] or \ + int(patch) < self._go_version_min[2]: + raise GoVersionIncompatible("Go version is incompatible. %s < %s" % (self._go_version_min, match)) + + def _verify_git_installed(self): + output, code = self.execute("version", override_command="git") + if code == 0: + return + + raise GitNotInstalled("Git does not seem to be installed. Code: %s, Output: %s" % (code, output)) + + def _verify_shapeshifter_installed(self): + output, code = self.execute("version", override_command=shapeshifter_binary) + print(output, code) + + def _install_shapeshifter(self): + + if shapeshifter_path.is_dir(): + shutil.rmtree(shapeshifter_path) + + output, code = self.execute( + "clone", + "https://github.com/OperatorFoundation/shapeshifter-dispatcher.git", + shapeshifter_path, + override_command="git") + + assert code == 0, "Git exited with error. %s" % (output,) + + current_working_dir = os.getcwd() + os.chdir(shapeshifter_path) + + output, code = self.execute("build", override_command="go") + os.chdir(current_working_dir) + + assert code == 0, "Building shapeshifter failed with output: %s" % (output,) + + def ensure_installed(self): + try: + super().ensure_installed() + except NotInstalledError: + + self._verify_go_installed() + self._verify_git_installed() + + try: + self._verify_shapeshifter_installed() + except FileNotFoundError: + self._install_shapeshifter() + + +if __name__ == "__main__": + x = ShapeShifterBase()