Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- # PYTHON_ARGCOMPLETE_OK
- __license__="""
- GoLismero 2.0 - The web knife.
- Authors:
- Daniel Garcia Garcia a.k.a cr0hn | cr0hn<@>cr0hn.com
- Mario Vilas | mvilas<@>gmail.com
- Golismero project site: https://github.com/golismero
- Golismero project mail: golismero.project<@>gmail.com
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- """
- __all__ = []
- #------------------------------------------------------------------------------
- # Fix the module load path.
- import sys
- from os import path
- script = __file__
- if path.islink(script):
- script = path.realpath(script)
- here = path.split(path.abspath(script))[0]
- assert here
- thirdparty_libs = path.join(here, "thirdparty_libs")
- assert path.exists(thirdparty_libs)
- has_here = here in sys.path
- has_thirdparty_libs = thirdparty_libs in sys.path
- if not (has_here and has_thirdparty_libs):
- if has_here:
- sys.path.remove(here)
- if has_thirdparty_libs:
- sys.path.remove(thirdparty_libs)
- sys.path.insert(0, thirdparty_libs)
- sys.path.insert(0, here)
- #------------------------------------------------------------------------------
- # Python version check.
- # We must do it now before trying to import any more modules.
- #
- # Note: this is mostly because of argparse, if you install it
- # separately you can try removing this check and seeing
- # what happens (we haven't tested it!).
- from golismero import show_banner
- from sys import version_info, exit
- if __name__ == "__main__":
- if version_info < (2, 7) or version_info >= (3, 0):
- show_banner()
- print "[!] You must use Python version 2.7"
- exit(1)
- # In OS X, python versions lower than 2.7.6 fails
- import platform
- if (
- platform.system() == "Darwin" and
- (version_info < (2,7,6) or version_info >= (3,0))
- ):
- show_banner()
- print (
- "[!] OS X can experiment some problems with Python versions lower than 2.7.6. It's recommended to upgrade"
- " http://www.python.org/download/releases/2.7.6/"
- )
- #------------------------------------------------------------------------------
- # Imported modules
- import argparse
- import os
- from ConfigParser import RawConfigParser
- from getpass import getpass
- from glob import glob
- from os import getenv, getpid
- from thread import get_ident
- #------------------------------------------------------------------------------
- # GoLismero modules
- from golismero.api.config import Config
- from golismero.api.external import run_external_tool
- from golismero.api.logger import Logger
- from golismero.api.plugin import CATEGORIES, STAGES
- from golismero.common import OrchestratorConfig, AuditConfig, get_profile, \
- get_available_profiles, get_default_plugins_folder
- from golismero.main import launcher
- from golismero.main.console import get_terminal_size, colorize, Console
- from golismero.main.testing import PluginTester
- from golismero.managers.pluginmanager import PluginManager
- from golismero.managers.processmanager import PluginContext
- #------------------------------------------------------------------------------
- # Custom argparse actions
- class ArgumentParserWithBanner(argparse.ArgumentParser):
- must_show_banner = True
- def error(self, message):
- if self.must_show_banner:
- self.must_show_banner = False
- show_banner()
- self.usage = None
- message += "\n\nUse -h to see the quick help, or --help to show the full help text."
- return super(ArgumentParserWithBanner, self).error(message)
- # --enable-plugin
- class EnablePluginAction(argparse.Action):
- def __call__(self, parser, namespace, values, option_string=None):
- parsed = [ (True, x.strip()) for x in values.split(",")]
- overrides = getattr(namespace, self.dest, [])
- overrides.extend(parsed)
- setattr(namespace, self.dest, overrides)
- # --disable-plugin
- class DisablePluginAction(argparse.Action):
- def __call__(self, parser, namespace, values, option_string=None):
- parsed = [ (False, x.strip()) for x in values.split(",")]
- overrides = getattr(namespace, self.dest, [])
- overrides.extend(parsed)
- setattr(namespace, self.dest, overrides)
- # --file
- class LoadListFromFileAction(argparse.Action):
- def __call__(self, parser, namespace, values, option_string=None):
- try:
- with open(values, "rU") as f:
- tokens = []
- for line in f:
- line = line.strip()
- if not line or line[0] == "#":
- continue
- tokens.append(tokens)
- except Exception:
- parser.error("Error reading file: %s" % values)
- setattr(namespace, self.dest, tokens)
- # --cookie-file
- class ReadValueFromFileAction(argparse.Action):
- def __call__(self, parser, namespace, values, option_string=None):
- try:
- with open(values, "rU") as f:
- data = f.read()
- except IOError, e:
- parser.error("Can't read file %r. Error: %s" % (values, str(e)))
- setattr(namespace, self.dest, data)
- # --plugin-arg
- class SetPluginArgumentAction(argparse.Action):
- def __call__(self, parser, namespace, values, option_string=None):
- d = getattr(namespace, self.dest, None)
- if d is None:
- d = []
- setattr(namespace, self.dest, d)
- try:
- plugin_id, token = values.split(":", 1)
- plugin_id = plugin_id.strip()
- key, value = token.split("=", 1)
- key = key.strip()
- value = value.strip()
- assert plugin_id
- assert key
- d.append( (plugin_id, key, value) )
- except Exception:
- parser.error("invalid plugin argument: %s" % values)
- # -h
- class QuickHelpAction(argparse._HelpAction):
- def __call__(self, parser, namespace, values, option_string=None):
- if parser.must_show_banner:
- parser.must_show_banner = False
- show_banner()
- parser._print_message(parser.quick_help)
- parser.exit()
- #------------------------------------------------------------------------------
- # Command line parser using argparse.
- COMMANDS = (
- # Scanning.
- "SCAN",
- "REPORT",
- "IMPORT",
- # Information.
- "PROFILES",
- "PLUGINS",
- "INFO",
- # Management.
- "DUMP",
- "UPDATE",
- )
- def cmdline_parser():
- # Fix the console width bug in argparse.
- try:
- os.environ["COLUMNS"] = str(get_terminal_size()[0])
- except Exception:
- pass
- # Use Bash autocompletion when available.
- try:
- from argcomplete import autocomplete
- from argcomplete.completers import ChoicesCompleter, FilesCompleter
- autocomplete_enabled = True
- except ImportError:
- autocomplete_enabled = False
- if autocomplete_enabled:
- def profiles_completer(prefix, **kwargs):
- return [
- v for v in get_available_profiles()
- if v.startswith(prefix)
- ]
- def plugins_completer(prefix, **kwargs):
- if ":" in prefix:
- return [prefix,]
- names = []
- base = get_default_plugins_folder()
- for cat in CATEGORIES:
- for (_, _, filenames) in os.walk(path.join(base, cat)):
- for filename in filenames:
- if filename.startswith(prefix):
- name, ext = path.splitext(filename)
- if ext.lower() == ".golismero":
- names.append(name)
- return names
- parser = ArgumentParserWithBanner(fromfile_prefix_chars="@", add_help=False)
- cmd = parser.add_argument("command", metavar="COMMAND", help="action to perform")
- if autocomplete_enabled:
- cmd.completer = ChoicesCompleter(COMMANDS + tuple(x.lower() for x in COMMANDS))
- parser.add_argument("targets", metavar="TARGET", nargs="*", help="zero or more arguments, meaning depends on command")
- parser.add_argument("-h", action=QuickHelpAction, default=argparse.SUPPRESS, help="show this help message and exit")
- parser.add_argument("--help", action='help', default=argparse.SUPPRESS, help="show this help message and exit")
- gr_main = parser.add_argument_group("main options")
- cmd = gr_main.add_argument("-f", "--file", metavar="FILE", action=LoadListFromFileAction, help="load a list of targets from a plain text file")
- if autocomplete_enabled:
- cmd.completer = FilesCompleter(directories=False)
- cmd = gr_main.add_argument("--config", metavar="FILE", help="global configuration file")
- if autocomplete_enabled:
- cmd.completer = FilesCompleter(allowednames=(".conf",), directories=False)
- cmd = gr_main.add_argument("--user-config", metavar="FILE", help="per-user configuration file")
- if autocomplete_enabled:
- cmd.completer = FilesCompleter(allowednames=(".conf",), directories=False)
- cmd = gr_main.add_argument("-p", "--profile", metavar="NAME", help="profile to use")
- if autocomplete_enabled:
- cmd.completer = profiles_completer
- cmd = gr_main.add_argument("--ui-mode", metavar="MODE", help="UI mode")
- if autocomplete_enabled:
- cmd.completer = ChoicesCompleter(("console", "disabled")) ##, "web"))
- gr_main.add_argument("-v", "--verbose", action="count", help="increase output verbosity")
- gr_main.add_argument("-q", "--quiet", action="store_const", dest="verbose", const=0, help="suppress text output")
- gr_main.add_argument("--color", action="store_true", default=None, dest="color", help="use colors in console output")
- gr_main.add_argument("--no-color", action="store_false", default=None, dest="color", help="suppress colors in console output")
- gr_audit = parser.add_argument_group("audit options")
- gr_audit.add_argument("--audit-name", metavar="NAME", help="customize the audit name")
- cmd = gr_audit.add_argument("-db", "--audit-db", metavar="DATABASE", dest="audit_db", help="specify a database filename")
- if autocomplete_enabled:
- cmd.completer = FilesCompleter(allowednames=(".db",), directories=False)
- gr_audit.add_argument("-nd", "--no-db", dest="audit_db", action="store_const", const=":memory:", help="do not store the results in a database")
- cmd = gr_audit.add_argument("-i", "--input", dest="imports", metavar="FILENAME", action="append", help="read results from external tools right before the audit")
- if autocomplete_enabled:
- cmd.completer = FilesCompleter(allowednames=(".csv", ".xml", ".nessus"), directories=False)
- gr_audit.add_argument("-ni", "--no-input", dest="disable_importing", action="store_true", default=False, help="do not read results from external tools")
- gr_report = parser.add_argument_group("report options")
- cmd = gr_report.add_argument("-o", "--output", dest="reports", metavar="FILENAME", action="append", help="write the results of the audit to this file (use - for stdout)")
- if autocomplete_enabled:
- cmd.completer = FilesCompleter(allowednames=(".html", ".rst", ".txt"), directories=False)
- gr_report.add_argument("-no", "--no-output", dest="disable_reporting", action="store_true", default=False, help="do not output the results")
- gr_report.add_argument("--full", action="store_false", default=None, dest="only_vulns", help="produce fully detailed reports")
- gr_report.add_argument("--brief", action="store_true", dest="only_vulns", help="report only the highlights")
- gr_net = parser.add_argument_group("network options")
- gr_net.add_argument("--allow-subdomains", action="store_true", default=None, dest="include_subdomains", help="include subdomains in the target scope")
- gr_net.add_argument("--forbid-subdomains", action="store_false", default=None, dest="include_subdomains", help="do not include subdomains in the target scope")
- gr_net.add_argument("--parent", action="store_true", default=None, dest="allow_parent", help="include parent folders in the target scope")
- gr_net.add_argument("-np", "--no-parent", action="store_false", default=None, dest="allow_parent", help="do not include parent folders in the target scope")
- cmd = gr_net.add_argument("-r", "--depth", help="maximum spidering depth (use \"infinite\" for no limit)")
- if autocomplete_enabled:
- cmd.completer = ChoicesCompleter(("1", "200", "infinite",))
- gr_net.add_argument("--follow-redirects", action="store_true", default=None, dest="follow_redirects", help="follow redirects")
- gr_net.add_argument("--no-follow-redirects", action="store_false", default=None, dest="follow_redirects", help="do not follow redirects")
- gr_net.add_argument("--follow-first", action="store_true", default=None, dest="follow_first_redirect", help="always follow a redirection on the target URL itself")
- gr_net.add_argument("--no-follow-first", action="store_false", default=None, dest="follow_first_redirect", help="don't treat a redirection on a target URL as a special case")
- gr_net.add_argument("--max-connections", help="maximum number of concurrent connections per host")
- gr_net.add_argument("-l", "--max-links", type=int, default=None, help="maximum number of links to analyze (0 => infinite)")
- gr_net.add_argument("-pu","--proxy-user", metavar="USER", help="HTTP proxy username")
- gr_net.add_argument("-pp","--proxy-pass", metavar="PASS", help="HTTP proxy password")
- gr_net.add_argument("-pa","--proxy-addr", metavar="ADDRESS", help="HTTP proxy address")
- gr_net.add_argument("-pn","--proxy-port", metavar="PORT", help="HTTP proxy port number")
- gr_net.add_argument("--cookie", metavar="COOKIE", help="set cookie for requests")
- gr_net.add_argument("--user-agent", metavar="USER_AGENT", help="set a custom user agent or 'random' value")
- cmd = gr_net.add_argument("--cookie-file", metavar="FILE", action=ReadValueFromFileAction, dest="cookie", help="load a cookie from file")
- if autocomplete_enabled:
- cmd.completer = FilesCompleter(directories=False)
- gr_net.add_argument("--persistent-cache", action="store_true", dest="use_cache_db", default=True, help="use a persistent network cache [default]")
- gr_net.add_argument("--volatile-cache", action="store_false", dest="use_cache_db", help="use a volatile network cache")
- gr_plugins = parser.add_argument_group("plugin options")
- cmd = gr_plugins.add_argument("-a", "--plugin-arg", metavar="PLUGIN:KEY=VALUE", action=SetPluginArgumentAction, dest="raw_plugin_args", help="pass an argument to a plugin")
- if autocomplete_enabled:
- cmd.completer = plugins_completer
- cmd = gr_plugins.add_argument("-e", "--enable-plugin", metavar="PLUGIN", action=EnablePluginAction, default=[], dest="plugin_load_overrides", help="enable a plugin")
- if autocomplete_enabled:
- cmd.completer = plugins_completer
- cmd = gr_plugins.add_argument("-d", "--disable-plugin", metavar="PLUGIN", action=DisablePluginAction, dest="plugin_load_overrides", help="disable a plugin")
- if autocomplete_enabled:
- cmd.completer = plugins_completer
- gr_plugins.add_argument("--max-concurrent", metavar="N", type=int, default=None, help="maximum number of plugins to run concurrently")
- gr_plugins.add_argument("--plugin-timeout", metavar="N", type=float, default=None, help="timeout in seconds for the execution of a plugin")
- cmd = gr_plugins.add_argument("--plugins-folder", metavar="PATH", help="customize the location of the plugins" )
- if autocomplete_enabled:
- cmd.completer = FilesCompleter(directories=True)
- if autocomplete_enabled:
- autocomplete(parser)
- quick_help = (
- ################################################################################
- "\n"
- " SCAN:\n"
- " Perform a vulnerability scan on the given targets. Optionally import\n"
- " results from other tools and write a report. The arguments that follow may\n"
- " be domain names, IP addresses or web pages.\n"
- "\n"
- " PROFILES:\n"
- " Show a list of available config profiles. This command takes no arguments.\n"
- "\n"
- " PLUGINS:\n"
- " Show a list of available plugins. This command takes no arguments.\n"
- "\n"
- " INFO:\n"
- " Show detailed information on a given plugin. The arguments that follow are\n"
- " the plugin IDs. You can use glob-style wildcards.\n"
- "\n"
- " REPORT:\n"
- " Write a report from an earlier scan. This command takes no arguments.\n"
- " To specify output files use the -o switch.\n"
- "\n"
- " IMPORT:\n"
- " Import results from other tools and optionally write a report, but don't\n"
- " scan the targets. This command takes no arguments. To specify input files\n"
- " use the -i switch.\n"
- "\n"
- " DUMP:\n"
- " Dump the database from an earlier scan in SQL format. This command takes no\n"
- " arguments. To specify output files use the -o switch.\n"
- "\n"
- " UPDATE:\n"
- " Update GoLismero to the latest version. Requires Git to be installed and\n"
- " available in the PATH. This command takes no arguments.\n"
- "\n"
- "examples:\n"
- "\n"
- " scan a website and show the results on screen:\n"
- " %(prog)s scan http://www.example.com\n"
- "\n"
- " grab Nmap results, scan all hosts found and write an HTML report:\n"
- " %(prog)s scan -i nmap_output.xml -o report.html\n"
- "\n"
- " grab results from OpenVAS and show them on screen, but don't scan anything:\n"
- " %(prog)s import -i openvas_output.xml\n"
- "\n"
- " show a list of all available configuration profiles:\n"
- " %(prog)s profiles\n"
- "\n"
- " show a list of all available plugins:\n"
- " %(prog)s plugins\n"
- "\n"
- " show information on all bruteforcer plugins:\n"
- " %(prog)s info brute_*\n"
- "\n"
- " dump the database from a previous scan:\n"
- " %(prog)s dump -db example.db -o dump.sql\n"
- "\n"
- ################################################################################
- )
- parser.usage = parser.format_usage()[7:] + \
- "\navailable commands:\n" + quick_help
- parser.quick_help = (
- "usage: %(prog)s COMMAND [TARGETS...] [--options]\n" \
- + quick_help) % {"prog": parser.prog}
- return parser
- #------------------------------------------------------------------------------
- def parse_plugin_args(manager, plugin_args):
- """
- Parse a list of tuples with plugin arguments as a dictionary of
- dictionaries, with plugin IDs sanitized.
- :param manager: Plugin manager.
- :type manager: PluginManager
- :param plugin_args: Arguments as specified in the command line.
- :type plugin_args: list(tuple(str, str, str))
- :returns: Sanitized plugin arguments. Dictionary mapping plugin
- names to dictionaries mapping argument names and values.
- :rtype: dict(str -> dict(str -> str))
- :raises KeyError: Plugin or argument not found.
- """
- parsed = {}
- for plugin_id, key, value in plugin_args:
- plugin_info = manager.guess_plugin_by_id(plugin_id)
- if not plugin_info:
- raise KeyError("Plugin not found: %s" % plugin_id)
- key = key.lower()
- if key not in plugin_info.plugin_args:
- raise KeyError(
- "Argument not found: %s:%s" % (plugin_id, key))
- try:
- target = parsed[plugin_info.plugin_id]
- except KeyError:
- parsed[plugin_info.plugin_id] = target = {}
- target[key] = value
- return parsed
- #------------------------------------------------------------------------------
- def build_config_from_cmdline():
- # Get the command line parser.
- parser = cmdline_parser()
- # Parse the command line options.
- try:
- args = sys.argv[1:]
- envcfg = getenv("GOLISMERO_SETTINGS")
- if envcfg:
- args = parser.convert_arg_line_to_args(envcfg) + args
- P, V = parser.parse_known_args(args)
- if P.targets:
- P.targets += V
- else:
- P.targets = V
- P.plugin_args = {}
- command = P.command.upper()
- if command in COMMANDS:
- P.command = command
- else:
- P.targets.insert(0, P.command)
- P.command = "SCAN"
- # Load the Orchestrator options.
- cmdParams = OrchestratorConfig()
- cmdParams.command = P.command
- if P.config:
- cmdParams.config_file = path.abspath(P.config)
- if not path.isfile(cmdParams.config_file):
- raise ValueError("File not found: %s" % cmdParams.config_file)
- if cmdParams.config_file:
- cmdParams.from_config_file(cmdParams.config_file,
- allow_profile = True)
- if P.user_config:
- cmdParams.user_config_file = path.abspath(P.user_config)
- if not path.isfile(cmdParams.user_config_file):
- raise ValueError(
- "File not found: %s" % cmdParams.user_config_file)
- if cmdParams.user_config_file:
- cmdParams.from_config_file(cmdParams.user_config_file,
- allow_profile = True)
- if P.profile:
- cmdParams.profile = P.profile
- cmdParams.profile_file = get_profile(cmdParams.profile)
- if cmdParams.profile_file:
- cmdParams.from_config_file(cmdParams.profile_file)
- cmdParams.from_object(P)
- cmdParams.plugin_load_overrides = P.plugin_load_overrides
- # Enable console colors if requested.
- Console.use_colors = cmdParams.color
- # Show the program banner.
- parser.must_show_banner = False
- if cmdParams.verbose:
- show_banner()
- # Load the target audit options.
- auditParams = AuditConfig()
- auditParams.profile = cmdParams.profile
- auditParams.profile_file = cmdParams.profile_file
- auditParams.config_file = cmdParams.config_file
- auditParams.user_config_file = cmdParams.user_config_file
- if auditParams.config_file:
- auditParams.from_config_file(auditParams.config_file)
- if auditParams.user_config_file:
- auditParams.from_config_file(auditParams.user_config_file)
- if auditParams.profile_file:
- auditParams.from_config_file(auditParams.profile_file)
- auditParams.from_object(P)
- auditParams.plugin_load_overrides = P.plugin_load_overrides
- # If importing is turned off, remove the list of imports.
- # FIXME this should be done by argparse in argument order!
- if P.disable_importing:
- auditParams.imports = []
- # If reports are turned off, remove the list of reports.
- # Otherwise, if no reports are specified, default to screen report.
- # FIXME this should be done by argparse in argument order!
- if P.disable_reporting:
- auditParams.reports = []
- elif (
- not auditParams.reports and
- (P.command != "REPORT" or not auditParams.targets)
- ):
- auditParams.reports = ["-"]
- if auditParams.only_vulns is None:
- auditParams.only_vulns = True
- # Show exceptions as command line parsing errors.
- except Exception, e:
- ##raise # XXX DEBUG
- parser.error("arguments error: %s" % str(e))
- # Get the plugins folder from the parameters.
- # If no plugins folder is given, use the default.
- plugins_folder = cmdParams.plugins_folder
- if not plugins_folder:
- plugins_folder = path.abspath(script)
- plugins_folder = path.dirname(plugins_folder)
- plugins_folder = path.join(plugins_folder, "plugins")
- if not path.isdir(plugins_folder):
- from golismero import common
- plugins_folder = path.abspath(common.__file__)
- plugins_folder = path.dirname(plugins_folder)
- plugins_folder = path.join(plugins_folder, "plugins")
- if not path.isdir(plugins_folder):
- parser.error("Default plugins folder not found, aborting!")
- cmdParams.plugins_folder = plugins_folder
- # Return the parser, options, and config objects.
- return parser, P, cmdParams, auditParams
- #------------------------------------------------------------------------------
- # Start of program.
- def main():
- # Command implementations.
- command = {
- "PLUGINS": command_plugins, # List plugins and quit.
- "INFO": command_info, # Display plugin info and quit.
- "PROFILES": command_profiles, # List profiles and quit.
- "DUMP": command_dump, # Dump the database and quit.
- "UPDATE": command_update, # Update GoLismero and quit.
- }
- # Parse the command line.
- parser, P, cmdParams, auditParams = build_config_from_cmdline()
- # Get the command implementation.
- implementation = command.get(P.command, command_run)
- # Run the command.
- implementation(parser, P, cmdParams, auditParams)
- #------------------------------------------------------------------------------
- def command_plugins(parser, P, cmdParams, auditParams):
- # Fail if we have arguments.
- if P.targets:
- parser.error("too many arguments")
- # Load the plugins list.
- try:
- manager = PluginManager()
- manager.find_plugins(cmdParams)
- except Exception, e:
- parser.error("error loading plugins list: %s" % str(e))
- # Show the list of plugins.
- print colorize("-------------", "red")
- print colorize(" Plugin list", "red")
- print colorize("-------------", "red")
- # Import plugins...
- import_plugins = manager.get_plugins("import")
- if import_plugins:
- print
- print colorize("-= Import plugins =-", "yellow")
- for name in sorted(import_plugins.keys()):
- info = import_plugins[name]
- print "\n%s:\n %s" % \
- (colorize(name[7:], "cyan"), info.description)
- # Testing plugins...
- testing_plugins = manager.get_plugins("testing")
- if testing_plugins:
- names = sorted(testing_plugins.keys())
- names = [x[8:] for x in names]
- stages = [ (v,k) for (k,v) in STAGES.iteritems() ]
- stages.sort()
- for _, stage in stages:
- s = stage + "/"
- p = len(s)
- s_slice = [x[p:] for x in names if x.startswith(s)]
- if s_slice:
- print
- print colorize("-= %s plugins =-" % stage.title(), "yellow")
- for name in s_slice:
- info = testing_plugins["testing/%s/%s" % (stage, name)]
- desc = info.description.strip()
- desc = desc.replace("\n", "\n ")
- print "\n%s:\n %s" % (colorize(name, "cyan"), desc)
- # Report plugins...
- report_plugins = manager.get_plugins("report")
- if report_plugins:
- print
- print colorize("-= Report plugins =-", "yellow")
- for name in sorted(report_plugins.keys()):
- info = report_plugins[name]
- desc = info.description.strip()
- desc = desc.replace("\n", "\n ")
- print "\n%s:\n %s" % (colorize(name[7:], "cyan"), desc)
- # UI plugins...
- ui_plugins = manager.get_plugins("ui")
- if ui_plugins:
- print
- print colorize("-= UI plugins =-", "yellow")
- for name in sorted(ui_plugins.keys()):
- info = ui_plugins[name]
- desc = info.description.strip()
- desc = desc.replace("\n", "\n ")
- print "\n%s:\n %s" % (colorize(name[3:], "cyan"), desc)
- if path.sep == "/":
- print
- exit(0)
- #------------------------------------------------------------------------------
- def command_info(parser, P, cmdParams, auditParams):
- # Fail if we don't have arguments.
- if not P.targets:
- parser.error("too few arguments")
- # Load the plugins list.
- try:
- manager = PluginManager()
- manager.find_plugins(cmdParams)
- except Exception, e:
- parser.error("error loading plugins list: %s" % str(e))
- # Show the plugin information.
- try:
- to_print = []
- plugin_infos = []
- for plugin_id in P.targets:
- m_found = manager.search_plugins_by_mask(plugin_id)
- plugin_infos.extend( m_found.values() )
- if not plugin_infos:
- raise KeyError()
- for info in plugin_infos:
- Config._context = PluginContext( orchestrator_pid = getpid(),
- orchestrator_tid = get_ident(),
- plugin_info = info,
- msg_queue = None )
- try:
- manager.load_plugin_by_id(info.plugin_id)
- except Exception:
- pass
- m_root = cmdParams.plugins_folder
- m_root = path.abspath(m_root)
- if not m_root.endswith(path.sep):
- m_root += path.sep
- m_location = info.descriptor_file[len(m_root):]
- a, b = path.split(m_location)
- b = colorize(b, "cyan")
- m_location = path.join(a, b)
- m_src = info.plugin_module[len(m_root):]
- a, b = path.split(m_src)
- b = colorize(b, "cyan")
- m_src = path.join(a, b)
- m_name = info.plugin_id
- p = m_name.rfind("/") + 1
- m_name = m_name[:p] + colorize(m_name[p:], "cyan")
- m_desc = info.description.strip()
- m_desc = m_desc.replace("\n", "\n ")
- to_print.append("")
- to_print.append("Information for plugin: %s" %
- colorize(info.display_name, "yellow"))
- to_print.append("-" * len("Information for plugin: %s" %
- info.display_name))
- to_print.append("%s %s" %
- (colorize("ID:", "green"), m_name))
- to_print.append("%s %s" %
- (colorize("Location:", "green"), m_location))
- to_print.append("%s %s" %
- (colorize("Source code:", "green"), m_src))
- if info.plugin_class:
- to_print.append("%s %s" %
- (colorize("Class name:", "green"),
- colorize(info.plugin_class, "cyan")))
- to_print.append("%s %s" %
- (colorize("Category:", "green"), info.category))
- to_print.append("%s %s" %
- (colorize("Stage:", "green"), info.stage))
- if info.description != info.display_name:
- to_print.append("")
- to_print.append("%s\n %s" %
- (colorize("Description:", "green"), m_desc))
- if info.plugin_args:
- to_print.append("")
- to_print.append(colorize("Arguments:", "green"))
- for name, default in sorted(info.plugin_args.iteritems()):
- if name in info.plugin_passwd_args:
- default = "****************"
- to_print.append("\t%s -> %s" %
- (colorize(name, "cyan"), default))
- to_print.append("")
- except KeyError:
- ##raise # XXX DEBUG
- parser.error("plugin ID not found")
- except ValueError:
- ##raise # XXX DEBUG
- parser.error("plugin ID not found")
- except Exception, e:
- ##raise # XXX DEBUG
- parser.error("error recovering plugin info: %s" % str(e))
- for line in to_print:
- print line
- exit(0)
- #------------------------------------------------------------------------------
- def command_profiles(parser, P, cmdParams, auditParams):
- if P.targets:
- parser.error("too many arguments")
- profiles = sorted(get_available_profiles())
- if not profiles:
- print "No available profiles!"
- else:
- print "--------------------"
- print " " + colorize("Available profiles", "yellow")
- print "--------------------"
- print
- for name in profiles:
- try:
- p = RawConfigParser()
- p.read(get_profile(name))
- desc = p.get("golismero", "description")
- except Exception:
- desc = None
- if desc:
- print "+ %s: %s" % (colorize(name, "cyan"), desc)
- else:
- print "+ %s" % colorize(name, "cyan")
- if path.sep == "/":
- print
- exit(0)
- #------------------------------------------------------------------------------
- def command_dump(parser, P, cmdParams, auditParams):
- if auditParams.is_new_audit():
- parser.error("missing audit database")
- if not P.reports:
- parser.error("missing output filename")
- if P.verbose != 0:
- print "Loading database: %s" % \
- colorize(auditParams.audit_db, "yellow")
- with PluginTester(autoinit=False, autodelete=False) as t:
- t.orchestrator_config.verbose = 0
- t.audit_config.audit_name = auditParams.audit_name
- t.audit_config.audit_db = auditParams.audit_db
- t.init_environment()
- Console.use_colors = cmdParams.color
- for filename in P.reports:
- if P.verbose != 0:
- print "Dumping to file: %s" % colorize(filename, "cyan")
- t.audit.database.dump(filename)
- exit(0)
- #------------------------------------------------------------------------------
- def command_update(parser, P, cmdParams, auditParams):
- # Fail if we got any arguments.
- if P.targets:
- parser.error("too many arguments")
- # Setup a dummy environment so we can call the API.
- with PluginTester(autoinit=False) as t:
- t.orchestrator_config.ui_mode = "console"
- t.orchestrator_config.verbose = cmdParams.verbose
- t.orchestrator_config.color = cmdParams.color
- t.init_environment(mock_audit=False)
- # Run Git here to download the latest version.
- if cmdParams.verbose:
- Logger.log("Updating GoLismero...")
- run_external_tool("git", ["pull"], cwd = here,
- callback = Logger.log if cmdParams.verbose else lambda x: x)
- # Update the TLD names.
- if cmdParams.verbose:
- Logger.log("Updating list of TLD names...")
- import tldextract
- tldextract.TLDExtract().update(True)
- # Done!
- if cmdParams.verbose:
- Logger.log("Update complete.")
- exit(0)
- #------------------------------------------------------------------------------
- def command_run(parser, P, cmdParams, auditParams):
- # For the SCAN command, assume targets are URLs whenever feasible.
- if P.command == "SCAN":
- guessed_urls = []
- for target in auditParams.targets:
- if not "://" in target:
- guessed_urls.append("http://" + target)
- auditParams.targets.extend(guessed_urls)
- # For all other commands, disable the testing plugins.
- else:
- auditParams.plugin_load_overrides.append( (False, "testing") )
- # For the IMPORT command, targets are import files.
- if P.command == "IMPORT":
- auditParams.imports = auditParams.targets # magic
- del auditParams.targets # magic
- # For the REPORT command, targets are report files.
- elif P.command == "REPORT":
- auditParams.reports = auditParams.targets # magic
- del auditParams.targets # magic
- # If we reached this point, we have an internal error!
- else:
- raise RuntimeError("Unsupported command: %s" % P.command)
- # Expand wildcards for filenames on Windows.
- # On other platforms this is not needed,
- # as the shell already does it for us.
- if os.path.sep == "\\":
- auditParams._imports = expand_wildcards(auditParams._imports)
- auditParams._reports = expand_wildcards(auditParams._reports)
- try:
- # Load the plugins.
- manager = PluginManager()
- manager.find_plugins(cmdParams)
- # Sanitize the plugin arguments.
- try:
- if P.raw_plugin_args:
- P.plugin_args = parse_plugin_args(manager, P.raw_plugin_args)
- except KeyError, e:
- ##raise # XXX DEBUG
- parser.error("error parsing plugin arguments: %s" % str(e))
- # Prompt for passwords.
- for plugin_id in P.plugin_args.keys():
- plugin_info = manager.get_plugin_by_id(plugin_id)
- target_args = P.plugin_args[plugin_id]
- for key, value in target_args.items():
- if not value and key in plugin_info.plugin_passwd_args:
- if len(plugin_info.plugin_passwd_args) > 1:
- msg = "Enter password for %s (%s): "
- msg %= (plugin_info.display_name, key)
- else:
- msg = "Enter password for %s: "
- msg %= plugin_info.display_name
- target_args[key] = getpass(msg)
- # Save the plugin arguments for the Orchestrator and the Audit.
- cmdParams.plugin_args = P.plugin_args
- auditParams.plugin_args = P.plugin_args
- # Check the parameters.
- cmdParams.check_params()
- auditParams.check_params()
- # Set the plugin arguments before loading the UI plugin.
- for plugin_id, plugin_args in cmdParams.plugin_args.iteritems():
- status = manager.set_plugin_args(plugin_id, plugin_args)
- if status != 0: # should never happen, but just in case...
- if status == 1:
- msg = "Unknown plugin: %s"
- elif status == 2:
- msg = "Invalid arguments for plugin: %s"
- else:
- msg = "Error setting arguments for plugin: %s"
- parser.error(msg % plugin_id)
- # Load the UI plugin.
- ui_plugin_id = "ui/" + cmdParams.ui_mode
- ui_plugin = manager.load_plugin_by_id(ui_plugin_id)
- # Show an error message if something goes wrong.
- except Exception, e:
- ##raise # XXX DEBUG
- parser.error("error loading plugins: %s" % str(e))
- # Check the settings with the UI plugin.
- try:
- ui_plugin.check_params(cmdParams, auditParams)
- except Exception, e:
- ##raise # XXX DEBUG
- msg = str(e)
- if not msg:
- msg = "configuration error!"
- parser.error(msg)
- # Launch GoLismero.
- launcher.run(cmdParams, auditParams)
- exit(0)
- #------------------------------------------------------------------------------
- def expand_wildcards(filenames):
- expanded = []
- for filename in filenames:
- if "*" in filename or "?" in filename:
- expanded.extend(glob(filename))
- else:
- expanded.append(filename)
- return expanded
- #------------------------------------------------------------------------------
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement