def _prepend(self, string):
        """Configure the `prepend` Transform, which prepends a static string to an arbitrary input.

        Args:
            string (str): The static string to be prepended.

        Raises:
            MalleableError: If `string` is null.
        """
        if string is None:
            MalleableError.throw(Transform.__class__, "prepend",
                                 "string argument must not be null")
        self.transform = lambda data: string + data
        self.transform_r = lambda data: data[len(string):]
        self.generate_python = lambda var: "%(var)s=b'%(string)s'+%(var)s\n" % {
            "var": var,
            "string": string
        }
        self.generate_python_r = lambda var: "%(var)s=%(var)s[%(len)i:]\n" % {
            "var": var,
            "len": len(string)
        }
        self.generate_powershell = lambda var: "%(var)s='%(string)s'+%(var)s;" % {
            "var": var,
            "string": string
        }
        self.generate_powershell_r = lambda var: "%(var)s=%(var)s.substring(%(len)i,%(var)s.Length-%(len)i);" % {
            "var": var,
            "len": len(string)
        }
    def _mask(self, key):
        """Configure the `mask` Transform, which encodes an arbitrary input using the XOR operation
        and a random key.

        Args:
            key (str): The key with which to encode / decode.

        Raises:
            MalleableError: If `key` is null or empty.
        """
        if not key:
            MalleableError.throw(Transform.__class__, "mask",
                                 "key argument must not be empty")
        self.transform = lambda data: "".join(
            [chr(ord(c) ^ ord(key[0])) for c in data])
        self.transform_r = self.transform
        self.generate_python = lambda var: "f_ord=ord if __import__('sys').version_info[0]<3 else int;%(var)s=''.join([chr(f_ord(_)^%(key)s) for _ in %(var)s])\n" % {
            "key": ord(key[0]),
            "var": var
        }
        self.generate_python_r = self.generate_python
        self.generate_powershell = lambda var: "%(var)s=[System.Text.Encoding]::Default.GetString($(for($_=0;$_ -lt %(var)s.length;$_++){[System.Text.Encoding]::Default.GetBytes(%(var)s)[$_] -bxor %(key)s}));" % {
            "key": ord(key[0]),
            "var": var
        }
        self.generate_powershell_r = self.generate_powershell
    def _append(self, string):
        """Configure the `append` Transform, which appends a static string to an arbitrary input.

        Args:
            string (str): The static string to be appended.

        Raises:
            MalleableError: If `string` is null.
        """
        if string is None:
            MalleableError.throw(Transform.__class__, "append",
                                 "string argument must not be null")
        self.transform = lambda data: data + string
        self.transform_r = lambda data: data[:-len(string)]
        self.generate_python = lambda var: "%(var)s+=b'%(string)s'\n" % {
            "var": var,
            "string": string
        }
        self.generate_python_r = lambda var: "%(var)s=%(var)s[:-%(len)i]\n" % {
            "var": var,
            "len": len(string)
        }
        self.generate_powershell = lambda var: "%(var)s+='%(string)s';" % {
            "var": var,
            "string": string
        }
        self.generate_powershell_r = lambda var: "%(var)s=%(var)s.Substring(0,%(var)s.Length-%(len)i);" % {
            "var": var,
            "len": len(string)
        }
    def parameter(self, parameter):
        """Use the specified parameter to store the data after transformation.

        Args:
            parameter (str)

        Rasie:
            MalleableError: If `parameter` is empty.
        """
        if not parameter:
            MalleableError.throw(Container, "parameter",
                                 "argument must not be null")
        self.terminator = Terminator(type=Terminator.PARAMETER, arg=parameter)
    def header(self, header):
        """Use the specified header to store the data after transformation.

        Args:
            header (str)

        Rasie:
            MalleableError: If `header` is empty.
        """
        if not header:
            MalleableError.throw(Container, "header",
                                 "argument must not be null")
        self.terminator = Terminator(type=Terminator.HEADER, arg=header)
Esempio n. 6
0
    def url(self, url):
        """Setter for the full url.

        Note: Actually sets parses the input into the urlparse.SplitResult _url.

        Args:
            url (str)
        """
        if "://" in url:
            if "http://" not in url.lower() and "https://" not in url.lower():
                MalleableError.throw(self.__class__, "url",
                                     "Scheme not supported: %s" % url)
        else:
            url = "http://" + url
        self._url = urlparse.urlsplit(url)
Esempio n. 7
0
    def ingest(self, file):
        """Ingest a profile file into the Profile object.

        Args:
            file (str): Filename to be read and parsed.
        """
        if not file or not os.path.isfile(file):
            MalleableError.throw(self.__class__, "ingest", "Invalid file: %s" % str(file))

        content = None
        with open(file) as f:
            content = f.read()

        if not content:
            MalleableError.throw(self.__class__, "ingest", "Empty file: %s" % str(file))

        self._parse(self._pattern().searchString(content))
Esempio n. 8
0
    def _deserialize(cls, data):
        """Deserialize data into a Profile object.

        Args:
            data (dict (str, obj)): Serialized data (json)

        Returns:
            Profile object
        """
        profile = super(Profile, cls)._deserialize(data)
        if data:
            try:
                profile.get = Get._deserialize(data["get"]) if "get" in data else Get()
                profile.post = Post._deserialize(data["post"] if "post" in data else Post())
                profile.stager = Stager._deserialize(data["stager"] if "stager" in data else Stager())
                profile.sleeptime = int(data["sleeptime"]) if "sleeptime" in data else 60000
                profile.jitter = int(data["jitter"]) if "jitter" in data else 0
            except Exception as e:
                MalleableError.throw(cls, "_deserialize", "An error occurred: " + str(e))
        return profile
    def generate_powershell_r(self, var):
        """Generate powershell code that would transform arbitrary data using the sequence
            of Transforms in reverse.

        Args:
            var (str): The variable name to be used in the powershell code.

        Returns:
            str: The powershell code.

        Raises:
            MalleableError: If `var` is empty.
        """
        if not var:
            MalleableError.throw(Container, "generate_powershell_r",
                                 "var must not be empty")
        code = ""
        for t in self.transforms[::-1]:
            code += t.generate_powershell_r(var)
        return code
Esempio n. 10
0
    def host(self, host):
        """Setter for the host.

        Args:
            host (str)

        Raises:
            MalleableError: If scheme not supported.
        """
        if "://" in host:
            if "http://" in host:
                host = host.lstrip("http://")
                self.scheme = "http"
            elif "https://" in host:
                host = host.lstrip("https://")
                self.scheme = "https"
            else:
                MalleableError.throw(self.__class__, "host",
                                     "Scheme not supported: %s" % host)
        if ":" not in host and self._url.port:
            host += ":" + str(self._url.port)
        self._url = self._url._replace(netloc=host)
Esempio n. 11
0
    def validate(self):
        """Validate the profile to verify it will succeed when used.

        Returns:
            bool: True if no checks fail.

        Raises:
            MalleableError: If a check fails.
        """
        host = "http://domain.com:80"
        data = string.printable
        for format, p in [("base", self), ("clone", self._clone()), ("serialized", Profile._deserialize(self._serialize()))]:
            test = p.get.construct_client(host, data)
            clone = MalleableRequest()
            clone.url = test.url
            clone.verb = test.verb
            clone.headers = test.headers
            clone.body = test.body
            if self.get.extract_client(clone) != data:
                MalleableError.throw(self.__class__, "validate", "Data-integrity check failed: %s-get-client-metadata" % format)

            test = p.get.construct_server(data)
            clone = MalleableResponse()
            clone.headers = test.headers
            clone.body = test.body
            if self.get.extract_server(clone) != data:
                MalleableError.throw(self.__class__, "validate", "Data-integrity check failed: %s-get-server-output" % format)

            test = p.post.construct_client(host, data, data)
            clone = MalleableRequest()
            clone.url = test.url
            clone.verb = test.verb
            clone.headers = test.headers
            clone.body = test.body
            id, output = self.post.extract_client(clone)
            if id != data:
                MalleableError.throw(self.__class__, "validate", "Data-integrity check failed: %s-post-client-id" % format)
            if output != data:
                MalleableError.throw(self.__class__, "validate", "Data-integrity check failed: %s-post-client-output" % format)

            test = p.post.construct_server(data)
            clone = MalleableResponse()
            clone.headers = test.headers
            clone.body = test.body
            if self.post.extract_server(clone) != data:
                MalleableError.throw(self.__class__, "validate", "Data-integrity check failed: %s-post-server-output" % format)

            test = p.stager.construct_client(host, data)
            clone = MalleableRequest()
            clone.url = test.url
            clone.verb = test.verb
            clone.headers = test.headers
            clone.body = test.body
            if self.stager.extract_client(clone) != data:
                MalleableError.throw(self.__class__, "validate", "Data-integrity check failed: %s-stager-client-metadata" % format)

            test = p.stager.construct_server(data)
            clone = MalleableResponse()
            clone.headers = test.headers
            clone.body = test.body
            if self.stager.extract_server(clone) != data:
                MalleableError.throw(self.__class__, "validate", "Data-integrity check failed: %s-stager-server-output" % format)

        if set(self.get.client.uris).intersection(set(self.post.client.uris)) or \
            set(self.post.client.uris).intersection(set(self.stager.client.uris)) or \
            set(self.stager.client.uris).intersection(set(self.get.client.uris)) or \
            len(self.get.client.uris + (self.post.client.uris if self.post.client.uris else ["/"])) == 0 or \
            len(self.post.client.uris + (self.stager.client.uris if self.stager.client.uris else ["/"])) == 0 or \
            len(self.stager.client.uris + (self.get.client.uris if self.get.client.uris else ["/"])) == 0 or \
            ("/" in self.get.client.uris and len(self.post.client.uris) == 0) or \
            ("/" in self.get.client.uris and len(self.stager.client.uris) == 0) or \
            ("/" in self.post.client.uris and len(self.stager.client.uris) == 0) or \
            ("/" in self.post.client.uris and len(self.get.client.uris) == 0) or \
            ("/" in self.stager.client.uris and len(self.get.client.uris) == 0) or \
            ("/" in self.stager.client.uris and len(self.post.client.uris) == 0):
            MalleableError.throw(self.__class__, "validate", "Cannot have duplicate uris: %s - %s - %s" % (
                self.get.client.uris if self.get.client.uris else ["/"],
                self.post.client.uris if self.post.client.uris else ["/"],
                self.stager.client.uris if self.stager.client.uris else ["/"]
            ))

        return True