def runSingleTool(self): """ Only run one tool """ service = self.arguments.args.service self.output.printInfo( 'Selected mode: Run single tool against service {0}'.format( service)) tool = self.settings.toolbox.searchInToolboxForService( self.arguments.args.single_tool, service) if not tool: sys.exit(0) output_file = FileUtils.absolute_path( FileUtils.concat_path(self.arguments.args.output_dir, tool.name + '.txt')) output_dir = FileUtils.absolute_path( FileUtils.concat_path(self.arguments.args.output_dir, tool.name)) print self.output.printTitle1(' ' + tool.name) try: tool.runTool(self.settings, self.output, self.arguments.args.output_dir, self.arguments.target, self.arguments.specific, auto_yes=self.arguments.args.auto_yes) except KeyboardInterrupt, SystemExit: print self.output.printError('Tool execution aborted')
def parseAllConfFiles(self, files): """ Parse all *.conf files into the config directory @Args files: list of config files to parse @Returns None """ # ---- # Parse INSTALL_STATUS_CONF_FILE if INSTALL_STATUS_CONF_FILE + CONF_EXT not in files: self.output.printError( 'Install status file ({0}/{1}.{2}) is missing'.format( SETTINGS_DIR, INSTALL_STATUS_CONF_FILE, CONF_EXT)) sys.exit(0) self.config_parsers[INSTALL_STATUS_CONF_FILE] = DefaultConfigParser() self.config_parsers[INSTALL_STATUS_CONF_FILE].read( FileUtils.concat_path(self.settings_dir, INSTALL_STATUS_CONF_FILE + CONF_EXT)) files.remove(INSTALL_STATUS_CONF_FILE + CONF_EXT) # ---- # Parse MULTI_SERVICES_CONF_FILE support_multi_services_tools = MULTI_SERVICES_CONF_FILE + CONF_EXT in files self.parseToolsConfFile(MULTI_SERVICES_CONF_FILE + CONF_EXT) files.remove(MULTI_SERVICES_CONF_FILE + CONF_EXT) # ---- # Parse services *.conf files for f in files: self.parseToolsConfFile(f)
def parseConfFiles(self, files): """ Parse all *.conf files into the config directory @Args files: list of config files to parse @Returns None """ # Process *.conf files for f in files: self.output.printInfo( 'Parsing configuration file "{0}" ...'.format(f)) full_path = FileUtils.concat_path(self.settings_dir, f) service_name = f[:f.rfind(CONF_EXT)].lower().strip() self.config_parsers[service_name] = DefaultConfigParser() self.config_parsers[service_name].read(full_path) #config_parser = DefaultConfigParser() #config_parser.read(full_path) # Add the entry into general settings for the service self.general_settings[service_name] = {} # General settings - [general] in .conf file self.general_settings[service_name]['tools_categories'] = [ e.lower() for e in self.config_parsers[service_name].safeGetList( 'general', 'tools_categories', ',', []) ] # General settings - Optional/Specific settings (depends on the targeted servicee) if service_name in SPECIFIC_TOOL_OPTIONS.keys(): for option in SPECIFIC_TOOL_OPTIONS[service_name]: if SPECIFIC_TOOL_OPTIONS[service_name][option]: setting_name = SPECIFIC_TOOL_OPTIONS[service_name][ option] self.general_settings[service_name][setting_name] = \ [ e.lower() for e in self.config_parsers[service_name].safeGetList('general', setting_name, ',', []) ] # Check general settings for the current service self.checkGeneralSettings(service_name) # Add service as new toolbox section self.toolbox.addService(service_name) # Add tools in current config file into the toolbox, under the correct service section for section in self.config_parsers[service_name].sections(): if section.startswith('tool_'): newtool = self.createToolFromConfiguration( section, service_name) if newtool: if not self.toolbox.addTool(newtool, service_name): self.output.printWarning( 'Unable to add tool "{0}" into the toolbox'. format(newtool.name)) else: #self.output.printSettings('Tool "{0}" added into the toolbox (category "{1}")'.format(newtool.name, # newtool.category)) pass
def defineOutputDir(self, output_dir, host, port, protocol, service): """ Define the output directory name for storing results @Args output_dir: name coming from argument (if defined by user) host: target host name port: target port number protocol: protocol tcp or udp service: @Returns the final name to use as directory name """ if output_dir: return output_dir return FileUtils.concat_path(DEFAULT_OUTPUT_DIR, \ 'output_{0}-{1}{2}_{3}_{4}'.format(host, port, protocol, service, str(time.time()).split('.')[0]))
def save(self, conf_filename): """ Save change permanently into the file :param conf_filename: Settings filename without extension :return: Boolean indicating status """ try: config_file = FileUtils.concat_path(SETTINGS_DIR, conf_filename+CONF_EXT) with open(config_file, 'w') as handle: self.config_parsers[conf_filename].write(handle) # Re-read to take change into account self.config_parsers[conf_filename].read(config_file, 'utf8') # warning: takes filename as param return True except: logger.error('Error occured when saving changes in settings file named "{filename}"'.format( filename=conf_filename)) traceback.print_exc() return False
def runToolboxAgainstService(self): """ Run the tools from the toolbox that target the service chosen by the user. Categories selection is taken into account. """ service = self.arguments.args.service for cat in self.arguments.selected_tools_categories: print self.output.printTitle0('Tools Category - {0}'.format(cat)) if not self.settings.toolbox.tools[service][cat]: self.output.printInfo('No tool to run in this category') continue if not self.arguments.args.auto_yes: self.output.printPrompt('Run tools in this category ? [Y/n]') if not CLIUtils.promptYesNo(self.output, default='Y'): self.output.printWarning('Category skipped.') continue output_dir = FileUtils.concat_path(self.arguments.args.output_dir, cat) if not FileUtils.create_directory(output_dir): self.output.printFail( 'Impossible to create output subdir "{0}"'.format(subdir)) sys.exit(0) self.output.printInfo( 'Output subdir "{0}" created'.format(output_dir)) for tool in self.settings.toolbox.tools[service][cat]: print self.output.printTitle1(' ' + tool.name) try: tool.runTool( self.settings, self.output, output_dir, self.arguments.target, self.arguments.specific, ignore_specific=self.arguments.args.ignore_specific, auto_yes=self.arguments.args.auto_yes) except KeyboardInterrupt, SystemExit: print self.output.printError('Tool execution aborted') print
def saveSettings(self, service_name): """ Save settings into config file. Make sure changes are thus taken into account. @Args service_name: service targeted by the tool @Returns Boolean indicating operation status """ try: config_file = FileUtils.concat_path(self.settings_dir, service_name + '.conf') with open(config_file, 'w') as handle: self.config_parsers[service_name].write(handle) # Re-read to take change into account self.config_parsers[service_name].read( config_file) # warning: takes filename as param return True except: traceback.print_exc() return False
def __parse_all_conf_files(self, files): """ Parse all *.conf files into the settings directory. Initialize ServicesConfig object with list of supported services :param files: List of files in settings directory :return: None """ list_services = list() for f in files: name = FileUtils.remove_ext(f).lower().strip() if name not in (INSTALL_STATUS_CONF_FILE, TOOLBOX_CONF_FILE): list_services.append(name) full_path = FileUtils.concat_path(SETTINGS_DIR, f) self.config_parsers[name] = DefaultConfigParser() self.config_parsers[name].read(full_path, 'utf8') # utf8 to avoid encoding issues list_services.append('multi') # Add support for special "multi" service self.services = ServicesConfig(list_services)
def saveSettings(self, conf_filename): """ Save settings into config file. Make sure changes are thus taken into account. @Args conf_filename: configuration filename (without extension) @Returns Boolean indicating operation status """ try: config_file = FileUtils.concat_path(self.settings_dir, conf_filename + CONF_EXT) with open(config_file, 'w') as handle: self.config_parsers[conf_filename].write(handle) # Re-read to take change into account self.config_parsers[conf_filename].read( config_file) # warning: takes filename as param return True except: traceback.print_exc() return False
def parseToolsConfFile(self, file): """ Parse a given settings file """ #self.output.printInfo('Parsing configuration file "{0}" ...'.format(file)) full_path = FileUtils.concat_path(self.settings_dir, file) conf_filename = FileUtils.remove_ext(file).lower().strip() self.config_parsers[conf_filename] = DefaultConfigParser() self.config_parsers[conf_filename].read(full_path) # Add the entry into general settings for the service self.general_settings[conf_filename] = {} if conf_filename == MULTI_SERVICES_CONF_FILE: self.general_settings[conf_filename]['tools_categories'] = ['all'] else: # General settings - [general] in .conf file tools_cats = self.config_parsers[conf_filename].safeGetList( 'general', 'tools_categories', ',', []) self.general_settings[conf_filename]['tools_categories'] = [ StringUtils.cleanSpecialChars(e).lower() for e in tools_cats ] # General settings - Optional/Specific settings (depends on the targeted service) if conf_filename in SPECIFIC_TOOL_OPTIONS.keys(): for option in SPECIFIC_TOOL_OPTIONS[conf_filename]: setting_name = SPECIFIC_TOOL_OPTIONS[conf_filename][option] if setting_name: self.general_settings[conf_filename][setting_name] = \ [ e.lower() for e in self.config_parsers[conf_filename].safeGetList('general', setting_name, ',', []) ] # Check general settings for the current service self.checkGeneralSettings(conf_filename) # Add service as new toolbox section self.toolbox.addService(conf_filename) # Add tools in current config file into the toolbox, under the correct service section for section in self.config_parsers[conf_filename].sections(): if section.startswith(PREFIX_TOOL_SECTIONNAME): if conf_filename != MULTI_SERVICES_CONF_FILE: newtool = self.createToolFromConfiguration( section, conf_filename, tooltype=ToolType.STANDARD) else: newtool = self.createToolFromConfiguration( section, conf_filename, tooltype=ToolType.MULTI_SERVICES) elif section.startswith(PREFIX_TOOL_USEMULTI_SECTIONNAME): newtool = self.createToolFromConfiguration( section, conf_filename, tooltype=ToolType.USE_MULTI) else: continue if newtool: if not self.toolbox.addTool(newtool, conf_filename): self.output.printWarning( 'Unable to add tool "{0}" into the toolbox'.format( newtool.name)) else: #self.output.printSettings('Tool "{0}" added into the toolbox (category "{1}")'.format(newtool.name, # newtool.category)) pass
def __init__(self, script_path, arguments, settings, output): self.script_path = script_path self.settings = settings self.arguments = arguments self.output = output # Toolbox management print if self.arguments.args.show_toolbox: service = self.arguments.args.show_toolbox self.output.printInfo( 'Selected mode: Show toolbox content for service {0}'.format( service)) self.settings.toolbox.printToolboxForService(self.output, service) sys.exit(0) if self.arguments.args.show_toolbox_brief: service = self.arguments.args.show_toolbox_brief self.output.printInfo( 'Selected mode: Show toolbox content (brief) for service {0}'. format(service)) self.settings.toolbox.printToolboxBriefForService( self.output, service) sys.exit(0) if self.arguments.args.install_toolbox: service = self.arguments.args.install_toolbox self.output.printInfo( 'Selected mode: Toolbox install for service {0}'.format( service)) self.settings.toolbox.installToolboxForService( self.output, service) sys.exit(0) if self.arguments.args.install_all: self.output.printInfo( 'Selected mode: Toolbox install for all services') self.settings.toolbox.installToolbox(self.output) sys.exit(0) if self.arguments.args.update_toolbox: service = self.arguments.args.update_toolbox self.output.printInfo( 'Selected mode: Toolbox update for service {0}'.format( service)) self.settings.toolbox.updateToolboxForService(self.output, service) sys.exit(0) if self.arguments.args.update_all: self.output.printInfo( 'Selected mode: Toolbox update for all services') self.settings.toolbox.updateToolbox(self.output) sys.exit(0) if self.arguments.args.uninstall_tool: tool_name = self.arguments.args.uninstall_tool self.output.printInfo( 'Selected mode: Uninstall tool named "{0}"'.format(tool_name)) self.settings.toolbox.removeTool(self.output, tool_name) sys.exit(0) if self.arguments.args.uninstall_toolbox: service = self.arguments.args.uninstall_toolbox self.output.printInfo( 'Selected mode: Uninstall toolbox for service {0}'.format( service)) self.settings.toolbox.removeToolboxForService(self.output, service) sys.exit(0) if self.arguments.args.uninstall_all: self.output.printInfo('Selected mode: Uninstall the whole toolbox') self.settings.toolbox.removeToolbox(self.output) sys.exit(0) if self.arguments.args.list_services: self.output.printInfo('Selected mode: List supported services') self.settings.toolbox.printListSupportedServices(self.output) sys.exit(0) if self.arguments.args.list_categories: service = self.arguments.args.list_categories self.output.printInfo( 'Selected mode: List tools categories for service {0}'.format( service)) self.settings.toolbox.printListCategories(self.output, service) sys.exit(0) if self.arguments.args.list_specific: service = self.arguments.args.list_specific self.output.printInfo( 'Selected mode: List context specific options for service {0}'. format(service)) SpecificOptions.listAvailableSpecificOptions( self.settings, service, self.output) sys.exit(0) service = self.arguments.args.service output.printInfo( 'Selected mode: Run tools againt target - Service {0}'.format( service)) print # Print target info output.printTitle0('Target Summary:') self.arguments.target.printSummary(output) begin = time.time() # Single tool mode if self.arguments.args.single_tool: tool = self.settings.toolbox.isInToolboxForService( self.arguments.args.single_tool, service) if not tool: sys.exit(0) output_file = FileUtils.absolute_path( FileUtils.concat_path(self.arguments.args.output_dir, tool.name + '.txt')) output_dir = FileUtils.absolute_path( FileUtils.concat_path(self.arguments.args.output_dir, tool.name)) print output.printTitle1(' ' + tool.name) try: tool.runTool(self.settings, output, output_file, output_dir, self.arguments.target, self.arguments.specific, False, False) except KeyboardInterrupt, SystemExit: print self.output.printError('Tool execution aborted') print
for cat in self.arguments.selected_tools_categories: print output.printTitle0('Tools Category - {0}'.format(cat)) if not self.settings.toolbox.tools[service][cat]: output.printInfo('No tool to run in this category') continue if not self.arguments.args.auto_yes: output.printPrompt('Run tools in this category ? [Y/n]') # Prompt to_run = CLIUtils.promptYesNo(output, default='Y') if not to_run: output.printWarning('Category skipped.') continue subdir = FileUtils.concat_path(self.arguments.args.output_dir, cat) if not FileUtils.create_directory(subdir): output.printFail( 'Impossible to create output subdir "{0}"'.format( subdir)) sys.exit(0) output.printInfo('Output subdir "{0}" created'.format(subdir)) for tool in self.settings.toolbox.tools[service][cat]: print output.printTitle1(' ' + tool.name) # Output for each tool is stored into a file output_file = FileUtils.absolute_path( FileUtils.concat_path(subdir, tool.name + '.txt')) # Some tools (e.g. skipfish) required an output dir too output_dir = FileUtils.absolute_path(
def getParsedCmdline(self, output_dir=None, output_filename=None, target=None, specific_args=None, remove_args=False): """ Return the parsed command line, i.e. with the tags replaced by their correct values according to the context @Args output_dir: Directory where outputs are saved (for RUN commands) output_filename: Filename for output (for RUN commands) target: Target object (for RUN commands) specific_args: Specific arguments (for RUN commands) remove_args: Boolean indicating if arguments from cmd must be deleted (for RUN commands) Used for check install commands @Returns Tuple (full parsed cmdline, shortened parsed cmdline) """ self.parsed_cmdline = self.cmdline if self.cmdtype == CommandType.RUN: if remove_args: self.parsed_cmdline = CmdUtils.removeArgsFromCmd( self.parsed_cmdline) else: if not output_dir or not output_filename or not target: raise ValueError('Missing required arguments') output_dir = FileUtils.absolute_path(output_dir) output_file = FileUtils.concat_path(output_dir, output_filename) output_subdir = FileUtils.concat_path( output_dir, FileUtils.remove_ext(output_filename)) self.replaceIP(target.ip) self.replaceURL(target.url) self.replaceHOST(target.host) self.replacePORT(target.port) self.replacePROTOCOL(target.protocol) self.replaceSERVICE(target.service) self.replaceOUTPUT(output_file) self.replaceOUTPUTDIR(output_subdir) self.replaceTOOLBOXDIR(self.toolbox_dir) self.replaceWORDLISTSDIR(Constants.WORDLISTS_DIR) self.replaceSpecificTags(target.service, specific_args) elif self.cmdtype in (CommandType.INSTALL, CommandType.UPDATE): self.replaceTOOLBOXDIR(self.toolbox_dir) else: raise ValueError('Invalid command type') # Shortened parsed command line: # - without "cd [...]" prefix # - without "2>&1 | tee [...]" suffix short_cmdline = self.parsed_cmdline endcmd_index = short_cmdline.rfind('2>&1 | tee') if endcmd_index > 0: short_cmdline = short_cmdline[:endcmd_index].strip() # Full parsed command line: self.parsed_cmdline = 'cd {0}; '.format( self.current_dir) + self.parsed_cmdline return self.parsed_cmdline, short_cmdline