コード例 #1
0
def main():
    my_envs = os.environ
    # If the script is run outside the dispatcher
    # the environment variables
    # are checked.

    tool = os.environ.get("EXECUTOR_CONFIG_TOOL", None)

    if "EXECUTOR_CONFIG_REPORT_NAME" in my_envs:
        report_name = os.environ.get("EXECUTOR_CONFIG_REPORT_NAME")
    else:
        print("Argument REPORT_NAME no set", file=sys.stderr)
        sys.exit()

    if "REPORTS_PATH" in my_envs:
        report_dir = os.environ.get("REPORTS_PATH")
    else:
        print("Environment variable REPORT_DIR no set", file=sys.stderr)
        sys.exit()

    filepath = Path(report_dir) / report_name
    manager = PluginsManager()

    if tool is not None:
        plugin = manager.get_plugin(tool)
    else:
        plugin = ReportAnalyzer(manager).get_plugin(filepath)
        print(f"Detector found it as an {plugin} report", file=sys.stderr)

    print(f"Parsing {filepath} report", file=sys.stderr)
    plugin.processReport(str(filepath))
    print(plugin.get_json())
コード例 #2
0
def main():
    # If the script is run outside the dispatcher the environment variables
    # are checked.
    # ['EXECUTOR_CONFIG_API_KEY', 'EXECUTOR_CONFIG_TARGET_URL']
    try:
        target = os.environ["EXECUTOR_CONFIG_TARGET_URL"]
        api_key = os.environ["EXECUTOR_CONFIG_API_KEY"]
    except KeyError:
        print("environment variable not found", file=sys.stderr)
        sys.exit()

    # zap is required to be started
    zap_run = subprocess.check_output("pgrep -f zap", shell=True)

    if len(zap_run.decode("utf-8").split("\n")) > 3:
        # the apikey from ZAP->Tools->Options-API
        zap = ZAPv2(apikey=api_key)
        # it passes the url to scan and starts
        scanID = zap.spider.scan(target)
        # Wait for the scan to finish
        while int(zap.spider.status(scanID)) < 100:
            time.sleep(1)
        # If finish the scan and the xml is generated
        zap_result = zap.core.xmlreport()
        plugin = PluginsManager().get_plugin("zap")
        plugin.parseOutputString(zap_result)
        print(plugin.get_json())

    else:
        print("ZAP not running", file=sys.stderr)
        sys.exit()
コード例 #3
0
ファイル: commands.py プロジェクト: infobyte/faraday_plugins
def list_plugins(custom_plugins_folder):
    plugins_manager = PluginsManager(custom_plugins_folder)
    click.echo(click.style(f"Faraday Plugins v{__version__}", fg="cyan"))
    click.echo(click.style("Available Plugins :", fg="cyan"))
    loaded_plugins = 0
    plugins_data = []
    for plugin_id, plugin in plugins_manager.get_plugins():
        console_enabled = plugin._command_regex is not None
        console_enabled_color = "green" if console_enabled else "red"
        console_enabled_text = click.style(
            f"{'Yes' if console_enabled else 'No'}", fg=console_enabled_color)
        report_enabled = isinstance(plugin, PluginByExtension)
        report_enabled_color = "green" if report_enabled else "red"
        report_enabled_text = click.style(
            f"{'Yes' if report_enabled else 'No'}", fg=report_enabled_color)
        plugins_data.append({
            "Name": plugin.name,
            "ID": plugin.id,
            "Command": console_enabled_text,
            "Report": report_enabled_text
        })
    click.echo(tabulate(
        plugins_data,
        headers="keys",
        tablefmt="simple",
    ))
    click.echo(click.style(f"Loaded Plugins: {len(plugins_data)}", fg="cyan"))
コード例 #4
0
ファイル: commands.py プロジェクト: infobyte/faraday_plugins
def process_report(report_file, plugin_id, custom_plugins_folder, summary,
                   output_file, ignore_info):
    if not os.path.isfile(report_file):
        click.echo(click.style(f"File {report_file} Don't Exists", fg="red"),
                   err=True)
    else:
        plugins_manager = PluginsManager(custom_plugins_folder,
                                         ignore_info=ignore_info)
        analyzer = ReportAnalyzer(plugins_manager)
        if plugin_id:
            plugin = plugins_manager.get_plugin(plugin_id)
            if not plugin:
                click.echo(click.style(f"Invalid Plugin: {plugin_id}",
                                       fg="red"),
                           err=True)
                return
        else:
            plugin = analyzer.get_plugin(report_file)
            if not plugin:
                click.echo(click.style(
                    f"Failed to detect report: {report_file}", fg="red"),
                           err=True)
                return
        plugin.processReport(Path(report_file), getpass.getuser())
        if summary:
            click.echo(json.dumps(plugin.get_summary(), indent=4))
        else:
            if output_file:
                with open(output_file, "w") as f:
                    json.dump(plugin.get_data(), f)
            else:
                click.echo(json.dumps(plugin.get_data(), indent=4))
コード例 #5
0
 def __init__(self, upload_reports_queue, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.upload_reports_queue = upload_reports_queue
     self.plugins_manager = PluginsManager(
         config.faraday_server.custom_plugins_folder,
         ignore_info=config.faraday_server.ignore_info_severity)
     self.__event = threading.Event()
コード例 #6
0
ファイル: commands.py プロジェクト: infobyte/faraday_plugins
def process_command(command, plugin_id, custom_plugins_folder, dont_run,
                    summary, output_file, show_output, ignore_info):
    plugins_manager = PluginsManager(custom_plugins_folder,
                                     ignore_info=ignore_info)
    analyzer = CommandAnalyzer(plugins_manager)
    if plugin_id:
        plugin = plugins_manager.get_plugin(plugin_id)
        if not plugin:
            click.echo(click.style(f"Invalid Plugin: {plugin_id}", fg="red"),
                       err=True)
            return
    else:
        plugin = analyzer.get_plugin(command)
        if not plugin:
            click.echo(click.style(f"Failed to detect command: {command}",
                                   fg="red"),
                       err=True)
            return
    current_path = os.path.abspath(os.getcwd())
    modified_command = plugin.processCommandString(getpass.getuser(),
                                                   current_path, command)
    if modified_command:
        command = modified_command
    if dont_run:
        color_message = click.style("Command: ", fg="green")
        click.echo(f"{color_message} {command}")
    else:
        p = subprocess.Popen(shlex.split(command),
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        output = io.StringIO()
        while True:
            retcode = p.poll()
            line = p.stdout.readline().decode('utf-8')
            if show_output:
                sys.stdout.write(line)
            output.write(line)
            if retcode is not None:
                extra_lines = map(lambda x: x.decode('utf-8'),
                                  p.stdout.readlines())
                if show_output:
                    sys.stdout.writelines(line)
                output.writelines(extra_lines)
                break
        output_value = output.getvalue()
        if retcode == 0:
            plugin.processOutput(output_value)
            if summary:
                click.echo(json.dumps(plugin.get_summary(), indent=4))
            else:
                if output_file:
                    with open(output_file, "w") as f:
                        json.dump(plugin.get_data(), f)
                else:
                    click.echo(json.dumps(plugin.get_data(), indent=4))
        else:
            click.echo(click.style("Command execution error!!", fg="red"),
                       err=True)
コード例 #7
0
def main():
    # If the script is run outside the dispatcher the environment variables
    # are checked.
    # ['EXECUTOR_CONFIG_TOKEN', 'EXECUTOR_CONFIG_URL', 'EXECUTOR_CONFIG_PROJECT']
    try:
        sonar_qube_url = os.environ["EXECUTOR_CONFIG_URL"]
        token = os.environ["EXECUTOR_CONFIG_TOKEN"]
        component_key = os.environ['EXECUTOR_CONFIG_COMPONENT_KEY']
    except KeyError:
        print("Environment variable not found", file=sys.stderr)
        sys.exit()

    session = requests.Session()

    # ATTENTION: SonarQube API requires an empty password when auth method is via token
    session.auth = (token, '')

    # Issues api config
    page = 0
    has_more_vulns = True

    vulnerabilities = []

    while has_more_vulns:
        page += 1

        params = {
            'componentKeys': component_key,
            'types': TYPE_VULNS,
            'p': page,
            'ps': PAGE_SIZE
        }

        response = session.get(
            url=f'{sonar_qube_url}/api/issues/search',
            params=params,
        )

        if not response.ok:
            print(
                f"There was an error finding issues. Component Key {component_key}; Status Code {response.status_code} - {response.content}",
                file=sys.stderr)
            sys.exit()

        response_json = response.json()
        issues = response_json.get('issues')
        vulnerabilities.extend(issues)
        total_items = response_json.get('paging').get('total')

        has_more_vulns = page * PAGE_SIZE < total_items

    plugin = PluginsManager().get_plugin("sonarqubeapi")

    vulns_json = json.dumps({'issues': vulnerabilities})
    plugin.parseOutputString(vulns_json)
    print(plugin.get_json())
コード例 #8
0
 def __init__(self, plugin_repo_path, pending_actions=None):
     self._controllers = {}
     self._plugin_modules = {}
     self._plugin_instances = {}
     self._plugin_settings = {}
     self.pending_actions = pending_actions
     self._plugins_manager = PluginsManager(CONF.getCustomPluginsPath())
     self.commands_analyzer = CommandAnalyzer(self._plugins_manager)
     self.report_analyzer = ReportAnalyzer(self._plugins_manager)
     self._loadSettings()
コード例 #9
0
ファイル: reports_processor.py プロジェクト: infobyte/faraday
def process_report(workspace_name: str, command_id: int, file_path: Path,
                   plugin_id: Optional[int], user_id: Optional[int]):
    from faraday.server.web import get_app  # pylint:disable=import-outside-toplevel
    with get_app().app_context():
        if plugin_id is not None:
            plugins_manager = PluginsManager(
                ReportsSettings.settings.custom_plugins_folder,
                ignore_info=ReportsSettings.settings.ignore_info_severity)
            logger.info(
                f"Reports Manager: [Custom plugins folder: "
                f"[{ReportsSettings.settings.custom_plugins_folder}]"
                f"[Ignore info severity: {ReportsSettings.settings.ignore_info_severity}]"
            )
            plugin = plugins_manager.get_plugin(plugin_id)
            if plugin:
                try:
                    logger.info(
                        f"Processing report [{file_path}] with plugin ["
                        f"{plugin.id}]")
                    plugin.processReport(str(file_path))
                    vulns_data = plugin.get_data()
                    del vulns_data['command']['duration']
                except Exception as e:
                    logger.error("Processing Error: %s", e)
                    logger.exception(e)
                    return
            else:
                logger.error(f"No plugin detected for report [{file_path}]")
                return
        else:
            try:
                with file_path.open("r") as f:
                    vulns_data = json.load(f)
            except Exception as e:
                logger.error("Loading data from json file: %s [%s]", file_path,
                             e)
                logger.exception(e)
                return
        if plugin_id is None:
            logger.debug("Removing file: %s", file_path)
            os.remove(file_path)
        else:
            if faraday_server.delete_report_after_process:
                os.remove(file_path)
        set_end_date = True
        try:
            send_report_data(workspace_name, command_id, vulns_data, user_id,
                             set_end_date)
            logger.info("Report processing finished")
        except Exception as e:
            logger.exception(e)
            logger.error("Save Error: %s", e)
コード例 #10
0
def main():
    NESSUS_SCAN_NAME = os.getenv("EXECUTOR_CONFIG_NESSUS_SCAN_NAME",
                                 get_report_name())
    NESSUS_URL = os.getenv("EXECUTOR_CONFIG_NESSUS_URL")  # https://nessus:port
    NESSUS_USERNAME = os.getenv("NESSUS_USERNAME")
    NESSUS_PASSWORD = os.getenv("NESSUS_PASSWORD")
    NESSUS_SCAN_TARGET = os.getenv(
        # ip, domain, range
        "EXECUTOR_CONFIG_NESSUS_SCAN_TARGET")
    NESSUS_SCAN_TEMPLATE = os.getenv(
        # name field
        "EXECUTOR_CONFIG_NESSUS_SCAN_TEMPLATE",
        "basic",
    )

    if not NESSUS_URL:
        NESSUS_URL = os.getenv("NESSUS_URL")
        if not NESSUS_URL:
            print("URL not provided", file=sys.stderr)
            sys.exit(1)

    scan_file = None

    token = nessus_login(NESSUS_URL, NESSUS_USERNAME, NESSUS_PASSWORD)
    if not token:
        sys.exit(1)

    x_token = get_x_api_token(NESSUS_URL, token)
    if not x_token:
        sys.exit(1)

    scan_id = nessus_add_target(
        NESSUS_URL,
        token,
        x_token,
        NESSUS_SCAN_TARGET,
        NESSUS_SCAN_TEMPLATE,
        NESSUS_SCAN_NAME,
    )
    if not scan_id:
        sys.exit(1)

    status = nessus_scan_run(NESSUS_URL, scan_id, token, x_token)
    if status != "error":
        scan_file = nessus_scan_export(NESSUS_URL, scan_id, token, x_token)

    if scan_file:
        plugin = PluginsManager().get_plugin("nessus")
        plugin.parseOutputString(scan_file)
        print(plugin.get_json())
    else:
        print("Scan file was empty", file=sys.stderr)
コード例 #11
0
def main():
    my_envs = os.environ
    # If the script is run outside the dispatcher
    # the environment variables
    # are checked.
    # ['EXECUTOR_CONFIG_NAME_URL', 'ARACHNI_PATH']
    if "EXECUTOR_CONFIG_NAME_URL" in my_envs:
        url_analyze = os.environ.get("EXECUTOR_CONFIG_NAME_URL")
        url = urlparse(url_analyze)
        if url.scheme != "http" and url.scheme != "https":
            url_analyze = f"http://{url_analyze}"
    else:
        print("Param NAME_URL no passed", file=sys.stderr)
        sys.exit()

    if "ARACHNI_PATH" in my_envs:
        path_arachni = os.environ.get("ARACHNI_PATH")
    else:
        print("Environment variable ARACHNI_PATH no set", file=sys.stderr)
        sys.exit()
    os.chdir(path_arachni)
    file_afr = tempfile.NamedTemporaryFile(mode="w", suffix=".afr")

    cmd = ["./arachni", url_analyze, "--report-save-path", file_afr.name]

    arachni_command = subprocess.run(cmd,
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE)
    flush_messages(arachni_command)

    name_xml = tempfile.NamedTemporaryFile(mode="w", suffix=".xml")

    cmd = [
        "./arachni_reporter",
        file_afr.name,
        "--reporter",
        f"xml:outfile={name_xml.name}",
    ]

    arachni_reporter_process = subprocess.run(cmd,
                                              stdout=subprocess.PIPE,
                                              stderr=subprocess.PIPE)
    flush_messages(arachni_reporter_process)

    plugin = PluginsManager().get_plugin("arachni")

    with open(name_xml.name, "r") as f:
        plugin.parseOutputString(f.read())
        print(plugin.get_json())

    name_xml.close()
    file_afr.close()
コード例 #12
0
class ReportsManager(Thread):

    def __init__(self, upload_reports_queue, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.upload_reports_queue = upload_reports_queue
        self.plugins_manager = PluginsManager(config.faraday_server.custom_plugins_folder)
        self.__event = threading.Event()

    def stop(self):
        logger.debug("Stop Reports Manager")
        self.__event.set()

    def send_report_request(self, workspace_name, report_json, user):
        logger.info("Send Report data to workspace [%s]", workspace_name)
        from faraday.server.web import app  # pylint:disable=import-outside-toplevel
        with app.app_context():
            ws = Workspace.query.filter_by(name=workspace_name).one()
            schema = BulkCreateSchema()
            data = schema.load(report_json)
            data = add_creator(data, user)
            bulk_create(ws, data, True)

    def process_report(self, workspace, file_path, plugin_id, user):
        plugin = self.plugins_manager.get_plugin(plugin_id)
        if plugin:
            try:
                logger.info("Processing report [%s] with plugin [%s]", file_path, plugin.id)
                plugin.processReport(file_path)
                vulns_data = plugin.get_data()
            except Exception as e:
                logger.error("Processing Error: %s", e)
                logger.exception(e)
            else:
                try:
                    self.send_report_request(workspace, vulns_data, user)
                    logger.info("Report processing finished")
                except Exception as e:
                    logger.exception(e)
                    logger.error("Save Error: %s", e)
        else:
            logger.info("No plugin detected for report [%s]", file_path)

    def run(self):
        logger.debug("Start Reports Manager")
        while not self.__event.is_set():
            try:
                workspace, file_path, plugin_id, user = self.upload_reports_queue.get(False, timeout=0.1)
                logger.info("Processing raw report %s", file_path)
                if os.path.isfile(file_path):
                    self.process_report(workspace, file_path, plugin_id, user)
                else:
                    logger.warning("Report file [%s] don't exists", file_path)
            except Empty:
                self.__event.wait(0.1)
            except KeyboardInterrupt:
                logger.info("Keyboard interrupt, stopping report processing thread")
                self.stop()
            except Exception as ex:
                logger.exception(ex)
                continue
コード例 #13
0
def generate_reports_tests(force, debug):
    generated_summaries = 0
    analysed_reports = 0
    click.echo(f"{colorama.Fore.GREEN}Generate Faraday Plugins Tests Summary")
    plugins_manager = PluginsManager()
    analyzer = ReportAnalyzer(plugins_manager)
    for report_file_path in list_report_files():
        if debug:
            click.echo(f"File: {report_file_path}")
        plugin: PluginBase = analyzer.get_plugin(report_file_path)
        if not plugin:
            click.echo(
                f"{colorama.Fore.YELLOW}Plugin for file: ({report_file_path}) not found"
            )
        else:
            with open(report_file_path, 'rb') as f:
                m = hashlib.md5(f.read())
            file_checksum = m.hexdigest()
            if file_checksum not in REPORTS_CHECKSUM:
                REPORTS_CHECKSUM.append(file_checksum)
            else:
                click.echo(
                    f"{colorama.Fore.YELLOW}Ignore duplicated file: ({report_file_path})"
                )
                continue
            analysed_reports += 1
            report_file_name = os.path.basename(report_file_path)
            plugin_name = plugin.id
            plugin_path = os.path.join(REPORT_COLLECTION_DIR,
                                       FARADAY_PLUGINS_TESTS_DIR, plugin_name)
            if not os.path.isdir(plugin_path):
                os.mkdir(plugin_path)
            dst_report_file_path = os.path.join(plugin_path, report_file_name)
            summary_needed = False
            summary_file = f"{os.path.splitext(dst_report_file_path)[0]}_summary.json"
            if not os.path.isfile(dst_report_file_path) or force:
                summary_needed = True
                shutil.copyfile(report_file_path, dst_report_file_path)
            if not os.path.isfile(summary_file) or force:
                summary_needed = True
            if summary_needed:
                try:
                    plugin.processReport(report_file_path)
                    click.echo(
                        f"{colorama.Fore.GREEN}Generate Summary for: {dst_report_file_path} [{plugin}]"
                    )
                    summary = plugin.get_summary()
                    with open(summary_file, "w") as f:
                        json.dump(summary, f)
                    generated_summaries += 1
                except Exception as e:
                    click.echo(
                        f"{colorama.Fore.RED}Error generating summary for file: {report_file_path} [{plugin}]: [{e}]"
                    )
    click.echo(
        f"Generated {generated_summaries} summaries of {analysed_reports} reports"
    )
コード例 #14
0
def test_autodetection_on_all_report_collection(report_filename):
    plugins_manager = PluginsManager()
    analyzer = ReportAnalyzer(plugins_manager)
    plugin: PluginBase = analyzer.get_plugin(report_filename)
    assert plugin, report_filename
    plugin.processReport(report_filename)
    plugin_json = json.loads(plugin.get_json())
    assert "hosts" in plugin_json
    assert "command" in plugin_json
    assert len(plugin_json) == 2
コード例 #15
0
def list_plugins(custom_plugins_folder):
    plugins_manager = PluginsManager(custom_plugins_folder)
    click.echo(click.style("Available Plugins:", fg="cyan"))
    loaded_plugins = 0
    for plugin_id, plugin in plugins_manager.get_plugins():
        console_enabled = plugin._command_regex is not None
        console_enabled_color = "green" if console_enabled else "red"
        console_enabled_text = click.style(
            f"{'Yes' if console_enabled else 'No'}", fg=console_enabled_color)
        report_enabled = isinstance(plugin, PluginByExtension)
        report_enabled_color = "green" if report_enabled else "red"
        report_enabled_text = click.style(
            f"{'Yes' if report_enabled else 'No'}", fg=report_enabled_color)
        click.echo(
            f"{plugin.id:15}  - [Command: {console_enabled_text:>12} - Report: {report_enabled_text:>12}] - {plugin.name} "
        )

        loaded_plugins += 1
    click.echo(click.style(f"Loaded Plugins: {loaded_plugins}", fg="cyan"))
コード例 #16
0
ファイル: commands.py プロジェクト: infobyte/faraday_plugins
def detect_command(command, custom_plugins_folder):
    plugins_manager = PluginsManager(custom_plugins_folder)
    analyzer = CommandAnalyzer(plugins_manager)
    plugin = analyzer.get_plugin(command)
    if plugin:
        click.echo(click.style(f"Faraday Plugin: {plugin.id}", fg="cyan"))
    else:
        click.echo(click.style(f"Failed to detect command: {command}",
                               fg="red"),
                   err=True)
コード例 #17
0
def test_detected_tools_on_all_report_collection(report_filename, benchmark):
    plugins_manager = PluginsManager()
    analyzer = ReportAnalyzer(plugins_manager)
    plugin: PluginBase = analyzer.get_plugin(report_filename)
    if not plugin:
        return
    assert plugin, report_filename
    benchmark(plugin.processReport, report_filename)
    plugin_json = json.loads(plugin.get_json())
    assert "hosts" in plugin_json
    assert "command" in plugin_json
    assert os.path.isfile(report_filename) is True
コード例 #18
0
ファイル: commands.py プロジェクト: infobyte/faraday_plugins
def detect_report(report_file, custom_plugins_folder):
    if not os.path.isfile(report_file):
        click.echo(click.style(f"File {report_file} Don't Exists", fg="red"))
    else:
        plugins_manager = PluginsManager(custom_plugins_folder)
        analyzer = ReportAnalyzer(plugins_manager)
        plugin = analyzer.get_plugin(report_file)
        if plugin:
            click.echo(click.style(f"Faraday Plugin: {plugin.id}", fg="cyan"))
        else:
            click.echo(click.style(f"Failed to detect report: {report_file}",
                                   fg="red"),
                       err=True)
コード例 #19
0
def main():
    """ main function """

    with RedirectOutput():
        scanner = ness6rest.Scanner(url=NESSUS_URL,
                                    login=NESSUS_USERNAME,
                                    password=NESSUS_PASSWORD,
                                    insecure=True)

        scantemplate = os.getenv("NESSUS_SCANTEMPLATE", "basic")
        scanner.scan_add(targets=NESSUS_SCANTARGET,
                         template=scantemplate,
                         name="Faraday Agent Scan")
        print("Starting scan")
        scanner.scan_run()

        #This blocks execution until the scan stops running
        scanner._scan_status()

        plugin = PluginsManager().get_plugin("nessus")
        plugin.parseOutputString(scanner.download_scan(export_format="nessus"))

    print(plugin.get_json())
コード例 #20
0
ファイル: shell.py プロジェクト: cript0nauta/faraday-cli
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.TABLE_PRETTY_FORMAT = "psql"
     # hide unwanted settings
     settings_to_hide = ["debug"]
     for setting_name in settings_to_hide:
         self.remove_settable(setting_name)
     f = Figlet(font="slant")
     intro = []
     intro.append(style(f.renderText("Faraday Cli"), fg="red"))
     if active_config.faraday_url and active_config.token:
         intro.append(
             style(f"Server: {active_config.faraday_url}", fg="green"))
         self.api_client = FaradayApi(
             active_config.faraday_url,
             ignore_ssl=active_config.ignore_ssl,
             token=active_config.token,
         )
     else:
         self.api_client = FaradayApi()
         intro.append(
             style(f"Missing faraday server, run 'auth'", fg="yellow"))
     self.intro = "\n".join(intro)
     self.data_queue = queue.Queue()
     self.custom_plugins_path = None
     self.update_prompt()
     self.add_settable(
         Settable(
             "custom_plugins_path",
             str,
             "Path of custom plugins",
             onchange_cb=self._onchange_custom_plugins_path,
         ))
     self.plugins_manager = PluginsManager(
         active_config.custom_plugins_folder)
     self.report_analyzer = ReportAnalyzer(self.plugins_manager)
     self.command_analyzer = CommandAnalyzer(self.plugins_manager)
コード例 #21
0
def list_plugins():
    plugins_manager = PluginsManager()
    for _, plugin in plugins_manager.get_plugins():
        click.echo(f"{plugin.id}")
コード例 #22
0
ファイル: command.py プロジェクト: 5l1v3r1/faraday-cli
def command(api_client, custom_plugins_folder, plugin_id, workspace,
            hide_output, command):

    if workspace:
        if not api_client.is_workspace_valid(workspace):
            click.secho(f"Invalid workspace: {workspace}", fg="red")
            return
        else:
            destination_workspace = workspace
    else:
        if not active_config.workspace:
            click.secho(f"Missing default workspace", fg="red")
            return
        else:
            destination_workspace = active_config.workspace
    plugins_manager = PluginsManager(custom_plugins_folder)
    analyzer = CommandAnalyzer(plugins_manager)
    if plugin_id:
        plugin = plugins_manager.get_plugin(plugin_id)
        if not plugin:
            click.echo(click.style(f"Invalid Plugin: {plugin_id}", fg="red"),
                       err=True)
            return
    else:
        plugin = analyzer.get_plugin(command)
        if not plugin:
            click.echo(click.style(f"Failed to detect command: {command}",
                                   fg="red"),
                       err=True)
            return
    current_path = os.path.abspath(os.getcwd())
    modified_command = plugin.processCommandString(getpass.getuser(),
                                                   current_path, command)
    if modified_command:
        command = modified_command
    p = subprocess.Popen(shlex.split(command),
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
    output = io.StringIO()
    while True:
        retcode = p.poll()
        line = p.stdout.readline().decode('utf-8')
        if not hide_output:
            sys.stdout.write(line)
        output.write(line)
        if retcode is not None:
            extra_lines = map(lambda x: x.decode('utf-8'),
                              p.stdout.readlines())
            if not hide_output:
                sys.stdout.writelines(line)
            output.writelines(extra_lines)
            break
    output_value = output.getvalue()
    if retcode == 0:
        plugin.processOutput(output_value)
        click.secho(
            f"Sending data from command {command} to {destination_workspace}",
            fg="green")
        api_client.bulk_create(destination_workspace, plugin.get_data())
    else:
        click.secho("Command execution error!!", fg="red")
コード例 #23
0
ファイル: shell.py プロジェクト: infobyte/faraday-cli
 def _create_plugin_manager(self):
     self.plugins_manager = PluginsManager(
         self.custom_plugins_path, ignore_info=self.ignore_info_severity)
     self.report_analyzer = ReportAnalyzer(self.plugins_manager)
     self.command_analyzer = CommandAnalyzer(self.plugins_manager)
コード例 #24
0
def main():
    # separate the target list with comma
    NUCLEI_TARGET = os.getenv("EXECUTOR_CONFIG_NUCLEI_TARGET")
    # separate the exclude list with comma
    NUCLEI_EXCLUDE = os.getenv("EXECUTOR_CONFIG_NUCLEI_EXCLUDE", None)
    NUCLEI_TEMPLATES = os.getenv("NUCLEI_TEMPLATES")

    target_list = NUCLEI_TARGET.split(",")

    with tempfile.TemporaryDirectory() as tempdirname:
        name_urls = Path(tempdirname) / "urls.txt"
        name_output = Path(tempdirname) / "output.json"

        if len(target_list) > 1:
            with open(name_urls, "w") as f:
                for url in target_list:
                    url_parse = urlparse(url)
                    if is_ip(url_parse.netloc) or is_ip(url_parse.path):
                        print(f"Is {url} not valid.", file=sys.stderr)
                    else:
                        if not url_parse.scheme:
                            f.write(f"http://{url}\n")
                        else:
                            f.write(f"{url}\n")
            cmd = [
                "nuclei",
                "-l",
                name_urls,
                "-t",
                NUCLEI_TEMPLATES,
            ]

        else:
            url_parse = urlparse(NUCLEI_TARGET)
            if is_ip(url_parse.hostname) or is_ip(url_parse.path):
                print(f"Is {NUCLEI_TARGET} not valid.", file=sys.stderr)
                sys.exit()
            else:
                if not url_parse.scheme:
                    url = f"http://{NUCLEI_TARGET}"
                else:
                    url = f"{NUCLEI_TARGET}"
                cmd = [
                    "nuclei",
                    "-target",
                    url,
                    "-t",
                    NUCLEI_TEMPLATES,
                ]

        if NUCLEI_EXCLUDE is not None:
            exclude_list = NUCLEI_EXCLUDE.split(",")
            for exclude in exclude_list:
                cmd += ["-exclude", str(Path(NUCLEI_TEMPLATES) / exclude)]

        cmd += ["-json", "-o", name_output]

        nuclei_process = subprocess.run(cmd,
                                        stdout=subprocess.PIPE,
                                        stderr=subprocess.PIPE)

        if len(nuclei_process.stdout) > 0:
            print(f"Nuclei stdout: {nuclei_process.stdout.decode('utf-8')}",
                  file=sys.stderr)

        if len(nuclei_process.stderr) > 0:
            print(f"Nuclei stderr: {nuclei_process.stderr.decode('utf-8')}",
                  file=sys.stderr)

        plugin = PluginsManager().get_plugin("nuclei")
        plugin.parseOutputString(nuclei_process.stdout.decode("utf-8"))
        print(plugin.get_json())
コード例 #25
0
 def __init__(self, upload_reports_queue, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.upload_reports_queue = upload_reports_queue
     self.plugins_manager = PluginsManager()
     self._must_stop = False
コード例 #26
0
def main():
    url_target = os.environ.get("EXECUTOR_CONFIG_W3AF_TARGET_URL")
    if not url_target:
        print("URL not provided", file=sys.stderr)
        sys.exit()

    # If the script is run outside the dispatcher the environment variables
    # are checked.
    # ['W3AF_PATH']
    if "W3AF_PATH" in os.environ:
        with tempfile.TemporaryDirectory() as tempdirname:
            name_result = Path(tempdirname) / "config_report_file.w3af"

            with open(name_result, "w") as f:
                command_text = ("plugins\n output console,xml_file\n"
                                " output\n output config xml_file\n "
                                "set output_file "
                                f"{tempdirname}/output-w3af.xml\n set verbose"
                                " True\n back\n output config console\n set "
                                "verbose False\n back\n crawl all, "
                                "!bing_spider, !google_spider, !spider_man\n "
                                "crawl\n grep all\n grep\n audit all\n "
                                "audit\n bruteforce all\n bruteforce\n "
                                f"back\n target\n set target {url_target}\n "
                                f"back\n start\n exit")
                f.write(command_text)

            try:
                os.chdir(path=os.environ.get("W3AF_PATH"))

            except FileNotFoundError:
                print(
                    "The directory where w3af is located could not be found. "
                    "Check environment variable W3AF_PATH = "
                    f'{os.environ.get("W3AF_PATH")}',
                    file=sys.stderr,
                )
                sys.exit()

            if os.path.isfile("w3af_console"):
                cmd = [
                    "./w3af_console",
                    "-s",
                    name_result,
                ]
                w3af_process = subprocess.run(cmd,
                                              stdout=subprocess.PIPE,
                                              stderr=subprocess.PIPE)
                if len(w3af_process.stdout) > 0:
                    print(
                        f"W3AF stdout: {w3af_process.stdout.decode('utf-8')}",
                        file=sys.stderr,
                    )
                if len(w3af_process.stderr) > 0:
                    print(
                        f"W3AF stderr: {w3af_process.stderr.decode('utf-8')}",
                        file=sys.stderr,
                    )

                plugin = PluginsManager().get_plugin("w3af")
                plugin.parseOutputString(f"{tempdirname}/output-w3af.xml")
                print(plugin.get_json())
            else:
                print(
                    "w3af_console file could not be found. For this reason the"
                    " command cannot be run. Actual value = "
                    f'{os.environ.get("W3AF_PATH")}/w3af_console ',
                    file=sys.stderr,
                )
                sys.exit()

    else:
        print("W3AF_PATH not set", file=sys.stderr)
        sys.exit()
コード例 #27
0
ファイル: upload_reports.py プロジェクト: funnyDog896/faraday
from flask_wtf.csrf import validate_csrf
from werkzeug.utils import secure_filename
from wtforms import ValidationError

from faraday.server.utils.web import gzipped
from faraday.server.models import Workspace, Command, db
from faraday.server import config

from faraday_plugins.plugins.manager import PluginsManager, ReportAnalyzer

upload_api = Blueprint('upload_reports', __name__)

logger = logging.getLogger(__name__)

plugins_manager = PluginsManager(config.faraday_server.custom_plugins_folder)
report_analyzer = ReportAnalyzer(plugins_manager)


@gzipped
@upload_api.route('/v2/ws/<workspace>/upload_report', methods=['POST'])
def file_upload(workspace=None):
    """
    Upload a report file to Server and process that report with Faraday client plugins.
    """
    logger.info("Importing new plugin report in server...")
    # Authorization code copy-pasted from server/api/base.py
    ws = Workspace.query.filter_by(name=workspace).first()
    if not ws or not ws.active:
        # Don't raise a 403 to prevent workspace name enumeration
        abort(404, f"Workspace disabled: {workspace}")
コード例 #28
0
ファイル: upload_reports.py プロジェクト: infobyte/faraday
    def file_upload(self, workspace_name=None):
        """
        ---
        post:
          tags: ["Workspace", "File"]
          description: Upload a report file to create data within the given workspace
          responses:
            201:
              description: Created
            400:
              description: Bad request
            403:
              description: Forbidden
        tags: ["Workspace", "File"]
        responses:
          200:
            description: Ok
        """
        logger.info("Importing new plugin report in server...")
        # Authorization code copy-pasted from server/api/base.py
        ws = Workspace.query.filter_by(name=workspace_name).first()
        if not ws or not ws.active:
            # Don't raise a 403 to prevent workspace name enumeration
            abort(404, f"Workspace disabled: {workspace_name}")

        if 'file' not in request.files:
            abort(400)

        try:
            validate_csrf(request.form.get('csrf_token'))
        except ValidationError:
            abort(403)

        report_file = request.files['file']

        if report_file:

            chars = string.ascii_uppercase + string.digits
            random_prefix = ''.join(random.choice(chars)
                                    for x in range(12))  # nosec
            raw_report_filename = f'{random_prefix}_{secure_filename(report_file.filename)}'

            try:
                file_path = CONST_FARADAY_HOME_PATH / 'uploaded_reports' \
                            / raw_report_filename
                with file_path.open('wb') as output:
                    output.write(report_file.read())
            except AttributeError:
                logger.warning(
                    "Upload reports in WEB-UI not configurated, run Faraday client and try again..."
                )
                abort(
                    make_response(
                        jsonify(
                            message=
                            "Upload reports not configurated: Run faraday client and start Faraday server again"
                        ), 500))
            else:
                logger.info(f"Get plugin for file: {file_path}")
                plugins_manager = PluginsManager(
                    ReportsSettings.settings.custom_plugins_folder)
                report_analyzer = ReportAnalyzer(plugins_manager)
                plugin = report_analyzer.get_plugin(file_path)
                if not plugin:
                    logger.info("Could not get plugin for file")
                    abort(
                        make_response(jsonify(message="Invalid report file"),
                                      400))
                else:
                    logger.info(
                        f"Plugin for file: {file_path} Plugin: {plugin.id}")
                    workspace_instance = Workspace.query.filter_by(
                        name=workspace_name).one()
                    command = Command()
                    command.workspace = workspace_instance
                    command.start_date = datetime.utcnow()
                    command.import_source = 'report'
                    # The data will be updated in the bulk_create function
                    command.tool = "In progress"
                    command.command = "In progress"

                    db.session.add(command)
                    db.session.commit()

                    REPORTS_QUEUE.put(
                        (workspace_instance.name, command.id, file_path,
                         plugin.id, flask_login.current_user.id))
                    return make_response(
                        jsonify(message="ok", command_id=command.id), 200)
        else:
            abort(make_response(jsonify(message="Missing report file"), 400))
コード例 #29
0
class ReportsManager(Thread):
    def __init__(self, upload_reports_queue, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.upload_reports_queue = upload_reports_queue
        self.plugins_manager = PluginsManager(
            config.faraday_server.custom_plugins_folder)
        self.__event = threading.Event()

    def stop(self):
        logger.debug("Stop Reports Manager")
        self.__event.set()

    def send_report_request(self, workspace_name: str, command_id: int,
                            report_json: dict, user_id: int):
        logger.info("Send Report data to workspace [%s]", workspace_name)
        from faraday.server.web import app  # pylint:disable=import-outside-toplevel
        with app.app_context():
            ws = Workspace.query.filter_by(name=workspace_name).one()
            command = Command.query.filter_by(id=command_id).one()
            user = User.query.filter_by(id=user_id).one()
            schema = BulkCreateSchema()
            data = schema.load(report_json)
            data = add_creator(data, user)
            bulk_create(ws, command, data, True, True)

    def process_report(self, workspace_name: str, command_id: int,
                       file_path: Path, plugin_id: int, user_id: int):
        plugin = self.plugins_manager.get_plugin(plugin_id)
        if plugin:
            try:
                logger.info(f"Processing report [{file_path}] with plugin ["
                            f"{plugin.id}")
                plugin.processReport(str(file_path))
                vulns_data = plugin.get_data()
                del vulns_data['command']['duration']
            except Exception as e:
                logger.error("Processing Error: %s", e)
                logger.exception(e)
            else:
                try:
                    self.send_report_request(workspace_name, command_id,
                                             vulns_data, user_id)
                    logger.info("Report processing finished")
                except Exception as e:
                    logger.exception(e)
                    logger.error("Save Error: %s", e)
        else:
            logger.info(f"No plugin detected for report [{file_path}]")

    def run(self):
        logger.debug("Start Reports Manager")
        while not self.__event.is_set():
            try:
                tpl: Tuple[str, int, Path, int, int] = \
                    self.upload_reports_queue.get(False, timeout=0.1)

                workspace_name, command_id, file_path, plugin_id, user_id = tpl

                logger.info(f"Processing raw report {file_path}")
                if file_path.is_file():
                    self.process_report(workspace_name, command_id, file_path,
                                        plugin_id, user_id)
                else:
                    logger.warning(f"Report file [{file_path}] don't exists",
                                   file_path)
            except Empty:
                self.__event.wait(0.1)
            except KeyboardInterrupt:
                logger.info(
                    "Keyboard interrupt, stopping report processing thread")
                self.stop()
            except Exception as ex:
                logger.exception(ex)
                continue
コード例 #30
0
import json
import pytest
from faraday_plugins.plugins.manager import PluginsManager, CommandAnalyzer
from faraday_plugins.plugins.plugin import PluginBase

plugins_manager = PluginsManager()
analyzer = CommandAnalyzer(plugins_manager)

COMMANDS_FILE = './tests/commands.json'


def list_commands():
    with open(COMMANDS_FILE) as f:
        commands_dict = json.load(f)
    for command_data in commands_dict["commands"]:
        yield command_data


@pytest.mark.parametrize("command_data", list_commands())
def test_autodetected_on_commands(command_data):
    plugin_id = command_data["plugin_id"]
    command_string = command_data["command"]
    command_result = command_data["command_result"]

    plugin: PluginBase = analyzer.get_plugin(command_string)
    assert plugin, command_string
    assert plugin.id.lower() == plugin_id.lower()
    assert plugin.command.lower() == command_result.lower()