From cf06e52e4a286c455905af01db321e653e6a1914 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ata=20Hak=C3=A7=C4=B1l?= Date: Wed, 20 May 2020 11:13:50 +0300 Subject: [PATCH 001/698] Fix nmap plugins handing of "NOT VULNERABLE" tag --- faraday_plugins/plugins/repo/nmap/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faraday_plugins/plugins/repo/nmap/plugin.py b/faraday_plugins/plugins/repo/nmap/plugin.py index 925152d9..ac3fc864 100644 --- a/faraday_plugins/plugins/repo/nmap/plugin.py +++ b/faraday_plugins/plugins/repo/nmap/plugin.py @@ -511,7 +511,7 @@ def parseOutputString(self, output, debug=False): desc = v.desc refs = v.refs - if re.search(r"VULNERABLE", desc): + if re.search(r"(? Date: Thu, 21 May 2020 11:54:37 -0300 Subject: [PATCH 002/698] change nmap default severity from 0 to 'info' --- faraday_plugins/plugins/repo/nmap/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faraday_plugins/plugins/repo/nmap/plugin.py b/faraday_plugins/plugins/repo/nmap/plugin.py index 3e83d585..7ad65c93 100644 --- a/faraday_plugins/plugins/repo/nmap/plugin.py +++ b/faraday_plugins/plugins/repo/nmap/plugin.py @@ -504,7 +504,7 @@ def parseOutputString(self, output, debug=False): description=srvname) for v in port.vulns: - severity = 0 + severity = "info" desc = v.desc refs = v.refs From c848db35a58729ebf2680b7226c0690e72d9a81e Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Thu, 21 May 2020 12:20:53 -0300 Subject: [PATCH 003/698] fix arachni to not delete report Also add a test to check this ipor other plugins --- .../plugins/repo/arachni/plugin.py | 20 ++++++++++--------- tests/test_report_collection.py | 8 ++++++++ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/faraday_plugins/plugins/repo/arachni/plugin.py b/faraday_plugins/plugins/repo/arachni/plugin.py index 245fb903..9bc6f4fd 100755 --- a/faraday_plugins/plugins/repo/arachni/plugin.py +++ b/faraday_plugins/plugins/repo/arachni/plugin.py @@ -351,17 +351,18 @@ def _parse_filename(self, filename): filename = filename['xml'] with open(filename, **self.open_options) as output: self.parseOutputString(output.read()) - if isinstance(filename, dict): - for _file in filename.values(): + if self._delete_temp_file: + if isinstance(filename, dict): + for _file in filename.values(): + try: + os.remove(_file) + except Exception as e: + self.logger.error("Error on delete file: (%s) [%s]", _file, e) + else: try: - os.remove(_file) + os.remove(filename) except Exception as e: - self.logger.error("Error on delete file: (%s) [%s]", _file, e) - else: - try: - os.remove(filename) - except Exception as e: - self.logger.error("Error on delete file: (%s) [%s]", filename, e) + self.logger.error("Error on delete file: (%s) [%s]", filename, e) def parseOutputString(self, output, debug=False): """ @@ -439,6 +440,7 @@ def processCommandString(self, username, current_path, command_string): self.vulns_data["command"]["params"] = params self.vulns_data["command"]["user"] = username self._output_file_path = {} + self._delete_temp_file = True for ext in self._temp_file_extension: self._output_file_path[ext] = self._get_temp_file(extension=ext) afr_file_path = self._output_file_path['afr'] diff --git a/tests/test_report_collection.py b/tests/test_report_collection.py index 083f7e11..b16116d5 100644 --- a/tests/test_report_collection.py +++ b/tests/test_report_collection.py @@ -152,3 +152,11 @@ def test_detected_tools_on_all_report_collection(report_filename, benchmark): plugin_json = json.loads(plugin.get_json()) assert "hosts" in plugin_json assert "command" in plugin_json + +@pytest.mark.parametrize("report_filename", list_report_files()) +def test_not_delete_report(report_filename): + plugins_manager = PluginsManager() + analyzer = ReportAnalyzer(plugins_manager) + plugin: PluginBase = analyzer.get_plugin(report_filename) + plugin.processReport(report_filename) + assert os.path.isfile(report_filename) is True From 1c9acf7ff5b00452bae11ddab6fcbbeff66b6ebb Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Thu, 21 May 2020 15:43:53 -0300 Subject: [PATCH 004/698] add tags support --- faraday_plugins/plugins/plugin.py | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/faraday_plugins/plugins/plugin.py b/faraday_plugins/plugins/plugin.py index e93ca526..45ef83f8 100644 --- a/faraday_plugins/plugins/plugin.py +++ b/faraday_plugins/plugins/plugin.py @@ -387,7 +387,7 @@ def createAndAddServiceToHost(self, host_id, name, def createAndAddVulnToHost(self, host_id, name, desc="", ref=None, severity="", resolution="", data="", external_id=None, run_date=None, impact=None, custom_fields=None, status="", policyviolations=None, - easeofresolution=None, confirmed=False): + easeofresolution=None, confirmed=False, tags=None): if ref is None: ref = [] if status == "": @@ -398,11 +398,14 @@ def createAndAddVulnToHost(self, host_id, name, desc="", ref=None, policyviolations = [] if custom_fields is None: custom_fields = {} - + if tags is None: + tags = [] + if isinstance(tags, str): + tags = [tags] vulnerability = {"name": name, "desc": desc, "severity": self.normalize_severity(severity), "refs": ref, "external_id": external_id, "type": "Vulnerability", "resolution": resolution, "data": data, "custom_fields": custom_fields, "status": status, "impact": impact, "policyviolations": policyviolations, - "confirmed": confirmed, "easeofresolution": easeofresolution + "confirmed": confirmed, "easeofresolution": easeofresolution, "tags": tags } if run_date: vulnerability["run_date"] = self.get_utctimestamp(run_date) @@ -422,7 +425,7 @@ def createAndAddVulnToInterface(self, host_id, interface_id, name, def createAndAddVulnToService(self, host_id, service_id, name, desc="", ref=None, severity="", resolution="", data="", external_id=None, run_date=None, custom_fields=None, policyviolations=None, impact=None, status="", - confirmed=False, easeofresolution=None): + confirmed=False, easeofresolution=None, tags=None): if ref is None: ref = [] if status == "": @@ -433,10 +436,14 @@ def createAndAddVulnToService(self, host_id, service_id, name, desc="", policyviolations = [] if custom_fields is None: custom_fields = {} + if tags is None: + tags = [] + if isinstance(tags, str): + tags = [tags] vulnerability = {"name": name, "desc": desc, "severity": self.normalize_severity(severity), "refs": ref, "external_id": external_id, "type": "Vulnerability", "resolution": resolution, "data": data, "custom_fields": custom_fields, "status": status, "impact": impact, "policyviolations": policyviolations, - "easeofresolution": easeofresolution, "confirmed": confirmed, + "easeofresolution": easeofresolution, "confirmed": confirmed, "tags": tags } if run_date: vulnerability["run_date"] = self.get_utctimestamp(run_date) @@ -449,7 +456,7 @@ def createAndAddVulnWebToService(self, host_id, service_id, name, desc="", response="", method="", pname="", params="", query="", category="", data="", external_id=None, confirmed=False, status="", easeofresolution=None, impact=None, - policyviolations=None, status_code=None, custom_fields=None, run_date=None): + policyviolations=None, status_code=None, custom_fields=None, run_date=None, tags=None): if params is None: params = "" if response is None: @@ -480,13 +487,17 @@ def createAndAddVulnWebToService(self, host_id, service_id, name, desc="", policyviolations = [] if custom_fields is None: custom_fields = {} + if tags is None: + tags = [] + if isinstance(tags, str): + tags = [tags] vulnerability = {"name": name, "desc": desc, "severity": self.normalize_severity(severity), "refs": ref, "external_id": external_id, "type": "VulnerabilityWeb", "resolution": resolution, "data": data, "website": website, "path": path, "request": request, "response": response, "method": method, "pname": pname, "params": params, "query": query, "category": category, "confirmed": confirmed, "status": status, "easeofresolution": easeofresolution, "impact": impact, "policyviolations": policyviolations, - "status_code": status_code, "custom_fields": custom_fields} + "status_code": status_code, "custom_fields": custom_fields, "tags": tags} if run_date: vulnerability["run_date"] = self.get_utctimestamp(run_date) vulnerability_id = self.save_service_vuln_cache(host_id, service_id, vulnerability) From d2e632de4e13e6112b698d69d6de6e8179c83e14 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Thu, 21 May 2020 15:58:06 -0300 Subject: [PATCH 005/698] add also tags to to services and hosts --- faraday_plugins/plugins/plugin.py | 25 +++++++++++++------ faraday_plugins/plugins/repo/nessus/plugin.py | 4 +-- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/faraday_plugins/plugins/plugin.py b/faraday_plugins/plugins/plugin.py index 45ef83f8..6e4347c5 100644 --- a/faraday_plugins/plugins/plugin.py +++ b/faraday_plugins/plugins/plugin.py @@ -312,7 +312,7 @@ def parseOutputString(self, output): """ raise NotImplementedError('This method must be implemented.') - def createAndAddHost(self, name, os="unknown", hostnames=None, mac=None, description=""): + def createAndAddHost(self, name, os="unknown", hostnames=None, mac=None, description="", tags=None): if not hostnames: hostnames = [] @@ -320,8 +320,12 @@ def createAndAddHost(self, name, os="unknown", hostnames=None, mac=None, descrip hostnames = [hostname for hostname in hostnames if hostname] if os is None: os = "unknown" + if tags is None: + tags = [] + if isinstance(tags, str): + tags = [tags] host = {"ip": name, "os": os, "hostnames": hostnames, "description": description, "mac": mac, - "credentials": [], "services": [], "vulnerabilities": []} + "credentials": [], "services": [], "vulnerabilities": [], "tags": tags} host_id = self.save_host_cache(host) return host_id @@ -362,13 +366,13 @@ def createAndAddInterface( def createAndAddServiceToInterface(self, host_id, interface_id, name, protocol="tcp", ports=None, status="open", version="unknown", - description=""): - return self.createAndAddServiceToHost(host_id, name, protocol, ports, status, version, description) + description="", tags=None): + return self.createAndAddServiceToHost(host_id, name, protocol, ports, status, version, description, tags) def createAndAddServiceToHost(self, host_id, name, protocol="tcp", ports=None, status="open", version="unknown", - description=""): + description="", tags=None): if ports: if isinstance(ports, list): ports = int(ports[0]) @@ -377,8 +381,13 @@ def createAndAddServiceToHost(self, host_id, name, if status not in VALID_SERVICE_STATUS: status = 'open' + if tags is None: + tags = [] + if isinstance(tags, str): + tags = [tags] service = {"name": name, "protocol": protocol, "port": ports, "status": status, - "version": version, "description": description, "credentials": [], "vulnerabilities": []} + "version": version, "description": description, "credentials": [], "vulnerabilities": [], + "tags": tags} service_id = self.save_service_cache(host_id, service) @@ -418,9 +427,9 @@ def createAndAddVulnToHost(self, host_id, name, desc="", ref=None, # to Host") def createAndAddVulnToInterface(self, host_id, interface_id, name, desc="", ref=None, severity="", - resolution="", data=""): + resolution="", data="", tags=None): return self.createAndAddVulnToHost(host_id, name, desc=desc, ref=ref, severity=severity, resolution=resolution, - data=data) + data=data, tags=tags) def createAndAddVulnToService(self, host_id, service_id, name, desc="", ref=None, severity="", resolution="", data="", external_id=None, run_date=None, diff --git a/faraday_plugins/plugins/repo/nessus/plugin.py b/faraday_plugins/plugins/repo/nessus/plugin.py index efe15c96..be3a7517 100644 --- a/faraday_plugins/plugins/repo/nessus/plugin.py +++ b/faraday_plugins/plugins/repo/nessus/plugin.py @@ -220,7 +220,7 @@ def parseOutputString(self, output): website = None host_name = None - host_id = self.createAndAddHost(ip_host, os=os, hostnames=host_name, mac=mac) + host_id = self.createAndAddHost(ip_host, os=os, hostnames=host_name, mac=mac, tags=["test_tag"]) interface_id = self.createAndAddInterface(host_id, ip, ipv6_address=ip, mac=mac) cve = [] @@ -336,7 +336,7 @@ def parseOutputString(self, output): interface_id, name=serv_name, protocol=serv_protocol, - ports=serv_port) + ports=serv_port, tags=["test_tag"]) if serv_name == 'www' or serv_name == 'http': self.createAndAddVulnWebToService(host_id, From 55984249362515a6a1b4ba4c67e8fd682eea8fea Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Thu, 21 May 2020 16:01:13 -0300 Subject: [PATCH 006/698] remove tags left in nessus by mistake --- faraday_plugins/plugins/repo/nessus/plugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/faraday_plugins/plugins/repo/nessus/plugin.py b/faraday_plugins/plugins/repo/nessus/plugin.py index be3a7517..efe15c96 100644 --- a/faraday_plugins/plugins/repo/nessus/plugin.py +++ b/faraday_plugins/plugins/repo/nessus/plugin.py @@ -220,7 +220,7 @@ def parseOutputString(self, output): website = None host_name = None - host_id = self.createAndAddHost(ip_host, os=os, hostnames=host_name, mac=mac, tags=["test_tag"]) + host_id = self.createAndAddHost(ip_host, os=os, hostnames=host_name, mac=mac) interface_id = self.createAndAddInterface(host_id, ip, ipv6_address=ip, mac=mac) cve = [] @@ -336,7 +336,7 @@ def parseOutputString(self, output): interface_id, name=serv_name, protocol=serv_protocol, - ports=serv_port, tags=["test_tag"]) + ports=serv_port) if serv_name == 'www' or serv_name == 'http': self.createAndAddVulnWebToService(host_id, From e743a1545ea3c101f87172a713eea632a7adba1f Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Thu, 21 May 2020 18:55:10 -0300 Subject: [PATCH 007/698] remove test to checko if report is deleted. Just add assert in other test --- tests/test_report_collection.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tests/test_report_collection.py b/tests/test_report_collection.py index b16116d5..ea82e98c 100644 --- a/tests/test_report_collection.py +++ b/tests/test_report_collection.py @@ -152,11 +152,5 @@ def test_detected_tools_on_all_report_collection(report_filename, benchmark): plugin_json = json.loads(plugin.get_json()) assert "hosts" in plugin_json assert "command" in plugin_json - -@pytest.mark.parametrize("report_filename", list_report_files()) -def test_not_delete_report(report_filename): - plugins_manager = PluginsManager() - analyzer = ReportAnalyzer(plugins_manager) - plugin: PluginBase = analyzer.get_plugin(report_filename) - plugin.processReport(report_filename) assert os.path.isfile(report_filename) is True + From 160492a87c289766ab8e1dfa514074c04d357061 Mon Sep 17 00:00:00 2001 From: Javier Date: Thu, 21 May 2020 22:17:49 -0400 Subject: [PATCH 008/698] [ADD] Tags to vulns in faraday_csv plugin Issue ref #101 --- faraday_plugins/plugins/repo/faraday_csv/plugin.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/faraday_plugins/plugins/repo/faraday_csv/plugin.py b/faraday_plugins/plugins/repo/faraday_csv/plugin.py index 4cb69222..bd5caaac 100644 --- a/faraday_plugins/plugins/repo/faraday_csv/plugin.py +++ b/faraday_plugins/plugins/repo/faraday_csv/plugin.py @@ -51,6 +51,7 @@ def __init__(self, csv_output, logger): "params", "query", "status_code", + "tags" ] self.items = self.parse_csv(csv_output) @@ -196,7 +197,7 @@ def build_vulnerability(self, row, custom_fields_names): if "impact_" in item: impact = re.match(r"impact_(\w+)", item).group(1) impact_dict[impact] = True if row[item] == "True" else False - elif item == "refs" or item == "policyviolations": + elif item in ["refs", "policyviolations", "tags"]: self.data[item] = literal_eval(row[item]) else: self.data[item] = row[item] @@ -288,7 +289,8 @@ def parseOutputString(self, output, debug=False): easeofresolution=item['easeofresolution'] or None, impact=item['impact'], policyviolations=item['policyviolations'], - custom_fields=item['custom_fields'] + custom_fields=item['custom_fields'], + tags=item['tags'] ) if not item['web_vulnerability'] and s_id: self.createAndAddVulnToService( @@ -306,7 +308,8 @@ def parseOutputString(self, output, debug=False): easeofresolution=item['easeofresolution'] or None, impact=item['impact'], policyviolations=item['policyviolations'], - custom_fields=item['custom_fields'] + custom_fields=item['custom_fields'], + tags=item['tags'] ) elif item['web_vulnerability']: self.createAndAddVulnWebToService( @@ -333,7 +336,8 @@ def parseOutputString(self, output, debug=False): impact=item['impact'], policyviolations=item['policyviolations'], status_code=item['status_code'] or None, - custom_fields=item['custom_fields'] + custom_fields=item['custom_fields'], + tags=item['tags'] ) From 3343e14edb6ecc46bdfc7d692d1f0626decbc1d8 Mon Sep 17 00:00:00 2001 From: Javier Date: Thu, 21 May 2020 22:20:39 -0400 Subject: [PATCH 009/698] [ADD] Tags to hosts and services in faraday_csv plugin --- .../plugins/repo/faraday_csv/plugin.py | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/faraday_plugins/plugins/repo/faraday_csv/plugin.py b/faraday_plugins/plugins/repo/faraday_csv/plugin.py index bd5caaac..337eea82 100644 --- a/faraday_plugins/plugins/repo/faraday_csv/plugin.py +++ b/faraday_plugins/plugins/repo/faraday_csv/plugin.py @@ -17,13 +17,15 @@ def __init__(self, csv_output, logger): "host_description", "os", "mac", - "hostnames" + "hostnames", + "host_tags" ] self.service_data = [ "service_name", "service_description", "version", - "service_status" + "service_status", + "service_tags" ] self.vuln_data = [ "name", @@ -159,7 +161,10 @@ def build_host(self, row): continue if item in row: - self.data[item] = row[item] + if item == "host_tags": + self.data[item] = literal_eval(row[item]) + else: + self.data[item] = row[item] else: self.data[item] = None @@ -173,6 +178,9 @@ def build_service(self, row): # If status is not specified, set it as 'open' self.data[item] = "open" continue + elif item == 'service_tags': + self.data[item] = literal_eval(row[item]) + continue self.data[item] = row[item] else: self.data[item] = None @@ -260,7 +268,8 @@ def parseOutputString(self, output, debug=False): os=item['os'], hostnames=item['hostnames'], mac=item['mac'], - description=item['host_description'] or "" + description=item['host_description'] or "", + tags=item['host_tags'] ) s_id = None if item['row_with_service']: @@ -271,7 +280,8 @@ def parseOutputString(self, output, debug=False): ports=item['port'], status=item['service_status'] or None, version=item['version'], - description=item['service_description'] + description=item['service_description'], + tags=item['service_tags'] ) if item['row_with_vuln']: if not item['web_vulnerability'] and not s_id: From fd854c6814726682b0707eb32b3254f45ae56ffa Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Fri, 22 May 2020 15:45:19 -0300 Subject: [PATCH 010/698] fix cobalt plugin --- faraday_plugins/commands.py | 7 +- faraday_plugins/plugins/plugins_utils.py | 21 ----- faraday_plugins/plugins/repo/cobalt/plugin.py | 86 ++++++++----------- 3 files changed, 40 insertions(+), 74 deletions(-) diff --git a/faraday_plugins/commands.py b/faraday_plugins/commands.py index 63e31730..da2ebe9e 100644 --- a/faraday_plugins/commands.py +++ b/faraday_plugins/commands.py @@ -9,7 +9,6 @@ import getpass from faraday_plugins.plugins.manager import PluginsManager, ReportAnalyzer, CommandAnalyzer -from faraday_plugins.plugins.plugins_utils import get_report_summary from faraday_plugins.plugins.plugin import PluginByExtension root_logger = logging.getLogger("faraday") @@ -71,8 +70,7 @@ def process_report(report_file, plugin_id, custom_plugins_folder, summary): plugin.processReport(report_file, getpass.getuser()) if summary: click.echo(click.style("\nPlugin Summary: ", fg="cyan")) - report_json = json.loads(plugin.get_json()) - click.echo(json.dumps(get_report_summary(report_json), indent=4)) + click.echo(json.dumps(plugin.get_summary(), indent=4)) else: click.echo(click.style("\nFaraday API json: ", fg="cyan")) click.echo(json.dumps(plugin.get_data(), indent=4)) @@ -121,8 +119,7 @@ def process_command(command, plugin_id, custom_plugins_folder, dont_run, summary plugin.processOutput(output_value) if summary: click.echo(click.style("\nPlugin Summary: ", fg="cyan")) - report_json = json.loads(plugin.get_json()) - click.echo(json.dumps(get_report_summary(report_json), indent=4)) + click.echo(json.dumps(plugin.get_summary(), indent=4)) else: click.echo(click.style("\nFaraday API json: ", fg="cyan")) click.echo(json.dumps(plugin.get_data(), indent=4)) diff --git a/faraday_plugins/plugins/plugins_utils.py b/faraday_plugins/plugins/plugins_utils.py index 67500054..c51a7ca4 100644 --- a/faraday_plugins/plugins/plugins_utils.py +++ b/faraday_plugins/plugins/plugins_utils.py @@ -98,27 +98,6 @@ def get_all_protocols(): yield item -def get_report_summary(plugin_json): - summary = {'hosts': len(plugin_json['hosts']), 'services': 0, - 'hosts_vulns': sum(list(map(lambda x: len(x['vulnerabilities']), plugin_json['hosts']))), - 'services_vulns': 0, 'severity_vulns': defaultdict(int)} - - hosts_with_services = filter(lambda x: len(x['services']) > 0, plugin_json['hosts']) - host_services = list(map(lambda x: x['services'], hosts_with_services)) - summary['services'] = sum(map(lambda x: len(x), host_services)) - services_vulns = 0 - for host in plugin_json['hosts']: - for vuln in host['vulnerabilities']: - summary['severity_vulns'][vuln['severity']] += 1 - for services in host_services: - for service in services: - services_vulns += len(service['vulnerabilities']) - for vuln in service['vulnerabilities']: - summary['severity_vulns'][vuln['severity']] += 1 - summary['services_vulns'] = services_vulns - return summary - - def resolve_hostname(hostname): try: ip_address = socket.gethostbyname(hostname) diff --git a/faraday_plugins/plugins/repo/cobalt/plugin.py b/faraday_plugins/plugins/repo/cobalt/plugin.py index 1d3b6cd0..08d28710 100644 --- a/faraday_plugins/plugins/repo/cobalt/plugin.py +++ b/faraday_plugins/plugins/repo/cobalt/plugin.py @@ -6,13 +6,11 @@ """ from faraday_plugins.plugins.plugin import PluginCSVFormat -import re -import os from urllib.parse import urlparse import csv -import io +import io +import dateutil -current_path = os.path.abspath(os.getcwd()) __author__ = "Blas" __copyright__ = "Copyright (c) 2019, Infobyte LLC" @@ -23,6 +21,8 @@ __email__ = "bmoyano@infobytesec.com" __status__ = "Development" +from faraday_plugins.plugins.plugins_utils import resolve_hostname + class CobaltParser: """ @@ -40,6 +40,9 @@ def __init__(self, output): self.headers = reader.fieldnames self.rows = [] for row in reader: + for k, v in row.items(): + if v.startswith("'"): + row[k] = v[1:] self.rows.append(row) @@ -50,66 +53,53 @@ class CobaltPlugin(PluginCSVFormat): def __init__(self): super().__init__() - self.extension = ".csv" self.csv_headers = [{'Token'}, {'Tag'}] self.id = "Cobalt" self.name = "Cobalt CSV Output Plugin" self.plugin_version = "0.0.1" self.version = "0.0.1" self.framework_version = "1.0.1" - self.options = None - self._current_output = None - self._current_path = None - self._command_regex = re.compile( - r'^(cobalt|sudo cobalt|\.\/cobalt).*?') - self.host = None - self.port = None - self.protocol = None - self.fail = None - - def canParseCommandString(self, current_input): - if self._command_regex.match(current_input.strip()): - return True - else: - return False - - def parseOutputString(self, output, debug=False): - """ - This method will discard the output the shell sends, it will read it from - the xml where it expects it to be present. - - NOTE: if 'debug' is true then it is being run from a test case and the - output being sent is valid. - """ + + def parseOutputString(self, output): try: parser = CobaltParser(output) except: print("Error parser output") return None - vul_ref = [] for row in parser.rows: - vul_ref_info = "Criticality Justification:{} Tools Used:{}".format(row['CriticalityJustification'], - row['ToolsUsed']) - vul_ref.append(vul_ref_info) - url = urlparse(row['BrowserUrl']) - protocol = url.scheme - port = url.port - if url.port is None: - if protocol == 'https': + url = row['BrowserUrl'] + if not url: + continue + url_data = urlparse(url) + scheme = url_data.scheme + port = url_data.port + try: + run_date = dateutil.parser.parse(row['CreatedAt']) + except: + run_date = None + if url_data.port is None: + if scheme == 'https': port = 443 - elif protocol == 'http': + elif scheme == 'http': port = 80 - else: - port = None - - h_id = self.createAndAddHost(name='0.0.0.0', hostnames=[row['BrowserUrl']]) - s_id = self.createAndAddServiceToInterface(h_id, protocol, "tcp", ports=port, status="open") + else: + port = url_data.port + name = resolve_hostname(url_data.netloc) + references = [] + if row['RefKey']: + references.append(row['RefKey']) + if row['ResearcherUrl']: + references.append(row['ResearcherUrl']) + references.append(row['ReportUrl']) + request = row['HttpRequest'] if row['HttpRequest'] else row['BrowserUrl'] + h_id = self.createAndAddHost(name=name, hostnames=[url_data.netloc]) + s_id = self.createAndAddServiceToHost(h_id, scheme, "tcp", ports=port, status="open") self.createAndAddVulnWebToService(h_id, s_id, name=row['Title'], desc=row['Description'], - ref=vul_ref, resolution=row['SuggestedFix'], - website=row['ReportUrl'], request=row['HttpRequest'], - pname=row['Tag'], category=row['Type'], - data=row['StepsToReproduce'], external_id=None) + ref=references, resolution=row['SuggestedFix'], + website=url_data.netloc, request=request, + pname=url_data.params, category=row['Type'], path=url_data.path, + data=row['StepsToReproduce'], external_id=row['Tag'], run_date=run_date) def createPlugin(): From e562e17604aec77d48ed0479c7f293a51247d944 Mon Sep 17 00:00:00 2001 From: Javier Date: Tue, 26 May 2020 19:51:25 -0400 Subject: [PATCH 011/698] [ADD] Tunnel details on service in Nmap plugin Issue ref #87 --- faraday_plugins/plugins/repo/nmap/plugin.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/faraday_plugins/plugins/repo/nmap/plugin.py b/faraday_plugins/plugins/repo/nmap/plugin.py index 7ad65c93..b0d619cf 100644 --- a/faraday_plugins/plugins/repo/nmap/plugin.py +++ b/faraday_plugins/plugins/repo/nmap/plugin.py @@ -400,6 +400,10 @@ def __init__(self, service_node): name = service_node.get("name") self.name = name if name else 'unknown' + self.tunnel = service_node.get("tunnel") + if self.tunnel == "ssl" and self.name == "http": + self.name = "https" + product = service_node.get("product") self.product = product if product else 'unknown' From ae8084676a53abffc6687eaa8cbae7f2a8a43b75 Mon Sep 17 00:00:00 2001 From: Javier Date: Wed, 27 May 2020 14:37:14 -0400 Subject: [PATCH 012/698] [ADD] More protocols --- faraday_plugins/plugins/repo/nmap/plugin.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/faraday_plugins/plugins/repo/nmap/plugin.py b/faraday_plugins/plugins/repo/nmap/plugin.py index b0d619cf..a9955215 100644 --- a/faraday_plugins/plugins/repo/nmap/plugin.py +++ b/faraday_plugins/plugins/repo/nmap/plugin.py @@ -401,8 +401,13 @@ def __init__(self, service_node): self.name = name if name else 'unknown' self.tunnel = service_node.get("tunnel") - if self.tunnel == "ssl" and self.name == "http": - self.name = "https" + if self.tunnel == "ssl": + if self.name == "http": + self.name = "https" + elif self.name == 'imap': + self.name = 'imaps' + elif self.name == 'pop3': + self.name = 'pop3s' product = service_node.get("product") self.product = product if product else 'unknown' From a9f5674a970eb70ef96b05528d369eb85cc601b0 Mon Sep 17 00:00:00 2001 From: Leonardo Lazzaro Date: Mon, 1 Jun 2020 14:32:34 -0300 Subject: [PATCH 013/698] increase plugins version --- faraday_plugins/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faraday_plugins/__init__.py b/faraday_plugins/__init__.py index 439eb0cd..64477cf2 100644 --- a/faraday_plugins/__init__.py +++ b/faraday_plugins/__init__.py @@ -1 +1 @@ -__version__ = '1.1' +__version__ = '1.2' From b90c587ba8e9ac537064eb16d0139e1d4edc1050 Mon Sep 17 00:00:00 2001 From: Leonardo Lazzaro Date: Mon, 1 Jun 2020 15:01:55 -0300 Subject: [PATCH 014/698] update publish pipy job --- .gitlab-ci.yml | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f5589b24..931f5d70 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -75,15 +75,12 @@ test_performance: publish_pypi: image: python:3 stage: publish - before_script: - - pip3 install virtualenv - - virtualenv -p python3 faraday_venv - - source faraday_venv/bin/activate - - pip install twine script: + - apt-get update -qy + - apt-get install twine -y - python setup.py sdist bdist_wheel - - twine upload dist/* -u $TWINE_USERNAME -p $TWINE_PASSWORD - + - twine upload -u $PYPI_USER -p $PYPI_PASS dist/* --verbose rules: - - if: '$CI_COMMIT_TAG =~ /^v[0-9.]+$/' + - if: '$CI_COMMIT_TAG' when: on_success + From 024df618e51ad482ab44cf95a66cc4b1bfa494d4 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Mon, 8 Jun 2020 10:54:41 -0300 Subject: [PATCH 015/698] add option to send plugin output to file --- faraday_plugins/commands.py | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/faraday_plugins/commands.py b/faraday_plugins/commands.py index da2ebe9e..924a01d1 100644 --- a/faraday_plugins/commands.py +++ b/faraday_plugins/commands.py @@ -51,7 +51,8 @@ def list_plugins(custom_plugins_folder): @click.option('--plugin_id', type=str) @click.option('-cpf', '--custom-plugins-folder', type=str) @click.option('--summary', is_flag=True) -def process_report(report_file, plugin_id, custom_plugins_folder, summary): +@click.option('-o', '--output-file', type=click.Path(exists=False)) +def process_report(report_file, plugin_id, custom_plugins_folder, summary, output_file): if not os.path.isfile(report_file): click.echo(click.style(f"File {report_file} Don't Exists", fg="red")) else: @@ -67,13 +68,19 @@ def process_report(report_file, plugin_id, custom_plugins_folder, summary): if not plugin: click.echo(click.style(f"Failed to detect report: {report_file}", fg="red")) return + color_message = click.style("Processing report:", fg="green") + click.echo(f"{color_message} {report_file} ({plugin.id})\n") plugin.processReport(report_file, getpass.getuser()) if summary: click.echo(click.style("\nPlugin Summary: ", fg="cyan")) click.echo(json.dumps(plugin.get_summary(), indent=4)) else: - click.echo(click.style("\nFaraday API json: ", fg="cyan")) - click.echo(json.dumps(plugin.get_data(), indent=4)) + if output_file: + with open(output_file, "w") as f: + json.dump(plugin.get_data(), f) + else: + click.echo(click.style("\nFaraday API json: ", fg="cyan")) + click.echo(json.dumps(plugin.get_data(), indent=4)) @cli.command() @@ -82,7 +89,8 @@ def process_report(report_file, plugin_id, custom_plugins_folder, summary): @click.option('-cpf', '--custom-plugins-folder', type=str) @click.option('-dr', '--dont-run', is_flag=True) @click.option('--summary', is_flag=True) -def process_command(command, plugin_id, custom_plugins_folder, dont_run, summary): +@click.option('-o', '--output-file', type=click.Path(exists=False)) +def process_command(command, plugin_id, custom_plugins_folder, dont_run, summary, output_file): plugins_manager = PluginsManager(custom_plugins_folder) analyzer = CommandAnalyzer(plugins_manager) if plugin_id: @@ -100,7 +108,7 @@ def process_command(command, plugin_id, custom_plugins_folder, dont_run, summary if modified_command: command = modified_command if not dont_run: - color_message = click.style("Running command: ", fg="green") + color_message = click.style("Running command:", fg="green") click.echo(f"{color_message} {command}\n") p = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE, stderr=subprocess.PIPE) output = io.StringIO() @@ -121,8 +129,12 @@ def process_command(command, plugin_id, custom_plugins_folder, dont_run, summary click.echo(click.style("\nPlugin Summary: ", fg="cyan")) click.echo(json.dumps(plugin.get_summary(), indent=4)) else: - click.echo(click.style("\nFaraday API json: ", fg="cyan")) - click.echo(json.dumps(plugin.get_data(), indent=4)) + if output_file: + with open(output_file, "w") as f: + json.dump(plugin.get_data(), f) + else: + click.echo(click.style("\nFaraday API json: ", fg="cyan")) + click.echo(json.dumps(plugin.get_data(), indent=4)) else: click.echo(click.style("Command execution error!!", fg="red")) else: From d0cd215ec66417ba261574a7b5e5681bcb2a6643 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Mon, 8 Jun 2020 14:13:48 -0300 Subject: [PATCH 016/698] fix test --- .gitlab-ci.yml | 2 +- tests/test_report_collection.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 931f5d70..c3c61a73 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -35,7 +35,7 @@ tests: - pip3 install virtualenv - virtualenv -p python3 faraday_venv - source faraday_venv/bin/activate - - pip3 install pytest pytest-xdist pytest-cov + - pip3 install pytest pytest-xdist pytest-cov Flask-Restless==0.17.0 - git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/faradaysec/faraday.git - git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/faradaysec/support/report-collection.git - cd faraday diff --git a/tests/test_report_collection.py b/tests/test_report_collection.py index ea82e98c..df82f41d 100644 --- a/tests/test_report_collection.py +++ b/tests/test_report_collection.py @@ -107,7 +107,9 @@ def test_schema_on_all_reports(report_filename): if plugin_json: serializer = BulkCreateSchema() res = serializer.loads(json.dumps(plugin_json)) - assert not res.errors + assert set(res.keys()) == {'hosts', 'command'} + + @pytest.mark.skip(reason="Skip validate ip format") From e376dd9567dd10f65a43c71c953c2747e929609d Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 10:06:44 -0300 Subject: [PATCH 017/698] add changelog --- CHANGELOG/current/add_output_file_to_faraday-plugins_command.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 CHANGELOG/current/add_output_file_to_faraday-plugins_command.md diff --git a/CHANGELOG/current/add_output_file_to_faraday-plugins_command.md b/CHANGELOG/current/add_output_file_to_faraday-plugins_command.md new file mode 100644 index 00000000..ee950889 --- /dev/null +++ b/CHANGELOG/current/add_output_file_to_faraday-plugins_command.md @@ -0,0 +1 @@ +Add --output-file parameter to faraday-plugins process command \ No newline at end of file From b11a0f7e915e2c26a6c70d0fe1734e16215f9ef2 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 10:32:05 -0300 Subject: [PATCH 018/698] clean accunetix --- faraday_plugins/plugins/repo/acunetix/plugin.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/faraday_plugins/plugins/repo/acunetix/plugin.py b/faraday_plugins/plugins/repo/acunetix/plugin.py index f8919454..aabc9ba9 100644 --- a/faraday_plugins/plugins/repo/acunetix/plugin.py +++ b/faraday_plugins/plugins/repo/acunetix/plugin.py @@ -243,18 +243,13 @@ def parseOutputString(self, output, debug=False): if site.ip is None: continue - if site.host != site.ip: - host = site.host - h_id = self.createAndAddHost(site.ip, site.os) - if site.host is None: - i_id = self.createAndAddInterface(h_id, site.ip, ipv4_address=site.ip) + if site.host != site.ip and site.host is not None: + hostnames = [site.host] else: - i_id = self.createAndAddInterface(h_id, site.ip, - ipv4_address=site.ip, - hostname_resolution=[host]) - s_id = self.createAndAddServiceToInterface( + hostnames = None + h_id = self.createAndAddHost(site.ip, site.os, hostnames=hostnames) + s_id = self.createAndAddServiceToHost( h_id, - i_id, "http", "tcp", ports=[site.port], From a20ceb894cab036c2f68d9ac26f50122dc876030 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 10:41:05 -0300 Subject: [PATCH 019/698] clean amap --- faraday_plugins/plugins/repo/amap/plugin.py | 26 ++++----------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/faraday_plugins/plugins/repo/amap/plugin.py b/faraday_plugins/plugins/repo/amap/plugin.py index 1e888fae..abd01f47 100644 --- a/faraday_plugins/plugins/repo/amap/plugin.py +++ b/faraday_plugins/plugins/repo/amap/plugin.py @@ -37,22 +37,15 @@ def parseOutputString(self, output): for line in output.split('\n'): if line.startswith('#'): continue - fields = self.get_info(line) - if len(fields) < 6: continue - address = fields[0] - h_id = self.createAndAddHost(address) - port = fields[1] protocol = fields[2] port_status = fields[3] - identification = fields[5] printable_banner = fields[6] - if port in services.keys(): if identification != 'unidentified': services[port][5] += ', ' + identification @@ -67,25 +60,16 @@ def parseOutputString(self, output): printable_banner, None] - args = {} - - if self.args.__getattribute__("6"): - self.ip = self.get_ip_6(self.args.m) - args['ipv6_address'] = address - else: - self.ip = resolve_hostname(self.args.m) - args['ipv4_address'] = address - if address != self.args.m: - args['hostname_resolution'] = [self.args.m] - - i_id = self.createAndAddInterface(h_id, name=address, **args) + hostnames = [self.args.m] + else: + hostnames = None + h_id = self.createAndAddHost(address, hostnames=hostnames) for key in services: service = services.get(key) - self.createAndAddServiceToInterface( + self.createAndAddServiceToHost( h_id, - i_id, service[5], service[2], ports=[service[1]], From b699a7729f4b50f3ffe7e47899a456b9a519759b Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 10:44:24 -0300 Subject: [PATCH 020/698] clean arachni --- faraday_plugins/plugins/repo/arachni/plugin.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/faraday_plugins/plugins/repo/arachni/plugin.py b/faraday_plugins/plugins/repo/arachni/plugin.py index 9bc6f4fd..2ebaa377 100755 --- a/faraday_plugins/plugins/repo/arachni/plugin.py +++ b/faraday_plugins/plugins/repo/arachni/plugin.py @@ -379,18 +379,11 @@ def parseOutputString(self, output, debug=False): self.address = resolve_hostname(parser.plugins.ip) # Create host and interface - host_id = self.createAndAddHost(self.address) - - interface_id = self.createAndAddInterface( - host_id, - self.address, - ipv4_address=self.address, - hostname_resolution=[self.hostname]) + host_id = self.createAndAddHost(self.address, hostnames=[self.hostname]) # Create service - service_id = self.createAndAddServiceToInterface( + service_id = self.createAndAddServiceToHost( host_id, - interface_id, self.protocol, 'tcp', ports=[self.port], From 4a2309badd5613d43999a39508158cff499e3b60 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 10:49:07 -0300 Subject: [PATCH 021/698] clean arp_scan --- faraday_plugins/plugins/repo/arp_scan/plugin.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/faraday_plugins/plugins/repo/arp_scan/plugin.py b/faraday_plugins/plugins/repo/arp_scan/plugin.py index 58ae0868..e955acb9 100644 --- a/faraday_plugins/plugins/repo/arp_scan/plugin.py +++ b/faraday_plugins/plugins/repo/arp_scan/plugin.py @@ -54,8 +54,7 @@ def parseOutputString(self, output): if len(vals[0].split(".")) == 4: host = vals[0] - h_id = self.createAndAddHost(host) - i_id = self.createAndAddInterface(h_id, host, ipv4_address=host, mac=vals[1]) + h_id = self.createAndAddHost(host, mac=vals[1]) return True From 367976f58750b0435a9907e0dc58a882c7c74e8d Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 10:59:01 -0300 Subject: [PATCH 022/698] clean brutexss --- faraday_plugins/plugins/repo/brutexss/plugin.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/faraday_plugins/plugins/repo/brutexss/plugin.py b/faraday_plugins/plugins/repo/brutexss/plugin.py index 95723bef..1b9dea6c 100644 --- a/faraday_plugins/plugins/repo/brutexss/plugin.py +++ b/faraday_plugins/plugins/repo/brutexss/plugin.py @@ -44,14 +44,12 @@ def parseOutputString(self, output, debug=False): vuln_list = re.findall("\w+", linea) if vuln_list[2] == "Vulnerable": parametro.append(vuln_list[1]) - found_vuln=len(parametro) > 0 - host_id = self.createAndAddHost(url) + found_vuln = len(parametro) > 0 address = resolve_hostname(url) - interface_id = self.createAndAddInterface(host_id, address, ipv4_address=address, - hostname_resolution=[url]) - service_id = self.createAndAddServiceToInterface(host_id, interface_id, self.protocol, 'tcp', - ports=[port], status='Open', version="", - description="") + host_id = self.createAndAddHost(url, hostnames=[url]) + service_id = self.createAndAddServiceToHost(host_id, self.protocol, 'tcp', + ports=[port], status='Open', version="", + description="") if found_vuln: self.createAndAddVulnWebToService(host_id, service_id, name="xss", desc="XSS", ref='', severity='med', website=url, path='', method='', pname='', params=''.join(parametro), From 5567f0d48af87f234f725ba5df6263fdbdb0b30e Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 11:04:24 -0300 Subject: [PATCH 023/698] clean burp --- faraday_plugins/plugins/repo/burp/plugin.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/faraday_plugins/plugins/repo/burp/plugin.py b/faraday_plugins/plugins/repo/burp/plugin.py index 93e86295..7da59fe8 100644 --- a/faraday_plugins/plugins/repo/burp/plugin.py +++ b/faraday_plugins/plugins/repo/burp/plugin.py @@ -228,17 +228,9 @@ def parseOutputString(self, output, debug=False): parser = BurpXmlParser(output) for item in parser.items: - h_id = self.createAndAddHost(item.ip) - - i_id = self.createAndAddInterface( - h_id, - item.ip, - ipv4_address=item.ip, - hostname_resolution=[item.host]) - - s_id = self.createAndAddServiceToInterface( + h_id = self.createAndAddHost(item.ip, hostnames=[item.host]) + s_id = self.createAndAddServiceToHost( h_id, - i_id, item.protocol, "tcp", ports=[str(item.port)], From 152e09894084ef1b2ce0008e9063508c96bde215 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 11:15:06 -0300 Subject: [PATCH 024/698] clean checkmarx --- faraday_plugins/plugins/repo/checkmarx/plugin.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/faraday_plugins/plugins/repo/checkmarx/plugin.py b/faraday_plugins/plugins/repo/checkmarx/plugin.py index 89c3b5c8..fbcf549d 100755 --- a/faraday_plugins/plugins/repo/checkmarx/plugin.py +++ b/faraday_plugins/plugins/repo/checkmarx/plugin.py @@ -106,18 +106,8 @@ def parseOutputString(self, output): else: port = 0 project_name = 'ProjectName' in parser.cx_xml_results_attribs - if project_name: - host_id = self.createAndAddHost(url.hostname, hostnames=[url.hostname]) - interface_id = self.createAndAddInterface(host_id, url.hostname, ipv4_address=url.hostname, - hostname_resolution=[url.netloc]) - service_to_interface = self.createAndAddServiceToInterface(host_id, interface_id, name=url.scheme, - ports=port) - else: - host_id = self.createAndAddHost(url.hostname, hostnames=[url.hostname]) - interface_id = self.createAndAddInterface(host_id, url.hostname, ipv4_address=url.hostname, - hostname_resolution=[url.netloc]) - service_to_interface = self.createAndAddServiceToInterface(host_id, interface_id, name=url.scheme, - ports=port) + host_id = self.createAndAddHost(url.hostname, hostnames=[url.hostname, url.netloc]) + service_to_interface = self.createAndAddServiceToHost(host_id, name=url.scheme, ports=port) for vulns in parser.query: refs = [] categories = 'categories' in vulns.query_attrib From 346cd207d378be02aa3fcbcd8b886c80ef8221ec Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 11:19:38 -0300 Subject: [PATCH 025/698] clean dig --- faraday_plugins/plugins/repo/dig/plugin.py | 29 +++------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/faraday_plugins/plugins/repo/dig/plugin.py b/faraday_plugins/plugins/repo/dig/plugin.py index 5e6a1daf..e5c43424 100644 --- a/faraday_plugins/plugins/repo/dig/plugin.py +++ b/faraday_plugins/plugins/repo/dig/plugin.py @@ -67,24 +67,7 @@ def parseOutputString(self, output): ip_address = resolve_hostname(domain) # Create host - host_id = self.createAndAddHost(ip_address) - - # create interface (special if type "AAAA") - if result.get(u"type") == u"AAAA": # AAAA = IPv6 address - # TODO is there a function to dynamically update the paramter ipv6_address of an already-created interface? - ipv6_address = result.get(u"data")[0] - interface_id = self.createAndAddInterface( - host_id, - ip_address, - ipv4_address=ip_address, - ipv6_address=ipv6_address, - hostname_resolution=[domain]) - else: - interface_id = self.createAndAddInterface( - host_id, - ip_address, - ipv4_address=ip_address, - hostname_resolution=[domain]) + host_id = self.createAndAddHost(ip_address, hostnames=[domain]) # all other TYPES that aren't 'A' and 'AAAA' are dealt here: @@ -92,9 +75,8 @@ def parseOutputString(self, output): mx_priority = result.get(u"data")[0] mx_record = result.get(u"data")[1] - service_id = self.createAndAddServiceToInterface( + service_id = self.createAndAddServiceToHost( host_id=host_id, - interface_id=interface_id, name=mx_record, protocol="SMTP", ports=[25], @@ -109,9 +91,7 @@ def parseOutputString(self, output): elif result.get(u"type") == u"NS": # Name server record ns_record = result.get(u"data")[0] - self.createAndAddServiceToInterface( - host_id=host_id, - interface_id=interface_id, + self.createAndAddServiceToHost( name=ns_record, protocol="DNS", ports=[53], @@ -126,9 +106,8 @@ def parseOutputString(self, output): upper_limit_time = result.get(u"data")[5] negative_result_ttl = result.get(u"data")[6] - service_id = self.createAndAddServiceToInterface( + service_id = self.createAndAddServiceToHost( host_id=host_id, - interface_id=interface_id, name=ns_record, protocol="DNS", ports=[53], From f92051fe9ab42a130f2ab26f060f14a7b46947f2 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 11:20:52 -0300 Subject: [PATCH 026/698] clean dirb --- faraday_plugins/plugins/repo/dirb/plugin.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/faraday_plugins/plugins/repo/dirb/plugin.py b/faraday_plugins/plugins/repo/dirb/plugin.py index 1f45bb4c..2aa305d6 100644 --- a/faraday_plugins/plugins/repo/dirb/plugin.py +++ b/faraday_plugins/plugins/repo/dirb/plugin.py @@ -88,19 +88,13 @@ def parseOutputString(self, output): puerto = self.getPort(url.group(1), proto) host_id = self.createAndAddHost(ip) - iface_id = self.createAndAddInterface(host_id, ip, ipv4_address = ip) - - serv_id = self.createAndAddServiceToInterface(host_id, iface_id, proto, protocol=proto, ports=[puerto], - status=status) - + serv_id = self.createAndAddServiceToHost(host_id, proto, protocol=proto, ports=[puerto], status=status) if len(self.text) > 0: self.createAndAddVulnWebToService(host_id, serv_id, 'Url Fuzzing', severity=0, desc=self.text, website=domain) - if len(paths) > 0: self.createAndAddVulnWebToService(host_id, serv_id, "Directory Listing", severity="med", website=domain, request=paths, method="GET") - return True def processCommandString(self, username, current_path, command_string): From a220644fa65b00363f2e5aaaf8a95ded636ff98d Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 11:22:49 -0300 Subject: [PATCH 027/698] clean dirsearch --- faraday_plugins/plugins/repo/dirsearch/plugin.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/faraday_plugins/plugins/repo/dirsearch/plugin.py b/faraday_plugins/plugins/repo/dirsearch/plugin.py index 01e634b6..bf57d241 100644 --- a/faraday_plugins/plugins/repo/dirsearch/plugin.py +++ b/faraday_plugins/plugins/repo/dirsearch/plugin.py @@ -84,17 +84,9 @@ def parse_json(self, contents): for (base_url, items) in data.items(): base_split = urlparse.urlsplit(base_url) ip = resolve_hostname(base_split.hostname) - h_id = self.createAndAddHost(ip) - - i_id = self.createAndAddInterface( - h_id, - name=ip, - ipv4_address=ip, - hostname_resolution=[base_split.hostname]) - - s_id = self.createAndAddServiceToInterface( + h_id = self.createAndAddHost(ip, hostnames=[base_split.hostname]) + s_id = self.createAndAddServiceToHost( h_id, - i_id, base_split.scheme, 'tcp', [base_split.port], From b22bb3788842e1cef9f556c1b60644d67096d92c Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 11:24:41 -0300 Subject: [PATCH 028/698] clear dnsenum --- faraday_plugins/plugins/repo/dnsenum/plugin.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/faraday_plugins/plugins/repo/dnsenum/plugin.py b/faraday_plugins/plugins/repo/dnsenum/plugin.py index 80c550c8..a4a8c934 100644 --- a/faraday_plugins/plugins/repo/dnsenum/plugin.py +++ b/faraday_plugins/plugins/repo/dnsenum/plugin.py @@ -176,12 +176,7 @@ def parseOutputString(self, output, debug=False): parser = DnsenumXmlParser(output) for item in parser.items: - h_id = self.createAndAddHost(item.ip) - i_id = self.createAndAddInterface( - h_id, - item.ip, - ipv4_address=item.ip, - hostname_resolution=[item.hostname]) + h_id = self.createAndAddHost(item.ip, hostnames=[item.hostname]) del parser From 83dc94e5ecd1040a1f4df4dbd127c6192508a5a7 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 11:28:44 -0300 Subject: [PATCH 029/698] clean dnsrecon --- .../plugins/repo/dnsrecon/plugin.py | 23 ++----------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/faraday_plugins/plugins/repo/dnsrecon/plugin.py b/faraday_plugins/plugins/repo/dnsrecon/plugin.py index f8b5b6ed..00a69912 100644 --- a/faraday_plugins/plugins/repo/dnsrecon/plugin.py +++ b/faraday_plugins/plugins/repo/dnsrecon/plugin.py @@ -1,6 +1,3 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - """ Faraday Penetration Test IDE Copyright (C) 2013 Infobyte LLC (http://www.infobytesec.com/) @@ -198,26 +195,10 @@ def parseOutputString(self, output, debug=False): elif host.type == "A": hostname = host.name - h_id = self.createAndAddHost(host.address) - - if self._isIPV4(str(host.address)): - i_id = self.createAndAddInterface( - h_id, - name=host.address, - ipv4_address=host.address, - hostname_resolution=[hostname]) - else: - i_id = self.createAndAddInterface( - h_id, - name=host.address, - ipv6_address=host.address, - hostname_resolution=[hostname]) - + h_id = self.createAndAddHost(host.address, hostnames=[hostname]) if host.type == "info": - - s_id = self.createAndAddServiceToInterface( + s_id = self.createAndAddServiceToHost( h_id, - i_id, "domain", protocol="tcp", ports=["53"], From fbddf5d995aef2de02e41efdfce84c3de470d054 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 11:31:16 -0300 Subject: [PATCH 030/698] clean dnswalk --- .../plugins/repo/dnswalk/plugin.py | 24 +++---------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/faraday_plugins/plugins/repo/dnswalk/plugin.py b/faraday_plugins/plugins/repo/dnswalk/plugin.py index 25350679..ef229cc2 100644 --- a/faraday_plugins/plugins/repo/dnswalk/plugin.py +++ b/faraday_plugins/plugins/repo/dnswalk/plugin.py @@ -94,33 +94,15 @@ def parseOutputString(self, output, debug=False): parser = DnswalkParser(output) for item in parser.items: - if item['type'] == "A": - - h_id = self.createAndAddHost(item['ip']) - i_id = self.createAndAddInterface( - h_id, - item['ip'], - ipv4_address=item['ip'], - hostname_resolution=[item['host']]) - + h_id = self.createAndAddHost(item['ip'], hostnames=[item['host']]) elif item['type'] == "info": - - h_id = self.createAndAddHost(item['ip']) - - i_id = self.createAndAddInterface( - h_id, - item['ip'], - ipv4_address=item['ip'], - hostname_resolution=[item['host']]) - - s_id = self.createAndAddServiceToInterface( + h_id = self.createAndAddHost(item['ip'], hostnames=[item['host']]) + s_id = self.createAndAddServiceToHost( h_id, - i_id, "domain", "tcp", ports=['53']) - self.createAndAddVulnToService( h_id, s_id, From ba82932ec23cd5e649530b04ec887d70a1c5dcb4 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 11:41:38 -0300 Subject: [PATCH 031/698] clean fruitywify --- faraday_plugins/plugins/repo/fruitywifi/plugin.py | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/faraday_plugins/plugins/repo/fruitywifi/plugin.py b/faraday_plugins/plugins/repo/fruitywifi/plugin.py index 04a54096..d887f399 100644 --- a/faraday_plugins/plugins/repo/fruitywifi/plugin.py +++ b/faraday_plugins/plugins/repo/fruitywifi/plugin.py @@ -56,18 +56,7 @@ def getSeverity(self, severity): return 5 def createHostInterfaceVuln(self, ip_address, macaddress, hostname, desc, vuln_name, severity): - h_id = self.createAndAddHost(ip_address) - if self._isIPV4(ip_address): - i_id = self.createAndAddInterface( - h_id, - ip_address, - macaddress, - ipv4_address=ip_address, - hostname_resolution=[hostname] - ) - else: - self.createAndAddInterface( - h_id, ip_address, ipv6_address=ip_address, hostname_resolution=[hostname]) + h_id = self.createAndAddHost(ip_address, hostnames=[hostname]) self.createAndAddVulnToHost( h_id, From e423096bc1dcfc41dee1876052c124c1ec240ce2 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 11:42:52 -0300 Subject: [PATCH 032/698] clean ftp --- faraday_plugins/plugins/repo/ftp/plugin.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/faraday_plugins/plugins/repo/ftp/plugin.py b/faraday_plugins/plugins/repo/ftp/plugin.py index aa86e214..45ff97cf 100644 --- a/faraday_plugins/plugins/repo/ftp/plugin.py +++ b/faraday_plugins/plugins/repo/ftp/plugin.py @@ -55,17 +55,9 @@ def parseOutputString(self, output, debug=False): if debug: print(ip_address) - h_id = self.createAndAddHost(ip_address) - - i_id = self.createAndAddInterface( - h_id, - ip_address, - ipv4_address=ip_address, - hostname_resolution=[hostname]) - - s_id = self.createAndAddServiceToInterface( + h_id = self.createAndAddHost(ip_address, hostnames=[hostname]) + s_id = self.createAndAddServiceToHost( h_id, - i_id, "ftp", "tcp", ports=[self._port], From ee45e113000e060c6e6c3110f449c7e6f2c391b9 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 11:52:22 -0300 Subject: [PATCH 033/698] clean hping3 --- faraday_plugins/plugins/repo/hping3/plugin.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/faraday_plugins/plugins/repo/hping3/plugin.py b/faraday_plugins/plugins/repo/hping3/plugin.py index 27f516ec..a2dd44da 100644 --- a/faraday_plugins/plugins/repo/hping3/plugin.py +++ b/faraday_plugins/plugins/repo/hping3/plugin.py @@ -41,10 +41,7 @@ def parseOutputString(self, output, debug=False): return hostname = output.split(" ")[1] - host_id = self.createAndAddHost(hostname) - - i_id = self.createAndAddInterface( - host_id, ip_address, ipv4_address=ip_address, hostname_resolution=[hostname]) + host_id = self.createAndAddHost(ip_address, hostnames=[hostname]) if re.match("HPING", output): @@ -54,8 +51,8 @@ def parseOutputString(self, output, debug=False): service = self.srv[sport.group(1)] if reci.group(1) == "SA": - s_id = self.createAndAddServiceToInterface( - host_id, i_id, service, protocol="tcp", ports=ssport, status="open") + s_id = self.createAndAddServiceToHost( + host_id, service, protocol="tcp", ports=ssport, status="open") lineas = output.split("\n") @@ -67,8 +64,8 @@ def parseOutputString(self, output, debug=False): port = [list[0]] if list[2] == "S" and list[3] == "A": - s_id = self.createAndAddServiceToInterface( - host_id, i_id, service, protocol="tcp", ports=port, status="open") + s_id = self.createAndAddServiceToHost( + host_id, service, protocol="tcp", ports=port, status="open") def createPlugin(): From 15047720da4c97611b621e02472dd21847627ae4 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 11:53:47 -0300 Subject: [PATCH 034/698] clean hydra --- faraday_plugins/plugins/repo/hydra/plugin.py | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/faraday_plugins/plugins/repo/hydra/plugin.py b/faraday_plugins/plugins/repo/hydra/plugin.py index 7d70d226..9bff8300 100644 --- a/faraday_plugins/plugins/repo/hydra/plugin.py +++ b/faraday_plugins/plugins/repo/hydra/plugin.py @@ -90,23 +90,8 @@ def parseOutputString(self, output, debug=False): for k, v in hosts.items(): h_id = self.createAndAddHost(k) - - if self._isIPV4(k): - - i_id = self.createAndAddInterface( - h_id, - k, - ipv4_address=k) - - else: - i_id = self.createAndAddInterface( - h_id, - k, - ipv6_address=k) - - s_id = self.createAndAddServiceToInterface( + s_id = self.createAndAddServiceToHost( h_id, - i_id, service, ports=[port], protocol="tcp", From 6c3cd34d062d8ecfb94547104ba6581a602ae553 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 11:56:02 -0300 Subject: [PATCH 035/698] clean impact --- faraday_plugins/plugins/repo/impact/plugin.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/faraday_plugins/plugins/repo/impact/plugin.py b/faraday_plugins/plugins/repo/impact/plugin.py index 71018e3f..da19171a 100644 --- a/faraday_plugins/plugins/repo/impact/plugin.py +++ b/faraday_plugins/plugins/repo/impact/plugin.py @@ -228,21 +228,12 @@ def parseOutputString(self, output, debug=False): mapped_services = {} mapped_ports = {} for item in parser.items: - - h_id = self.createAndAddHost( - item.ip, - item.os + " " + item.arch) - - i_id = self.createAndAddInterface( - h_id, - item.ip, - ipv4_address=item.ip, - hostname_resolution=[item.host]) + os_string = f"{item.os} {item.arch }" + h_id = self.createAndAddHost(item.ip, os=os_string, hostnames=[item.host]) for service in item.services: - s_id = self.createAndAddServiceToInterface( + s_id = self.createAndAddServiceToHost( h_id, - i_id, service['name'], service['protocol'], ports=[service['port']], @@ -282,9 +273,8 @@ def parseOutputString(self, output, debug=False): ref=v.ref) for p in item.ports: - s_id = self.createAndAddServiceToInterface( + s_id = self.createAndAddServiceToHost( h_id, - i_id, p['port'], p['protocol'], ports=[p['port']], From 66fe0958988310645e8bbd26d4e8dc6e695b6c78 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 11:59:14 -0300 Subject: [PATCH 036/698] clean ip360 --- faraday_plugins/plugins/plugin.py | 3 +++ faraday_plugins/plugins/repo/ip360/plugin.py | 15 ++------------- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/faraday_plugins/plugins/plugin.py b/faraday_plugins/plugins/plugin.py index 6e4347c5..c6ed9987 100644 --- a/faraday_plugins/plugins/plugin.py +++ b/faraday_plugins/plugins/plugin.py @@ -316,6 +316,9 @@ def createAndAddHost(self, name, os="unknown", hostnames=None, mac=None, descrip if not hostnames: hostnames = [] + if not isinstance(hostnames, list): + self.logger.warning("hostnames parameter must be a list and is (%s)", type(hostnames)) + hostnames = [hostnames] # Some plugins sends a list with None, we filter empty and None values. hostnames = [hostname for hostname in hostnames if hostname] if os is None: diff --git a/faraday_plugins/plugins/repo/ip360/plugin.py b/faraday_plugins/plugins/repo/ip360/plugin.py index a2c95348..7ff96ca2 100644 --- a/faraday_plugins/plugins/repo/ip360/plugin.py +++ b/faraday_plugins/plugins/repo/ip360/plugin.py @@ -79,17 +79,7 @@ def parseOutputString(self, output, debug=False): parser = Ip360Parser(output) for host, interface, service, vulnerability in parser.parse(): - - h_id = self.createAndAddHost(host.get("name"), host.get("os")) - - i_id = self.createAndAddInterface( - h_id, - interface.get("name"), - ipv4_address=interface.get("name"), - hostname_resolution=interface.get("hostname_resolution"), - network_segment=interface.get("network_segment")) - - + h_id = self.createAndAddHost(host.get("name"), host.get("os"), hostnames=interface.get("hostname_resolution")) if service.get("port") == "-": port = "0" protocol = "unknown" @@ -97,9 +87,8 @@ def parseOutputString(self, output, debug=False): port = service.get("port").split("/")[0] protocol = service.get("port").split("/")[1] - s_id = self.createAndAddServiceToInterface( + s_id = self.createAndAddServiceToHost( h_id, - i_id, service.get("port"), protocol=protocol, ports=[port]) From 2e5a0963c7ef5f29b9221964c91975e0a8d899d1 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 20:50:06 -0300 Subject: [PATCH 037/698] clean junit --- faraday_plugins/plugins/repo/junit/plugin.py | 1 - 1 file changed, 1 deletion(-) diff --git a/faraday_plugins/plugins/repo/junit/plugin.py b/faraday_plugins/plugins/repo/junit/plugin.py index f237b03c..2ee240d0 100644 --- a/faraday_plugins/plugins/repo/junit/plugin.py +++ b/faraday_plugins/plugins/repo/junit/plugin.py @@ -137,7 +137,6 @@ def parseOutputString(self, output, debug=False): parser = JunitXmlParser(output) for item in parser.items: h_id = self.createAndAddHost(item.host, os="Linux") - i_id = self.createAndAddInterface(h_id, item.host, ipv4_address=item.host) self.createAndAddVulnToHost(h_id, name=item.name, desc=item.message, ref=[], severity="High") del parser From c53c06f7b80bf134133bdfc621cd2bdb85952872 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 20:51:32 -0300 Subject: [PATCH 038/698] clean medusa --- faraday_plugins/plugins/repo/medusa/plugin.py | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/faraday_plugins/plugins/repo/medusa/plugin.py b/faraday_plugins/plugins/repo/medusa/plugin.py index 9c362011..7aa69d62 100644 --- a/faraday_plugins/plugins/repo/medusa/plugin.py +++ b/faraday_plugins/plugins/repo/medusa/plugin.py @@ -85,25 +85,12 @@ def parseOutputString(self, output): for item in parser.items: - h_id = self.createAndAddHost(item['ip']) - if self._isIPV4(item['ip']): - i_id = self.createAndAddInterface( - h_id, - item['ip'], - ipv4_address=item['ip'], - hostname_resolution=[item['host']]) - else: - i_id = self.createAndAddInterface( - h_id, - item['ip'], - ipv6_address=item['ip'], - hostname_resolution=[item['host']]) + h_id = self.createAndAddHost(item['ip'], hostnames=[item['host']]) port = self.port if self.port else item['port'] - s_id = self.createAndAddServiceToInterface( + s_id = self.createAndAddServiceToHost( h_id, - i_id, item['service'], ports=[port], protocol="tcp", From 86bebff910febaf87b8bd1610ea7dcbbcd9806cb Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 20:53:32 -0300 Subject: [PATCH 039/698] clean nessus --- faraday_plugins/plugins/repo/nessus/plugin.py | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/faraday_plugins/plugins/repo/nessus/plugin.py b/faraday_plugins/plugins/repo/nessus/plugin.py index efe15c96..07b8fce8 100644 --- a/faraday_plugins/plugins/repo/nessus/plugin.py +++ b/faraday_plugins/plugins/repo/nessus/plugin.py @@ -221,8 +221,6 @@ def parseOutputString(self, output): host_name = None host_id = self.createAndAddHost(ip_host, os=os, hostnames=host_name, mac=mac) - - interface_id = self.createAndAddInterface(host_id, ip, ipv6_address=ip, mac=mac) cve = [] for serv in parser.report.report_json['serv'][set_info -1]: serv_name = serv[1] @@ -332,11 +330,8 @@ def parseOutputString(self, output): if 'xref' in data: ref.append(data['xref']) - service_id = self.createAndAddServiceToInterface(host_id, - interface_id, - name=serv_name, - protocol=serv_protocol, - ports=serv_port) + service_id = self.createAndAddServiceToHost(host_id, name=serv_name, protocol=serv_protocol, + ports=serv_port) if serv_name == 'www' or serv_name == 'http': self.createAndAddVulnWebToService(host_id, @@ -363,13 +358,9 @@ def parseOutputString(self, output): run_date=run_date) else: ip = '0.0.0.0' - host_id = self.createAndAddHost(ip, hostnames="Not Information") - interface_id = self.createAndAddInterface(host_id, ip) - service_id = self.createAndAddServiceToInterface(host_id, interface_id, name="Not Information") - self.createAndAddVulnToService(host_id, - service_id, - name=parser.policy.policy_name, - desc="No Description") + host_id = self.createAndAddHost(ip, hostnames=None) + service_id = self.createAndAddServiceToHost(host_id,name="Not Information") + self.createAndAddVulnToService(host_id, service_id, name=parser.policy.policy_name, desc="No Description") def createPlugin(): From e625c6fe43f6a89fea53acc07b895423b61d1e5d Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 20:57:19 -0300 Subject: [PATCH 040/698] clean netdiscover --- faraday_plugins/plugins/repo/netdiscover/plugin.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/faraday_plugins/plugins/repo/netdiscover/plugin.py b/faraday_plugins/plugins/repo/netdiscover/plugin.py index 43c1d7db..b87e7a17 100644 --- a/faraday_plugins/plugins/repo/netdiscover/plugin.py +++ b/faraday_plugins/plugins/repo/netdiscover/plugin.py @@ -34,10 +34,7 @@ def parseOutputString(self, output): ip_address = stdout[0] mac = stdout[2] hostname = stdout[6].strip() - - h_id = self.createAndAddHost(ip_address) - self.createAndAddInterface(h_id, ip_address, ipv4_address=ip_address, mac=mac, hostname_resolution=[hostname]) - + h_id = self.createAndAddHost(ip_address, hostnames=[hostname]) return True From 654c350135af53009c568e4dc1c60c4c31be0357 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 20:58:16 -0300 Subject: [PATCH 041/698] clean netsparckercloud --- faraday_plugins/plugins/repo/netsparkercloud/plugin.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/faraday_plugins/plugins/repo/netsparkercloud/plugin.py b/faraday_plugins/plugins/repo/netsparkercloud/plugin.py index 6679e8ca..fedb0647 100644 --- a/faraday_plugins/plugins/repo/netsparkercloud/plugin.py +++ b/faraday_plugins/plugins/repo/netsparkercloud/plugin.py @@ -196,10 +196,8 @@ def parseOutputString(self, output, debug=False): for i in parser.items: if first: ip = resolve_hostname(i.hostname) - h_id = self.createAndAddHost(ip) - i_id = self.createAndAddInterface(h_id, ip, ipv4_address=ip, hostname_resolution=[i.hostname]) - s_id = self.createAndAddServiceToInterface(h_id, i_id, i.protocol, ports=[i.port], status="open") - + h_id = self.createAndAddHost(ip, hostnames=[i.hostname]) + s_id = self.createAndAddServiceToHost(h_id, i.protocol, ports=[i.port], status="open") first = False v_id = self.createAndAddVulnWebToService(h_id, s_id, i.name, ref=i.ref, website=i.hostname, severity=i.severity, desc=i.desc, path=i.url.path, method=i.method, From a0962c4377e657f5274d50a2c24116c0f38e60f4 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 21:06:02 -0300 Subject: [PATCH 042/698] clean nexposefull --- .../plugins/repo/nexpose_full/plugin.py | 26 ++++--------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/faraday_plugins/plugins/repo/nexpose_full/plugin.py b/faraday_plugins/plugins/repo/nexpose_full/plugin.py index dcff8d80..137907e8 100644 --- a/faraday_plugins/plugins/repo/nexpose_full/plugin.py +++ b/faraday_plugins/plugins/repo/nexpose_full/plugin.py @@ -264,29 +264,15 @@ def parseOutputString(self, output, debug=False): parser = NexposeFullXmlParser(output) for item in parser.items: - h_id = self.createAndAddHost(item['name'], item['os'], hostnames=item['hostnames']) pattern = '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$' if not item['mac']: item['mac'] = '0000000000000000' - match = re.search(pattern, item['mac']) - else: - match = re.search(pattern, item['mac']) + match = re.search(pattern, item['mac']) if match: - i_id = self.createAndAddInterface( - h_id, - item['name'], - mac=item['mac'], - ipv4_address=item['name'], - hostname_resolution=item['hostnames'] - ) + mac = item['mac'] else: - i_id = self.createAndAddInterface( - h_id, - item['name'], - mac=':'.join(item['mac'][i:i + 2] for i in range(0, 12, 2)), - ipv4_address=item['name'], - hostname_resolution=item['hostnames']) - + mac = ':'.join(item['mac'][i:i + 2] for i in range(0, 12, 2)) + h_id = self.createAndAddHost(item['name'], item['os'], hostnames=item['hostnames'], mac=mac) for v in item['vulns']: v['data'] = {"vulnerable_since": v['vulnerable_since'], "scan_id": v['scan_id'], "PCI": v['pci']} v_id = self.createAndAddVulnToHost( @@ -301,10 +287,8 @@ def parseOutputString(self, output, debug=False): for s in item['services']: web = False version = s.get("version", "") - - s_id = self.createAndAddServiceToInterface( + s_id = self.createAndAddServiceToHost( h_id, - i_id, s['name'], s['protocol'], ports=[str(s['port'])], From 0b2999cc880e94e0aa92f50d0e879a37ad74a772 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 21:10:11 -0300 Subject: [PATCH 043/698] clean nmap, pasteanalyzer, peepingtom, ping --- faraday_plugins/plugins/repo/nmap/plugin.py | 18 ++---------------- .../plugins/repo/pasteanalyzer/plugin.py | 4 +--- .../plugins/repo/peepingtom/plugin.py | 4 +--- faraday_plugins/plugins/repo/ping/plugin.py | 10 +--------- 4 files changed, 5 insertions(+), 31 deletions(-) diff --git a/faraday_plugins/plugins/repo/nmap/plugin.py b/faraday_plugins/plugins/repo/nmap/plugin.py index a9955215..a0444e82 100644 --- a/faraday_plugins/plugins/repo/nmap/plugin.py +++ b/faraday_plugins/plugins/repo/nmap/plugin.py @@ -464,22 +464,9 @@ def parseOutputString(self, output, debug=False): if host.ipv4_address != 'unknown': minterfase = host.ipv4_address - h_id = self.createAndAddHost(minterfase, host.os) - i_id = self.createAndAddInterface( - h_id, - minterfase, - host.mac_address, - ipv4_address=host.ipv4_address, - hostname_resolution=host.hostnames) else: minterfase = host.ipv6_address - h_id = self.createAndAddHost(minterfase, host.os) - i_id = self.createAndAddInterface( - h_id, - minterfase, - host.mac_address, - ipv6_address=host.ipv6_address, - hostname_resolution=host.hostnames) + h_id = self.createAndAddHost(minterfase, host.os, mac=host.mac_address, hostnames=host.hostnames) for v in host.vulns: desc = v.desc @@ -502,9 +489,8 @@ def parseOutputString(self, output, debug=False): srvversion = port.service.product if port.service.product != "unknown" else "" srvversion += " " + port.service.version if port.service.version != "unknown" else "" - s_id = self.createAndAddServiceToInterface( + s_id = self.createAndAddServiceToHost( h_id, - i_id, srvname, port.protocol, ports=[port.number], diff --git a/faraday_plugins/plugins/repo/pasteanalyzer/plugin.py b/faraday_plugins/plugins/repo/pasteanalyzer/plugin.py index e6f58fb9..1e7fd647 100644 --- a/faraday_plugins/plugins/repo/pasteanalyzer/plugin.py +++ b/faraday_plugins/plugins/repo/pasteanalyzer/plugin.py @@ -45,10 +45,8 @@ def parseOutputString(self, output): return # Configuration initial. hostId = self.createAndAddHost("pasteAnalyzer") - interfaceId = self.createAndAddInterface(hostId, "Results") - serviceId = self.createAndAddServiceToInterface( + serviceId = self.createAndAddServiceToHost( hostId, - interfaceId, "Web", "TcpHTTP", ['80'] diff --git a/faraday_plugins/plugins/repo/peepingtom/plugin.py b/faraday_plugins/plugins/repo/peepingtom/plugin.py index 7e00313e..cc50f3fd 100644 --- a/faraday_plugins/plugins/repo/peepingtom/plugin.py +++ b/faraday_plugins/plugins/repo/peepingtom/plugin.py @@ -51,9 +51,7 @@ def parseOutputString(self, output): url_parsed = urlparse(url) address = resolve_hostname(url_parsed.netloc) host = self.createAndAddHost(address) - iface = self.createAndAddInterface( - host, address, ipv4_address=address) - service = self.createAndAddServiceToInterface(host, iface, "http", protocol="tcp", ports=[80]) + service = self.createAndAddServiceToHost(host, "http", protocol="tcp", ports=[80]) self.createAndAddNoteToService( host, service, diff --git a/faraday_plugins/plugins/repo/ping/plugin.py b/faraday_plugins/plugins/repo/ping/plugin.py index 2a0061fe..1b1616ff 100644 --- a/faraday_plugins/plugins/repo/ping/plugin.py +++ b/faraday_plugins/plugins/repo/ping/plugin.py @@ -38,15 +38,7 @@ def parseOutputString(self, output, debug=False): ip_address = reg.group(3) hostname = reg.group(1) - - h_id = self.createAndAddHost(ip_address) - if self._isIPV4(ip_address): - i_id = self.createAndAddInterface( - h_id, ip_address, ipv4_address=ip_address, hostname_resolution=[hostname]) - else: - self.createAndAddInterface( - h_id, ip_address, ipv6_address=ip_address, hostname_resolution=[hostname]) - + h_id = self.createAndAddHost(ip_address, hostnames=[hostname]) return True def _isIPV4(self, ip): From cda8ad7bc9f5820f207989012246270f3a812d18 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 21:11:09 -0300 Subject: [PATCH 044/698] clean propecia --- faraday_plugins/plugins/repo/propecia/plugin.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/faraday_plugins/plugins/repo/propecia/plugin.py b/faraday_plugins/plugins/repo/propecia/plugin.py index 300ed0b4..3dbd83a7 100644 --- a/faraday_plugins/plugins/repo/propecia/plugin.py +++ b/faraday_plugins/plugins/repo/propecia/plugin.py @@ -49,14 +49,8 @@ def parseOutputString(self, output, debug=False): for host in output.splitlines(): if host != "": h_id = self.createAndAddHost(host) - i_id = self.createAndAddInterface( - h_id, host, ipv4_address=host) - s_id = self.createAndAddServiceToInterface(h_id, i_id, str(self._port), - "tcp", - ports=[self._port], - status="open", - version="", - description="") + s_id = self.createAndAddServiceToHost(h_id, str(self._port), "tcp", ports=[self._port], + status="open", version="", description="") if debug is True: self.logger.info("Debug is active") From ef6357c511ee1e4c9ff0946532f16c1d8a63c8be Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 21:12:26 -0300 Subject: [PATCH 045/698] clean retina --- faraday_plugins/plugins/repo/retina/plugin.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/faraday_plugins/plugins/repo/retina/plugin.py b/faraday_plugins/plugins/repo/retina/plugin.py index 4ba8270e..2cd80e00 100644 --- a/faraday_plugins/plugins/repo/retina/plugin.py +++ b/faraday_plugins/plugins/repo/retina/plugin.py @@ -187,10 +187,8 @@ def parseOutputString(self, output, debug=False): parser = RetinaXmlParser(output) for item in parser.items: - h_id = self.createAndAddHost(item.ip, item.os) - hostname = item.hostname if item.hostname else item.ip - i_id = self.createAndAddInterface( - h_id, item.ip, ipv4_address=item.ip, hostname_resolution=[hostname]) + hostname = item.hostname if item.hostname else None + h_id = self.createAndAddHost(item.ip, item.os,hostnames=[hostname]) if not item.netbiosname == 'N/A': self.createAndAddNoteToHost( @@ -204,10 +202,8 @@ def parseOutputString(self, output, debug=False): if k: for v in vulns: web = False - s_id = self.createAndAddServiceToInterface(h_id, i_id, 'unknown', - v.protocol.lower(), - ports=[str(v.port)], - status="open") + s_id = self.createAndAddServiceToHost(h_id, 'unknown', v.protocol.lower(), ports=[str(v.port)], + status="open") if v.port in ['80', '443'] or re.search("ssl|http", v.name.lower()): web = True else: From a09326e71de81a03a89d28b619fd7659cd455c4d Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 21:13:07 -0300 Subject: [PATCH 046/698] clen reverseraider --- faraday_plugins/plugins/repo/reverseraider/plugin.py | 1 - 1 file changed, 1 deletion(-) diff --git a/faraday_plugins/plugins/repo/reverseraider/plugin.py b/faraday_plugins/plugins/repo/reverseraider/plugin.py index de006a91..decad09c 100644 --- a/faraday_plugins/plugins/repo/reverseraider/plugin.py +++ b/faraday_plugins/plugins/repo/reverseraider/plugin.py @@ -74,7 +74,6 @@ def parseOutputString(self, output): parser = ReverseraiderParser(output) for item in parser.items: h_id = self.createAndAddHost(item['ip']) - i_id = self.createAndAddInterface(h_id, item['ip'], ipv4_address=item['ip']) del parser From d1428845025f171017cb08b104ff69a4dc9ae44a Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 21:14:28 -0300 Subject: [PATCH 047/698] clean skipfish --- faraday_plugins/plugins/repo/skipfish/plugin.py | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/faraday_plugins/plugins/repo/skipfish/plugin.py b/faraday_plugins/plugins/repo/skipfish/plugin.py index cf3ddd10..e1cd78c8 100644 --- a/faraday_plugins/plugins/repo/skipfish/plugin.py +++ b/faraday_plugins/plugins/repo/skipfish/plugin.py @@ -166,20 +166,8 @@ def parseOutputString(self, output): ip = resolve_hostname(host) - h_id = self.createAndAddHost(ip) - i_id = self.createAndAddInterface( - h_id, - ip, - ipv4_address=ip, - hostname_resolution=[host]) - - s_id = self.createAndAddServiceToInterface( - h_id, - i_id, - "http", - "tcp", - ports=[port], - status="open") + h_id = self.createAndAddHost(ip, hostnames=[host]) + s_id = self.createAndAddServiceToHost(h_id, "http", "tcp", ports=[port], status="open") hostc[sample["url"]] = { 'h_id': h_id, @@ -187,7 +175,6 @@ def parseOutputString(self, output): 'port': port, 'host': host, 'protocol': protocol, - 'i_id': i_id, 's_id': s_id} try: From 858a953146bff99363fc6411b3f15ebdebb1d6f2 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 21:15:09 -0300 Subject: [PATCH 048/698] clean sshdefaultscan --- faraday_plugins/plugins/repo/sshdefaultscan/plugin.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/faraday_plugins/plugins/repo/sshdefaultscan/plugin.py b/faraday_plugins/plugins/repo/sshdefaultscan/plugin.py index 23f80cf7..2b5699af 100644 --- a/faraday_plugins/plugins/repo/sshdefaultscan/plugin.py +++ b/faraday_plugins/plugins/repo/sshdefaultscan/plugin.py @@ -39,11 +39,7 @@ def parseOutputString(self, output): if output_rexeg_match: credentials, address = line.split("@") host = self.createAndAddHost(address) - iface = self.createAndAddInterface( - host, address, ipv4_address=address) - service = self.createAndAddServiceToInterface( - host, iface, "ssh", protocol="tcp", ports=[22] - ) + service = self.createAndAddServiceToHost(host, "ssh", protocol="tcp", ports=[22]) username, password = credentials.split(":") cred = self.createAndAddCredToService( host, service, username, password) From 8461ff1ed38143c3a3ca5756bc6b6c027a437633 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 21:16:03 -0300 Subject: [PATCH 049/698] clean telnet --- faraday_plugins/plugins/repo/telnet/plugin.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/faraday_plugins/plugins/repo/telnet/plugin.py b/faraday_plugins/plugins/repo/telnet/plugin.py index f100b7eb..92800b0a 100644 --- a/faraday_plugins/plugins/repo/telnet/plugin.py +++ b/faraday_plugins/plugins/repo/telnet/plugin.py @@ -64,13 +64,8 @@ def parseOutputString(self, output, debug=False): ip_address = resolve_hostname(hostname) if host_info is not None: - h_id = self.createAndAddHost(ip_address) - i_id = self.createAndAddInterface( - h_id, ip_address, ipv4_address=ip_address, hostname_resolution=[hostname]) - s_id = self.createAndAddServiceToInterface(h_id, i_id, self._port, - "tcp", - ports=[self._port], - status="open") + h_id = self.createAndAddHost(ip_address, hostnames=[hostname]) + s_id = self.createAndAddServiceToHost(h_id, self._port, "tcp", ports=[self._port], status="open") return True def processCommandString(self, username, current_path, command_string): From 1abfa73f123cde40d29d2e08499c515ee97737cf Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 21:16:42 -0300 Subject: [PATCH 050/698] clean theharverster --- faraday_plugins/plugins/repo/theharvester/plugin.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/faraday_plugins/plugins/repo/theharvester/plugin.py b/faraday_plugins/plugins/repo/theharvester/plugin.py index 771c20ba..75fe3733 100644 --- a/faraday_plugins/plugins/repo/theharvester/plugin.py +++ b/faraday_plugins/plugins/repo/theharvester/plugin.py @@ -122,10 +122,7 @@ def parseOutputString(self, output, debug=False): host = [] if item['host'] != item['ip']: host = [item['host']] - h_id = self.createAndAddHost(item['ip']) - i_id = self.createAndAddInterface(h_id, item['ip'], ipv4_address=item[ - 'ip'], hostname_resolution=host) - + h_id = self.createAndAddHost(item['ip'], hostnames=host) del parser From 120781552de96ce9e3e5c051673aa336057a2ccd Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 21:17:24 -0300 Subject: [PATCH 051/698] clean w3af --- faraday_plugins/plugins/repo/w3af/plugin.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/faraday_plugins/plugins/repo/w3af/plugin.py b/faraday_plugins/plugins/repo/w3af/plugin.py index 73838cee..8128137d 100644 --- a/faraday_plugins/plugins/repo/w3af/plugin.py +++ b/faraday_plugins/plugins/repo/w3af/plugin.py @@ -229,9 +229,8 @@ def parseOutputString(self, output, debug=False): parser = W3afXmlParser(output) ip = resolve_hostname(parser.host) - h_id = self.createAndAddHost(ip) - i_id = self.createAndAddInterface(h_id, ip, ipv4_address=ip, hostname_resolution=[parser.host]) - s_id = self.createAndAddServiceToInterface(h_id, i_id, "http", "tcp", ports=[parser.port], status="open") + h_id = self.createAndAddHost(ip, hostnames=[parser.host]) + s_id = self.createAndAddServiceToHost(h_id, "http", "tcp", ports=[parser.port], status="open") for item in parser.items: v_id = self.createAndAddVulnWebToService(h_id, s_id, item.name, From 621d37978697196c6bff4569f77475194d9dc3cd Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 21:18:10 -0300 Subject: [PATCH 052/698] clean wcscan --- faraday_plugins/plugins/repo/wcscan/plugin.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/faraday_plugins/plugins/repo/wcscan/plugin.py b/faraday_plugins/plugins/repo/wcscan/plugin.py index 122d871f..db7981eb 100644 --- a/faraday_plugins/plugins/repo/wcscan/plugin.py +++ b/faraday_plugins/plugins/repo/wcscan/plugin.py @@ -105,17 +105,7 @@ def parseOutputString(self, output): host = parser.scaninfo[file]['host'] port = parser.scaninfo[file]['port'] h_id = self.createAndAddHost(host) - if(re.match("(^[2][0-5][0-5]|^[1]{0,1}[0-9]{1,2})\.([0-2][0-5][0-5]|[1]{0,1}[0-9]{1,2})\.([0-2][0-5][0-5]|[1]{0,1}[0-9]{1,2})\.([0-2][0-5][0-5]|[1]{0,1}[0-9]{1,2})$", host)): - i_id = self.createAndAddInterface(h_id, - host, - ipv4_address=host) - else: - i_id = self.createAndAddInterface(h_id, - host, - ipv6_address=host) - - s_id = self.createAndAddServiceToInterface( - h_id, i_id, "http", protocol="tcp", ports=port) + s_id = self.createAndAddServiceToHost(h_id, "http", protocol="tcp", ports=port) for vuln in parser.result[file]: if parser.scaninfo[file]['type'] == "phpini": vuln_name = f"{parser.scaninfo[file]['file']}: {vuln}" From b0502feda45ec093c17ae02c59469834243e5b6b Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 21:19:17 -0300 Subject: [PATCH 053/698] clean webfuzzer --- .../plugins/repo/webfuzzer/plugin.py | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/faraday_plugins/plugins/repo/webfuzzer/plugin.py b/faraday_plugins/plugins/repo/webfuzzer/plugin.py index 42902343..1d6ef7ea 100644 --- a/faraday_plugins/plugins/repo/webfuzzer/plugin.py +++ b/faraday_plugins/plugins/repo/webfuzzer/plugin.py @@ -114,24 +114,15 @@ def parseOutputString(self, output, debug=False): return False parser = WebfuzzerParser(self._output_path) - - h_id = self.createAndAddHost(parser.ipaddress) - - i_id = self.createAndAddInterface( - h_id, parser.ipaddress, ipv4_address=parser.ipaddress, hostname_resolution=[parser.hostname]) - + h_id = self.createAndAddHost(parser.ipaddress, hostnames=[parser.hostname]) first = True for item in parser.items: if first: - s_id = self.createAndAddServiceToInterface(h_id, i_id, parser.port, - "tcp", - ports=[parser.port]) + s_id = self.createAndAddServiceToHost(h_id, parser.port, "tcp", ports=[parser.port]) first = False - - v_id = self.createAndAddVulnWebToService(h_id, s_id, name=item['desc'], - path=item['url'], response=item[ - 'resp'], - method=item['method'], website=parser.hostname) + v_id = self.createAndAddVulnWebToService(h_id, s_id, name=item['desc'],path=item['url'], + response=item['resp'], method=item['method'], + website=parser.hostname) del parser From d0f333fccfb89d8c91369c968605235111e07ed9 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 21:20:45 -0300 Subject: [PATCH 054/698] clean webinspect --- faraday_plugins/plugins/repo/webinspect/plugin.py | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/faraday_plugins/plugins/repo/webinspect/plugin.py b/faraday_plugins/plugins/repo/webinspect/plugin.py index b8740dd0..65428d1e 100644 --- a/faraday_plugins/plugins/repo/webinspect/plugin.py +++ b/faraday_plugins/plugins/repo/webinspect/plugin.py @@ -132,17 +132,10 @@ def parseOutputString(self, output): for vuln in vulns: - host_id = self.createAndAddHost( - vuln.get("Host").get("name")) - - interface_id = self.createAndAddInterface( - host_id, vuln.get("Host").get("name")) - - service_id = self.createAndAddServiceToInterface( - host_id, interface_id, - vuln.get("Service").get("name"), - protocol=vuln.get("Service").get("name"), - ports=[vuln.get("Service").get("port")]) + host_id = self.createAndAddHost(vuln.get("Host").get("name")) + service_id = self.createAndAddServiceToHost(host_id, vuln.get("Service").get("name"), + protocol=vuln.get("Service").get("name"), + ports=[vuln.get("Service").get("port")]) self.createAndAddVulnWebToService( host_id, service_id, From eab4b4048331905c2c71c4409bf979c0caf2277e Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 21:21:20 -0300 Subject: [PATCH 055/698] clean whois --- faraday_plugins/plugins/repo/whois/plugin.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/faraday_plugins/plugins/repo/whois/plugin.py b/faraday_plugins/plugins/repo/whois/plugin.py index 353b3d9d..c032fbc8 100644 --- a/faraday_plugins/plugins/repo/whois/plugin.py +++ b/faraday_plugins/plugins/repo/whois/plugin.py @@ -75,9 +75,7 @@ def parseOutputString(self, output, debug=False): for m in matches: m = m.strip() ip = resolve_hostname(m) - h_id = self.createAndAddHost(ip, "os unknown") - i_id = self.createAndAddInterface( - h_id, ip, "00:00:00:00:00:00", ip, hostname_resolution=[m]) + h_id = self.createAndAddHost(ip, "os unknown", hostnames=[m]) return True From e013117188a62bf285ab895ce5d47478e7315a54 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 21:22:07 -0300 Subject: [PATCH 056/698] clean x1 --- faraday_plugins/plugins/repo/x1/plugin.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/faraday_plugins/plugins/repo/x1/plugin.py b/faraday_plugins/plugins/repo/x1/plugin.py index a65bcc12..471e8a60 100644 --- a/faraday_plugins/plugins/repo/x1/plugin.py +++ b/faraday_plugins/plugins/repo/x1/plugin.py @@ -173,13 +173,9 @@ def parseOutputString(self, output, debug=False): parser = X1XmlParser(output) for item in parser.items: - h_id = self.createAndAddHost(item.host, item.name) - i_id = self.createAndAddInterface( - h_id, item.host, ipv4_address=item.host, hostname_resolution=[item.vclass]) - s_id = self.createAndAddServiceToInterface(h_id, i_id, item.srvname, - item.protocol, - ports=[str(item.port)], - status="open") + h_id = self.createAndAddHost(item.host, item.name, hostnames=[item.vclass]) + s_id = self.createAndAddServiceToHost(h_id, item.srvname, item.protocol, ports=[str(item.port)], + status="open") for v in item.results: desc = v.description v_id = self.createAndAddVulnToService(h_id, s_id, v.name, desc=desc, From e07b8f9171cb66d36217acabc3c0ee21eafc52c8 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 21:23:33 -0300 Subject: [PATCH 057/698] clean xssniper --- faraday_plugins/plugins/repo/xsssniper/plugin.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/faraday_plugins/plugins/repo/xsssniper/plugin.py b/faraday_plugins/plugins/repo/xsssniper/plugin.py index 32ea18a1..cf6f436e 100644 --- a/faraday_plugins/plugins/repo/xsssniper/plugin.py +++ b/faraday_plugins/plugins/repo/xsssniper/plugin.py @@ -36,10 +36,8 @@ def parseOutputString(self, output, debug=False): linea = linea.lower() if ((linea.find("target:")>0)): url = re.findall('(?:[-\w.]|(?:%[\da-fA-F]{2}))+', linea) - print(url) - host_id = self.createAndAddHost(url[3]) address = resolve_hostname(url[3]) - interface_id = self.createAndAddInterface(host_id,address,ipv4_address=address,hostname_resolution=url[3]) + host_id = self.createAndAddHost(address, hostnames=url[3]) if ((linea.find("method")>0)): list_a = re.findall("\w+", linea) metodo= list_a[1] @@ -49,8 +47,8 @@ def parseOutputString(self, output, debug=False): if ((linea.find("param:")>0)): list2 = re.findall("\w+",linea) parametro.append(list2[1]) - service_id = self.createAndAddServiceToInterface(host_id, interface_id, self.protocol, 'tcp', - ports=['80'], status='Open', version="", description="") + service_id = self.createAndAddServiceToHost(host_id, self.protocol, 'tcp', ports=['80'], status='Open', + version="", description="") if aux != 0: self.createAndAddVulnWebToService(host_id, service_id, name="xss", desc="XSS", ref='', severity='med', website=url[0], path='', method=metodo, pname='', From f6288333e5bc17654e38b14a1e137026b9aacdfa Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 21:24:38 -0300 Subject: [PATCH 058/698] clean zap --- faraday_plugins/plugins/repo/zap/plugin.py | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/faraday_plugins/plugins/repo/zap/plugin.py b/faraday_plugins/plugins/repo/zap/plugin.py index 252281c0..b567e303 100644 --- a/faraday_plugins/plugins/repo/zap/plugin.py +++ b/faraday_plugins/plugins/repo/zap/plugin.py @@ -255,23 +255,9 @@ def parseOutputString(self, output, debug=False): if site.host != site.ip: host = [site.host] - h_id = self.createAndAddHost(site.ip) - - i_id = self.createAndAddInterface( - h_id, - site.ip, - ipv4_address=site.ip, - hostname_resolution=host - ) - - s_id = self.createAndAddServiceToInterface( - h_id, - i_id, - "http", - "tcp", - ports=[site.port], - status='open' - ) + h_id = self.createAndAddHost(site.ip, hostnames=host) + + s_id = self.createAndAddServiceToHost(h_id, "http", "tcp", ports=[site.port], status='open') for item in site.items: self.createAndAddVulnWebToService( From 4a6b6ff3e13f184b93c3cfe057479e2e63699798 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 21:29:22 -0300 Subject: [PATCH 059/698] clean maltego --- .../plugins/repo/maltego/plugin.py | 63 ++++++++----------- 1 file changed, 26 insertions(+), 37 deletions(-) diff --git a/faraday_plugins/plugins/repo/maltego/plugin.py b/faraday_plugins/plugins/repo/maltego/plugin.py index 312de8f0..dd453d31 100755 --- a/faraday_plugins/plugins/repo/maltego/plugin.py +++ b/faraday_plugins/plugins/repo/maltego/plugin.py @@ -397,18 +397,15 @@ def parseOutputString(self, output, debug=False): ip = '0.0.0.0' else: ip = host.ip - host_id = self.createAndAddHost(name=ip) + try: + network_segment = host.netblock["ipv4_range"] + hostname_resolution = [host.dns_name["value"]] + except TypeError: + pass + network_segment = "unknown" + hostname_resolution = "unknown" + host_id = self.createAndAddHost(name=ip, hostnames=[hostname_resolution]) # Create interface - try: - network_segment = host.netblock["ipv4_range"] - hostname_resolution = [host.dns_name["value"]] - except TypeError: - pass - network_segment = "unknown" - hostname_resolution = "unknown" - interface_id = self.createAndAddInterface(host_id=host_id, name=ip, ipv4_address=ip, - network_segment=network_segment, - hostname_resolution=[hostname_resolution]) # Create note with NetBlock information if host.netblock: try: @@ -440,9 +437,9 @@ def parseOutputString(self, output, debug=False): except TypeError: description = "unknown" - service_id = self.createAndAddServiceToInterface(host_id=host_id, interface_id=interface_id, - name=host.website["name"], protocol="TCP:HTTP", - ports=[80], description=description) + service_id = self.createAndAddServiceToHost(host_id=host_id, name=host.website["name"], + protocol="TCP:HTTP", ports=[80], + description=description) try: text = f'Urls: \n {host.website["urls"]}' @@ -452,30 +449,23 @@ def parseOutputString(self, output, debug=False): pass if host.mx_record: - self.createAndAddServiceToInterface(host_id=host_id, interface_id=interface_id, - name=host.mx_record["value"], protocol="SMTP", ports=[25], - description="E-mail Server") + self.createAndAddServiceToHost(host_id=host_id, name=host.mx_record["value"], protocol="SMTP", + ports=[25], description="E-mail Server") if host.ns_record: - self.createAndAddServiceToInterface(host_id=host_id, interface_id=interface_id, - name=host.ns_record["value"], protocol="DNS", ports=[53], - description="DNS Server") + self.createAndAddServiceToHost(host_id=host_id, name=host.ns_record["value"], protocol="DNS", + ports=[53], description="DNS Server") else: maltego_parser = MaltegoMtgxParser(output, self.extension[0]) + if maltego_parser.xml.get('DNS'): + hostname_resolution = maltego_parser.getInfoMtgl(maltego_parser.xml['DNS'], 'fqdn') + else: + hostname_resolution = None if maltego_parser.xml.get('ipv4'): host_ip = maltego_parser.getInfoMtgl(maltego_parser.xml['ipv4'], 'ipv4-address') - host_id = self.createAndAddHost(name=host_ip) else: - host_id = self.createAndAddHost(name=self.name) host_ip = '0.0.0.0' - - if maltego_parser.xml.get('DNS'): - hostname_resolution = maltego_parser.getInfoMtgl(maltego_parser.xml['DNS'], 'fqdn') - interface_id = self.createAndAddInterface(host_id=host_id, name=host_ip, ipv4_address=host_ip, - hostname_resolution=[hostname_resolution]) - else: - interface_id = self.createAndAddInterface(host_id=host_id, name=host_ip, ipv4_address=host_ip) - + host_id = self.createAndAddHost(name=host_ip, hostnames=hostname_resolution) if maltego_parser.xml.get('location'): location_name = maltego_parser.getInfoMtgl(maltego_parser.xml['location'], 'location.name') location_area = maltego_parser.getInfoMtgl(maltego_parser.xml['location'], 'location.area') @@ -500,9 +490,8 @@ def parseOutputString(self, output, debug=False): web_ssh = maltego_parser.getInfoMtgl(maltego_parser.xml['web'], 'website.ssl-enabled') description = f'SSL Enabled: {web_ssh}' - service_id = self.createAndAddServiceToInterface(host_id=host_id, interface_id=interface_id, - name=web_name, protocol="TCP:HTTP", ports=web_port, - description=description) + service_id = self.createAndAddServiceToHost(host_id=host_id, name=web_name, protocol="TCP:HTTP", + ports=web_port, description=description) self.createAndAddNoteToService(host_id=host_id, service_id=service_id, name="URLs", text=text.encode('ascii', 'ignore')) @@ -510,13 +499,13 @@ def parseOutputString(self, output, debug=False): if maltego_parser.xml.get('mxrecord'): mx_name = maltego_parser.getInfoMtgl(maltego_parser.xml['mxrecord'], 'fqdn') - self.createAndAddServiceToInterface(host_id=host_id, interface_id=interface_id, name=mx_name, - protocol="SMTP", ports=[25], description="E-mail Server") + self.createAndAddServiceToHost(host_id=host_id, name=mx_name, protocol="SMTP", ports=[25], + description="E-mail Server") if maltego_parser.xml.get('nsrecord'): ns_name = maltego_parser.getInfoMtgl(maltego_parser.xml['nsrecord'], 'fqdn') - self.createAndAddServiceToInterface(host_id=host_id, interface_id=interface_id, name=ns_name, - protocol="DNS", ports=[53], description="DNS Server") + self.createAndAddServiceToHost(host_id=host_id, name=ns_name, protocol="DNS", ports=[53], + description="DNS Server") From 59d6cfb34801e99a6da8abb2fbd096c5b3a76fa0 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 21:33:23 -0300 Subject: [PATCH 060/698] delete Interface methods --- faraday_plugins/plugins/plugin.py | 52 ------------------------------- 1 file changed, 52 deletions(-) diff --git a/faraday_plugins/plugins/plugin.py b/faraday_plugins/plugins/plugin.py index c6ed9987..3d480201 100644 --- a/faraday_plugins/plugins/plugin.py +++ b/faraday_plugins/plugins/plugin.py @@ -332,46 +332,6 @@ def createAndAddHost(self, name, os="unknown", hostnames=None, mac=None, descrip host_id = self.save_host_cache(host) return host_id - # @deprecation.deprecated(deprecated_in="3.0", removed_in="3.5", - # current_version=VERSION, - # details="Interface object removed. Use host or service instead") - def createAndAddInterface( - self, host_id, name="", mac="00:00:00:00:00:00", - ipv4_address="0.0.0.0", ipv4_mask="0.0.0.0", ipv4_gateway="0.0.0.0", - ipv4_dns=None, ipv6_address="0000:0000:0000:0000:0000:0000:0000:0000", - ipv6_prefix="00", - ipv6_gateway="0000:0000:0000:0000:0000:0000:0000:0000", ipv6_dns=None, - network_segment="", hostname_resolution=None): - if ipv4_dns is None: - ipv4_dns = [] - if ipv6_dns is None: - ipv6_dns = [] - if hostname_resolution is None: - hostname_resolution = [] - if not isinstance(hostname_resolution, list): - self.logger.warning("hostname_resolution parameter must be a list and is (%s)", type(hostname_resolution)) - hostname_resolution = [hostname_resolution] - # We don't use interface anymore, so return a host id to maintain - # backwards compatibility - # Little hack because we dont want change all the plugins for add hostnames in Host object. - # SHRUG - host = self.get_from_cache(host_id) - for hostname in hostname_resolution: - if hostname not in host["hostnames"]: - host["hostnames"].append(hostname) - host["mac"] = mac - return host_id - - # @deprecation.deprecated(deprecated_in="3.0", removed_in="3.5", - # current_version=VERSION, - # details="Interface object removed. Use host or service instead. Service will be attached - # to Host!") - def createAndAddServiceToInterface(self, host_id, interface_id, name, - protocol="tcp", ports=None, - status="open", version="unknown", - description="", tags=None): - return self.createAndAddServiceToHost(host_id, name, protocol, ports, status, version, description, tags) - def createAndAddServiceToHost(self, host_id, name, protocol="tcp", ports=None, status="open", version="unknown", @@ -424,16 +384,6 @@ def createAndAddVulnToHost(self, host_id, name, desc="", ref=None, vulnerability_id = self.save_host_vuln_cache(host_id, vulnerability) return vulnerability_id - # @deprecation.deprecated(deprecated_in="3.0", removed_in="3.5", - # current_version=VERSION, - # details="Interface object removed. Use host or service instead. Vuln will be added - # to Host") - def createAndAddVulnToInterface(self, host_id, interface_id, name, - desc="", ref=None, severity="", - resolution="", data="", tags=None): - return self.createAndAddVulnToHost(host_id, name, desc=desc, ref=ref, severity=severity, resolution=resolution, - data=data, tags=tags) - def createAndAddVulnToService(self, host_id, service_id, name, desc="", ref=None, severity="", resolution="", data="", external_id=None, run_date=None, custom_fields=None, policyviolations=None, impact=None, status="", @@ -518,8 +468,6 @@ def createAndAddVulnWebToService(self, host_id, service_id, name, desc="", def createAndAddNoteToHost(self, host_id, name, text): return None - def createAndAddNoteToInterface(self, host_id, interface_id, name, text): - return None def createAndAddNoteToService(self, host_id, service_id, name, text): return None From d34f0dccee5df05e028ae78d1990951b5edf3731 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Jun 2020 22:07:02 -0300 Subject: [PATCH 061/698] delete debug parameter --- .../plugins/repo/acunetix/plugin.py | 2 +- .../plugins/repo/arachni/plugin.py | 2 +- faraday_plugins/plugins/repo/beef/plugin.py | 2 +- .../plugins/repo/brutexss/plugin.py | 2 +- faraday_plugins/plugins/repo/burp/plugin.py | 2 +- .../plugins/repo/dnsenum/plugin.py | 2 +- faraday_plugins/plugins/repo/dnsmap/plugin.py | 2 +- .../plugins/repo/dnsrecon/plugin.py | 2 +- .../plugins/repo/dnswalk/plugin.py | 2 +- .../plugins/repo/faraday_csv/plugin.py | 2 +- faraday_plugins/plugins/repo/fierce/plugin.py | 2 +- .../plugins/repo/fortify/plugin.py | 2 +- .../plugins/repo/fruitywifi/plugin.py | 2 +- faraday_plugins/plugins/repo/ftp/plugin.py | 9 +------ faraday_plugins/plugins/repo/hping3/plugin.py | 2 +- faraday_plugins/plugins/repo/hydra/plugin.py | 2 +- faraday_plugins/plugins/repo/impact/plugin.py | 2 +- faraday_plugins/plugins/repo/ip360/plugin.py | 2 +- faraday_plugins/plugins/repo/junit/plugin.py | 2 +- .../plugins/repo/maltego/plugin.py | 2 +- .../plugins/repo/metasploit/plugin.py | 5 +--- faraday_plugins/plugins/repo/ndiff/plugin.py | 2 +- .../plugins/repo/netsparkercloud/plugin.py | 2 +- .../plugins/repo/nexpose_full/plugin.py | 2 +- faraday_plugins/plugins/repo/nikto/plugin.py | 2 +- faraday_plugins/plugins/repo/nmap/plugin.py | 2 +- .../plugins/repo/openvas/plugin.py | 5 +--- faraday_plugins/plugins/repo/ping/plugin.py | 2 +- .../plugins/repo/propecia/plugin.py | 5 +--- .../plugins/repo/qualysguard/plugin.py | 2 +- faraday_plugins/plugins/repo/retina/plugin.py | 2 +- faraday_plugins/plugins/repo/sslyze/plugin.py | 2 +- faraday_plugins/plugins/repo/telnet/plugin.py | 2 +- .../plugins/repo/theharvester/plugin.py | 26 +++++-------------- .../plugins/repo/traceroute/plugin.py | 2 +- faraday_plugins/plugins/repo/w3af/plugin.py | 5 +--- .../plugins/repo/webfuzzer/plugin.py | 5 +--- faraday_plugins/plugins/repo/wfuzz/plugin.py | 2 +- .../plugins/repo/whitesource/plugin.py | 2 +- faraday_plugins/plugins/repo/whois/plugin.py | 2 +- faraday_plugins/plugins/repo/wpscan/plugin.py | 2 +- faraday_plugins/plugins/repo/x1/plugin.py | 2 +- .../plugins/repo/xsssniper/plugin.py | 2 +- faraday_plugins/plugins/repo/zap/plugin.py | 5 +--- 44 files changed, 50 insertions(+), 87 deletions(-) diff --git a/faraday_plugins/plugins/repo/acunetix/plugin.py b/faraday_plugins/plugins/repo/acunetix/plugin.py index aabc9ba9..644850da 100644 --- a/faraday_plugins/plugins/repo/acunetix/plugin.py +++ b/faraday_plugins/plugins/repo/acunetix/plugin.py @@ -229,7 +229,7 @@ def __init__(self): self._current_output = None self.target = None - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it from the xml where it expects it to be present. diff --git a/faraday_plugins/plugins/repo/arachni/plugin.py b/faraday_plugins/plugins/repo/arachni/plugin.py index 2ebaa377..b3ff438c 100755 --- a/faraday_plugins/plugins/repo/arachni/plugin.py +++ b/faraday_plugins/plugins/repo/arachni/plugin.py @@ -364,7 +364,7 @@ def _parse_filename(self, filename): except Exception as e: self.logger.error("Error on delete file: (%s) [%s]", filename, e) - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it from the xml where it expects it to be present. diff --git a/faraday_plugins/plugins/repo/beef/plugin.py b/faraday_plugins/plugins/repo/beef/plugin.py index a2d0fe03..b4cc400a 100644 --- a/faraday_plugins/plugins/repo/beef/plugin.py +++ b/faraday_plugins/plugins/repo/beef/plugin.py @@ -40,7 +40,7 @@ def __init__(self): "Authkey", str, "c818c7798ae1da38b45a6406c8dd0d6d4d007098") self.addSetting("Enable", str, "0") - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it from the xml where it expects it to be present. diff --git a/faraday_plugins/plugins/repo/brutexss/plugin.py b/faraday_plugins/plugins/repo/brutexss/plugin.py index 1b9dea6c..59cacef6 100644 --- a/faraday_plugins/plugins/repo/brutexss/plugin.py +++ b/faraday_plugins/plugins/repo/brutexss/plugin.py @@ -27,7 +27,7 @@ def __init__(self): self._command_regex = re.compile(r'^(sudo brutexss|brutexss|sudo brutexss\.py|brutexss\.py|python brutexss\.py|' r'\.\/brutexss\.py)\s+.*?') - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): lineas = output.split("\n") parametro = [] found_vuln = False diff --git a/faraday_plugins/plugins/repo/burp/plugin.py b/faraday_plugins/plugins/repo/burp/plugin.py index 7da59fe8..1b5b195e 100644 --- a/faraday_plugins/plugins/repo/burp/plugin.py +++ b/faraday_plugins/plugins/repo/burp/plugin.py @@ -223,7 +223,7 @@ def __init__(self): self.target = None - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): parser = BurpXmlParser(output) for item in parser.items: diff --git a/faraday_plugins/plugins/repo/dnsenum/plugin.py b/faraday_plugins/plugins/repo/dnsenum/plugin.py index a4a8c934..9fba1611 100644 --- a/faraday_plugins/plugins/repo/dnsenum/plugin.py +++ b/faraday_plugins/plugins/repo/dnsenum/plugin.py @@ -164,7 +164,7 @@ def __init__(self): r'^(sudo dnsenum|dnsenum|sudo dnsenum\.pl|dnsenum\.pl|perl dnsenum\.pl|\.\/dnsenum\.pl)\s+.*?') self.xml_arg_re = re.compile(r"^.*(-o\s*[^\s]+).*$") - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it from the xml where it expects it to be present. diff --git a/faraday_plugins/plugins/repo/dnsmap/plugin.py b/faraday_plugins/plugins/repo/dnsmap/plugin.py index ab77b5f1..4ceebf98 100644 --- a/faraday_plugins/plugins/repo/dnsmap/plugin.py +++ b/faraday_plugins/plugins/repo/dnsmap/plugin.py @@ -111,7 +111,7 @@ def canParseCommandString(self, current_input): else: return False - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it from the xml where it expects it to be present. diff --git a/faraday_plugins/plugins/repo/dnsrecon/plugin.py b/faraday_plugins/plugins/repo/dnsrecon/plugin.py index 00a69912..fd5a3c07 100644 --- a/faraday_plugins/plugins/repo/dnsrecon/plugin.py +++ b/faraday_plugins/plugins/repo/dnsrecon/plugin.py @@ -175,7 +175,7 @@ def validHosts(self, hosts): hosts = list(filter(lambda h: h.type in valid_records, hosts)) return hosts - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it from the xml where it expects it to be present. diff --git a/faraday_plugins/plugins/repo/dnswalk/plugin.py b/faraday_plugins/plugins/repo/dnswalk/plugin.py index ef229cc2..8ae73dc5 100644 --- a/faraday_plugins/plugins/repo/dnswalk/plugin.py +++ b/faraday_plugins/plugins/repo/dnswalk/plugin.py @@ -87,7 +87,7 @@ def canParseCommandString(self, current_input): else: return False - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): """ output is the shell output of command Dnswalk. """ diff --git a/faraday_plugins/plugins/repo/faraday_csv/plugin.py b/faraday_plugins/plugins/repo/faraday_csv/plugin.py index 337eea82..934313d7 100644 --- a/faraday_plugins/plugins/repo/faraday_csv/plugin.py +++ b/faraday_plugins/plugins/repo/faraday_csv/plugin.py @@ -259,7 +259,7 @@ def _parse_filename(self, filename): with open(filename, **self.open_options) as output: self.parseOutputString(output) - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): parser = CSVParser(output, self.logger) for item in parser.items: diff --git a/faraday_plugins/plugins/repo/fierce/plugin.py b/faraday_plugins/plugins/repo/fierce/plugin.py index 5647391f..25a7adfa 100644 --- a/faraday_plugins/plugins/repo/fierce/plugin.py +++ b/faraday_plugins/plugins/repo/fierce/plugin.py @@ -132,7 +132,7 @@ def resolveNS(self, item, items): pass return item - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): parser = FierceParser(output) for item in parser.items: diff --git a/faraday_plugins/plugins/repo/fortify/plugin.py b/faraday_plugins/plugins/repo/fortify/plugin.py index a7486f31..6da3afae 100644 --- a/faraday_plugins/plugins/repo/fortify/plugin.py +++ b/faraday_plugins/plugins/repo/fortify/plugin.py @@ -74,7 +74,7 @@ def _process_webinspect_vulns(self, fp): severity=vuln_data['severity'] ) - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): fp = FortifyParser(output) if fp.fvdl is not None: self._process_fvdl_vulns(fp) diff --git a/faraday_plugins/plugins/repo/fruitywifi/plugin.py b/faraday_plugins/plugins/repo/fruitywifi/plugin.py index d887f399..86b6bfcb 100644 --- a/faraday_plugins/plugins/repo/fruitywifi/plugin.py +++ b/faraday_plugins/plugins/repo/fruitywifi/plugin.py @@ -66,7 +66,7 @@ def createHostInterfaceVuln(self, ip_address, macaddress, hostname, desc, vuln_n severity=severity ) - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): try: output = json.loads(output) diff --git a/faraday_plugins/plugins/repo/ftp/plugin.py b/faraday_plugins/plugins/repo/ftp/plugin.py index 45ff97cf..81faf91e 100644 --- a/faraday_plugins/plugins/repo/ftp/plugin.py +++ b/faraday_plugins/plugins/repo/ftp/plugin.py @@ -44,7 +44,7 @@ def __init__(self): - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): host_info = re.search(r"Connected to (.+)\.", output) banner = re.search("220?([\w\W]+)$", output) @@ -52,9 +52,6 @@ def parseOutputString(self, output, debug=False): hostname = host_info.group(1) ip_address = resolve_hostname(hostname) self._version = banner.groups(0) if banner else "" - if debug: - print(ip_address) - h_id = self.createAndAddHost(ip_address, hostnames=[hostname]) s_id = self.createAndAddServiceToHost( h_id, @@ -62,10 +59,6 @@ def parseOutputString(self, output, debug=False): "tcp", ports=[self._port], status="open") - - if debug is True: - self.logger.info("Debug is active") - return True def processCommandString(self, username, current_path, command_string): diff --git a/faraday_plugins/plugins/repo/hping3/plugin.py b/faraday_plugins/plugins/repo/hping3/plugin.py index a2dd44da..6ba684e9 100644 --- a/faraday_plugins/plugins/repo/hping3/plugin.py +++ b/faraday_plugins/plugins/repo/hping3/plugin.py @@ -29,7 +29,7 @@ def __init__(self): self._command_regex = re.compile(r'^(sudo hping3|hping3)\s+.*$') - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): regex_ipv4 = re.search(r"(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}" r"|2[0-4][0-9]|25[0-5])\)\:", output) diff --git a/faraday_plugins/plugins/repo/hydra/plugin.py b/faraday_plugins/plugins/repo/hydra/plugin.py index 9bff8300..530d80f3 100644 --- a/faraday_plugins/plugins/repo/hydra/plugin.py +++ b/faraday_plugins/plugins/repo/hydra/plugin.py @@ -61,7 +61,7 @@ def __init__(self): self._temp_file_extension = "txt" self.xml_arg_re = re.compile(r"^.*(-o\s*[^\s]+).*$") - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it from the xml where it expects it to be present. diff --git a/faraday_plugins/plugins/repo/impact/plugin.py b/faraday_plugins/plugins/repo/impact/plugin.py index da19171a..ddf72d90 100644 --- a/faraday_plugins/plugins/repo/impact/plugin.py +++ b/faraday_plugins/plugins/repo/impact/plugin.py @@ -223,7 +223,7 @@ def __init__(self): self.framework_version = "1.0.0" self.options = None - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): parser = ImpactXmlParser(output) mapped_services = {} mapped_ports = {} diff --git a/faraday_plugins/plugins/repo/ip360/plugin.py b/faraday_plugins/plugins/repo/ip360/plugin.py index 7ff96ca2..3df01e6a 100644 --- a/faraday_plugins/plugins/repo/ip360/plugin.py +++ b/faraday_plugins/plugins/repo/ip360/plugin.py @@ -75,7 +75,7 @@ def __init__(self): self.plugin_version = "0.0.1" self.options = None - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): parser = Ip360Parser(output) for host, interface, service, vulnerability in parser.parse(): diff --git a/faraday_plugins/plugins/repo/junit/plugin.py b/faraday_plugins/plugins/repo/junit/plugin.py index 2ee240d0..958383ff 100644 --- a/faraday_plugins/plugins/repo/junit/plugin.py +++ b/faraday_plugins/plugins/repo/junit/plugin.py @@ -132,7 +132,7 @@ def __init__(self): self.options = None self._current_output = None - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): parser = JunitXmlParser(output) for item in parser.items: diff --git a/faraday_plugins/plugins/repo/maltego/plugin.py b/faraday_plugins/plugins/repo/maltego/plugin.py index dd453d31..a8e8a379 100755 --- a/faraday_plugins/plugins/repo/maltego/plugin.py +++ b/faraday_plugins/plugins/repo/maltego/plugin.py @@ -385,7 +385,7 @@ def __init__(self): r'^(sudo maltego|maltego|\.\/maltego).*?') global current_path - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): if 'Graphs/Graph1.graphml' in output.namelist(): maltego_parser = MaltegoMtgxParser(output, self.extension[1]) diff --git a/faraday_plugins/plugins/repo/metasploit/plugin.py b/faraday_plugins/plugins/repo/metasploit/plugin.py index 1b31770f..914d8238 100644 --- a/faraday_plugins/plugins/repo/metasploit/plugin.py +++ b/faraday_plugins/plugins/repo/metasploit/plugin.py @@ -337,13 +337,10 @@ def __init__(self): self.target = None - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it from the xml where it expects it to be present. - - NOTE: if 'debug' is true then it is being run from a test case and the - output being sent is valid. """ parser = MetasploitXmlParser(output) diff --git a/faraday_plugins/plugins/repo/ndiff/plugin.py b/faraday_plugins/plugins/repo/ndiff/plugin.py index 04ffef2b..f7263331 100644 --- a/faraday_plugins/plugins/repo/ndiff/plugin.py +++ b/faraday_plugins/plugins/repo/ndiff/plugin.py @@ -117,7 +117,7 @@ def __init__(self): self.version = "1.0.0" self._command_regex = re.compile(r'^(sudo ndiff|ndiff)\s+.*?') - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): parser = NdiffXmlParser(output) for host in parser.hostDiff: if host.ip is None: diff --git a/faraday_plugins/plugins/repo/netsparkercloud/plugin.py b/faraday_plugins/plugins/repo/netsparkercloud/plugin.py index fedb0647..e609fe6d 100644 --- a/faraday_plugins/plugins/repo/netsparkercloud/plugin.py +++ b/faraday_plugins/plugins/repo/netsparkercloud/plugin.py @@ -190,7 +190,7 @@ def __init__(self): self.framework_version = "1.0.0" self.options = None - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): parser = NetsparkerCloudXmlParser(output) first = True for i in parser.items: diff --git a/faraday_plugins/plugins/repo/nexpose_full/plugin.py b/faraday_plugins/plugins/repo/nexpose_full/plugin.py index 137907e8..c565809e 100644 --- a/faraday_plugins/plugins/repo/nexpose_full/plugin.py +++ b/faraday_plugins/plugins/repo/nexpose_full/plugin.py @@ -259,7 +259,7 @@ def __init__(self): self.framework_version = "1.0.0" self.options = None - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): parser = NexposeFullXmlParser(output) diff --git a/faraday_plugins/plugins/repo/nikto/plugin.py b/faraday_plugins/plugins/repo/nikto/plugin.py index e22fad5c..ee556abf 100644 --- a/faraday_plugins/plugins/repo/nikto/plugin.py +++ b/faraday_plugins/plugins/repo/nikto/plugin.py @@ -303,7 +303,7 @@ def __init__(self): - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it from the xml where it expects it to be present. diff --git a/faraday_plugins/plugins/repo/nmap/plugin.py b/faraday_plugins/plugins/repo/nmap/plugin.py index a0444e82..cfc0cd41 100644 --- a/faraday_plugins/plugins/repo/nmap/plugin.py +++ b/faraday_plugins/plugins/repo/nmap/plugin.py @@ -444,7 +444,7 @@ def __init__(self): self.xml_arg_re = re.compile(r"^.*(-oX\s*[^\s]+).*$") self.addSetting("Scan Technique", str, "-sS") - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it from the xml where it expects it to be present. diff --git a/faraday_plugins/plugins/repo/openvas/plugin.py b/faraday_plugins/plugins/repo/openvas/plugin.py index ede9af41..da185c61 100644 --- a/faraday_plugins/plugins/repo/openvas/plugin.py +++ b/faraday_plugins/plugins/repo/openvas/plugin.py @@ -338,13 +338,10 @@ def report_belongs_to(self, **kwargs): return re.search("OpenVAS", output) is not None or re.search('', output) is not None return False - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it from the xml where it expects it to be present. - - NOTE: if 'debug' is true then it is being run from a test case and the - output being sent is valid. """ parser = OpenvasXmlParser(output, self.logger) web = False diff --git a/faraday_plugins/plugins/repo/ping/plugin.py b/faraday_plugins/plugins/repo/ping/plugin.py index 1b1616ff..89bb6216 100644 --- a/faraday_plugins/plugins/repo/ping/plugin.py +++ b/faraday_plugins/plugins/repo/ping/plugin.py @@ -31,7 +31,7 @@ def __init__(self): self.version = "1.0.0" self._command_regex = re.compile(r'^(sudo ping|ping|sudo ping6|ping6)\s+.*?') - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): reg = re.search(r"PING ([\w\.-:]+)( |)\(([\w\.:]+)\)", output) if re.search("0 received|unknown host", output) is None and reg is not None: diff --git a/faraday_plugins/plugins/repo/propecia/plugin.py b/faraday_plugins/plugins/repo/propecia/plugin.py index 3dbd83a7..b762c62f 100644 --- a/faraday_plugins/plugins/repo/propecia/plugin.py +++ b/faraday_plugins/plugins/repo/propecia/plugin.py @@ -38,7 +38,7 @@ def __init__(self): self._host_ip = None self._port = "23" - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): host_info = re.search( r"(\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)", output) @@ -51,9 +51,6 @@ def parseOutputString(self, output, debug=False): h_id = self.createAndAddHost(host) s_id = self.createAndAddServiceToHost(h_id, str(self._port), "tcp", ports=[self._port], status="open", version="", description="") - if debug is True: - self.logger.info("Debug is active") - return True def processCommandString(self, username, current_path, command_string): diff --git a/faraday_plugins/plugins/repo/qualysguard/plugin.py b/faraday_plugins/plugins/repo/qualysguard/plugin.py index ca372820..46658a8c 100644 --- a/faraday_plugins/plugins/repo/qualysguard/plugin.py +++ b/faraday_plugins/plugins/repo/qualysguard/plugin.py @@ -346,7 +346,7 @@ def __init__(self): self.options = None self.open_options = {"mode": "r", "encoding": "utf-8"} - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): parser = QualysguardXmlParser(output) diff --git a/faraday_plugins/plugins/repo/retina/plugin.py b/faraday_plugins/plugins/repo/retina/plugin.py index 2cd80e00..ff196cc5 100644 --- a/faraday_plugins/plugins/repo/retina/plugin.py +++ b/faraday_plugins/plugins/repo/retina/plugin.py @@ -183,7 +183,7 @@ def __init__(self): self.options = None - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): parser = RetinaXmlParser(output) for item in parser.items: diff --git a/faraday_plugins/plugins/repo/sslyze/plugin.py b/faraday_plugins/plugins/repo/sslyze/plugin.py index 6fc97737..e01ce70c 100644 --- a/faraday_plugins/plugins/repo/sslyze/plugin.py +++ b/faraday_plugins/plugins/repo/sslyze/plugin.py @@ -108,7 +108,7 @@ def report_belongs_to(self, **kwargs): return re.search("SSLyzeVersion", output) is not None return False - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): parser = SslyzeXmlParser(output) host = parser.target[0].attrib['host'] ip = parser.target[0].attrib['ip'] diff --git a/faraday_plugins/plugins/repo/telnet/plugin.py b/faraday_plugins/plugins/repo/telnet/plugin.py index 92800b0a..47f270e2 100644 --- a/faraday_plugins/plugins/repo/telnet/plugin.py +++ b/faraday_plugins/plugins/repo/telnet/plugin.py @@ -56,7 +56,7 @@ def __init__(self): - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): host_info = re.search(r"Connected to (.+)\.", output) diff --git a/faraday_plugins/plugins/repo/theharvester/plugin.py b/faraday_plugins/plugins/repo/theharvester/plugin.py index 75fe3733..bd88e57f 100644 --- a/faraday_plugins/plugins/repo/theharvester/plugin.py +++ b/faraday_plugins/plugins/repo/theharvester/plugin.py @@ -100,29 +100,17 @@ def __init__(self): } - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it from the xml where it expects it to be present. - - NOTE: if 'debug' is true then it is being run from a test case and the - output being sent is valid. """ - - print("este es el output (%s)" % output) - - if debug: - parser = TheharvesterParser(output) - else: - - parser = TheharvesterParser(output) - - print(len(parser.items)) - for item in parser.items: - host = [] - if item['host'] != item['ip']: - host = [item['host']] - h_id = self.createAndAddHost(item['ip'], hostnames=host) + parser = TheharvesterParser(output) + for item in parser.items: + host = [] + if item['host'] != item['ip']: + host = [item['host']] + h_id = self.createAndAddHost(item['ip'], hostnames=host) del parser diff --git a/faraday_plugins/plugins/repo/traceroute/plugin.py b/faraday_plugins/plugins/repo/traceroute/plugin.py index f90bcf13..a2de5cd8 100644 --- a/faraday_plugins/plugins/repo/traceroute/plugin.py +++ b/faraday_plugins/plugins/repo/traceroute/plugin.py @@ -24,7 +24,7 @@ def __init__(self): self.command_string = "" self._command_regex = re.compile(r'^(traceroute|traceroute6)\s+.*?') - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): print("[*]Parsing Output...") diff --git a/faraday_plugins/plugins/repo/w3af/plugin.py b/faraday_plugins/plugins/repo/w3af/plugin.py index 8128137d..77c4c03d 100644 --- a/faraday_plugins/plugins/repo/w3af/plugin.py +++ b/faraday_plugins/plugins/repo/w3af/plugin.py @@ -225,7 +225,7 @@ def __init__(self): "-h": "Display this help message.", } - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): parser = W3afXmlParser(output) ip = resolve_hostname(parser.host) @@ -240,9 +240,6 @@ def parseOutputString(self, output, debug=False): del parser - def setHost(self): - pass - def createPlugin(): return W3afPlugin() diff --git a/faraday_plugins/plugins/repo/webfuzzer/plugin.py b/faraday_plugins/plugins/repo/webfuzzer/plugin.py index 1d6ef7ea..eb575f6d 100644 --- a/faraday_plugins/plugins/repo/webfuzzer/plugin.py +++ b/faraday_plugins/plugins/repo/webfuzzer/plugin.py @@ -98,13 +98,10 @@ def __init__(self): self._output_path = None - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it from the xml where it expects it to be present. - - NOTE: if 'debug' is true then it is being run from a test case and the - output being sent is valid. """ if self._output_path is None: diff --git a/faraday_plugins/plugins/repo/wfuzz/plugin.py b/faraday_plugins/plugins/repo/wfuzz/plugin.py index 3b448fbf..5eb8c819 100644 --- a/faraday_plugins/plugins/repo/wfuzz/plugin.py +++ b/faraday_plugins/plugins/repo/wfuzz/plugin.py @@ -52,7 +52,7 @@ def parseData(self, output): return data - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): output_list = output.split('\n') info = self.parseData(output_list) diff --git a/faraday_plugins/plugins/repo/whitesource/plugin.py b/faraday_plugins/plugins/repo/whitesource/plugin.py index 6690a149..39fae1e5 100644 --- a/faraday_plugins/plugins/repo/whitesource/plugin.py +++ b/faraday_plugins/plugins/repo/whitesource/plugin.py @@ -30,7 +30,7 @@ def __init__(self): self.version = "3.4.5" self.json_keys = {"vulnerabilities"} - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): parser = json.loads(output) if parser.get('vulnerabilities'): for vulnerability in parser['vulnerabilities']: diff --git a/faraday_plugins/plugins/repo/whois/plugin.py b/faraday_plugins/plugins/repo/whois/plugin.py index c032fbc8..33191de7 100644 --- a/faraday_plugins/plugins/repo/whois/plugin.py +++ b/faraday_plugins/plugins/repo/whois/plugin.py @@ -70,7 +70,7 @@ def __init__(self): - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): matches = re.findall("Name Server:\s*(.*)\s*", output) for m in matches: m = m.strip() diff --git a/faraday_plugins/plugins/repo/wpscan/plugin.py b/faraday_plugins/plugins/repo/wpscan/plugin.py index 0c3e7b59..07e8de8c 100644 --- a/faraday_plugins/plugins/repo/wpscan/plugin.py +++ b/faraday_plugins/plugins/repo/wpscan/plugin.py @@ -57,7 +57,7 @@ def __init__(self): self.version = "3.4.5" self.json_keys = {"target_url", "effective_url", "interesting_findings"} - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): parser = WPScanJsonParser(output) url_data = parser.parse_url(parser.json_data['target_url']) host_id = self.createAndAddHost(url_data['address'], hostnames=[url_data['hostname']]) diff --git a/faraday_plugins/plugins/repo/x1/plugin.py b/faraday_plugins/plugins/repo/x1/plugin.py index 471e8a60..e506d1a4 100644 --- a/faraday_plugins/plugins/repo/x1/plugin.py +++ b/faraday_plugins/plugins/repo/x1/plugin.py @@ -169,7 +169,7 @@ def __init__(self): - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): parser = X1XmlParser(output) for item in parser.items: diff --git a/faraday_plugins/plugins/repo/xsssniper/plugin.py b/faraday_plugins/plugins/repo/xsssniper/plugin.py index cf6f436e..5afe36e8 100644 --- a/faraday_plugins/plugins/repo/xsssniper/plugin.py +++ b/faraday_plugins/plugins/repo/xsssniper/plugin.py @@ -26,7 +26,7 @@ def __init__(self): self._command_regex = re.compile(r'^(sudo xsssniper|xsssniper|sudo xsssniper\.py|xsssniper\.py|sudo python' r'xsssniper\.py|.\/xsssniper\.py|python xsssniper\.py)\s+') - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): parametro = [] lineas = output.split("\n") aux = 0 diff --git a/faraday_plugins/plugins/repo/zap/plugin.py b/faraday_plugins/plugins/repo/zap/plugin.py index b567e303..98de0ee9 100644 --- a/faraday_plugins/plugins/repo/zap/plugin.py +++ b/faraday_plugins/plugins/repo/zap/plugin.py @@ -238,13 +238,10 @@ def __init__(self): self.options = None - def parseOutputString(self, output, debug=False): + def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it from the xml where it expects it to be present. - - NOTE: if 'debug' is true then it is being run from a test case and the - output being sent is valid. """ parser = ZapXmlParser(output) From 0e1184a84640b6aeabfe06722e409c90daa9e7c4 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Fri, 12 Jun 2020 13:56:59 -0300 Subject: [PATCH 062/698] maltego fixes --- .../plugins/repo/maltego/plugin.py | 168 +++++++++--------- 1 file changed, 85 insertions(+), 83 deletions(-) diff --git a/faraday_plugins/plugins/repo/maltego/plugin.py b/faraday_plugins/plugins/repo/maltego/plugin.py index a8e8a379..26061a81 100755 --- a/faraday_plugins/plugins/repo/maltego/plugin.py +++ b/faraday_plugins/plugins/repo/maltego/plugin.py @@ -8,6 +8,8 @@ import os import zipfile +from faraday_plugins.plugins.plugins_utils import resolve_hostname + try: import xml.etree.cElementTree as ET import xml.etree.ElementTree as ET_ORIG @@ -18,7 +20,6 @@ ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] -current_path = os.path.abspath(os.getcwd()) __author__ = "Ezequiel Tavella" __copyright__ = "Copyright (c) 2015, Infobyte LLC" @@ -58,7 +59,7 @@ def readMtgl(mtgl_file): if maltego_file_dns in mtgl_file.namelist(): xml_dns = ET.parse(mtgl_file.open(maltego_file_dns)) - check_files.update({"DNS": xml_dns}) + check_files.update({"domain": xml_dns}) if maltego_file_domain in mtgl_file.namelist(): xml_domain = ET.parse(mtgl_file.open(maltego_file_domain)) @@ -112,7 +113,7 @@ class Host(): def __init__(self): self.ip = "" self.node_id = "" - self.dns_name = "" + self.dns_name = set() self.website = "" self.netblock = "" self.location = "" @@ -120,7 +121,7 @@ def __init__(self): self.ns_record = "" -class MaltegoMtgxParser(): +class MaltegoParser(): def __init__(self, xml_file, extension): @@ -169,8 +170,10 @@ def getIpAndId(self, node): entity = node.find( "{http://graphml.graphdrawing.org/xmlns}data/" "{http://maltego.paterva.com/xml/mtgx}MaltegoEntity") + + # Check if is IPv4Address - if entity.get("type") != "maltego.IPv4Address": + if entity.get("type") not in ("maltego.IPv4Address", "maltego.Domain", "maltego.Website"): return None # Get IP value @@ -178,8 +181,13 @@ def getIpAndId(self, node): "{http://maltego.paterva.com/xml/mtgx}Properties/" "{http://maltego.paterva.com/xml/mtgx}Property/" "{http://maltego.paterva.com/xml/mtgx}Value") - - return {"node_id": node_id, "ip": value.text} + if entity.get("type") in ("maltego.Domain", "maltego.Website"): + ip = resolve_hostname(value.text) + hostname = value.text + else: + ip = value.text + hostname = None + return {"node_id": node_id, "ip": ip, "hostname": hostname} def getNode(self, node_id): @@ -324,7 +332,8 @@ def parse(self): host = Host() host.ip = result.get("ip") host.node_id = result.get("node_id") - + if result.get("hostname"): + host.dns_name.add(result.get("hostname")) # Get relations with other nodes node_relations = self.relations[host.node_id] @@ -335,8 +344,8 @@ def parse(self): target_type = self.getType(target_node) # Check type of node y add data to host... - if target_type == "maltego.DNSName": - host.dns_name = self.getValue(target_node) + if target_type in ("maltego.DNSName", "maltego.Domain"): + host.dns_name.add(self.getValue(target_node)['value']) elif target_type == "maltego.Website": host.website = self.getWebsite(target_node) elif target_type == "maltego.Netblock": @@ -378,94 +387,87 @@ def __init__(self): "Entities/maltego.Person.entity", "Entities/maltego.PhoneNumber.entity", "Entities/maltego.Website.entity", "Entities/maltego.Hash.entity", "Entities/maltego.hashtag.entity", "Entities/maltego.TwitterUserList.entity"} - self.current_path = None - self.options = None - self._current_output = None - self._command_regex = re.compile( - r'^(sudo maltego|maltego|\.\/maltego).*?') - global current_path def parseOutputString(self, output): - if 'Graphs/Graph1.graphml' in output.namelist(): - maltego_parser = MaltegoMtgxParser(output, self.extension[1]) - if not maltego_parser.parse(): + maltego_parser = MaltegoParser(output, self.extension[1]) + hosts = maltego_parser.parse() + if not hosts: + self.logger.warning("No hosts data found in maltego report") pass else: - for host in maltego_parser.parse(): + for host in hosts: if host.ip is None: ip = '0.0.0.0' + self.logger.warning("Unknown IP") else: ip = host.ip - try: - network_segment = host.netblock["ipv4_range"] - hostname_resolution = [host.dns_name["value"]] - except TypeError: - pass - network_segment = "unknown" - hostname_resolution = "unknown" - host_id = self.createAndAddHost(name=ip, hostnames=[hostname_resolution]) - # Create interface - # Create note with NetBlock information - if host.netblock: - try: - text = f'Network owner:\n {host.netblock["network_owner"]} ' \ - f'Country:\n {host.netblock["country"]}' - except TypeError: - text = "unknown" - - self.createAndAddNoteToHost(host_id=host_id, name="Netblock Information", - text=text.encode('ascii', 'ignore')) - - # Create note with host location - if host.location: - try: - text = f'Location:\n {host.location["name"]} \nArea:\n {host.location["area"]} ' \ - f'\nArea 2:\n {host.location["area_2"]} ' \ - f'\nCountry_code:\n { host.location["country_code"]} ' \ - f'\nLatitude:\n {host.location["latitude"]} \nLongitude:\n {host.location["longitude"]}' - except TypeError: - text = "unknown" - - self.createAndAddNoteToHost(host_id=host_id, name="Location Information", - text=text.encode('ascii', 'ignore')) - - # Create service web server - if host.website: - try: - description = f'SSL Enabled: {host.website["ssl_enabled"]}' - except TypeError: - description = "unknown" - - service_id = self.createAndAddServiceToHost(host_id=host_id, name=host.website["name"], - protocol="TCP:HTTP", ports=[80], - description=description) - - try: - text = f'Urls: \n {host.website["urls"]}' - self.createAndAddNoteToService(host_id=host_id, service_id=service_id, name="URLs", - text=text.encode('ascii', 'ignore')) - except TypeError: - pass - - if host.mx_record: - self.createAndAddServiceToHost(host_id=host_id, name=host.mx_record["value"], protocol="SMTP", - ports=[25], description="E-mail Server") - - if host.ns_record: - self.createAndAddServiceToHost(host_id=host_id, name=host.ns_record["value"], protocol="DNS", - ports=[53], description="DNS Server") + host_id = self.createAndAddHost(ip, hostnames=list(host.dns_name)) + # Create note with NetBlock information + if host.netblock: + try: + text = f'Network owner:\n {host.netblock["network_owner"]} ' \ + f'Country:\n {host.netblock["country"]}' + except TypeError: + text = "unknown" + + self.createAndAddNoteToHost(host_id=host_id, name="Netblock Information", + text=text.encode('ascii', 'ignore')) + + # Create note with host location + if host.location: + try: + text = f'Location:\n {host.location["name"]} \nArea:\n {host.location["area"]} ' \ + f'\nArea 2:\n {host.location["area_2"]} ' \ + f'\nCountry_code:\n { host.location["country_code"]} ' \ + f'\nLatitude:\n {host.location["latitude"]} \nLongitude:\n {host.location["longitude"]}' + except TypeError: + text = "unknown" + + self.createAndAddNoteToHost(host_id=host_id, name="Location Information", + text=text.encode('ascii', 'ignore')) + + # Create service web server + if host.website: + try: + description = f'SSL Enabled: {host.website["ssl_enabled"]}' + except TypeError: + description = "unknown" + + service_id = self.createAndAddServiceToHost(host_id=host_id, name=host.website["name"], + protocol="TCP:HTTP", ports=[80], + description=description) + + try: + text = f'Urls: \n {host.website["urls"]}' + self.createAndAddNoteToService(host_id=host_id, service_id=service_id, name="URLs", + text=text.encode('ascii', 'ignore')) + except TypeError: + pass + + if host.mx_record: + self.createAndAddServiceToHost(host_id=host_id, name=host.mx_record["value"], protocol="SMTP", + ports=[25], description="E-mail Server") + + if host.ns_record: + self.createAndAddServiceToHost(host_id=host_id, name=host.ns_record["value"], protocol="DNS", + ports=[53], description="DNS Server") else: - maltego_parser = MaltegoMtgxParser(output, self.extension[0]) - if maltego_parser.xml.get('DNS'): - hostname_resolution = maltego_parser.getInfoMtgl(maltego_parser.xml['DNS'], 'fqdn') + maltego_parser = MaltegoParser(output, self.extension[0]) + if not maltego_parser.xml.get('domain') or not maltego_parser.xml.get('ipv4'): + return + if maltego_parser.xml.get('domain'): + hostnames = maltego_parser.getInfoMtgl(maltego_parser.xml['domain'], 'fqdn') else: - hostname_resolution = None + hostnames = None if maltego_parser.xml.get('ipv4'): host_ip = maltego_parser.getInfoMtgl(maltego_parser.xml['ipv4'], 'ipv4-address') + host_id = self.createAndAddHost(name=host_ip, hostnames=hostnames) else: host_ip = '0.0.0.0' - host_id = self.createAndAddHost(name=host_ip, hostnames=hostname_resolution) + host_id = self.createAndAddHost(name=host_ip, hostnames=hostnames) + + if maltego_parser.xml.get('location'): location_name = maltego_parser.getInfoMtgl(maltego_parser.xml['location'], 'location.name') location_area = maltego_parser.getInfoMtgl(maltego_parser.xml['location'], 'location.area') From 506e3a0449118dc23a8c1b324812b3e2cfcebcde Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Fri, 12 Jun 2020 14:45:34 -0300 Subject: [PATCH 063/698] add debug to generate_summary --- tests/generate_reports_summary.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/generate_reports_summary.py b/tests/generate_reports_summary.py index 19e629f5..81d868f3 100755 --- a/tests/generate_reports_summary.py +++ b/tests/generate_reports_summary.py @@ -37,13 +37,16 @@ def list_report_files(): @click.command() @click.option('--force', is_flag=True) -def generate_reports_tests(force): +@click.option('--debug', is_flag=False) +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") From 5c416133579977da5e92c9dfefe02793559814ac Mon Sep 17 00:00:00 2001 From: Blas Date: Sun, 14 Jun 2020 20:12:20 -0300 Subject: [PATCH 064/698] fix to report generated to arachni faraday executor --- .../plugins/repo/arachni/plugin.py | 58 ++++++++++++------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/faraday_plugins/plugins/repo/arachni/plugin.py b/faraday_plugins/plugins/repo/arachni/plugin.py index 9bc6f4fd..7acd46fd 100755 --- a/faraday_plugins/plugins/repo/arachni/plugin.py +++ b/faraday_plugins/plugins/repo/arachni/plugin.py @@ -55,13 +55,15 @@ def getPlugins(self, tree): def getSystem(self, tree): system_tree = tree.find('system') - return System(system_tree) + if system_tree is None: + return System(tree, False) + else: + return System(system_tree, True) class Issue(): def __init__(self, issue_node): - self.node = issue_node self.name = self.getDesc('name') self.severity = self.getDesc('severity') @@ -131,7 +133,6 @@ def getParameters(self): except: parameters = '' - return ' - '.join(result) def getRequest(self): @@ -161,33 +162,50 @@ def getResponse(self): class System(): - def __init__(self, node): - + def __init__(self, node, tag_exists): self.node = node - self.user_agent = None - self.url = None - self.audited_elements = None - self.modules = '' - self.cookies = None - - self.getOptions() - - self.version = self.getDesc('version') - self.start_time = self.getDesc('start_datetime') - self.finish_time = self.getDesc('finish_datetime') - - self.note = self.getNote() + if not tag_exists: + self.user_agent = 'Arachni' + self.url = self.getUrl() + self.modules = '' + self.version = self.node.find('version') + self.start_time = self.node.find('start_datetime') + self.finish_time = self.node.find('finish_datetime') + else: + self.user_agent = None + self.url = None + self.audited_elements = None + self.modules = '' + self.cookies = None + self.getOptions() + self.version = self.getDesc('version') + self.start_time = self.getDesc('start_datetime') + self.finish_time = self.getDesc('finish_datetime') + + self.note = self.getNote() + + def getUrl(self): + sitemap = self.node.find("sitemap/entry") + return sitemap.get('url') def getOptions(self): # Get values of options scan - options = self.node.find('options') + try: + options = self.node.find('options') + except: + options = False if options: options_string = options.text else: options_string = None - self.user_agent = self.node.find('user_agent').text + + try: + self.user_agent = self.node.find('user_agent').text + except: + self.user_agent = None + self.url = self.node.find('url').text tags_audited_elements = self.node.find('audited_elements') element_text = [] From 114a734cb007e236d5f9bf3f6d92c9a7ddc5b260 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Tue, 16 Jun 2020 10:59:53 -0300 Subject: [PATCH 065/698] delete some unused methods --- .DS_Store | Bin 0 -> 6148 bytes faraday_plugins/.DS_Store | Bin 0 -> 6148 bytes faraday_plugins/plugins/plugin.py | 9 --------- faraday_plugins/plugins/repo/dirsearch/plugin.py | 2 +- .../plugins/repo/netsparker/plugin.py | 2 +- .../plugins/repo/netsparkercloud/plugin.py | 2 +- 6 files changed, 3 insertions(+), 12 deletions(-) create mode 100644 .DS_Store create mode 100644 faraday_plugins/.DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..32eb81520beb94352971cdbc65d58ac415eb1556 GIT binary patch literal 6148 zcmeHK%Sr=55Ukc50v^oKo#Lg;XL^{vd;2v+d#WQx3>eC75UgCkgJ^efX zfGr*|;N^9_A9hc}Hg7q7jIvTd3P=GdAO)nrFBS0KOPgOLDoOzs3--bz_9}7xm|ewzoGvy{~wdIlLAuUUnyX-)q1t$D^+iuyqx#iM!%zb%?I6$ p>!2`1J0?au=EmFcRTO1i^EIFM!Z9)E%mH1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 Date: Tue, 16 Jun 2020 11:00:25 -0300 Subject: [PATCH 066/698] delete .DS_Store --- .DS_Store | Bin 6148 -> 0 bytes faraday_plugins/.DS_Store | Bin 6148 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store delete mode 100644 faraday_plugins/.DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 32eb81520beb94352971cdbc65d58ac415eb1556..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK%Sr=55Ukc50v^oKo#Lg;XL^{vd;2v+d#WQx3>eC75UgCkgJ^efX zfGr*|;N^9_A9hc}Hg7q7jIvTd3P=GdAO)nrFBS0KOPgOLDoOzs3--bz_9}7xm|ewzoGvy{~wdIlLAuUUnyX-)q1t$D^+iuyqx#iM!%zb%?I6$ p>!2`1J0?au=EmFcRTO1i^EIFM!Z9)E%mH1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 Date: Tue, 16 Jun 2020 11:02:40 -0300 Subject: [PATCH 067/698] fix flake8 --- faraday_plugins/plugins/repo/maltego/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faraday_plugins/plugins/repo/maltego/plugin.py b/faraday_plugins/plugins/repo/maltego/plugin.py index 26061a81..b1d2113e 100755 --- a/faraday_plugins/plugins/repo/maltego/plugin.py +++ b/faraday_plugins/plugins/repo/maltego/plugin.py @@ -403,7 +403,7 @@ def parseOutputString(self, output): else: ip = host.ip host_id = self.createAndAddHost(ip, hostnames=list(host.dns_name)) - # Create note with NetBlock information + # Create note with NetBlock information if host.netblock: try: text = f'Network owner:\n {host.netblock["network_owner"]} ' \ From 560d81174158f76a94350b414dd5d0dfa11aaa25 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Tue, 16 Jun 2020 12:14:10 -0300 Subject: [PATCH 068/698] add changelog --- CHANGELOG/current/delete_old_methods.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 CHANGELOG/current/delete_old_methods.md diff --git a/CHANGELOG/current/delete_old_methods.md b/CHANGELOG/current/delete_old_methods.md new file mode 100644 index 00000000..f36561a1 --- /dev/null +++ b/CHANGELOG/current/delete_old_methods.md @@ -0,0 +1 @@ +delete old deprecated methods \ No newline at end of file From 92287d7b34dd3d1368278bcea9d34664bbab7c3d Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 17 Jun 2020 14:06:26 -0300 Subject: [PATCH 069/698] dont show baners un process-xxx commands --- faraday_plugins/commands.py | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/faraday_plugins/commands.py b/faraday_plugins/commands.py index 924a01d1..e3983f02 100644 --- a/faraday_plugins/commands.py +++ b/faraday_plugins/commands.py @@ -54,32 +54,28 @@ def list_plugins(custom_plugins_folder): @click.option('-o', '--output-file', type=click.Path(exists=False)) def process_report(report_file, plugin_id, custom_plugins_folder, summary, output_file): if not os.path.isfile(report_file): - click.echo(click.style(f"File {report_file} Don't Exists", fg="red")) + click.echo(click.style(f"File {report_file} Don't Exists", fg="red"), err=True) else: plugins_manager = PluginsManager(custom_plugins_folder) 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")) + 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")) + click.echo(click.style(f"Failed to detect report: {report_file}", fg="red"), err=True) return - color_message = click.style("Processing report:", fg="green") - click.echo(f"{color_message} {report_file} ({plugin.id})\n") plugin.processReport(report_file, getpass.getuser()) if summary: - click.echo(click.style("\nPlugin Summary: ", fg="cyan")) 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(click.style("\nFaraday API json: ", fg="cyan")) click.echo(json.dumps(plugin.get_data(), indent=4)) @@ -90,53 +86,52 @@ def process_report(report_file, plugin_id, custom_plugins_folder, summary, outpu @click.option('-dr', '--dont-run', is_flag=True) @click.option('--summary', is_flag=True) @click.option('-o', '--output-file', type=click.Path(exists=False)) -def process_command(command, plugin_id, custom_plugins_folder, dont_run, summary, output_file): +@click.option('--show-output', is_flag=True) +def process_command(command, plugin_id, custom_plugins_folder, dont_run, summary, output_file, show_output): 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")) + 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")) + 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 not dont_run: - color_message = click.style("Running command:", fg="green") - click.echo(f"{color_message} {command}\n") 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') - sys.stdout.write(line) - output.write(line) + 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()) - sys.stdout.writelines(line) - output.writelines(extra_lines) + 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(click.style("\nPlugin Summary: ", fg="cyan")) 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(click.style("\nFaraday API json: ", fg="cyan")) click.echo(json.dumps(plugin.get_data(), indent=4)) else: - click.echo(click.style("Command execution error!!", fg="red")) + click.echo(click.style("Command execution error!!", fg="red"), err=True) else: color_message = click.style("Command: ", fg="green") click.echo(f"{color_message} {command}") @@ -156,7 +151,7 @@ def detect_report(report_file, custom_plugins_folder): 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")) + click.echo(click.style(f"Failed to detect report: {report_file}", fg="red"), err=True) @cli.command() @@ -169,4 +164,4 @@ def detect_command(command, custom_plugins_folder): 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")) + click.echo(click.style(f"Failed to detect command: {command}", fg="red"), err=True) From 46cca202f54ededd1aae3cb74ca4ff2021eaa1c5 Mon Sep 17 00:00:00 2001 From: Leonardo Lazzaro Date: Wed, 17 Jun 2020 22:32:05 -0300 Subject: [PATCH 070/698] add default.nix --- default.nix | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 default.nix diff --git a/default.nix b/default.nix new file mode 100644 index 00000000..67a6ced2 --- /dev/null +++ b/default.nix @@ -0,0 +1,24 @@ +with import {}; +pkgs.python38Packages.buildPythonPackage rec { + name = "env"; + + env = buildEnv { name = name; paths = buildInputs; }; + + buildInputs = [ + (python38.buildEnv.override { + ignoreCollisions = true; + extraLibs = with python38Packages; [ + requests + click + simplejson + requests + lxml + html2text + beautifulsoup4 + pytz + python-dateutil + colorama + ]; + }) + ]; +} From e5017267c539223a49a9540dd24b17da02eea62f Mon Sep 17 00:00:00 2001 From: Leonardo Lazzaro Date: Wed, 17 Jun 2020 23:10:13 -0300 Subject: [PATCH 071/698] add changelog --- CHANGELOG/current/fix_Arachni.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 CHANGELOG/current/fix_Arachni.md diff --git a/CHANGELOG/current/fix_Arachni.md b/CHANGELOG/current/fix_Arachni.md new file mode 100644 index 00000000..3a812d06 --- /dev/null +++ b/CHANGELOG/current/fix_Arachni.md @@ -0,0 +1 @@ +* Bug fix: Arachni Plugin 'NoneType' object has no attribute 'find' From 084b682a9aec8d4733c4342aeb7e4c72a50ef51b Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Fri, 19 Jun 2020 17:31:59 -0300 Subject: [PATCH 072/698] update readme --- CHANGELOG/current/update_readme.md | 1 + README.md | 113 ++++++++++++++++++++--------- faraday_plugins/commands.py | 14 ++-- 3 files changed, 87 insertions(+), 41 deletions(-) create mode 100644 CHANGELOG/current/update_readme.md diff --git a/CHANGELOG/current/update_readme.md b/CHANGELOG/current/update_readme.md new file mode 100644 index 00000000..4cfa6d9c --- /dev/null +++ b/CHANGELOG/current/update_readme.md @@ -0,0 +1 @@ +Update Readme \ No newline at end of file diff --git a/README.md b/README.md index 66d71700..c531f402 100644 --- a/README.md +++ b/README.md @@ -8,62 +8,61 @@ pip install faraday-plugins > List Plugins +List all plugins and if its compatible with command or/and report + +Optional params: + +- -cpf / --custom-plugins-folder PATH: If given will also look for custom plugins on that path + ```shell script -faraday-plugins show +faraday-plugins list-plugins ``` > Test autodetect plugin from command ```shell script faraday-plugins detect-command "ping -c 4 www.google.com" -> Faraday Plugin: ping + +Faraday Plugin: ping ``` -> Test command with plugin +> Test process command with plugin Optional params: -- -dr: Dont run, just show the generated command +- --plugin_id PLUGIN_ID: Dont detect the plugin, use this one +- -cpf / --custom-plugins-folder PATH: If given will also look for custom plugins on that path +- -dr / --dont-run: Dont run, just show the generated command +- -o / --output-file PATH: send json outout to file instead of stdout +- -sh / --show-output: show the output of the command ```shell script faraday-plugins process-command "ping -c4 www.google.com" -Running command: ping -c4 www.google.com - -PING www.google.com (216.58.222.36): 56 data bytes -64 bytes from 216.58.222.36: icmp_seq=0 ttl=54 time=11.144 ms -64 bytes from 216.58.222.36: icmp_seq=1 ttl=54 time=14.330 ms -64 bytes from 216.58.222.36: icmp_seq=2 ttl=54 time=11.997 ms -64 bytes from 216.58.222.36: icmp_seq=3 ttl=54 time=11.190 ms - ---- www.google.com ping statistics --- -4 packets transmitted, 4 packets received, 0.0% packet loss -round-trip min/avg/max/stddev = 11.144/12.165/14.330/1.295 ms - -Faraday API json: { "hosts": [ { - "ip": "216.58.222.36", + "ip": "216.58.202.36", "os": "unknown", "hostnames": [ "www.google.com" ], "description": "", - "mac": "00:00:00:00:00:00", + "mac": null, "credentials": [], "services": [], - "vulnerabilities": [] + "vulnerabilities": [], + "tags": [] } ], "command": { "tool": "ping", "command": "ping", "params": "-c4 www.google.com", - "user": "aenima", + "user": "user", "hostname": "", - "start_date": "2020-05-05T23:09:39.656132", - "duration": 56789, - "import_source": "report" + "start_date": "2020-06-19T17:02:37.982293", + "duration": 39309, + "import_source": "shell" } } ``` @@ -72,24 +71,70 @@ Faraday API json: ```shell script faraday-plugins detect-report /path/to/report.xml + +Faraday Plugin: Nmap ``` > Test report with plugin -```shell script -faraday-plugins process-report /path/to/report.xml -``` - -> Process options: +Optional params: -Both process-xxx command have this optional parameters +- --plugin_id PLUGIN_ID: Dont detect the plugin, use this one +- -cpf / --custom-plugins-folder PATH: If given will also look for custom plugins on that path -- --plugin_id: If given will use that plugin instead of try to detect it -- --summary: If given will generate a summary of the findings instead of the result -- -cpf/--custom-plugins-folder: If given will also look for custom plugins if that path +```shell script +faraday-plugins process-report /path/to/nmap_report.xml -NOTE: you can also use -cpf in **show** command to test if your custom plugins load ok +{ + "hosts": [ + { + "ip": "192.168.66.1", + "os": "unknown", + "hostnames": [], + "description": "", + "mac": "00:00:00:00:00:00", + "credentials": [], + "services": [ + { + "name": "domain", + "protocol": "tcp", + "port": 53, + "status": "open", + "version": "", + "description": "domain", + "credentials": [], + "vulnerabilities": [], + "tags": [] + }, + { + "name": "netbios-ssn", + "protocol": "tcp", + "port": 139, + "status": "open", + "version": "", + "description": "netbios-ssn", + "credentials": [], + "vulnerabilities": [], + "tags": [] + } + ], + "vulnerabilities": [], + "tags": [] + } + ], + "command": { + "tool": "Nmap", + "command": "Nmap", + "params": "/path/to/nmap_report.xml", + "user": "user", + "hostname": "", + "start_date": "2020-06-19T17:22:11.608134", + "duration": 1233, + "import_source": "report" + } +} +``` > Plugin Logger diff --git a/faraday_plugins/commands.py b/faraday_plugins/commands.py index e3983f02..c4fc1cc7 100644 --- a/faraday_plugins/commands.py +++ b/faraday_plugins/commands.py @@ -86,7 +86,7 @@ def process_report(report_file, plugin_id, custom_plugins_folder, summary, outpu @click.option('-dr', '--dont-run', is_flag=True) @click.option('--summary', is_flag=True) @click.option('-o', '--output-file', type=click.Path(exists=False)) -@click.option('--show-output', is_flag=True) +@click.option('-sh', '--show-output', is_flag=True) def process_command(command, plugin_id, custom_plugins_folder, dont_run, summary, output_file, show_output): plugins_manager = PluginsManager(custom_plugins_folder) analyzer = CommandAnalyzer(plugins_manager) @@ -104,7 +104,10 @@ def process_command(command, plugin_id, custom_plugins_folder, dont_run, summary modified_command = plugin.processCommandString(getpass.getuser(), current_path, command) if modified_command: command = modified_command - if not dont_run: + 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: @@ -112,12 +115,12 @@ def process_command(command, plugin_id, custom_plugins_folder, dont_run, summary line = p.stdout.readline().decode('utf-8') if show_output: sys.stdout.write(line) - output.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) + output.writelines(extra_lines) break output_value = output.getvalue() if retcode == 0: @@ -132,9 +135,6 @@ def process_command(command, plugin_id, custom_plugins_folder, dont_run, summary click.echo(json.dumps(plugin.get_data(), indent=4)) else: click.echo(click.style("Command execution error!!", fg="red"), err=True) - else: - color_message = click.style("Command: ", fg="green") - click.echo(f"{color_message} {command}") From 4468f661e54efc3dd78ffad367b41c0844fb6144 Mon Sep 17 00:00:00 2001 From: Eric Horvat Date: Fri, 19 Jun 2020 18:03:36 -0300 Subject: [PATCH 073/698] [MOD] version --- faraday_plugins/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faraday_plugins/__init__.py b/faraday_plugins/__init__.py index 64477cf2..3f262a63 100644 --- a/faraday_plugins/__init__.py +++ b/faraday_plugins/__init__.py @@ -1 +1 @@ -__version__ = '1.2' +__version__ = '1.2.1' From 7a758fe96d25103fc8b0f19d846430c2413bc3df Mon Sep 17 00:00:00 2001 From: Blas Date: Fri, 19 Jun 2020 23:31:13 -0300 Subject: [PATCH 074/698] prowler parser, add changelog --- CHANGELOG/current/add_prowler.md | 1 + .../plugins/repo/awsprowler/plugin.py | 32 +++++++++++-------- 2 files changed, 20 insertions(+), 13 deletions(-) create mode 100644 CHANGELOG/current/add_prowler.md diff --git a/CHANGELOG/current/add_prowler.md b/CHANGELOG/current/add_prowler.md new file mode 100644 index 00000000..b4d6355d --- /dev/null +++ b/CHANGELOG/current/add_prowler.md @@ -0,0 +1 @@ +Add plugins prowler \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/awsprowler/plugin.py b/faraday_plugins/plugins/repo/awsprowler/plugin.py index 4e69bfb8..4e072d1e 100644 --- a/faraday_plugins/plugins/repo/awsprowler/plugin.py +++ b/faraday_plugins/plugins/repo/awsprowler/plugin.py @@ -22,18 +22,9 @@ class AwsProwlerJsonParser: def __init__(self, json_output): - string_manipulate = json_output.replace("}", "},") - json_manipulate = string_manipulate[:len(string_manipulate) - 2] - json_bla = "{%s}" % json_manipulate - - self.json_data = json.loads(json_bla) - - def get_address(self, hostname): - # Returns remote IP address from hostname. - try: - return socket.gethostbyname(hostname) - except socket.error as msg: - return '0.0.0.0' + string_manipulate = json_output.replace("}", "} #") + string_manipulate = string_manipulate[:len(string_manipulate) - 2] + self.report_aws = string_manipulate.split("#") class AwsProwlerPlugin(PluginJsonFormat): @@ -51,7 +42,22 @@ def __init__(self): def parseOutputString(self, output, debug=False): parser = AwsProwlerJsonParser(output) - print(parser) + host_id = self.createAndAddHost(name='0.0.0.0', description="AWS Prowler") + for vuln in parser.report_aws: + json_vuln = json.loads(vuln) + vuln_name = json_vuln.get('Account Number', 'Not Info') + vuln_desc = json_vuln.get('Control', 'Not Info') + vuln_severity = json_vuln.get('Level', 'Not Info') + vuln_run_date = json_vuln.get('Timestamp', 'Not Info') + vuln_status = json_vuln.get('Status', 'Not Info') + vuln_external_id = json_vuln.get('Control ID', 'Not Info') + vuln_data = json_vuln.get('Message', 'Not Info') + + self.createAndAddVulnToHost(host_id=host_id, name=vuln_name, desc=vuln_desc, + severity=self.normalize_severity(vuln_severity), + run_date=vuln_run_date, status=vuln_status, + external_id=vuln_external_id, data=vuln_data) + def createPlugin(): return AwsProwlerPlugin() From e44193c101e358556e145cb6adc291518cb215ea Mon Sep 17 00:00:00 2001 From: Blas Date: Sun, 21 Jun 2020 16:40:30 -0300 Subject: [PATCH 075/698] ADD plugin appspider --- CHANGELOG/current/add_appspider.md | 1 + .../plugins/repo/appspider/__init__.py | 0 .../plugins/repo/appspider/plugin.py | 117 ++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 CHANGELOG/current/add_appspider.md create mode 100644 faraday_plugins/plugins/repo/appspider/__init__.py create mode 100644 faraday_plugins/plugins/repo/appspider/plugin.py diff --git a/CHANGELOG/current/add_appspider.md b/CHANGELOG/current/add_appspider.md new file mode 100644 index 00000000..a2dabc6e --- /dev/null +++ b/CHANGELOG/current/add_appspider.md @@ -0,0 +1 @@ +ADD plugin AppSpider diff --git a/faraday_plugins/plugins/repo/appspider/__init__.py b/faraday_plugins/plugins/repo/appspider/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/faraday_plugins/plugins/repo/appspider/plugin.py b/faraday_plugins/plugins/repo/appspider/plugin.py new file mode 100644 index 00000000..d3ebd48a --- /dev/null +++ b/faraday_plugins/plugins/repo/appspider/plugin.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Faraday Penetration Test IDE +Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/) +See the file 'doc/LICENSE' for the license information +""" +from faraday_plugins.plugins.plugin import PluginXMLFormat +from datetime import datetime +try: + import xml.etree.cElementTree as ET +except ImportError: + import xml.etree.ElementTree as ET + +__author__ = 'Blas Moyano' +__copyright__ = 'Copyright 2020, Faraday Project' +__credits__ = ['Blas Moyano'] +__license__ = '' +__version__ = '1.0.0' +__status__ = 'Development' + + +class AppSpiderParser: + def __init__(self, xml_output): + self.tree = self.parse_xml(xml_output) + if self.tree: + self.vuln_list = self.tree.find('VulnList') + self.name_scan = self.tree.find('ScanName').text + else: + self.tree = None + + def parse_xml(self, xml_output): + try: + tree = ET.fromstring(xml_output) + except SyntaxError as err: + print('SyntaxError In xml: %s. %s' % (err, xml_output)) + return None + return tree + + +class AppSpiderPlugin(PluginXMLFormat): + def __init__(self): + super().__init__() + self.identifier_tag = ["VulnSummary"] + self.id = 'AppSpider' + self.name = 'AppSpider XML Output Plugin' + self.plugin_version = '1.0.0' + self.version = '1.0.0' + self.framework_version = '1.0.0' + self.options = None + self.protocol = None + self.port = '80' + self.address = None + + def parseOutputString(self, output): + parser = AppSpiderParser(output) + websites = [] + websites_ip = [] + + for vuln in parser.vuln_list: + websites.append(vuln.find('WebSite').text) + websites_ip.append(vuln.find('WebSiteIP').text) + + url = set(websites) + ip = set(websites_ip) + if None in ip: + ip.remove(None) + + host_id = self.createAndAddHost(name=sorted(list(ip))[0], hostnames=sorted(list(url)), + description=parser.name_scan) + data_info = [] + + for vulns in parser.vuln_list: + vuln_name = vulns.find('VulnType').text + vuln_desc = vulns.find('Description').text + vuln_ref = vulns.find('VulnUrl').text + severity = vulns.find('AttackScore').text + vuln_resolution = vulns.find('Recommendation').text + vuln_external_id = vulns.find('DbId').text + vuln_run_date = vulns.find('ScanDate').text + data_info.append(vulns.find('AttackClass').text) + data_info.append(vulns.find('CweId').text) + data_info.append(vulns.find('CAPEC').text) + data_info.append(vulns.find('DISSA_ASC').text) + data_info.append(vulns.find('OWASP2007').text) + data_info.append(vulns.find('OWASP2010').text) + data_info.append(vulns.find('OWASP2013').text) + data_info.append(vulns.find('OVAL').text) + data_info.append(vulns.find('WASC').text) + + if severity == '1-Informational': + severity = 0 + elif severity == '2-Low': + severity = 1 + elif severity == '3-Medium': + severity = 2 + elif severity == '4-High': + severity = 3 + else: + severity = 10 + + str_data = f'AttackClass: {data_info[0]}, CweId: {data_info[1]}, CAPEC: {data_info[2]}, ' \ + f'DISSA_ASC: {data_info[3]}, OWASP2007: {data_info[4]}, OWASP2010: {data_info[5]}, ' \ + f'OWASP2013: {data_info[6]}, OVAL: {data_info[7]}, WASC: {data_info[8]}' + + if vuln_run_date is None: + vuln_run_date = None + else: + vuln_run_date = datetime.strptime(vuln_run_date, '%Y-%m-%d %H:%M:%S') + + self.createAndAddVulnToHost(host_id=host_id, name=vuln_name, desc=vuln_desc, ref=[vuln_ref], + severity=severity, resolution=vuln_resolution, run_date=vuln_run_date, + external_id=vuln_external_id, data=str_data) + + +def createPlugin(): + return AppSpiderPlugin() From d09817c9cf4da20ff45af017a6b9813a1806eac2 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Mon, 22 Jun 2020 11:38:48 -0300 Subject: [PATCH 076/698] add cli tests --- CHANGELOG/current/add_cli_tests.md | 1 + tests/test_cli.py | 63 ++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 CHANGELOG/current/add_cli_tests.md create mode 100644 tests/test_cli.py diff --git a/CHANGELOG/current/add_cli_tests.md b/CHANGELOG/current/add_cli_tests.md new file mode 100644 index 00000000..9d2aa581 --- /dev/null +++ b/CHANGELOG/current/add_cli_tests.md @@ -0,0 +1 @@ +Add tests to faraday-plugins cli \ No newline at end of file diff --git a/tests/test_cli.py b/tests/test_cli.py new file mode 100644 index 00000000..70e64763 --- /dev/null +++ b/tests/test_cli.py @@ -0,0 +1,63 @@ +import json +import os +import re +from click.testing import CliRunner +from faraday_plugins.commands import cli + + +def test_list_plugins(): + runner = CliRunner() + result = runner.invoke(cli, ['list-plugins']) + assert result.exit_code == 0 + loaded_plugins = re.search(r'Loaded Plugins: (?P\d+)', result.output) + assert loaded_plugins + assert int(loaded_plugins.groupdict().get('loaded_plugins', 0)) > 0 + + +def test_detect_invalid_command(): + runner = CliRunner() + result = runner.invoke(cli, ['detect-command', 'invalid_command']) + assert result.exit_code == 0 + assert result.output.strip() == "Failed to detect command: invalid_command" + + +def test_detect_command(): + runner = CliRunner() + result = runner.invoke(cli, ['detect-command', 'ping -c www.google.com']) + assert result.exit_code == 0 + assert result.output.strip() == "Faraday Plugin: ping" + + +def test_detect_report(): + report_file = os.path.join('./report-collection', 'faraday_plugins_tests', 'Nmap', 'nmap_5.21.xml') + runner = CliRunner() + result = runner.invoke(cli, ['detect-report', report_file]) + assert result.exit_code == 0 + assert "Faraday Plugin: Nmap" == result.output.strip() + + +def test_detect_report_dont_exists(): + report_file = os.path.join('../report-collection', 'faraday_plugins_tests', 'Nmap', 'nmap_5.21.xml') + runner = CliRunner() + result = runner.invoke(cli, ['detect-report', report_file]) + assert result.exit_code == 0 + assert "Don't Exists" in result.output.strip() + + +def test_process_report(): + report_file = os.path.join('./report-collection', 'faraday_plugins_tests', 'Nmap', 'nmap_5.21.xml') + summary_file = os.path.join('./report-collection', 'faraday_plugins_tests', 'Nmap', 'nmap_5.21_summary.json') + runner = CliRunner() + result = runner.invoke(cli, ['process-report', report_file, '--summary']) + assert result.exit_code == 0 + summary = json.loads(result.output.strip()) + with open(summary_file) as f: + saved_summary = json.load(f) + vuln_hashes = set(summary['vuln_hashes']) + saved_vuln_hashes = set(saved_summary.get('vuln_hashes', [])) + assert summary['hosts'] == saved_summary['hosts'] + assert summary['services'] == saved_summary['services'] + assert summary['hosts_vulns'] == saved_summary['hosts_vulns'] + assert summary['services_vulns'] == saved_summary['services_vulns'] + assert summary['severity_vulns'] == saved_summary['severity_vulns'] + assert vuln_hashes == saved_vuln_hashes \ No newline at end of file From e239bbefe7801579b4f60efc9335bc1f84ff1839 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Mon, 22 Jun 2020 12:50:56 -0300 Subject: [PATCH 077/698] add process_command test --- tests/test_cli.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index 70e64763..2b7bd387 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -23,11 +23,19 @@ def test_detect_invalid_command(): def test_detect_command(): runner = CliRunner() - result = runner.invoke(cli, ['detect-command', 'ping -c www.google.com']) + result = runner.invoke(cli, ['detect-command', 'ping -c 1 www.google.com']) assert result.exit_code == 0 assert result.output.strip() == "Faraday Plugin: ping" +def test_process_command(): + runner = CliRunner() + result = runner.invoke(cli, ['process-command', 'ping -c 1 www.google.com', '--summary']) + assert result.exit_code == 0 + summary = json.loads(result.output.strip()) + assert summary['hosts'] == 1 + + def test_detect_report(): report_file = os.path.join('./report-collection', 'faraday_plugins_tests', 'Nmap', 'nmap_5.21.xml') runner = CliRunner() From b67112590b58d0808c1535e4a9ba1dcbfd309d76 Mon Sep 17 00:00:00 2001 From: Blas Date: Mon, 22 Jun 2020 13:54:53 -0300 Subject: [PATCH 078/698] add mbsa plugin --- CHANGELOG/current/add_microsoft_baseline.md | 1 + faraday_plugins/plugins/repo/mbsa/__init__.py | 0 faraday_plugins/plugins/repo/mbsa/plugin.py | 41 +++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 CHANGELOG/current/add_microsoft_baseline.md create mode 100644 faraday_plugins/plugins/repo/mbsa/__init__.py create mode 100644 faraday_plugins/plugins/repo/mbsa/plugin.py diff --git a/CHANGELOG/current/add_microsoft_baseline.md b/CHANGELOG/current/add_microsoft_baseline.md new file mode 100644 index 00000000..a35a029a --- /dev/null +++ b/CHANGELOG/current/add_microsoft_baseline.md @@ -0,0 +1 @@ +Add microsoft baseline security analyzer diff --git a/faraday_plugins/plugins/repo/mbsa/__init__.py b/faraday_plugins/plugins/repo/mbsa/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/faraday_plugins/plugins/repo/mbsa/plugin.py b/faraday_plugins/plugins/repo/mbsa/plugin.py new file mode 100644 index 00000000..39ebc6f8 --- /dev/null +++ b/faraday_plugins/plugins/repo/mbsa/plugin.py @@ -0,0 +1,41 @@ +""" +Faraday Penetration Test IDE +Copyright (C) 2015 Infobyte LLC (http://www.infobytesec.com/) +See the file 'doc/LICENSE' for the license information +""" +from faraday_plugins.plugins.plugin import PluginByExtension +import re +import os + +__author__ = "Blas Moyano" +__copyright__ = "Copyright (c) 2020, Infobyte LLC" +__credits__ = ["Blas Moyano"] +__license__ = "" +__version__ = "1.0.0" +__maintainer__ = "Blas Moyano" +__status__ = "Development" + + +class MbsaParser: + def __init__(self, xml_output): + self.tree = self.parse_xml(xml_output) + + +class MaltegoPlugin(PluginByExtension): + def __init__(self): + super().__init__() + self.id = "MBSA" + self.name = "Microsoft Baseline Security Analyzer" + self.plugin_version = "1.0.1" + self.version = "MBSA 1.0" + self.framework_version = "1.0.0" + self.extension = ".log" + + def parseOutputString(self, output): + print(type(output.find())) + + #parser = MbsaParser(output) + + +def createPlugin(): + return MaltegoPlugin() From b8fb9f2478f6f3bf7ea5c369e0c83545907fb82c Mon Sep 17 00:00:00 2001 From: Blas Date: Mon, 22 Jun 2020 14:44:50 -0300 Subject: [PATCH 079/698] FIX Import xml from OpenVas doesnt work --- CHANGELOG/current/fix_Openvas.md | 1 + faraday_plugins/plugins/repo/openvas/plugin.py | 9 --------- 2 files changed, 1 insertion(+), 9 deletions(-) create mode 100644 CHANGELOG/current/fix_Openvas.md diff --git a/CHANGELOG/current/fix_Openvas.md b/CHANGELOG/current/fix_Openvas.md new file mode 100644 index 00000000..ce3f6e02 --- /dev/null +++ b/CHANGELOG/current/fix_Openvas.md @@ -0,0 +1 @@ +* Bug fix: Openvas Plugin - Import xml from OpenVas doesnt work diff --git a/faraday_plugins/plugins/repo/openvas/plugin.py b/faraday_plugins/plugins/repo/openvas/plugin.py index da185c61..a7849777 100644 --- a/faraday_plugins/plugins/repo/openvas/plugin.py +++ b/faraday_plugins/plugins/repo/openvas/plugin.py @@ -330,14 +330,6 @@ def __init__(self): self.framework_version = "1.0.0" self.options = None - def report_belongs_to(self, **kwargs): - if super().report_belongs_to(**kwargs): - report_path = kwargs.get("report_path", "") - with open(report_path) as f: - output = f.read() - return re.search("OpenVAS", output) is not None or re.search('', output) is not None - return False - def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it @@ -441,7 +433,6 @@ def _isIPV4(self, ip): else: return False - def setHost(self): pass From a887f03c7894b2059cfd59da2a83b2dfe2c034da Mon Sep 17 00:00:00 2001 From: Blas Date: Mon, 22 Jun 2020 15:11:47 -0300 Subject: [PATCH 080/698] add report_belongs_to --- faraday_plugins/plugins/repo/openvas/plugin.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/faraday_plugins/plugins/repo/openvas/plugin.py b/faraday_plugins/plugins/repo/openvas/plugin.py index a7849777..ebbd768c 100644 --- a/faraday_plugins/plugins/repo/openvas/plugin.py +++ b/faraday_plugins/plugins/repo/openvas/plugin.py @@ -330,6 +330,16 @@ def __init__(self): self.framework_version = "1.0.0" self.options = None + def report_belongs_to(self, **kwargs): + if super().report_belongs_to(**kwargs): + report_path = kwargs.get("report_path", "") + with open(report_path) as f: + output = f.read() + return re.search("OpenVAS", output) is not None \ + or re.search('', output) is not None\ + or re.search('', output) is not None + return False + def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it From 159b7abbdf59d3b058f4871efd80a18ef21dd9a3 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Mon, 22 Jun 2020 16:19:07 -0300 Subject: [PATCH 081/698] add process_command tests --- tests/test_cli.py | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index 2b7bd387..4d7d9c22 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,13 +1,14 @@ import json import os import re +from tempfile import NamedTemporaryFile from click.testing import CliRunner -from faraday_plugins.commands import cli +from faraday_plugins.commands import list_plugins, detect_command, process_command, detect_report, process_report def test_list_plugins(): runner = CliRunner() - result = runner.invoke(cli, ['list-plugins']) + result = runner.invoke(list_plugins) assert result.exit_code == 0 loaded_plugins = re.search(r'Loaded Plugins: (?P\d+)', result.output) assert loaded_plugins @@ -16,47 +17,59 @@ def test_list_plugins(): def test_detect_invalid_command(): runner = CliRunner() - result = runner.invoke(cli, ['detect-command', 'invalid_command']) + result = runner.invoke(detect_command, args=['invalid_command']) assert result.exit_code == 0 assert result.output.strip() == "Failed to detect command: invalid_command" def test_detect_command(): runner = CliRunner() - result = runner.invoke(cli, ['detect-command', 'ping -c 1 www.google.com']) + result = runner.invoke(detect_command, args=['ping -c 1 www.google.com']) assert result.exit_code == 0 assert result.output.strip() == "Faraday Plugin: ping" def test_process_command(): runner = CliRunner() - result = runner.invoke(cli, ['process-command', 'ping -c 1 www.google.com', '--summary']) + result = runner.invoke(process_command, args=['ping -c 1 www.google.com', '--summary']) assert result.exit_code == 0 summary = json.loads(result.output.strip()) assert summary['hosts'] == 1 +def test_process_command_to_file(): + runner = CliRunner() + with runner.isolated_filesystem() as file_system: + output_file = os.path.join(file_system, "test.json") + result = runner.invoke(process_command, args=['ping -c 1 www.google.com', '-o', output_file]) + assert result.exit_code == 0 + assert os.path.isfile(output_file) + with open(output_file) as f: + vuln_json = json.load(f) + assert len(vuln_json['hosts']) == 1 + + def test_detect_report(): report_file = os.path.join('./report-collection', 'faraday_plugins_tests', 'Nmap', 'nmap_5.21.xml') runner = CliRunner() - result = runner.invoke(cli, ['detect-report', report_file]) + result = runner.invoke(detect_report, args=[report_file]) assert result.exit_code == 0 assert "Faraday Plugin: Nmap" == result.output.strip() def test_detect_report_dont_exists(): - report_file = os.path.join('../report-collection', 'faraday_plugins_tests', 'Nmap', 'nmap_5.21.xml') + report_file = os.path.join('./report-collection', 'faraday_plugins_tests', 'Nmap', 'invalid_report.xml') runner = CliRunner() - result = runner.invoke(cli, ['detect-report', report_file]) + result = runner.invoke(detect_report, args=[report_file]) assert result.exit_code == 0 assert "Don't Exists" in result.output.strip() -def test_process_report(): +def test_process_report_summary(): report_file = os.path.join('./report-collection', 'faraday_plugins_tests', 'Nmap', 'nmap_5.21.xml') summary_file = os.path.join('./report-collection', 'faraday_plugins_tests', 'Nmap', 'nmap_5.21_summary.json') runner = CliRunner() - result = runner.invoke(cli, ['process-report', report_file, '--summary']) + result = runner.invoke(process_report, args=[report_file, '--summary']) assert result.exit_code == 0 summary = json.loads(result.output.strip()) with open(summary_file) as f: @@ -68,4 +81,5 @@ def test_process_report(): assert summary['hosts_vulns'] == saved_summary['hosts_vulns'] assert summary['services_vulns'] == saved_summary['services_vulns'] assert summary['severity_vulns'] == saved_summary['severity_vulns'] - assert vuln_hashes == saved_vuln_hashes \ No newline at end of file + assert vuln_hashes == saved_vuln_hashes + From 95fcf00858a6edff4bd22e55443baa6a0bafb7fb Mon Sep 17 00:00:00 2001 From: Blas Date: Tue, 23 Jun 2020 15:09:13 -0300 Subject: [PATCH 082/698] change 0.0.0.0 for name ADD report_belongs_to --- .../plugins/repo/awsprowler/plugin.py | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/faraday_plugins/plugins/repo/awsprowler/plugin.py b/faraday_plugins/plugins/repo/awsprowler/plugin.py index 4e072d1e..7e37096d 100644 --- a/faraday_plugins/plugins/repo/awsprowler/plugin.py +++ b/faraday_plugins/plugins/repo/awsprowler/plugin.py @@ -6,6 +6,8 @@ """ import socket import json +from datetime import datetime +import re from faraday_plugins.plugins.plugin import PluginJsonFormat @@ -34,29 +36,41 @@ class AwsProwlerPlugin(PluginJsonFormat): def __init__(self): super().__init__() + self.json_keys = {""} self.id = "awsprowler" self.name = "AWS Prowler" self.plugin_version = "0.1" self.version = "0.0.1" self.json_keys = {""} + def report_belongs_to(self, **kwargs): + with open(kwargs.get("report_path", "")) as f: + output = f.read() + return re.search("Region", output) is not None + def parseOutputString(self, output, debug=False): parser = AwsProwlerJsonParser(output) - host_id = self.createAndAddHost(name='0.0.0.0', description="AWS Prowler") + region_list = [] + for region in parser.report_aws: + json_reg = json.loads(region) + region_list.append(json_reg.get('Region', 'Not Info')) + + host_id = self.createAndAddHost(name=f'{self.name} - {region_list}', description="AWS Prowler") + for vuln in parser.report_aws: json_vuln = json.loads(vuln) - vuln_name = json_vuln.get('Account Number', 'Not Info') - vuln_desc = json_vuln.get('Control', 'Not Info') + vuln_name = json_vuln.get('Control', 'Not Info') + vuln_desc = json_vuln.get('Message', 'Not Info') vuln_severity = json_vuln.get('Level', 'Not Info') vuln_run_date = json_vuln.get('Timestamp', 'Not Info') - vuln_status = json_vuln.get('Status', 'Not Info') vuln_external_id = json_vuln.get('Control ID', 'Not Info') - vuln_data = json_vuln.get('Message', 'Not Info') - + vuln_policy = f'{vuln_name}:{vuln_external_id}' + vuln_run_date = vuln_run_date.replace('T',' ') + vuln_run_date = vuln_run_date.replace('Z', '') self.createAndAddVulnToHost(host_id=host_id, name=vuln_name, desc=vuln_desc, severity=self.normalize_severity(vuln_severity), - run_date=vuln_run_date, status=vuln_status, - external_id=vuln_external_id, data=vuln_data) + run_date=datetime.strptime(vuln_run_date, '%Y-%m-%d %H:%M:%S'), + external_id=vuln_external_id, policyviolations=[vuln_policy]) def createPlugin(): From 321c3c5181e6c0dffcb4b409cde7ac86f6480f97 Mon Sep 17 00:00:00 2001 From: Blas Date: Wed, 24 Jun 2020 11:59:28 -0300 Subject: [PATCH 083/698] Fix detect report aws --- faraday_plugins/plugins/repo/awsprowler/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faraday_plugins/plugins/repo/awsprowler/plugin.py b/faraday_plugins/plugins/repo/awsprowler/plugin.py index 7e37096d..21056a00 100644 --- a/faraday_plugins/plugins/repo/awsprowler/plugin.py +++ b/faraday_plugins/plugins/repo/awsprowler/plugin.py @@ -46,7 +46,7 @@ def __init__(self): def report_belongs_to(self, **kwargs): with open(kwargs.get("report_path", "")) as f: output = f.read() - return re.search("Region", output) is not None + return re.search("Account Number", output) is not None and re.search('"Control:"', output) is not None def parseOutputString(self, output, debug=False): parser = AwsProwlerJsonParser(output) From fbdbf7efbc2fe4e9678a68fdfef4be304348a428 Mon Sep 17 00:00:00 2001 From: Blas Date: Thu, 25 Jun 2020 15:54:09 -0300 Subject: [PATCH 084/698] fix detect plugin --- faraday_plugins/plugins/repo/awsprowler/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faraday_plugins/plugins/repo/awsprowler/plugin.py b/faraday_plugins/plugins/repo/awsprowler/plugin.py index 21056a00..7a4e1860 100644 --- a/faraday_plugins/plugins/repo/awsprowler/plugin.py +++ b/faraday_plugins/plugins/repo/awsprowler/plugin.py @@ -46,7 +46,7 @@ def __init__(self): def report_belongs_to(self, **kwargs): with open(kwargs.get("report_path", "")) as f: output = f.read() - return re.search("Account Number", output) is not None and re.search('"Control:"', output) is not None + return re.search("Account Number", output) is not None def parseOutputString(self, output, debug=False): parser = AwsProwlerJsonParser(output) From 69cc68418a441d1cff32353249a660a24ae98b17 Mon Sep 17 00:00:00 2001 From: Leonardo Lazzaro Date: Mon, 29 Jun 2020 18:21:12 -0300 Subject: [PATCH 085/698] new plugins version --- faraday_plugins/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faraday_plugins/__init__.py b/faraday_plugins/__init__.py index 3f262a63..923b9879 100644 --- a/faraday_plugins/__init__.py +++ b/faraday_plugins/__init__.py @@ -1 +1 @@ -__version__ = '1.2.1' +__version__ = '1.2.2' From 16fc8386434d62c1cb8d521feb1659e3d249dfb1 Mon Sep 17 00:00:00 2001 From: Blas Date: Tue, 30 Jun 2020 14:16:52 -0300 Subject: [PATCH 086/698] init SSL LABS --- CHANGELOG/current/add_ssl_labs.md | 1 + .../plugins/repo/ssl_labs/__init__.py | 0 .../plugins/repo/ssl_labs/plugin.py | 112 ++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 CHANGELOG/current/add_ssl_labs.md create mode 100644 faraday_plugins/plugins/repo/ssl_labs/__init__.py create mode 100644 faraday_plugins/plugins/repo/ssl_labs/plugin.py diff --git a/CHANGELOG/current/add_ssl_labs.md b/CHANGELOG/current/add_ssl_labs.md new file mode 100644 index 00000000..2491ffe3 --- /dev/null +++ b/CHANGELOG/current/add_ssl_labs.md @@ -0,0 +1 @@ +Add plugins ssl labs \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/ssl_labs/__init__.py b/faraday_plugins/plugins/repo/ssl_labs/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/faraday_plugins/plugins/repo/ssl_labs/plugin.py b/faraday_plugins/plugins/repo/ssl_labs/plugin.py new file mode 100644 index 00000000..1feeaf1c --- /dev/null +++ b/faraday_plugins/plugins/repo/ssl_labs/plugin.py @@ -0,0 +1,112 @@ +""" +Faraday Penetration Test IDE +Copyright (C) 2020 Infobyte LLC (http://www.infobytesec.com/) +See the file 'doc/LICENSE' for the license information + +""" +import re +import json +from urllib.parse import urlparse +from faraday_plugins.plugins.plugin import PluginJsonFormat +from faraday_plugins.plugins.plugins_utils import resolve_hostname + +__author__ = "Blas Moyano" +__copyright__ = "Copyright (c) 2020, Infobyte LLC" +__credits__ = ["Blas Moyano"] +__license__ = "" +__version__ = "0.0.1" +__maintainer__ = "Blas Moyano" +__email__ = "bmoyano@infobytesec.com" +__status__ = "Development" + + +class SslLabsJsonParser: + + def __init__(self, json_output): + list_data = json.loads(json_output) + self.json_data = list_data[0] + + def host_info(self, data): + host_information = { + "url": data.get('host', 'Not Info'), + "description_host": "SSL Labs", + "port": data.get('port', 0), + "protocol": data.get('protocol', 'Not Info'), + "status": data.get('status', 'Not Info'), + "version": data.get('engineVersion', '0.0.0'), + "run_date": data.get('startTime', 'Not Info') + } + return host_information + + def get_ip(self, data): + for ip in data: + return ip.get('ipAddress', '0.0.0.0') + + def get_vulns(self, data): + chain = data.get('chain', None) + vuln_list = [] + policies_list = [data.get('hstsPolicy', 'No Information'), + data.get('hpkpPolicy', 'No Information'), + data.get('hpkpRoPolicy', 'No Information')] + + for vulns in chain['certs']: + vuln = { + "name": vulns.get('issuerLabel', 'No Information'), + "desc": vulns.get('issuerSubject', 'No Information'), + "data": f'SHA1HASH: {vulns.get("sha1Hash", "No Information")}' + f'PINSHA256: {vulns.get("pinSha256", "No Information")}' + f'RAW: {vulns.get("raw", "No Information")}', + "policy": policies_list + } + vuln_list.append(vuln) + return vuln_list + + +class SslLabsPlugin(PluginJsonFormat): + """ Handle the SSL Labs tool. Detects the output of the tool + and adds the information to Faraday. + """ + + def __init__(self): + super().__init__() + self.id = "ssllabs" + self.name = "SSL Labs" + self.plugin_version = "0.1" + self.version = "3.4.5" + self.json_keys = {"host", "criteriaVersion", "engineVersion"} + + def report_belongs_to(self, **kwargs): + with open(kwargs.get("report_path", "")) as f: + output = f.read() + return re.search("criteriaVersion", output) is not None + + def parseOutputString(self, output): + parser = SslLabsJsonParser(output) + host = parser.host_info(parser.json_data) + + host_id = self.createAndAddHost( + name=parser.get_ip(parser.json_data['endpoints']), + hostnames=[host['url']], + description=host['description_host']) + + service_id = self.createAndAddServiceToHost( + host_id=host_id, + name=host['url'], + protocol=host['protocol'], + ports=host['port'], + status=host['status'], + version=host['version']) + + vulns = parser.get_vulns(parser.json_data['endpoints'][0]['details']) + + for vuln in vulns: + self.createAndAddVulnToService(host_id, + service_id=service_id, + name=vuln['name'], + desc=vuln['desc'], + policyviolations=vuln['policy'], + data=vuln['data']) + + +def createPlugin(): + return SslLabsPlugin() From c64ecd859b376d465123cc4f0e25cbc895368051 Mon Sep 17 00:00:00 2001 From: Leonardo Lazzaro Date: Wed, 1 Jul 2020 18:50:39 -0300 Subject: [PATCH 087/698] try to recover broken xml files --- faraday_plugins/plugins/repo/nmap/plugin.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/faraday_plugins/plugins/repo/nmap/plugin.py b/faraday_plugins/plugins/repo/nmap/plugin.py index cfc0cd41..c9f059d2 100644 --- a/faraday_plugins/plugins/repo/nmap/plugin.py +++ b/faraday_plugins/plugins/repo/nmap/plugin.py @@ -5,10 +5,9 @@ """ -from faraday_plugins.plugins.plugin import PluginXMLFormat import re import os - +from io import BytesIO try: import xml.etree.cElementTree as ET @@ -17,11 +16,14 @@ except ImportError: import xml.etree.ElementTree as ET ETREE_VERSION = ET.VERSION +from lxml import etree +from lxml.etree import XMLParser ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] - current_path = os.path.abspath(os.getcwd()) +from faraday_plugins.plugins.plugin import PluginXMLFormat + class NmapXmlParser: """ @@ -55,7 +57,8 @@ def parse_xml(self, xml_output): """ try: - return ET.fromstring(xml_output) + magical_parser = XMLParser(recover=True) + return etree.parse(BytesIO(xml_output), magical_parser) except SyntaxError as err: #logger.error("SyntaxError: %s." % (err)) return None From ddb71ca7dbe693b5b51747c3190ee4935f5bdc71 Mon Sep 17 00:00:00 2001 From: Leonardo Lazzaro Date: Wed, 1 Jul 2020 21:05:33 -0300 Subject: [PATCH 088/698] fix pep8 --- faraday_plugins/plugins/repo/nmap/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faraday_plugins/plugins/repo/nmap/plugin.py b/faraday_plugins/plugins/repo/nmap/plugin.py index c9f059d2..0c493b56 100644 --- a/faraday_plugins/plugins/repo/nmap/plugin.py +++ b/faraday_plugins/plugins/repo/nmap/plugin.py @@ -18,11 +18,11 @@ ETREE_VERSION = ET.VERSION from lxml import etree from lxml.etree import XMLParser +from faraday_plugins.plugins.plugin import PluginXMLFormat ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] current_path = os.path.abspath(os.getcwd()) -from faraday_plugins.plugins.plugin import PluginXMLFormat class NmapXmlParser: From b9db8cad7a0df88e03ad6a2a3da13c3b13949a57 Mon Sep 17 00:00:00 2001 From: Leonardo Lazzaro Date: Wed, 1 Jul 2020 21:38:38 -0300 Subject: [PATCH 089/698] add changelog --- CHANGELOG/current/fix_xml_nmap.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 CHANGELOG/current/fix_xml_nmap.md diff --git a/CHANGELOG/current/fix_xml_nmap.md b/CHANGELOG/current/fix_xml_nmap.md new file mode 100644 index 00000000..bba79048 --- /dev/null +++ b/CHANGELOG/current/fix_xml_nmap.md @@ -0,0 +1 @@ +* Fix broken xml on nmap plugin From f46ca79cdab038c70da4990695141ed66def6988 Mon Sep 17 00:00:00 2001 From: Leonardo Lazzaro Date: Thu, 2 Jul 2020 14:00:37 -0300 Subject: [PATCH 090/698] increase version --- faraday_plugins/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faraday_plugins/__init__.py b/faraday_plugins/__init__.py index 923b9879..5a5df3be 100644 --- a/faraday_plugins/__init__.py +++ b/faraday_plugins/__init__.py @@ -1 +1 @@ -__version__ = '1.2.2' +__version__ = '1.2.3' From 18f125d1271e79e485fe52bf63aa2222b3b58c2f Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Fri, 3 Jul 2020 17:05:33 -0300 Subject: [PATCH 091/698] update zap plugin --- faraday_plugins/plugins/repo/zap/plugin.py | 53 +++++++++++++--------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/faraday_plugins/plugins/repo/zap/plugin.py b/faraday_plugins/plugins/repo/zap/plugin.py index 98de0ee9..187de0be 100644 --- a/faraday_plugins/plugins/repo/zap/plugin.py +++ b/faraday_plugins/plugins/repo/zap/plugin.py @@ -183,16 +183,19 @@ def __init__(self, item_node): for elem in arr: uri = elem.find('uri').text - self.parse_uri(uri) + method_element = elem.find('method') + if method_element: + method = elem.find('method').text + else: + method = "" + self.parse_uri(uri, method) - self.requests = "\n".join([i['uri'] for i in self.items]) + def parse_uri(self, uri, method): - def parse_uri(self, uri): - - url_parse = urlparse(uri) - protocol = url_parse.scheme - host = url_parse.netloc - port = url_parse.port + parsed_url = urlparse(uri) + protocol = parsed_url.scheme + host = parsed_url.netloc + port = parsed_url.port try: params = [i.split('=')[0] @@ -204,8 +207,12 @@ def parse_uri(self, uri): 'uri': uri, 'params': ', '.join(params), 'host': host, + 'website': f"{protocol}://{host}", 'protocol': protocol, - 'port': port + 'port': port, + 'method': method, + 'path': parsed_url.path, + 'query': parsed_url.query } self.items.append(item) @@ -257,19 +264,21 @@ def parseOutputString(self, output): s_id = self.createAndAddServiceToHost(h_id, "http", "tcp", ports=[site.port], status='open') for item in site.items: - self.createAndAddVulnWebToService( - h_id, - s_id, - item.name, - item.desc, - website=site.host, - severity=item.severity, - path=item.items[0]['uri'], - params=item.items[0]['params'], - request=item.requests, - ref=item.ref, - resolution=item.resolution - ) + for instance in item.items: + self.createAndAddVulnWebToService( + h_id, + s_id, + item.name, + item.desc, + website=instance['website'], + query=instance['query'], + severity=item.severity, + path=instance['path'], + params=instance['params'], + method=instance['method'], + ref=item.ref, + resolution=item.resolution + ) del parser From 9a25747c905ce0130143f6479d9f19fb6effc404 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Fri, 3 Jul 2020 17:09:02 -0300 Subject: [PATCH 092/698] add changelog --- CHANGELOG/current/update_zap.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 CHANGELOG/current/update_zap.md diff --git a/CHANGELOG/current/update_zap.md b/CHANGELOG/current/update_zap.md new file mode 100644 index 00000000..1fd14e86 --- /dev/null +++ b/CHANGELOG/current/update_zap.md @@ -0,0 +1 @@ +Fix how ZAP genereate vulns \ No newline at end of file From 9e2e34ca346e2b381781571f27ae45147990e8e7 Mon Sep 17 00:00:00 2001 From: Blas Date: Sat, 4 Jul 2020 16:36:50 -0300 Subject: [PATCH 093/698] fix in report_belongs_to --- faraday_plugins/plugins/repo/awsprowler/plugin.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/faraday_plugins/plugins/repo/awsprowler/plugin.py b/faraday_plugins/plugins/repo/awsprowler/plugin.py index 7a4e1860..d5a797f6 100644 --- a/faraday_plugins/plugins/repo/awsprowler/plugin.py +++ b/faraday_plugins/plugins/repo/awsprowler/plugin.py @@ -10,7 +10,6 @@ import re from faraday_plugins.plugins.plugin import PluginJsonFormat - __author__ = "Blas Moyano" __copyright__ = "Copyright (c) 2020, Infobyte LLC" __credits__ = ["Blas Moyano"] @@ -36,17 +35,19 @@ class AwsProwlerPlugin(PluginJsonFormat): def __init__(self): super().__init__() - self.json_keys = {""} self.id = "awsprowler" self.name = "AWS Prowler" self.plugin_version = "0.1" self.version = "0.0.1" - self.json_keys = {""} + self.json_keys = set() def report_belongs_to(self, **kwargs): - with open(kwargs.get("report_path", "")) as f: + if super().report_belongs_to(**kwargs): + report_path = kwargs.get("report_path", "") + with open(report_path) as f: output = f.read() - return re.search("Account Number", output) is not None + return re.search("Account Number", output) is not None + return False def parseOutputString(self, output, debug=False): parser = AwsProwlerJsonParser(output) @@ -65,7 +66,7 @@ def parseOutputString(self, output, debug=False): vuln_run_date = json_vuln.get('Timestamp', 'Not Info') vuln_external_id = json_vuln.get('Control ID', 'Not Info') vuln_policy = f'{vuln_name}:{vuln_external_id}' - vuln_run_date = vuln_run_date.replace('T',' ') + vuln_run_date = vuln_run_date.replace('T', ' ') vuln_run_date = vuln_run_date.replace('Z', '') self.createAndAddVulnToHost(host_id=host_id, name=vuln_name, desc=vuln_desc, severity=self.normalize_severity(vuln_severity), From b7d6077d11b28d504ae2d7a79635befd76f03eba Mon Sep 17 00:00:00 2001 From: Blas Date: Sat, 4 Jul 2020 19:07:30 -0300 Subject: [PATCH 094/698] Raedline check --- faraday_plugins/plugins/repo/awsprowler/plugin.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/faraday_plugins/plugins/repo/awsprowler/plugin.py b/faraday_plugins/plugins/repo/awsprowler/plugin.py index d5a797f6..16f30403 100644 --- a/faraday_plugins/plugins/repo/awsprowler/plugin.py +++ b/faraday_plugins/plugins/repo/awsprowler/plugin.py @@ -45,8 +45,14 @@ def report_belongs_to(self, **kwargs): if super().report_belongs_to(**kwargs): report_path = kwargs.get("report_path", "") with open(report_path) as f: - output = f.read() - return re.search("Account Number", output) is not None + output = f.readlines() + for line in output: + prueba = json.loads(line) + if prueba.keys() >= {"Profile", "Account Number"}: + pass + else: + return False + return True return False def parseOutputString(self, output, debug=False): From b3c560ed1ceae6f2b9af10e237d74ac37de0b555 Mon Sep 17 00:00:00 2001 From: Blas Date: Sat, 4 Jul 2020 19:08:55 -0300 Subject: [PATCH 095/698] ADD changelog --- CHANGELOG/current/fix_prowler.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 CHANGELOG/current/fix_prowler.md diff --git a/CHANGELOG/current/fix_prowler.md b/CHANGELOG/current/fix_prowler.md new file mode 100644 index 00000000..2608bd7d --- /dev/null +++ b/CHANGELOG/current/fix_prowler.md @@ -0,0 +1 @@ +* Bug Fix: Detect plugins AWS Prowler From 4eb8cc5cc4256ec5ce48589231762ce6d6e0a307 Mon Sep 17 00:00:00 2001 From: Blas Date: Sat, 4 Jul 2020 19:13:42 -0300 Subject: [PATCH 096/698] detect report fix --- faraday_plugins/plugins/repo/ssl_labs/plugin.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/faraday_plugins/plugins/repo/ssl_labs/plugin.py b/faraday_plugins/plugins/repo/ssl_labs/plugin.py index 1feeaf1c..b3d30a83 100644 --- a/faraday_plugins/plugins/repo/ssl_labs/plugin.py +++ b/faraday_plugins/plugins/repo/ssl_labs/plugin.py @@ -75,11 +75,6 @@ def __init__(self): self.version = "3.4.5" self.json_keys = {"host", "criteriaVersion", "engineVersion"} - def report_belongs_to(self, **kwargs): - with open(kwargs.get("report_path", "")) as f: - output = f.read() - return re.search("criteriaVersion", output) is not None - def parseOutputString(self, output): parser = SslLabsJsonParser(output) host = parser.host_info(parser.json_data) From 177a0c5b3bb641e371739ad440b5606b939bb428 Mon Sep 17 00:00:00 2001 From: Blas Date: Mon, 6 Jul 2020 10:55:07 -0300 Subject: [PATCH 097/698] fix for inside with in report belong to --- faraday_plugins/plugins/repo/awsprowler/plugin.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/faraday_plugins/plugins/repo/awsprowler/plugin.py b/faraday_plugins/plugins/repo/awsprowler/plugin.py index 16f30403..fbeb25b9 100644 --- a/faraday_plugins/plugins/repo/awsprowler/plugin.py +++ b/faraday_plugins/plugins/repo/awsprowler/plugin.py @@ -46,12 +46,12 @@ def report_belongs_to(self, **kwargs): report_path = kwargs.get("report_path", "") with open(report_path) as f: output = f.readlines() - for line in output: - prueba = json.loads(line) - if prueba.keys() >= {"Profile", "Account Number"}: - pass - else: - return False + for line in output: + prueba = json.loads(line) + if prueba.keys() >= {"Profile", "Account Number"}: + pass + else: + return False return True return False From 85699bec5f3703555c5e30f66e0050f4c0476c8e Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Tue, 7 Jul 2020 11:21:12 -0300 Subject: [PATCH 098/698] fix hydra to resolve ip --- CHANGELOG/current/fix_hydra_to_resolve_ip.md | 1 + faraday_plugins/plugins/plugins_utils.py | 5 +++++ faraday_plugins/plugins/repo/hydra/plugin.py | 18 +++++++++--------- 3 files changed, 15 insertions(+), 9 deletions(-) create mode 100644 CHANGELOG/current/fix_hydra_to_resolve_ip.md diff --git a/CHANGELOG/current/fix_hydra_to_resolve_ip.md b/CHANGELOG/current/fix_hydra_to_resolve_ip.md new file mode 100644 index 00000000..8a5fe528 --- /dev/null +++ b/CHANGELOG/current/fix_hydra_to_resolve_ip.md @@ -0,0 +1 @@ +Fix Hydra plugin to resolve ip address \ No newline at end of file diff --git a/faraday_plugins/plugins/plugins_utils.py b/faraday_plugins/plugins/plugins_utils.py index c51a7ca4..628ecd3a 100644 --- a/faraday_plugins/plugins/plugins_utils.py +++ b/faraday_plugins/plugins/plugins_utils.py @@ -99,6 +99,11 @@ def get_all_protocols(): def resolve_hostname(hostname): + try: + socket.inet_aton(hostname) # is already an ip + return hostname + except socket.error: + pass try: ip_address = socket.gethostbyname(hostname) except Exception as e: diff --git a/faraday_plugins/plugins/repo/hydra/plugin.py b/faraday_plugins/plugins/repo/hydra/plugin.py index 530d80f3..3e8ca486 100644 --- a/faraday_plugins/plugins/repo/hydra/plugin.py +++ b/faraday_plugins/plugins/repo/hydra/plugin.py @@ -4,7 +4,9 @@ See the file 'doc/LICENSE' for the license information """ from faraday_plugins.plugins.plugin import PluginBase +from faraday_plugins.plugins.plugins_utils import resolve_hostname import re +from collections import defaultdict __author__ = "Francisco Amato" __copyright__ = "Copyright (c) 2013, Infobyte LLC" @@ -71,9 +73,7 @@ def parseOutputString(self, output): """ parser = HydraParser(output) - - i = 0 - hosts = {} + hosts = defaultdict(list) service = '' port = '' @@ -81,15 +81,15 @@ def parseOutputString(self, output): service = item['plugin'] port = item['port'] - - if item['ip'] not in hosts: - hosts[item['ip']] = [] - hosts[item['ip']].append([item['login'], item['password']]) for k, v in hosts.items(): - - h_id = self.createAndAddHost(k) + ip = resolve_hostname(k) + if ip != k: + hostnames = [k] + else: + hostnames = None + h_id = self.createAndAddHost(ip, hostnames=hostnames) s_id = self.createAndAddServiceToHost( h_id, service, From 49932790c81fed3e2c6981733fbce320fcfe2c59 Mon Sep 17 00:00:00 2001 From: Blas Date: Tue, 14 Jul 2020 18:22:01 -0300 Subject: [PATCH 099/698] fix Detect plugins --- faraday_plugins/plugins/repo/awsprowler/plugin.py | 15 +++++++++------ faraday_plugins/plugins/repo/ssl_labs/plugin.py | 14 +++++++++++++- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/faraday_plugins/plugins/repo/awsprowler/plugin.py b/faraday_plugins/plugins/repo/awsprowler/plugin.py index fbeb25b9..ff84068a 100644 --- a/faraday_plugins/plugins/repo/awsprowler/plugin.py +++ b/faraday_plugins/plugins/repo/awsprowler/plugin.py @@ -46,12 +46,15 @@ def report_belongs_to(self, **kwargs): report_path = kwargs.get("report_path", "") with open(report_path) as f: output = f.readlines() - for line in output: - prueba = json.loads(line) - if prueba.keys() >= {"Profile", "Account Number"}: - pass - else: - return False + try: + for line in output: + check_line = json.loads(line) + if check_line.keys() >= {"Profile", "Account Number"}: + pass + else: + return False + except ValueError: + return False return True return False diff --git a/faraday_plugins/plugins/repo/ssl_labs/plugin.py b/faraday_plugins/plugins/repo/ssl_labs/plugin.py index b3d30a83..33be2353 100644 --- a/faraday_plugins/plugins/repo/ssl_labs/plugin.py +++ b/faraday_plugins/plugins/repo/ssl_labs/plugin.py @@ -73,7 +73,19 @@ def __init__(self): self.name = "SSL Labs" self.plugin_version = "0.1" self.version = "3.4.5" - self.json_keys = {"host", "criteriaVersion", "engineVersion"} + self.json_keys = set() + + def report_belongs_to(self, **kwargs): + result = False + if super().report_belongs_to(**kwargs): + report_path = kwargs.get("report_path", "") + with open(report_path) as f: + output = f.readlines() + for line in output: + check = line.find('"criteriaVersion":') + if check > 0: + result = True + return result def parseOutputString(self, output): parser = SslLabsJsonParser(output) From 73b50c03f9a0fcec8b344efb833bd7cad8ac92b8 Mon Sep 17 00:00:00 2001 From: Blas Date: Sun, 19 Jul 2020 15:30:57 -0300 Subject: [PATCH 100/698] FIX detect operation system --- CHANGELOG/current/fix_QualysWebapp.md | 1 + .../plugins/repo/qualyswebapp/plugin.py | 26 ++++++++++++------- 2 files changed, 18 insertions(+), 9 deletions(-) create mode 100644 CHANGELOG/current/fix_QualysWebapp.md diff --git a/CHANGELOG/current/fix_QualysWebapp.md b/CHANGELOG/current/fix_QualysWebapp.md new file mode 100644 index 00000000..97a2b0d9 --- /dev/null +++ b/CHANGELOG/current/fix_QualysWebapp.md @@ -0,0 +1 @@ +* Bug fix: QualysWebApp Plugin, error in get info OPERATING_SYSTEM diff --git a/faraday_plugins/plugins/repo/qualyswebapp/plugin.py b/faraday_plugins/plugins/repo/qualyswebapp/plugin.py index 90543786..76eae4de 100644 --- a/faraday_plugins/plugins/repo/qualyswebapp/plugin.py +++ b/faraday_plugins/plugins/repo/qualyswebapp/plugin.py @@ -55,10 +55,12 @@ def get_results_vul(self, tree): for self.results_tags in tree.find('VULNERABILITY_LIST'): yield Results(self.results_tags) + class Appendix(): def __init__(self, appendix_tags): if appendix_tags.tag == 'SCAN_LIST': self.lista_scan = self.get_scan(appendix_tags.find('SCAN')) + elif appendix_tags.tag == 'WEBAPP': self.lista_webapp = self.get_webapp(appendix_tags) @@ -124,13 +126,15 @@ def parseOutputString(self, output): for host_create in parser.info_appendix: self.scan_list_result.append(host_create) - self.credential = self.scan_list_result[0].lista_scan.get('AUTHENTICATION_RECORD') - os = self.scan_list_result[1].lista_webapp.get('OPERATING_SYSTEM') - - if self.scan_list_result[1].lista_webapp.get('URL'): - initial_url = self.scan_list_result[1].lista_webapp.get('URL') - parsed_url = urlparse(initial_url) - hostnames = [parsed_url.netloc] + for k in self.scan_list_result: + if 'result_scan' in k.__dict__: + self.credential = k.lista_scan.get('AUTHENTICATION_RECORD') + elif 'result_webapp' in k.__dict__: + operating_system = k.lista_webapp.get('OPERATING_SYSTEM') + if k.lista_webapp.get('URL'): + initial_url = k.lista_webapp.get('URL') + parsed_url = urlparse(initial_url) + hostnames = [parsed_url.netloc] glossary = [] for glossary_qid in parser.info_glossary: @@ -139,7 +143,7 @@ def parseOutputString(self, output): for v in parser.info_results: url = urlparse(v.dict_result_vul.get('URL')) - host_id = self.createAndAddHost(name=url.netloc, os=os, hostnames=hostnames) + host_id = self.createAndAddHost(name=url.netloc, os=operating_system, hostnames=hostnames) vuln_scan_id = v.dict_result_vul.get('QID') @@ -151,7 +155,11 @@ def parseOutputString(self, output): raw_severity = int(vuln_data.get('SEVERITY', 0)) vuln_severity = raw_severity - 1 - run_date = parse(v.dict_result_vul.get('FIRST_TIME_DETECTED')) + if not v.dict_result_vul.get('FIRST_TIME_DETECTED'): + run_date = '' + else: + run_date = parse(v.dict_result_vul.get('FIRST_TIME_DETECTED')) + vuln_resolution = vuln_data.get('SOLUTION') vuln_ref = [] From b2a411d473004ca14e292b5cabe47e324bb942c1 Mon Sep 17 00:00:00 2001 From: Blas Date: Sun, 19 Jul 2020 23:09:08 -0300 Subject: [PATCH 101/698] ADD Changelog, INIT hcl_asoc, plugin detect --- CHANGELOG/current/add_hcl_asoc.md | 1 + .../plugins/repo/appscan/plugin.py | 11 ++- .../plugins/repo/hcl_asoc/__init__.py | 0 .../plugins/repo/hcl_asoc/plugin.py | 75 +++++++++++++++++++ 4 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 CHANGELOG/current/add_hcl_asoc.md create mode 100644 faraday_plugins/plugins/repo/hcl_asoc/__init__.py create mode 100644 faraday_plugins/plugins/repo/hcl_asoc/plugin.py diff --git a/CHANGELOG/current/add_hcl_asoc.md b/CHANGELOG/current/add_hcl_asoc.md new file mode 100644 index 00000000..a89bd028 --- /dev/null +++ b/CHANGELOG/current/add_hcl_asoc.md @@ -0,0 +1 @@ +ADD plugin HCL ASOC \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/appscan/plugin.py b/faraday_plugins/plugins/repo/appscan/plugin.py index fa274bf5..d2bae6c5 100644 --- a/faraday_plugins/plugins/repo/appscan/plugin.py +++ b/faraday_plugins/plugins/repo/appscan/plugin.py @@ -3,7 +3,7 @@ Copyright (C) 2017 Infobyte LLC (http://www.infobytesec.com/) See the file 'doc/LICENSE' for the license information """ - +import re from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import resolve_hostname from lxml import objectify @@ -134,6 +134,15 @@ def __init__(self): self.options = None self.open_options = {"mode": "r", "encoding": "utf-8"} + def report_belongs_to(self, **kwargs): + if super().report_belongs_to(**kwargs): + report_path = kwargs.get("report_path", "") + with open(report_path) as f: + output = f.read() + return re.search("url-group", output) is not None + return False + + def parseOutputString(self, output): try: parser = AppscanParser(output, self.logger) diff --git a/faraday_plugins/plugins/repo/hcl_asoc/__init__.py b/faraday_plugins/plugins/repo/hcl_asoc/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/faraday_plugins/plugins/repo/hcl_asoc/plugin.py b/faraday_plugins/plugins/repo/hcl_asoc/plugin.py new file mode 100644 index 00000000..18ba990f --- /dev/null +++ b/faraday_plugins/plugins/repo/hcl_asoc/plugin.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from faraday_plugins.plugins.plugin import PluginXMLFormat +from datetime import datetime +try: + import xml.etree.cElementTree as ET +except ImportError: + import xml.etree.ElementTree as ET +import re + +__author__ = 'Blas Moyano' +__copyright__ = 'Copyright 2020, Faraday Project' +__credits__ = ['Blas Moyano'] +__license__ = '' +__version__ = '1.0.0' +__status__ = 'Development' + + +class HclAsocParser: + def __init__(self, xml_output): + self.tree = self.parse_xml(xml_output) + if self.tree: + self.vuln_list = self.tree.find('VulnList') + self.name_scan = self.tree.find('ScanName').text + else: + self.tree = None + + def parse_xml(self, xml_output): + try: + tree = ET.fromstring(xml_output) + except SyntaxError as err: + print('SyntaxError In xml: %s. %s' % (err, xml_output)) + return None + return tree + + +class HclAsocPlugin(PluginXMLFormat): + def __init__(self): + super().__init__() + self.identifier_tag = "xml-report" + self.id = 'HclAsoc' + self.name = 'HCL ASOC XML Output Plugin' + self.plugin_version = '1.0.0' + self.version = '1.0.0' + self.framework_version = '1.0.0' + self.options = None + self.protocol = None + self.port = '80' + self.address = None + + def report_belongs_to(self, **kwargs): + if super().report_belongs_to(**kwargs): + report_path = kwargs.get("report_path", "") + with open(report_path) as f: + output = f.read() + return re.search("createdByAppScan", output) is not None + return False + + + def parseOutputString(self, output): + parser = HclAsocParser(output) + + + # host_id = self.createAndAddHost(name=sorted(list(ip))[0], hostnames=sorted(list(url)), + # description=parser.name_scan) + + # vuln_run_date = datetime.strptime(vuln_run_date, '%Y-%m-%d %H:%M:%S') + + # self.createAndAddVulnToHost(host_id=host_id, name=vuln_name, desc=vuln_desc, ref=[vuln_ref], + # severity=severity, resolution=vuln_resolution, run_date=vuln_run_date, + # external_id=vuln_external_id, data=str_data) + + +def createPlugin(): + return HclAsocPlugin() From 6b583a1061a51a02b71bdd0e5c5b242a9902ec24 Mon Sep 17 00:00:00 2001 From: Blas Date: Mon, 20 Jul 2020 16:54:34 -0300 Subject: [PATCH 102/698] get xml info --- .../plugins/repo/appscan/plugin.py | 3 +- .../plugins/repo/hcl_asoc/plugin.py | 121 +++++++++++++++++- 2 files changed, 120 insertions(+), 4 deletions(-) diff --git a/faraday_plugins/plugins/repo/appscan/plugin.py b/faraday_plugins/plugins/repo/appscan/plugin.py index d2bae6c5..ae02eddd 100644 --- a/faraday_plugins/plugins/repo/appscan/plugin.py +++ b/faraday_plugins/plugins/repo/appscan/plugin.py @@ -18,7 +18,6 @@ __status__ = "Development" - class AppscanParser(): def __init__(self, output, logger): @@ -139,7 +138,7 @@ def report_belongs_to(self, **kwargs): report_path = kwargs.get("report_path", "") with open(report_path) as f: output = f.read() - return re.search("url-group", output) is not None + return re.search("filtered-link-group", output) is not None return False diff --git a/faraday_plugins/plugins/repo/hcl_asoc/plugin.py b/faraday_plugins/plugins/repo/hcl_asoc/plugin.py index 18ba990f..6ad147e5 100644 --- a/faraday_plugins/plugins/repo/hcl_asoc/plugin.py +++ b/faraday_plugins/plugins/repo/hcl_asoc/plugin.py @@ -20,8 +20,16 @@ class HclAsocParser: def __init__(self, xml_output): self.tree = self.parse_xml(xml_output) if self.tree: - self.vuln_list = self.tree.find('VulnList') - self.name_scan = self.tree.find('ScanName').text + self.operating_system = self.tree.attrib['technology'] + url_group = [tags.tag for tags in self.tree] + check_url = True if 'url-group' in url_group else False + if check_url: + self.urls = self.get_urls_info(self.tree.find('url-group')) + else: + self.urls = None + self.layout = self.get_layout_info(self.tree.find('layout')) + self.item = self.get_issue_type(self.tree.find('issue-type-group')) + self.name_scan = self.get_issue_data(self.tree.find('advisory-group')) else: self.tree = None @@ -33,6 +41,115 @@ def parse_xml(self, xml_output): return None return tree + def get_layout_info(self, tree): + info_layout = { + "name": "Not info" if tree.find("application-name") is None else tree.find("application-name").text, + "date": "Not info" if tree.find("report-date") is None else tree.find("report-date").text, + "details": f'Departamento: {"Not info" if tree.find("department") is None else tree.find("department").text}' + f'Compania: {"Not info" if tree.find("company") is None else tree.find("company").text}' + f'Titulo Reporte: {"Not info" if tree.find("title") is None else tree.find("title").text}' + } + return info_layout + + def get_issue_type(self, tree): + list_item = [] + for item in tree: + item_info = { + "id": item.attrib.get('id', None), + "name": item.find("name").text, + "severity_id": item.attrib.get('severity-id', None), + "severity": item.attrib.get('severity', None) + } + list_item.append(item_info) + + return list_item + + def get_issue_data(self, tree): + list_item_data = [] + item_data = {} + for item in tree: + for adivisory in item: + item_data = { + "id": item.attrib.get('id', None), + "name": "Not info" if adivisory.find("name") is None else adivisory.find("name").text, + "description": "Not info" if adivisory.find("testDescription") is None else + adivisory.find("testDescription").text, + "threatClassification": { + "name": "Not info" if adivisory.find("threatClassification/name") is None else + adivisory.find("threatClassification/name").text, + "reference": "Not info" if adivisory.find("threatClassification/reference") is None else + adivisory.find("threatClassification/reference").text, + }, + "testTechnicalDescription": self.get_parser(adivisory.find("testTechnicalDescription")), + "causes": "Not info" if adivisory.find("causes/cause") is None else + adivisory.find("causes/cause").text, + "securityRisks": "Not info" if adivisory.find("securityRisks/securityRisk") is None else + adivisory.find("securityRisks/securityRisk").text, + "affectedProducts": "Not info" if adivisory.find("affectedProducts/affectedProduct") is None else + adivisory.find("affectedProducts/affectedProduct").text, + "cwe": "Not info" if adivisory.find("cwe/link") is None else adivisory.find("cwe/link").text, + "xfid": "Not info" if adivisory.find("xfid/link") is None else adivisory.find("cwe/link").text, + "references": self.get_parser(adivisory.find("references")), + "fixRecommendations": self.get_parser(adivisory.find("fixRecommendations/fixRecommendation")) + } + return list_item_data + + def get_parser(self, tree): + text_join = "" + code_join = "" + link_join = "" + + if tree.tag == 'testTechnicalDescription': + for text_info in tree.findall('text'): + text_join += text_info.text + + for code_info in tree.findall('code'): + text_join += code_info.text + + tech_data = { + "text": text_join, + "code": code_join + } + + elif tree.tag == 'references': + for text_info in tree.findall('text'): + text_join += "no info " if text_info.text is None else text_info.text + + for link_info in tree.findall('link'): + link_join += "no info " if link_info.text is None else link_info.text + link_join += link_info.attrib.get('target', 'not target') + + tech_data = { + "text": text_join, + "Link": link_join + } + + elif tree.tag == 'fixRecommendation': + for text_info in tree.findall('text'): + text_join += "no info " if text_info.text is None else text_info.text + + for link_info in tree.findall('link'): + link_join += "no info " if link_info.text is None else link_info.text + link_join += link_info.attrib.get('target', 'not target') + + tech_data = { + "text": text_join, + "link": link_join + } + + return tech_data + + def get_urls_info(self, tree): + list_url = [] + for url in tree: + url_info = { + "id": "Not info" if url.find("issue-type") is None else url.find("issue-type").text, + "url": "Not info" if url.find("name") is None else url.find("name").text, + } + list_url.append(url_info) + + return list_url + class HclAsocPlugin(PluginXMLFormat): def __init__(self): From cbcd85f808d526c5702907376a30a56011f4ca6b Mon Sep 17 00:00:00 2001 From: Blas Date: Fri, 24 Jul 2020 16:49:59 -0300 Subject: [PATCH 103/698] appscan new --- .../plugins/repo/appscan/plugin.py | 461 +++++++++++------- .../plugins/repo/appscan/pluginapp.py | 202 ++++++++ .../plugins/repo/hcl_asoc/__init__.py | 0 .../plugins/repo/hcl_asoc/plugin.py | 192 -------- 4 files changed, 483 insertions(+), 372 deletions(-) create mode 100644 faraday_plugins/plugins/repo/appscan/pluginapp.py delete mode 100644 faraday_plugins/plugins/repo/hcl_asoc/__init__.py delete mode 100644 faraday_plugins/plugins/repo/hcl_asoc/plugin.py diff --git a/faraday_plugins/plugins/repo/appscan/plugin.py b/faraday_plugins/plugins/repo/appscan/plugin.py index ae02eddd..7c8908ec 100644 --- a/faraday_plugins/plugins/repo/appscan/plugin.py +++ b/faraday_plugins/plugins/repo/appscan/plugin.py @@ -1,202 +1,303 @@ -""" -Faraday Penetration Test IDE -Copyright (C) 2017 Infobyte LLC (http://www.infobytesec.com/) -See the file 'doc/LICENSE' for the license information -""" -import re +#!/usr/bin/env python +# -*- coding: utf-8 -*- from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import resolve_hostname -from lxml import objectify -from urllib.parse import urlparse - -__author__ = "Alejando Parodi, Ezequiel Tavella" -__copyright__ = "Copyright (c) 2015, Infobyte LLC" -__credits__ = ["Alejando Parodi", "Ezequiel Tavella"] -__license__ = "" -__version__ = "1.0" -__maintainer__ = "Ezequiel Tavella" -__status__ = "Development" - - -class AppscanParser(): - - def __init__(self, output, logger): - self.issue_list = [] - self.logger = logger - self.obj_xml = objectify.fromstring(output) - - def parse_issues(self): - issue_type = self.parse_issue_type() - for issue in self.obj_xml["issue-group"]["item"]: - issue_data = issue_type[issue['issue-type']['ref']] - obj_issue = {} - obj_issue["name"] = issue_data["name"] - obj_issue['advisory'] = issue_data["advisory"] - if "cve" in issue_data: - obj_issue['cve'] = issue_data["cve"].text - obj_issue['url'] = self.get_url(issue['url']['ref'].text) - obj_issue['cvss_score'] = issue["cvss-score"].text - obj_issue['response'] = self.get_response(issue) - obj_issue['request'] = issue['variant-group']['item']["test-http-traffic"].text - obj_issue['method'] = self.get_method(issue['variant-group']['item']["test-http-traffic"].text) - obj_issue['severity'] = issue['severity'].text - obj_issue['issue-description'] = self.parse_advisory_group(issue_data['advisory']) - for recommendation in self.obj_xml["fix-recommendation-group"]["item"]: - full_data = "" - if recommendation.attrib['id'] == issue_data["fix-recommendation"]: - for data in recommendation['general']['fixRecommendation']["text"]: - full_data += '' + data - obj_issue["recomendation"] = full_data - if hasattr(recommendation['general']['fixRecommendation'], 'link'): - obj_issue["ref_link"] = recommendation['general']['fixRecommendation']['link'].text - self.issue_list.append(obj_issue) - return self.issue_list - - def parse_hosts(self): - hosts_list = [] - for host in self.obj_xml['scan-configuration']['scanned-hosts']['item']: - hosts_dict = {} - hosts_dict['ip'] = resolve_hostname(host['host'].text) - hosts_dict['hostname'] = host['host'].text - hosts_dict['os'] = host['operating-system'].text - hosts_dict['port'] = host['port'].text - if host['port'].text == '443': - hosts_dict['scheme'] = 'https' +from datetime import datetime +try: + import xml.etree.cElementTree as ET +except ImportError: + import xml.etree.ElementTree as ET +import re + +__author__ = 'Blas Moyano' +__copyright__ = 'Copyright 2020, Faraday Project' +__credits__ = ['Blas Moyano'] +__license__ = '' +__version__ = '1.0.0' +__status__ = 'Development' + + +class HclAsocParser: + def __init__(self, xml_output): + self.tree = self.parse_xml(xml_output) + if self.tree: + self.operating_system = self.tree.attrib['technology'] + url_group = [tags.tag for tags in self.tree] + check_url = True if 'url-group' in url_group else False + if check_url: + self.urls = self.get_urls_info(self.tree.find('url-group')) else: - hosts_dict['scheme'] = 'http' - hosts_list.append(hosts_dict) - return hosts_list - - def parse_issue_type(self): - res = {} - for issue_type in self.obj_xml["issue-type-group"]["item"]: - res[issue_type.attrib['id']] = { - 'name': issue_type.name.text, - 'advisory': issue_type["advisory"]["ref"].text, - 'fix-recommendation': issue_type["fix-recommendation"]["ref"].text - } - if "cve" in issue_type: - res[issue_type.attrib['id']] = {'cve': issue_type["cve"].text} - return res - - def parse_advisory_group(self, advisory): - """ - Function that parse advisory-group in order to get the item's description - """ - for item in self.obj_xml["advisory-group"]["item"]: - if item.attrib['id'] == advisory: - return item['advisory']['testTechnicalDescription']['text'].text - - def get_url(self, ref): - for item in self.obj_xml['url-group']['item']: - if item.attrib['id'] == ref: - return item['name'].text - - def get_method(self, http_traffic): - methods_list = ['GET', 'POST', 'PUT', 'DELETE', 'CONNECT', 'PATCH', 'HEAD', 'OPTIONS'] - try: - if http_traffic: - for item in methods_list: - if http_traffic.startswith(item): - return item - except TypeError: - return None - return None + self.urls = None + self.layout = self.get_layout_info(self.tree.find('layout')) + self.item = self.get_issue_type(self.tree.find('issue-type-group')) + self.name_scan = self.get_issue_data(self.tree.find('advisory-group')) + self.host_data = None if self.tree.find('scan-configuration/scanned-hosts/item') is None else \ + self.get_scan_conf_data(self.tree.find('scan-configuration/scanned-hosts/item')) + #self.fix_recomendation = self.get_fix_info(self.tree.find('fix-recommendation-group')) + self.req_res = self.get_req_res(self.tree.find("issue-group")) + + else: + self.tree = None - def get_response(self, node): + def parse_xml(self, xml_output): try: - response = node['variant-group']['item']['issue-information']["testResponseChunk"].text - return response - except AttributeError: + tree = ET.fromstring(xml_output) + except SyntaxError as err: + print('SyntaxError In xml: %s. %s' % (err, xml_output)) return None + return tree + + def get_req_res(sef,tree): + data_res_req = [] + for item in tree: + if item.find("variant-group/item/issue-information"): + resp = item.find("variant-group/item/issue-information").text + else: + resp = "Not Response" + + json_res_req = { + "request": "Not request" if item.find("variant-group/item/test-http-traffic") is None else + item.find("variant-group/item/test-http-traffic").text, + "response": resp + } + data_res_req.append(json_res_req) + return data_res_req + + # def get_fix_info(self, tree): + # list_fix = [] + # for item in tree: + # text_info_join = [] + # if tree.find("general"): + # # ACA VALIDA APP SCAN + # pass + # else: + # for text_tag in item.find('fixRecommendations/fixRecommendation'): + # text_info_join.append(text_tag.text) + # info_fix = { + # "id": item.attrib.get('id', None), + # "name": item.attrib.get('name', None), + # "text": text_info_join + # } + # list_fix.append(info_fix) + # return list_fix + + def get_layout_info(self, tree): + info_layout = { + "name": "Not info" if tree.find("application-name") is None else tree.find("application-name").text, + "date": "Not info" if tree.find("report-date") is None else tree.find("report-date").text, + "details": f'Departamento: {"Not info" if tree.find("department") is None else tree.find("department").text}' + f'Compania: {"Not info" if tree.find("company") is None else tree.find("company").text}' + f'Titulo Reporte: {"Not info" if tree.find("title") is None else tree.find("title").text}' + } + return info_layout + + def get_issue_type(self, tree): + list_item = [] + for item in tree: + severity = item.attrib.get('severity-id', None) + if severity is None: + severity = item.attrib.get('maxIssueSeverity', None) + + item_info = { + "id": item.attrib.get('id', None), + "name": item.find("name").text, + "severity_id": severity, + "severity": item.attrib.get('severity', None), + "cwe": "Not info" if item.find("cme") is None else item.find("cwe").text, + "xfid": "Not info" if item.find("xfid") is None else item.find("xfid").text, + "advisory": "Not info" if item.find("advisory/ref") is None else item.find("advisory/ref").text, + } + list_item.append(item_info) + + return list_item + + def get_issue_data(self, tree): + list_item_data = [] + item_data = {} + for item in tree: + for adivisory in item: + if adivisory.find("cwe/link"): + cwe = adivisory.find("cwe/link").text + else: + cwe = "Not Response" + + if adivisory.find("xfid/link"): + xfid = adivisory.find("xfid/link").text + else: + xfid = "Not Response" + + + item_data = { + "id": item.attrib.get('id', None), + "name": "Not info" if adivisory.find("name") is None else adivisory.find("name").text, + "description": "Not info" if adivisory.find("testDescription") is None else + adivisory.find("testDescription").text, + "threatClassification": { + "name": "Not info" if adivisory.find("threatClassification/name") is None else + adivisory.find("threatClassification/name").text, + "reference": "Not info" if adivisory.find("threatClassification/reference") is None else + adivisory.find("threatClassification/reference").text, + }, + "testTechnicalDescription": "Not info" if adivisory.find("testTechnicalDescription") is None else + self.get_parser(adivisory.find("testTechnicalDescription")), + "causes": "Not info" if adivisory.find("causes/cause") is None else + adivisory.find("causes/cause").text, + "securityRisks": "Not info" if adivisory.find("securityRisks/securityRisk") is None else + adivisory.find("securityRisks/securityRisk").text, + "affectedProducts": "Not info" if adivisory.find("affectedProducts/affectedProduct") is None else + adivisory.find("affectedProducts/affectedProduct").text, + "cwe": cwe, + "xfid": xfid, + "references": "Not info" if adivisory.find("references") is None else + self.get_parser(adivisory.find("references")), + "fixRecommendations": "Not info" if adivisory.find("fixRecommendations/fixRecommendation") is None else + self.get_parser(adivisory.find("fixRecommendations/fixRecommendation")) + } + list_item_data.append(item_data) + return list_item_data - def get_scan_information(self): + def get_parser(self, tree): + text_join = "" + code_join = "" + link_join = "" - scan_information = "File: " + self.obj_xml["scan-information"]["scan-file-name"]\ - + "\nStart: " + self.obj_xml["scan-information"]["scan-date-and-time"]\ - + "\nSoftware: " + self.obj_xml["scan-information"]["product-name"]\ - + "\nVersion: " + self.obj_xml["scan-information"]["product-version"]\ - + "\nScanner Elapsed time: " + self.obj_xml["scan-summary"]["scan-Duration"] + if tree.tag == 'testTechnicalDescription': - return scan_information + for text_info in tree.findall('text'): + text_join += text_info.text + for code_info in tree.findall('code'): + text_join += code_info.text -class AppscanPlugin(PluginXMLFormat): - """ Example plugin to parse Appscan XML report""" + tech_data = { + "text": text_join, + "code": code_join + } + elif tree.tag == 'references': + for text_info in tree.findall('text'): + text_join += "no info " if text_info.text is None else text_info.text + + for link_info in tree.findall('link'): + link_join += "no info " if link_info.text is None else link_info.text + link_join += link_info.attrib.get('target', 'not target') + + tech_data = { + "text": text_join, + "Link": link_join + } + + elif tree.tag == 'fixRecommendation': + for text_info in tree.findall('text'): + text_join += "no info " if text_info.text is None else text_info.text + + for link_info in tree.findall('link'): + link_join += "no info " if link_info.text is None else link_info.text + link_join += link_info.attrib.get('target', 'not target') + + tech_data = { + "text": text_join, + "link": link_join + } + + return tech_data + + def get_urls_info(self, tree): + list_url = [] + for url in tree: + url_info = { + "id": "Not info" if url.find("issue-type") is None else url.find("issue-type").text, + "url": "Not info" if url.find("name") is None else url.find("name").text, + } + list_url.append(url_info) + + return list_url + + def get_scan_conf_data(self, host_info): + info_host = { + "host": "Not info" if host_info.find("host") is None else host_info.find("host").text, + "port": "Not info" if host_info.find("port") is None else host_info.find("port").text, + "os": "Not info" if host_info.find("operating-system") is None else host_info.find("operating-system").text, + "webserver": "Not info" if host_info.find("web-server") is None else host_info.find("web-server").text, + "appserver": "Not info" if host_info.find("application-server") is None else host_info.find("application-server").text, + } + return info_host + + +class HclAsocPlugin(PluginXMLFormat): def __init__(self): super().__init__() self.identifier_tag = "xml-report" - self.id = "Appscan" - self.name = "Appscan XML Plugin" - self.plugin_version = "0.0.1" + self.id = 'appscan' + self.name = 'HCL ASOC XML Output Plugin' + self.plugin_version = '1.0.0' + self.version = '1.0.0' + self.framework_version = '1.0.0' self.options = None - self.open_options = {"mode": "r", "encoding": "utf-8"} - - def report_belongs_to(self, **kwargs): - if super().report_belongs_to(**kwargs): - report_path = kwargs.get("report_path", "") - with open(report_path) as f: - output = f.read() - return re.search("filtered-link-group", output) is not None - return False + self.protocol = None + self.port = '80' + self.address = None + # def report_belongs_to(self, **kwargs): + # if super().report_belongs_to(**kwargs): + # report_path = kwargs.get("report_path", "") + # with open(report_path) as f: + # output = f.read() + # return re.search("createdByAppScan", output) is not None + # return False def parseOutputString(self, output): - try: - parser = AppscanParser(output, self.logger) - issues = parser.parse_issues() - scanned_hosts = parser.parse_hosts() - hosts_dict = {} - for host in scanned_hosts: - host_id = self.createAndAddHost(host['ip'], os=host['os'], hostnames=[host['hostname']]) - service_id = self.createAndAddServiceToHost( - host_id, - host['scheme'], - ports=[host['port']], - protocol="tcp?HTTP") - if host['port']: - if host['port'] not in ('443', '80'): - key_url = f"{host['scheme']}://{host['hostname']}:{host['port']}" - else: - key_url = f"{host['scheme']}://{host['hostname']}" - else: - key_url = f"{host['scheme']}://{host['hostname']}" - hosts_dict[key_url] = {'host_id': host_id, 'service_id': service_id} - for issue in issues: - url_parsed = urlparse(issue['url']) - url_string = f'{url_parsed.scheme}://{url_parsed.netloc}' - for key in hosts_dict: - if url_string == key: - h_id = hosts_dict[key]['host_id'] - s_id = hosts_dict[key]['service_id'] - refs = [] - if "ref_link" in issue: - refs.append(f"Fix link: {issue['ref_link']}" ) - if "cvss_score" in issue: - refs.append(f"CVSS Score: {issue['cvss_score']}") - if "cve" in issue: - refs.append(f"CVE: {issue['cve']}") - if "advisory" in issue: - refs.append(f"Advisory: {issue['advisory']}") - self.createAndAddVulnWebToService( - h_id, - s_id, - issue["name"], - desc=issue["issue_description"] if "issue_description" in issue else "", - ref=refs, - severity=issue["severity"], - resolution=issue["recomendation"], - website=url_parsed.netloc, - path=url_parsed.path, - request=issue["request"] if "request" in issue else "", - response=issue["response"] if issue["response"] else "", - method=issue["method"] if issue["method"] else "") - except Exception as e: - self.logger.error("Parsing Output Error: %s", e) + parser = HclAsocParser(output) + layout = parser.layout + operating_system = parser.operating_system + host_data = parser.host_data + # Listas + urls = parser.urls + item = parser.item + name_scan = parser.name_scan + #fixs = parser.fix_recomendation + res_req = parser.req_res + if operating_system == 'DAST': + host_id = self.createAndAddHost(resolve_hostname(host_data['host']), os=host_data['os'], + hostnames=[host_data['host']], description=layout['details']) -def createPlugin(): - return AppscanPlugin() + service_id = self.createAndAddServiceToHost(host_id, host_data['host'], ports=host_data['port'], + protocol="tcp?HTTP", description=f'{host_data["webserver"]} - {host_data["appserver"]}') + + for vulnserv in name_scan: + for sev in item: + if sev['id'] == vulnserv['id']: + info_severity = sev['severity_id'] + ref = f'cwe: {sev["cwe"]} xfid: {sev["xfid"]} advisory: {sev["advisory"]}' + + for url in urls: + if url['id'] == vulnserv['id']: + url_name = url['url'] + + for info_rs_rq in res_req: + print(info_rs_rq) + request = info_rs_rq['request'] + response = info_rs_rq['response'] -# I'm Py3 + self.createAndAddVulnWebToService(host_id=host_id, service_id=service_id, name=vulnserv['name'], + desc=vulnserv['description'], severity=info_severity, + path=url_name, website=host_data['host'], ref=ref, + resolution=vulnserv['fixRecommendations'], request=request, + response=response, method=request, + data=f'xfix: {vulnserv["xfid"]} cme: {vulnserv["cwe"]}') + + + else: + host_id = self.createAndAddHost('0.0.0.0', os=operating_system) + for vulnserv in name_scan: + for sev in item: + if sev['id'] == vulnserv['id']: + info_severity = sev['severity_id'] + + self.createAndAddVulnToHost(host_id=host_id,name=vulnserv['name'], desc=vulnserv['description'], + severity=info_severity, resolution=vulnserv['fixRecommendations'], + data=f'xfix: {vulnserv["xfid"]} cme: {vulnserv["cwe"]}', run_date=None) + +def createPlugin(): + return HclAsocPlugin() diff --git a/faraday_plugins/plugins/repo/appscan/pluginapp.py b/faraday_plugins/plugins/repo/appscan/pluginapp.py new file mode 100644 index 00000000..ae02eddd --- /dev/null +++ b/faraday_plugins/plugins/repo/appscan/pluginapp.py @@ -0,0 +1,202 @@ +""" +Faraday Penetration Test IDE +Copyright (C) 2017 Infobyte LLC (http://www.infobytesec.com/) +See the file 'doc/LICENSE' for the license information +""" +import re +from faraday_plugins.plugins.plugin import PluginXMLFormat +from faraday_plugins.plugins.plugins_utils import resolve_hostname +from lxml import objectify +from urllib.parse import urlparse + +__author__ = "Alejando Parodi, Ezequiel Tavella" +__copyright__ = "Copyright (c) 2015, Infobyte LLC" +__credits__ = ["Alejando Parodi", "Ezequiel Tavella"] +__license__ = "" +__version__ = "1.0" +__maintainer__ = "Ezequiel Tavella" +__status__ = "Development" + + +class AppscanParser(): + + def __init__(self, output, logger): + self.issue_list = [] + self.logger = logger + self.obj_xml = objectify.fromstring(output) + + def parse_issues(self): + issue_type = self.parse_issue_type() + for issue in self.obj_xml["issue-group"]["item"]: + issue_data = issue_type[issue['issue-type']['ref']] + obj_issue = {} + obj_issue["name"] = issue_data["name"] + obj_issue['advisory'] = issue_data["advisory"] + if "cve" in issue_data: + obj_issue['cve'] = issue_data["cve"].text + obj_issue['url'] = self.get_url(issue['url']['ref'].text) + obj_issue['cvss_score'] = issue["cvss-score"].text + obj_issue['response'] = self.get_response(issue) + obj_issue['request'] = issue['variant-group']['item']["test-http-traffic"].text + obj_issue['method'] = self.get_method(issue['variant-group']['item']["test-http-traffic"].text) + obj_issue['severity'] = issue['severity'].text + obj_issue['issue-description'] = self.parse_advisory_group(issue_data['advisory']) + for recommendation in self.obj_xml["fix-recommendation-group"]["item"]: + full_data = "" + if recommendation.attrib['id'] == issue_data["fix-recommendation"]: + for data in recommendation['general']['fixRecommendation']["text"]: + full_data += '' + data + obj_issue["recomendation"] = full_data + if hasattr(recommendation['general']['fixRecommendation'], 'link'): + obj_issue["ref_link"] = recommendation['general']['fixRecommendation']['link'].text + self.issue_list.append(obj_issue) + return self.issue_list + + def parse_hosts(self): + hosts_list = [] + for host in self.obj_xml['scan-configuration']['scanned-hosts']['item']: + hosts_dict = {} + hosts_dict['ip'] = resolve_hostname(host['host'].text) + hosts_dict['hostname'] = host['host'].text + hosts_dict['os'] = host['operating-system'].text + hosts_dict['port'] = host['port'].text + if host['port'].text == '443': + hosts_dict['scheme'] = 'https' + else: + hosts_dict['scheme'] = 'http' + hosts_list.append(hosts_dict) + return hosts_list + + def parse_issue_type(self): + res = {} + for issue_type in self.obj_xml["issue-type-group"]["item"]: + res[issue_type.attrib['id']] = { + 'name': issue_type.name.text, + 'advisory': issue_type["advisory"]["ref"].text, + 'fix-recommendation': issue_type["fix-recommendation"]["ref"].text + } + if "cve" in issue_type: + res[issue_type.attrib['id']] = {'cve': issue_type["cve"].text} + return res + + def parse_advisory_group(self, advisory): + """ + Function that parse advisory-group in order to get the item's description + """ + for item in self.obj_xml["advisory-group"]["item"]: + if item.attrib['id'] == advisory: + return item['advisory']['testTechnicalDescription']['text'].text + + def get_url(self, ref): + for item in self.obj_xml['url-group']['item']: + if item.attrib['id'] == ref: + return item['name'].text + + def get_method(self, http_traffic): + methods_list = ['GET', 'POST', 'PUT', 'DELETE', 'CONNECT', 'PATCH', 'HEAD', 'OPTIONS'] + try: + if http_traffic: + for item in methods_list: + if http_traffic.startswith(item): + return item + except TypeError: + return None + return None + + def get_response(self, node): + try: + response = node['variant-group']['item']['issue-information']["testResponseChunk"].text + return response + except AttributeError: + return None + + def get_scan_information(self): + + scan_information = "File: " + self.obj_xml["scan-information"]["scan-file-name"]\ + + "\nStart: " + self.obj_xml["scan-information"]["scan-date-and-time"]\ + + "\nSoftware: " + self.obj_xml["scan-information"]["product-name"]\ + + "\nVersion: " + self.obj_xml["scan-information"]["product-version"]\ + + "\nScanner Elapsed time: " + self.obj_xml["scan-summary"]["scan-Duration"] + + return scan_information + + +class AppscanPlugin(PluginXMLFormat): + """ Example plugin to parse Appscan XML report""" + + def __init__(self): + super().__init__() + self.identifier_tag = "xml-report" + self.id = "Appscan" + self.name = "Appscan XML Plugin" + self.plugin_version = "0.0.1" + self.options = None + self.open_options = {"mode": "r", "encoding": "utf-8"} + + def report_belongs_to(self, **kwargs): + if super().report_belongs_to(**kwargs): + report_path = kwargs.get("report_path", "") + with open(report_path) as f: + output = f.read() + return re.search("filtered-link-group", output) is not None + return False + + + def parseOutputString(self, output): + try: + parser = AppscanParser(output, self.logger) + issues = parser.parse_issues() + scanned_hosts = parser.parse_hosts() + hosts_dict = {} + for host in scanned_hosts: + host_id = self.createAndAddHost(host['ip'], os=host['os'], hostnames=[host['hostname']]) + service_id = self.createAndAddServiceToHost( + host_id, + host['scheme'], + ports=[host['port']], + protocol="tcp?HTTP") + if host['port']: + if host['port'] not in ('443', '80'): + key_url = f"{host['scheme']}://{host['hostname']}:{host['port']}" + else: + key_url = f"{host['scheme']}://{host['hostname']}" + else: + key_url = f"{host['scheme']}://{host['hostname']}" + hosts_dict[key_url] = {'host_id': host_id, 'service_id': service_id} + for issue in issues: + url_parsed = urlparse(issue['url']) + url_string = f'{url_parsed.scheme}://{url_parsed.netloc}' + for key in hosts_dict: + if url_string == key: + h_id = hosts_dict[key]['host_id'] + s_id = hosts_dict[key]['service_id'] + refs = [] + if "ref_link" in issue: + refs.append(f"Fix link: {issue['ref_link']}" ) + if "cvss_score" in issue: + refs.append(f"CVSS Score: {issue['cvss_score']}") + if "cve" in issue: + refs.append(f"CVE: {issue['cve']}") + if "advisory" in issue: + refs.append(f"Advisory: {issue['advisory']}") + self.createAndAddVulnWebToService( + h_id, + s_id, + issue["name"], + desc=issue["issue_description"] if "issue_description" in issue else "", + ref=refs, + severity=issue["severity"], + resolution=issue["recomendation"], + website=url_parsed.netloc, + path=url_parsed.path, + request=issue["request"] if "request" in issue else "", + response=issue["response"] if issue["response"] else "", + method=issue["method"] if issue["method"] else "") + except Exception as e: + self.logger.error("Parsing Output Error: %s", e) + + +def createPlugin(): + return AppscanPlugin() + +# I'm Py3 diff --git a/faraday_plugins/plugins/repo/hcl_asoc/__init__.py b/faraday_plugins/plugins/repo/hcl_asoc/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/faraday_plugins/plugins/repo/hcl_asoc/plugin.py b/faraday_plugins/plugins/repo/hcl_asoc/plugin.py deleted file mode 100644 index 6ad147e5..00000000 --- a/faraday_plugins/plugins/repo/hcl_asoc/plugin.py +++ /dev/null @@ -1,192 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -from faraday_plugins.plugins.plugin import PluginXMLFormat -from datetime import datetime -try: - import xml.etree.cElementTree as ET -except ImportError: - import xml.etree.ElementTree as ET -import re - -__author__ = 'Blas Moyano' -__copyright__ = 'Copyright 2020, Faraday Project' -__credits__ = ['Blas Moyano'] -__license__ = '' -__version__ = '1.0.0' -__status__ = 'Development' - - -class HclAsocParser: - def __init__(self, xml_output): - self.tree = self.parse_xml(xml_output) - if self.tree: - self.operating_system = self.tree.attrib['technology'] - url_group = [tags.tag for tags in self.tree] - check_url = True if 'url-group' in url_group else False - if check_url: - self.urls = self.get_urls_info(self.tree.find('url-group')) - else: - self.urls = None - self.layout = self.get_layout_info(self.tree.find('layout')) - self.item = self.get_issue_type(self.tree.find('issue-type-group')) - self.name_scan = self.get_issue_data(self.tree.find('advisory-group')) - else: - self.tree = None - - def parse_xml(self, xml_output): - try: - tree = ET.fromstring(xml_output) - except SyntaxError as err: - print('SyntaxError In xml: %s. %s' % (err, xml_output)) - return None - return tree - - def get_layout_info(self, tree): - info_layout = { - "name": "Not info" if tree.find("application-name") is None else tree.find("application-name").text, - "date": "Not info" if tree.find("report-date") is None else tree.find("report-date").text, - "details": f'Departamento: {"Not info" if tree.find("department") is None else tree.find("department").text}' - f'Compania: {"Not info" if tree.find("company") is None else tree.find("company").text}' - f'Titulo Reporte: {"Not info" if tree.find("title") is None else tree.find("title").text}' - } - return info_layout - - def get_issue_type(self, tree): - list_item = [] - for item in tree: - item_info = { - "id": item.attrib.get('id', None), - "name": item.find("name").text, - "severity_id": item.attrib.get('severity-id', None), - "severity": item.attrib.get('severity', None) - } - list_item.append(item_info) - - return list_item - - def get_issue_data(self, tree): - list_item_data = [] - item_data = {} - for item in tree: - for adivisory in item: - item_data = { - "id": item.attrib.get('id', None), - "name": "Not info" if adivisory.find("name") is None else adivisory.find("name").text, - "description": "Not info" if adivisory.find("testDescription") is None else - adivisory.find("testDescription").text, - "threatClassification": { - "name": "Not info" if adivisory.find("threatClassification/name") is None else - adivisory.find("threatClassification/name").text, - "reference": "Not info" if adivisory.find("threatClassification/reference") is None else - adivisory.find("threatClassification/reference").text, - }, - "testTechnicalDescription": self.get_parser(adivisory.find("testTechnicalDescription")), - "causes": "Not info" if adivisory.find("causes/cause") is None else - adivisory.find("causes/cause").text, - "securityRisks": "Not info" if adivisory.find("securityRisks/securityRisk") is None else - adivisory.find("securityRisks/securityRisk").text, - "affectedProducts": "Not info" if adivisory.find("affectedProducts/affectedProduct") is None else - adivisory.find("affectedProducts/affectedProduct").text, - "cwe": "Not info" if adivisory.find("cwe/link") is None else adivisory.find("cwe/link").text, - "xfid": "Not info" if adivisory.find("xfid/link") is None else adivisory.find("cwe/link").text, - "references": self.get_parser(adivisory.find("references")), - "fixRecommendations": self.get_parser(adivisory.find("fixRecommendations/fixRecommendation")) - } - return list_item_data - - def get_parser(self, tree): - text_join = "" - code_join = "" - link_join = "" - - if tree.tag == 'testTechnicalDescription': - for text_info in tree.findall('text'): - text_join += text_info.text - - for code_info in tree.findall('code'): - text_join += code_info.text - - tech_data = { - "text": text_join, - "code": code_join - } - - elif tree.tag == 'references': - for text_info in tree.findall('text'): - text_join += "no info " if text_info.text is None else text_info.text - - for link_info in tree.findall('link'): - link_join += "no info " if link_info.text is None else link_info.text - link_join += link_info.attrib.get('target', 'not target') - - tech_data = { - "text": text_join, - "Link": link_join - } - - elif tree.tag == 'fixRecommendation': - for text_info in tree.findall('text'): - text_join += "no info " if text_info.text is None else text_info.text - - for link_info in tree.findall('link'): - link_join += "no info " if link_info.text is None else link_info.text - link_join += link_info.attrib.get('target', 'not target') - - tech_data = { - "text": text_join, - "link": link_join - } - - return tech_data - - def get_urls_info(self, tree): - list_url = [] - for url in tree: - url_info = { - "id": "Not info" if url.find("issue-type") is None else url.find("issue-type").text, - "url": "Not info" if url.find("name") is None else url.find("name").text, - } - list_url.append(url_info) - - return list_url - - -class HclAsocPlugin(PluginXMLFormat): - def __init__(self): - super().__init__() - self.identifier_tag = "xml-report" - self.id = 'HclAsoc' - self.name = 'HCL ASOC XML Output Plugin' - self.plugin_version = '1.0.0' - self.version = '1.0.0' - self.framework_version = '1.0.0' - self.options = None - self.protocol = None - self.port = '80' - self.address = None - - def report_belongs_to(self, **kwargs): - if super().report_belongs_to(**kwargs): - report_path = kwargs.get("report_path", "") - with open(report_path) as f: - output = f.read() - return re.search("createdByAppScan", output) is not None - return False - - - def parseOutputString(self, output): - parser = HclAsocParser(output) - - - # host_id = self.createAndAddHost(name=sorted(list(ip))[0], hostnames=sorted(list(url)), - # description=parser.name_scan) - - # vuln_run_date = datetime.strptime(vuln_run_date, '%Y-%m-%d %H:%M:%S') - - # self.createAndAddVulnToHost(host_id=host_id, name=vuln_name, desc=vuln_desc, ref=[vuln_ref], - # severity=severity, resolution=vuln_resolution, run_date=vuln_run_date, - # external_id=vuln_external_id, data=str_data) - - -def createPlugin(): - return HclAsocPlugin() From 0390e36c25a15b2958d4a4437382e8abf4abc9a2 Mon Sep 17 00:00:00 2001 From: Blas Date: Tue, 28 Jul 2020 12:09:19 -0300 Subject: [PATCH 104/698] update appscan new report HCL --- CHANGELOG/current/add_hcl_asoc.md | 1 - CHANGELOG/current/update_appscan.md | 1 + .../plugins/repo/appscan/plugin.py | 80 ++++--- .../plugins/repo/appscan/pluginapp.py | 202 ------------------ 4 files changed, 37 insertions(+), 247 deletions(-) delete mode 100644 CHANGELOG/current/add_hcl_asoc.md create mode 100644 CHANGELOG/current/update_appscan.md delete mode 100644 faraday_plugins/plugins/repo/appscan/pluginapp.py diff --git a/CHANGELOG/current/add_hcl_asoc.md b/CHANGELOG/current/add_hcl_asoc.md deleted file mode 100644 index a89bd028..00000000 --- a/CHANGELOG/current/add_hcl_asoc.md +++ /dev/null @@ -1 +0,0 @@ -ADD plugin HCL ASOC \ No newline at end of file diff --git a/CHANGELOG/current/update_appscan.md b/CHANGELOG/current/update_appscan.md new file mode 100644 index 00000000..0b95a040 --- /dev/null +++ b/CHANGELOG/current/update_appscan.md @@ -0,0 +1 @@ +UPDATE xml report to appscan \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/appscan/plugin.py b/faraday_plugins/plugins/repo/appscan/plugin.py index 7c8908ec..5384bcca 100644 --- a/faraday_plugins/plugins/repo/appscan/plugin.py +++ b/faraday_plugins/plugins/repo/appscan/plugin.py @@ -2,19 +2,19 @@ # -*- coding: utf-8 -*- from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import resolve_hostname -from datetime import datetime try: import xml.etree.cElementTree as ET except ImportError: import xml.etree.ElementTree as ET -import re -__author__ = 'Blas Moyano' -__copyright__ = 'Copyright 2020, Faraday Project' -__credits__ = ['Blas Moyano'] -__license__ = '' -__version__ = '1.0.0' -__status__ = 'Development' + +__author__ = "Alejando Parodi, Ezequiel Tavella, Blas Moyano" +__copyright__ = "Copyright (c) 2015, Infobyte LLC" +__credits__ = ["Alejando Parodi", "Ezequiel Tavella"] +__license__ = "" +__version__ = "1.0" +__maintainer__ = "Ezequiel Tavella" +__status__ = "Development" class HclAsocParser: @@ -33,7 +33,6 @@ def __init__(self, xml_output): self.name_scan = self.get_issue_data(self.tree.find('advisory-group')) self.host_data = None if self.tree.find('scan-configuration/scanned-hosts/item') is None else \ self.get_scan_conf_data(self.tree.find('scan-configuration/scanned-hosts/item')) - #self.fix_recomendation = self.get_fix_info(self.tree.find('fix-recommendation-group')) self.req_res = self.get_req_res(self.tree.find("issue-group")) else: @@ -58,29 +57,15 @@ def get_req_res(sef,tree): json_res_req = { "request": "Not request" if item.find("variant-group/item/test-http-traffic") is None else item.find("variant-group/item/test-http-traffic").text, - "response": resp + "response": resp, + "location": "Not Location" if item.find("location") is None else item.find("location").text, + "source_file": "0.0.0.0" if item.find("source-file") is None else item.find("source-file").text, + "line": 0 if item.find("line") is None else item.find("line").text } + data_res_req.append(json_res_req) return data_res_req - # def get_fix_info(self, tree): - # list_fix = [] - # for item in tree: - # text_info_join = [] - # if tree.find("general"): - # # ACA VALIDA APP SCAN - # pass - # else: - # for text_tag in item.find('fixRecommendations/fixRecommendation'): - # text_info_join.append(text_tag.text) - # info_fix = { - # "id": item.attrib.get('id', None), - # "name": item.attrib.get('name', None), - # "text": text_info_join - # } - # list_fix.append(info_fix) - # return list_fix - def get_layout_info(self, tree): info_layout = { "name": "Not info" if tree.find("application-name") is None else tree.find("application-name").text, @@ -126,7 +111,6 @@ def get_issue_data(self, tree): else: xfid = "Not Response" - item_data = { "id": item.attrib.get('id', None), "name": "Not info" if adivisory.find("name") is None else adivisory.find("name").text, @@ -228,9 +212,9 @@ class HclAsocPlugin(PluginXMLFormat): def __init__(self): super().__init__() self.identifier_tag = "xml-report" - self.id = 'appscan' - self.name = 'HCL ASOC XML Output Plugin' - self.plugin_version = '1.0.0' + self.id = 'Appscan' + self.name = 'Appscan XML Plugin' + self.plugin_version = '0.0.1' self.version = '1.0.0' self.framework_version = '1.0.0' self.options = None @@ -238,24 +222,14 @@ def __init__(self): self.port = '80' self.address = None - # def report_belongs_to(self, **kwargs): - # if super().report_belongs_to(**kwargs): - # report_path = kwargs.get("report_path", "") - # with open(report_path) as f: - # output = f.read() - # return re.search("createdByAppScan", output) is not None - # return False - def parseOutputString(self, output): parser = HclAsocParser(output) layout = parser.layout operating_system = parser.operating_system host_data = parser.host_data - # Listas urls = parser.urls item = parser.item name_scan = parser.name_scan - #fixs = parser.fix_recomendation res_req = parser.req_res if operating_system == 'DAST': @@ -287,17 +261,35 @@ def parseOutputString(self, output): response=response, method=request, data=f'xfix: {vulnserv["xfid"]} cme: {vulnserv["cwe"]}') + elif operating_system == 'SAST': + + for info_loc_source in res_req: + location = info_loc_source['location'] + source_file = info_loc_source['source_file'] + line = info_loc_source["line"] + host_id = self.createAndAddHost(source_file, os=operating_system) + service_id = self.createAndAddServiceToHost(host_id, location, ports=line) + for vulnserv in name_scan: + for sev in item: + if sev['id'] == vulnserv['id']: + info_severity = sev['severity_id'] + + self.createAndAddVulnToService(host_id=host_id, service_id=service_id, name=vulnserv['name'], + desc=vulnserv['description'], severity=info_severity, + resolution=vulnserv['fixRecommendations'], run_date=None, + data=f'xfix: {vulnserv["xfid"]} cme: {vulnserv["cwe"]}') else: - host_id = self.createAndAddHost('0.0.0.0', os=operating_system) + host_id = self.createAndAddHost(layout['name'], os=operating_system) for vulnserv in name_scan: for sev in item: if sev['id'] == vulnserv['id']: info_severity = sev['severity_id'] - self.createAndAddVulnToHost(host_id=host_id,name=vulnserv['name'], desc=vulnserv['description'], + self.createAndAddVulnToHost(host_id=host_id, name=vulnserv['name'], desc=vulnserv['description'], severity=info_severity, resolution=vulnserv['fixRecommendations'], data=f'xfix: {vulnserv["xfid"]} cme: {vulnserv["cwe"]}', run_date=None) + def createPlugin(): return HclAsocPlugin() diff --git a/faraday_plugins/plugins/repo/appscan/pluginapp.py b/faraday_plugins/plugins/repo/appscan/pluginapp.py deleted file mode 100644 index ae02eddd..00000000 --- a/faraday_plugins/plugins/repo/appscan/pluginapp.py +++ /dev/null @@ -1,202 +0,0 @@ -""" -Faraday Penetration Test IDE -Copyright (C) 2017 Infobyte LLC (http://www.infobytesec.com/) -See the file 'doc/LICENSE' for the license information -""" -import re -from faraday_plugins.plugins.plugin import PluginXMLFormat -from faraday_plugins.plugins.plugins_utils import resolve_hostname -from lxml import objectify -from urllib.parse import urlparse - -__author__ = "Alejando Parodi, Ezequiel Tavella" -__copyright__ = "Copyright (c) 2015, Infobyte LLC" -__credits__ = ["Alejando Parodi", "Ezequiel Tavella"] -__license__ = "" -__version__ = "1.0" -__maintainer__ = "Ezequiel Tavella" -__status__ = "Development" - - -class AppscanParser(): - - def __init__(self, output, logger): - self.issue_list = [] - self.logger = logger - self.obj_xml = objectify.fromstring(output) - - def parse_issues(self): - issue_type = self.parse_issue_type() - for issue in self.obj_xml["issue-group"]["item"]: - issue_data = issue_type[issue['issue-type']['ref']] - obj_issue = {} - obj_issue["name"] = issue_data["name"] - obj_issue['advisory'] = issue_data["advisory"] - if "cve" in issue_data: - obj_issue['cve'] = issue_data["cve"].text - obj_issue['url'] = self.get_url(issue['url']['ref'].text) - obj_issue['cvss_score'] = issue["cvss-score"].text - obj_issue['response'] = self.get_response(issue) - obj_issue['request'] = issue['variant-group']['item']["test-http-traffic"].text - obj_issue['method'] = self.get_method(issue['variant-group']['item']["test-http-traffic"].text) - obj_issue['severity'] = issue['severity'].text - obj_issue['issue-description'] = self.parse_advisory_group(issue_data['advisory']) - for recommendation in self.obj_xml["fix-recommendation-group"]["item"]: - full_data = "" - if recommendation.attrib['id'] == issue_data["fix-recommendation"]: - for data in recommendation['general']['fixRecommendation']["text"]: - full_data += '' + data - obj_issue["recomendation"] = full_data - if hasattr(recommendation['general']['fixRecommendation'], 'link'): - obj_issue["ref_link"] = recommendation['general']['fixRecommendation']['link'].text - self.issue_list.append(obj_issue) - return self.issue_list - - def parse_hosts(self): - hosts_list = [] - for host in self.obj_xml['scan-configuration']['scanned-hosts']['item']: - hosts_dict = {} - hosts_dict['ip'] = resolve_hostname(host['host'].text) - hosts_dict['hostname'] = host['host'].text - hosts_dict['os'] = host['operating-system'].text - hosts_dict['port'] = host['port'].text - if host['port'].text == '443': - hosts_dict['scheme'] = 'https' - else: - hosts_dict['scheme'] = 'http' - hosts_list.append(hosts_dict) - return hosts_list - - def parse_issue_type(self): - res = {} - for issue_type in self.obj_xml["issue-type-group"]["item"]: - res[issue_type.attrib['id']] = { - 'name': issue_type.name.text, - 'advisory': issue_type["advisory"]["ref"].text, - 'fix-recommendation': issue_type["fix-recommendation"]["ref"].text - } - if "cve" in issue_type: - res[issue_type.attrib['id']] = {'cve': issue_type["cve"].text} - return res - - def parse_advisory_group(self, advisory): - """ - Function that parse advisory-group in order to get the item's description - """ - for item in self.obj_xml["advisory-group"]["item"]: - if item.attrib['id'] == advisory: - return item['advisory']['testTechnicalDescription']['text'].text - - def get_url(self, ref): - for item in self.obj_xml['url-group']['item']: - if item.attrib['id'] == ref: - return item['name'].text - - def get_method(self, http_traffic): - methods_list = ['GET', 'POST', 'PUT', 'DELETE', 'CONNECT', 'PATCH', 'HEAD', 'OPTIONS'] - try: - if http_traffic: - for item in methods_list: - if http_traffic.startswith(item): - return item - except TypeError: - return None - return None - - def get_response(self, node): - try: - response = node['variant-group']['item']['issue-information']["testResponseChunk"].text - return response - except AttributeError: - return None - - def get_scan_information(self): - - scan_information = "File: " + self.obj_xml["scan-information"]["scan-file-name"]\ - + "\nStart: " + self.obj_xml["scan-information"]["scan-date-and-time"]\ - + "\nSoftware: " + self.obj_xml["scan-information"]["product-name"]\ - + "\nVersion: " + self.obj_xml["scan-information"]["product-version"]\ - + "\nScanner Elapsed time: " + self.obj_xml["scan-summary"]["scan-Duration"] - - return scan_information - - -class AppscanPlugin(PluginXMLFormat): - """ Example plugin to parse Appscan XML report""" - - def __init__(self): - super().__init__() - self.identifier_tag = "xml-report" - self.id = "Appscan" - self.name = "Appscan XML Plugin" - self.plugin_version = "0.0.1" - self.options = None - self.open_options = {"mode": "r", "encoding": "utf-8"} - - def report_belongs_to(self, **kwargs): - if super().report_belongs_to(**kwargs): - report_path = kwargs.get("report_path", "") - with open(report_path) as f: - output = f.read() - return re.search("filtered-link-group", output) is not None - return False - - - def parseOutputString(self, output): - try: - parser = AppscanParser(output, self.logger) - issues = parser.parse_issues() - scanned_hosts = parser.parse_hosts() - hosts_dict = {} - for host in scanned_hosts: - host_id = self.createAndAddHost(host['ip'], os=host['os'], hostnames=[host['hostname']]) - service_id = self.createAndAddServiceToHost( - host_id, - host['scheme'], - ports=[host['port']], - protocol="tcp?HTTP") - if host['port']: - if host['port'] not in ('443', '80'): - key_url = f"{host['scheme']}://{host['hostname']}:{host['port']}" - else: - key_url = f"{host['scheme']}://{host['hostname']}" - else: - key_url = f"{host['scheme']}://{host['hostname']}" - hosts_dict[key_url] = {'host_id': host_id, 'service_id': service_id} - for issue in issues: - url_parsed = urlparse(issue['url']) - url_string = f'{url_parsed.scheme}://{url_parsed.netloc}' - for key in hosts_dict: - if url_string == key: - h_id = hosts_dict[key]['host_id'] - s_id = hosts_dict[key]['service_id'] - refs = [] - if "ref_link" in issue: - refs.append(f"Fix link: {issue['ref_link']}" ) - if "cvss_score" in issue: - refs.append(f"CVSS Score: {issue['cvss_score']}") - if "cve" in issue: - refs.append(f"CVE: {issue['cve']}") - if "advisory" in issue: - refs.append(f"Advisory: {issue['advisory']}") - self.createAndAddVulnWebToService( - h_id, - s_id, - issue["name"], - desc=issue["issue_description"] if "issue_description" in issue else "", - ref=refs, - severity=issue["severity"], - resolution=issue["recomendation"], - website=url_parsed.netloc, - path=url_parsed.path, - request=issue["request"] if "request" in issue else "", - response=issue["response"] if issue["response"] else "", - method=issue["method"] if issue["method"] else "") - except Exception as e: - self.logger.error("Parsing Output Error: %s", e) - - -def createPlugin(): - return AppscanPlugin() - -# I'm Py3 From 2d06afd7db659b977f4514d395a95a3a5f6ac7ee Mon Sep 17 00:00:00 2001 From: Leonardo Lazzaro Date: Tue, 28 Jul 2020 14:41:46 -0300 Subject: [PATCH 105/698] add new rdpscan plugin --- .../plugins/repo/rdpscan/__init__.py | 0 .../plugins/repo/rdpscan/plugin.py | 65 +++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 faraday_plugins/plugins/repo/rdpscan/__init__.py create mode 100644 faraday_plugins/plugins/repo/rdpscan/plugin.py diff --git a/faraday_plugins/plugins/repo/rdpscan/__init__.py b/faraday_plugins/plugins/repo/rdpscan/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/faraday_plugins/plugins/repo/rdpscan/plugin.py b/faraday_plugins/plugins/repo/rdpscan/plugin.py new file mode 100644 index 00000000..0762929c --- /dev/null +++ b/faraday_plugins/plugins/repo/rdpscan/plugin.py @@ -0,0 +1,65 @@ +import re +from collections import defaultdict + +from faraday_plugins.plugins.plugin import PluginBase +from faraday_plugins.plugins.plugins_utils import resolve_hostname + + +class RDPScanPlugin(PluginBase): + + def __init__(self): + super().__init__() + self.identifier_tag = "rdpscan" + self.id = "rdpscan" + self.name = "rdpscan" + self._command_regex = re.compile(r'rdpscan') + + def parseOutputString(self, output): + services = defaultdict(set) + for info in output.split('\n'): + if info: + ip, status, data = info.split('-', 2) + ip = ip.strip() + status = status.strip() + data = data.strip() + if status.lower() == 'unknown': + continue + + host_id = self.createAndAddHost(ip) + service_id = self.createAndAddServiceToHost( + host_id=host_id, + name='rdp', + ports=3389, + protocol='tcp', + ) + if status.lower() == 'vulnerable': + description = "A remote code execution vulnerability exists in Remote Desktop Services formerly known as Terminal Services when an unauthenticated attacker connects to the target system using RDP and sends specially crafted requests, aka 'Remote Desktop Services Remote Code Execution Vulnerability'. " + self.createAndAddVulnToService( + host_id=host_id, + service_id=service_id, + name='Remote Desktop Services Remote Code Execution Vulnerability', + desc=description, + ref=['CVE-2019-0708'] + ) + + + for ip_address, parsed_urls in services.items(): + hostnames = list(set([parsed_url.netloc.split(':').pop() for parsed_url in parsed_urls])) + h_id = self.createAndAddHost(ip_address, hostnames=hostnames) + for parsed_url in parsed_urls: + port = parsed_url.port + if not port: + if parsed_url.scheme == 'http': + port = 80 + if parsed_url.scheme == 'https': + port = 443 + self.createAndAddServiceToHost( + host_id=h_id, + name=parsed_url.scheme, + ports=port, + protocol='tcp', + ) + + +def createPlugin(): + return RDPScanPlugin() From 8275f2ebf3aad0dc474647e9b137ca06bb5eed5d Mon Sep 17 00:00:00 2001 From: Leonardo Lazzaro Date: Tue, 28 Jul 2020 14:42:08 -0300 Subject: [PATCH 106/698] add changelog --- CHANGELOG/current/new_rdpscan_plugin.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 CHANGELOG/current/new_rdpscan_plugin.md diff --git a/CHANGELOG/current/new_rdpscan_plugin.md b/CHANGELOG/current/new_rdpscan_plugin.md new file mode 100644 index 00000000..65802044 --- /dev/null +++ b/CHANGELOG/current/new_rdpscan_plugin.md @@ -0,0 +1 @@ +* Add new rdpscan plugin From aa93f762f7e62a4c891bb110ab875227f27a8d1e Mon Sep 17 00:00:00 2001 From: Leonardo Lazzaro Date: Tue, 28 Jul 2020 14:45:22 -0300 Subject: [PATCH 107/698] delete code from other plugin --- faraday_plugins/plugins/repo/rdpscan/plugin.py | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/faraday_plugins/plugins/repo/rdpscan/plugin.py b/faraday_plugins/plugins/repo/rdpscan/plugin.py index 0762929c..183b323a 100644 --- a/faraday_plugins/plugins/repo/rdpscan/plugin.py +++ b/faraday_plugins/plugins/repo/rdpscan/plugin.py @@ -43,23 +43,5 @@ def parseOutputString(self, output): ) - for ip_address, parsed_urls in services.items(): - hostnames = list(set([parsed_url.netloc.split(':').pop() for parsed_url in parsed_urls])) - h_id = self.createAndAddHost(ip_address, hostnames=hostnames) - for parsed_url in parsed_urls: - port = parsed_url.port - if not port: - if parsed_url.scheme == 'http': - port = 80 - if parsed_url.scheme == 'https': - port = 443 - self.createAndAddServiceToHost( - host_id=h_id, - name=parsed_url.scheme, - ports=port, - protocol='tcp', - ) - - def createPlugin(): return RDPScanPlugin() From 8393fbc5574967b8edb1c701e0443746c3853f47 Mon Sep 17 00:00:00 2001 From: Blas Date: Fri, 31 Jul 2020 20:54:05 -0300 Subject: [PATCH 108/698] FIX policyviolations not list --- faraday_plugins/plugins/repo/ssl_labs/plugin.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/faraday_plugins/plugins/repo/ssl_labs/plugin.py b/faraday_plugins/plugins/repo/ssl_labs/plugin.py index 33be2353..f3b9112a 100644 --- a/faraday_plugins/plugins/repo/ssl_labs/plugin.py +++ b/faraday_plugins/plugins/repo/ssl_labs/plugin.py @@ -107,11 +107,17 @@ def parseOutputString(self, output): vulns = parser.get_vulns(parser.json_data['endpoints'][0]['details']) for vuln in vulns: + policy_info = f"Long max age: {vuln['policy'][0]['LONG_MAX_AGE']}" \ + f"Status: {vuln['policy'][0]['status']} | {vuln['policy'][1]['status']} | {vuln['policy'][2]['status']} " \ + f"directives: {vuln['policy'][0]['directives']} | {vuln['policy'][1]['directives']} | {vuln['policy'][2]['directives']}" \ + f"pins: {vuln['policy'][1]['directives']} | {vuln['policy'][2]['directives']} " \ + f"matchedPins: {vuln['policy'][1]['matchedPins']} | {vuln['policy'][2]['matchedPins']} " + self.createAndAddVulnToService(host_id, service_id=service_id, name=vuln['name'], desc=vuln['desc'], - policyviolations=vuln['policy'], + policyviolations=[policy_info], data=vuln['data']) From 696d3b1808a42069fb36f68aedba47099e008981 Mon Sep 17 00:00:00 2001 From: Blas Date: Sat, 1 Aug 2020 14:47:42 -0300 Subject: [PATCH 109/698] fix types --- faraday_plugins/plugins/repo/appscan/plugin.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/faraday_plugins/plugins/repo/appscan/plugin.py b/faraday_plugins/plugins/repo/appscan/plugin.py index 5384bcca..9447b433 100644 --- a/faraday_plugins/plugins/repo/appscan/plugin.py +++ b/faraday_plugins/plugins/repo/appscan/plugin.py @@ -250,19 +250,17 @@ def parseOutputString(self, output): url_name = url['url'] for info_rs_rq in res_req: - print(info_rs_rq) request = info_rs_rq['request'] response = info_rs_rq['response'] - + resolution = f'Text: {vulnserv["fixRecommendations"]["text"]}. Link: {vulnserv["fixRecommendations"]["link"]}' self.createAndAddVulnWebToService(host_id=host_id, service_id=service_id, name=vulnserv['name'], desc=vulnserv['description'], severity=info_severity, - path=url_name, website=host_data['host'], ref=ref, - resolution=vulnserv['fixRecommendations'], request=request, + path=url_name, website=host_data['host'], ref=[ref], + resolution=resolution, request=request, response=response, method=request, data=f'xfix: {vulnserv["xfid"]} cme: {vulnserv["cwe"]}') elif operating_system == 'SAST': - for info_loc_source in res_req: location = info_loc_source['location'] source_file = info_loc_source['source_file'] @@ -285,9 +283,14 @@ def parseOutputString(self, output): for sev in item: if sev['id'] == vulnserv['id']: info_severity = sev['severity_id'] + if vulnserv['description'] is None: + desc = "" + else: + desc = vulnserv['description'] - self.createAndAddVulnToHost(host_id=host_id, name=vulnserv['name'], desc=vulnserv['description'], - severity=info_severity, resolution=vulnserv['fixRecommendations'], + resolution = f"Text:{vulnserv['fixRecommendations']['text']}. Link: {vulnserv['fixRecommendations']['link']}." + self.createAndAddVulnToHost(host_id=host_id, name=vulnserv['name'], desc=desc, + severity=info_severity, resolution=resolution, data=f'xfix: {vulnserv["xfid"]} cme: {vulnserv["cwe"]}', run_date=None) From 5cc76156c70af55da8d2af07a69392956d64f739 Mon Sep 17 00:00:00 2001 From: Blas Date: Sat, 1 Aug 2020 15:12:01 -0300 Subject: [PATCH 110/698] fix severity vuln --- CHANGELOG/current/fix_nessus.md | 1 + faraday_plugins/plugins/repo/nessus/plugin.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 CHANGELOG/current/fix_nessus.md diff --git a/CHANGELOG/current/fix_nessus.md b/CHANGELOG/current/fix_nessus.md new file mode 100644 index 00000000..c8cba9d5 --- /dev/null +++ b/CHANGELOG/current/fix_nessus.md @@ -0,0 +1 @@ +Fix Nessus mod severity HIGH for INFO \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/nessus/plugin.py b/faraday_plugins/plugins/repo/nessus/plugin.py index 07b8fce8..58bfda98 100644 --- a/faraday_plugins/plugins/repo/nessus/plugin.py +++ b/faraday_plugins/plugins/repo/nessus/plugin.py @@ -276,7 +276,8 @@ def parseOutputString(self, output): ref.append(policy_check_data) if 'FAILED' in policy_item: - risk_factor = 'high' + # risk_factor = 'high' + risk_factor = 'info' policyviolations.append(policy_item) vulnerability_name = f'{serv[6]} {vulnerability_name} {policy_item}' From 653dda1f29b71de353f72a712971463221363dbb Mon Sep 17 00:00:00 2001 From: Blas Date: Mon, 3 Aug 2020 14:29:26 -0300 Subject: [PATCH 111/698] MOD secerity High to Low and ADD tags info --- faraday_plugins/plugins/repo/nessus/plugin.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/faraday_plugins/plugins/repo/nessus/plugin.py b/faraday_plugins/plugins/repo/nessus/plugin.py index 58bfda98..3b5e886b 100644 --- a/faraday_plugins/plugins/repo/nessus/plugin.py +++ b/faraday_plugins/plugins/repo/nessus/plugin.py @@ -268,6 +268,7 @@ def parseOutputString(self, output): if serv[6] == 'Policy Compliance': # This condition was added to support CIS Benchmark in policy violation field. risk_factor = 'info' + tags_info = "Passed Checks" bis_benchmark_data = serv[7].split('\n') policy_item = bis_benchmark_data[0] @@ -276,8 +277,8 @@ def parseOutputString(self, output): ref.append(policy_check_data) if 'FAILED' in policy_item: - # risk_factor = 'high' - risk_factor = 'info' + risk_factor = 'low' + tags_info = "Failed checks" policyviolations.append(policy_item) vulnerability_name = f'{serv[6]} {vulnerability_name} {policy_item}' @@ -291,7 +292,8 @@ def parseOutputString(self, output): ref=ref, policyviolations=policyviolations, external_id=external_id, - run_date=run_date) + run_date=run_date, + tags=tags_info) else: data = serv[9] if not data: From fd31953643b67e20ced884bfcdaf7172c17ae546 Mon Sep 17 00:00:00 2001 From: Blas Date: Mon, 3 Aug 2020 14:57:38 -0300 Subject: [PATCH 112/698] FIX tags in vuln --- CHANGELOG/current/fix_nessus.md | 2 +- faraday_plugins/plugins/repo/nessus/plugin.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG/current/fix_nessus.md b/CHANGELOG/current/fix_nessus.md index c8cba9d5..50c470c6 100644 --- a/CHANGELOG/current/fix_nessus.md +++ b/CHANGELOG/current/fix_nessus.md @@ -1 +1 @@ -Fix Nessus mod severity HIGH for INFO \ No newline at end of file +Fix Nessus mod severity HIGH for Low \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/nessus/plugin.py b/faraday_plugins/plugins/repo/nessus/plugin.py index 3b5e886b..d7b8edbb 100644 --- a/faraday_plugins/plugins/repo/nessus/plugin.py +++ b/faraday_plugins/plugins/repo/nessus/plugin.py @@ -265,6 +265,7 @@ def parseOutputString(self, output): ref = [] policyviolations = [] + tags_info = None if serv[6] == 'Policy Compliance': # This condition was added to support CIS Benchmark in policy violation field. risk_factor = 'info' @@ -282,7 +283,6 @@ def parseOutputString(self, output): policyviolations.append(policy_item) vulnerability_name = f'{serv[6]} {vulnerability_name} {policy_item}' - self.createAndAddVulnToHost(host_id, vulnerability_name, desc=desc, From 83100b29322a47b4b88ccd6bf6668e500c03846c Mon Sep 17 00:00:00 2001 From: Blas Date: Wed, 5 Aug 2020 16:09:27 -0300 Subject: [PATCH 113/698] fix in generete vuln --- .../plugins/repo/appscan/plugin.py | 107 +++++++++++++----- 1 file changed, 76 insertions(+), 31 deletions(-) diff --git a/faraday_plugins/plugins/repo/appscan/plugin.py b/faraday_plugins/plugins/repo/appscan/plugin.py index 9447b433..c441abab 100644 --- a/faraday_plugins/plugins/repo/appscan/plugin.py +++ b/faraday_plugins/plugins/repo/appscan/plugin.py @@ -17,7 +17,7 @@ __status__ = "Development" -class HclAsocParser: +class AppScanParser: def __init__(self, xml_output): self.tree = self.parse_xml(xml_output) if self.tree: @@ -33,7 +33,8 @@ def __init__(self, xml_output): self.name_scan = self.get_issue_data(self.tree.find('advisory-group')) self.host_data = None if self.tree.find('scan-configuration/scanned-hosts/item') is None else \ self.get_scan_conf_data(self.tree.find('scan-configuration/scanned-hosts/item')) - self.req_res = self.get_req_res(self.tree.find("issue-group")) + self.issue_group = self.get_info_issue_group(self.tree.find("issue-group")) + self.fix_recomendation = self.get_fix_info(self.tree.find('fix-recommendation-group')) else: self.tree = None @@ -46,7 +47,21 @@ def parse_xml(self, xml_output): return None return tree - def get_req_res(sef,tree): + def get_fix_info(self, tree): + list_fix = [] + for item in tree: + text_info_join = [] + if item.find("general/fixRecommendation"): + for text_tag in tree.findall('text'): + text_info_join += text_tag.text + info_fix = { + "id": item.attrib.get('id', None), + "text": text_info_join + } + list_fix.append(info_fix) + return list_fix + + def get_info_issue_group(sef,tree): data_res_req = [] for item in tree: if item.find("variant-group/item/issue-information"): @@ -60,7 +75,15 @@ def get_req_res(sef,tree): "response": resp, "location": "Not Location" if item.find("location") is None else item.find("location").text, "source_file": "0.0.0.0" if item.find("source-file") is None else item.find("source-file").text, - "line": 0 if item.find("line") is None else item.find("line").text + "line": 0 if item.find("line") is None else item.find("line").text, + "id_item": item.attrib.get('id', 'Not id item'), + "severity": 0 if item.find("severity-id") is None else item.find("severity-id").text, + "cvss": "No cvss" if item.find("cvss-score") is None else item.find("cvss-score").text, + "cwe": "No cwe" if item.find("cwe") is None else item.find("cwe").text, + "remediation": "No remedation" if item.find("remediation/ref") is None else item.find( + "remediation/ref").text, + "advisory": "No advisory" if item.find("advisory/ref") is None else item.find("advisory/ref").text, + "url_id": "No url id" if item.find("url/ref") is None else item.find("url/ref").text } data_res_req.append(json_res_req) @@ -72,7 +95,8 @@ def get_layout_info(self, tree): "date": "Not info" if tree.find("report-date") is None else tree.find("report-date").text, "details": f'Departamento: {"Not info" if tree.find("department") is None else tree.find("department").text}' f'Compania: {"Not info" if tree.find("company") is None else tree.find("company").text}' - f'Titulo Reporte: {"Not info" if tree.find("title") is None else tree.find("title").text}' + f'Titulo Reporte: {"Not info" if tree.find("title") is None else tree.find("title").text}', + "nro_issues": None if tree.find("total-issues-in-application") is None else tree.find("total-issues-in-application").text, } return info_layout @@ -190,6 +214,7 @@ def get_urls_info(self, tree): list_url = [] for url in tree: url_info = { + "id_item": url.attrib.get('id', 'Not id item'), "id": "Not info" if url.find("issue-type") is None else url.find("issue-type").text, "url": "Not info" if url.find("name") is None else url.find("name").text, } @@ -208,7 +233,7 @@ def get_scan_conf_data(self, host_info): return info_host -class HclAsocPlugin(PluginXMLFormat): +class AppScanPlugin(PluginXMLFormat): def __init__(self): super().__init__() self.identifier_tag = "xml-report" @@ -223,45 +248,65 @@ def __init__(self): self.address = None def parseOutputString(self, output): - parser = HclAsocParser(output) + parser = AppScanParser(output) layout = parser.layout operating_system = parser.operating_system host_data = parser.host_data urls = parser.urls item = parser.item name_scan = parser.name_scan - res_req = parser.req_res + issues = parser.issue_group + recomendation = parser.fix_recomendation if operating_system == 'DAST': host_id = self.createAndAddHost(resolve_hostname(host_data['host']), os=host_data['os'], hostnames=[host_data['host']], description=layout['details']) service_id = self.createAndAddServiceToHost(host_id, host_data['host'], ports=host_data['port'], - protocol="tcp?HTTP", description=f'{host_data["webserver"]} - {host_data["appserver"]}') + protocol="tcp?HTTP", + description=f'{host_data["webserver"]} - {host_data["appserver"]}') + if layout['nro_issues'] is None: + nro_check = True - for vulnserv in name_scan: - for sev in item: - if sev['id'] == vulnserv['id']: - info_severity = sev['severity_id'] - ref = f'cwe: {sev["cwe"]} xfid: {sev["xfid"]} advisory: {sev["advisory"]}' - - for url in urls: - if url['id'] == vulnserv['id']: - url_name = url['url'] - - for info_rs_rq in res_req: - request = info_rs_rq['request'] - response = info_rs_rq['response'] - resolution = f'Text: {vulnserv["fixRecommendations"]["text"]}. Link: {vulnserv["fixRecommendations"]["link"]}' - self.createAndAddVulnWebToService(host_id=host_id, service_id=service_id, name=vulnserv['name'], - desc=vulnserv['description'], severity=info_severity, - path=url_name, website=host_data['host'], ref=[ref], - resolution=resolution, request=request, - response=response, method=request, - data=f'xfix: {vulnserv["xfid"]} cme: {vulnserv["cwe"]}') + else: + nro_check = False + check_issues = [] + + for issue in issues: + id = f"{issue['url_id']}{issue['advisory']}" + if id in check_issues and nro_check is True: + check_issues.append(id) + else: + check_issues.append(id) + for info in name_scan: + if info['id'] == issue['advisory']: + vuln_name = info['name'] + vuln_desc = info['description'] + resolution = f'Text: {info["fixRecommendations"]["text"]}. ' \ + f'Link: {info["fixRecommendations"]["link"]}' + vuln_data = f'xfix: {info["xfid"]} cme: {info["cwe"]}' + + for url in urls: + if url['id'] == issue['advisory']: + url_name = url['url'] + elif url['id_item'] == issue['id_item']: + url_name = url['url'] + else: + url_name = None + + for rec in recomendation: + if rec['id'] == issue['advisory']: + vuln_data = f'{vuln_data}, {rec["text"]} ' + + ref = f'cwe: {issue["cwe"]} cvss: {issue["cvss"]} remediation: {issue["remediation"]}' + self.createAndAddVulnWebToService(host_id=host_id, service_id=service_id, name=vuln_name, + desc=vuln_desc, severity=issue['severity'], ref=[ref], + website=host_data['host'], request=issue['request'], + response=issue['response'], method=issue['request'], + resolution=resolution, data=vuln_data, path=url_name) elif operating_system == 'SAST': - for info_loc_source in res_req: + for info_loc_source in issues: location = info_loc_source['location'] source_file = info_loc_source['source_file'] line = info_loc_source["line"] @@ -295,4 +340,4 @@ def parseOutputString(self, output): def createPlugin(): - return HclAsocPlugin() + return AppScanPlugin() From cc7cb1a215f3aa83edb5f2bdd30a6218e864c8f4 Mon Sep 17 00:00:00 2001 From: Leonardo Lazzaro Date: Fri, 7 Aug 2020 20:33:30 -0300 Subject: [PATCH 114/698] fix command detection --- faraday_plugins/plugins/repo/rdpscan/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faraday_plugins/plugins/repo/rdpscan/plugin.py b/faraday_plugins/plugins/repo/rdpscan/plugin.py index 183b323a..473ead5a 100644 --- a/faraday_plugins/plugins/repo/rdpscan/plugin.py +++ b/faraday_plugins/plugins/repo/rdpscan/plugin.py @@ -12,7 +12,7 @@ def __init__(self): self.identifier_tag = "rdpscan" self.id = "rdpscan" self.name = "rdpscan" - self._command_regex = re.compile(r'rdpscan') + self._command_regex = re.compile(r'^(sudo rdpscan|rdpscan|\.\/rdpscan)\s+.*?') def parseOutputString(self, output): services = defaultdict(set) From 4e70a3dc358f2b543544d17811625bcf115bf03f Mon Sep 17 00:00:00 2001 From: Eric Horvat Date: Mon, 10 Aug 2020 21:12:46 +0000 Subject: [PATCH 115/698] CI with report-collection branches --- .gitlab-ci.yml | 80 ++++++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c3c61a73..58f0594c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -14,6 +14,25 @@ workflow: when: never - when: always +.install_faraday_venv: &install_faraday_venv +- pip3 install virtualenv +- virtualenv -p python3 faraday_venv +- source faraday_venv/bin/activate +- pip3 install pytest pytest-xdist pytest-cov +- git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/faradaysec/faraday.git +- cd faraday +- pip3 install $PIP_FLAGS . +- pip uninstall faraday-plugins -y # we need to install fardaysec for marshmallow schemas, we remove plugins from pypi +- cd .. + +.clone_reports: &clone_reports +- git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/faradaysec/support/report-collection.git +- cd report-collection +- (git branch -a | grep $CI_COMMIT_BRANCH) && export REPORT_REF=$CI_COMMIT_BRANCH || export REPORT_REF=master +- git checkout $REPORT_REF +- cd .. + + flake8: image: python:3 stage: pre_testing @@ -27,50 +46,29 @@ flake8: after_script: - wc -l files.processed -tests: - image: python:3.7 - stage: testing - coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/' - before_script: - - pip3 install virtualenv - - virtualenv -p python3 faraday_venv - - source faraday_venv/bin/activate - - pip3 install pytest pytest-xdist pytest-cov Flask-Restless==0.17.0 - - git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/faradaysec/faraday.git - - git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/faradaysec/support/report-collection.git - - cd faraday - - python3 setup.py install - - pip uninstall faraday-plugins -y # we need to install fardaysec for marshmallow schemas, we remove plugins from pypi - - cd .. - script: - - source faraday_venv/bin/activate - - python3 setup.py install - - pytest tests --capture=sys -v --cov=faraday_plugins --color=yes --disable-warnings +.test_base: + stage: testing + coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/' + script: + - *clone_reports + - *install_faraday_venv + - pip3 install $PIP_FLAGS . + - pytest tests --capture=sys -v --cov=faraday_plugins --color=yes --disable-warnings $PYTEST_FLAGS +tests: + extends: .test_base + image: python:3 test_performance: - image: python:3.7 - stage: post_testing - coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/' - allow_failure: true - before_script: - - pip3 install virtualenv - - virtualenv -p python3 faraday_venv - - source faraday_venv/bin/activate - - pip3 install pytest pytest-xdist pytest-cov - - git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/faradaysec/faraday.git - - git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/faradaysec/support/report-collection.git - - cd faraday - - python3 setup.py install - - pip uninstall faraday-plugins -y # we need to install fardaysec for marshmallow schemas, we remove plugins from pypi - - cd .. - script: - - source faraday_venv/bin/activate - - python3 setup.py install - - pytest tests --capture=sys -v --cov=faraday_plugins --color=yes --disable-warnings --performance - rules: - - if: '$CI_COMMIT_BRANCH == "develop"' - when: on_success + extends: .test_base + image: python:3 + stage: post_testing + allow_failure: true + variables: + PYTEST_FLAGS: --performance + rules: + - if: '$CI_COMMIT_BRANCH == "dev"' + when: on_success publish_pypi: image: python:3 From 2025eb8daf3a74a314c2c07c5046b45572673f16 Mon Sep 17 00:00:00 2001 From: Blas Date: Wed, 12 Aug 2020 18:34:22 -0300 Subject: [PATCH 116/698] update report sast --- .../plugins/repo/appscan/plugin.py | 61 ++++++++++++++----- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/faraday_plugins/plugins/repo/appscan/plugin.py b/faraday_plugins/plugins/repo/appscan/plugin.py index c441abab..363bd79d 100644 --- a/faraday_plugins/plugins/repo/appscan/plugin.py +++ b/faraday_plugins/plugins/repo/appscan/plugin.py @@ -83,7 +83,8 @@ def get_info_issue_group(sef,tree): "remediation": "No remedation" if item.find("remediation/ref") is None else item.find( "remediation/ref").text, "advisory": "No advisory" if item.find("advisory/ref") is None else item.find("advisory/ref").text, - "url_id": "No url id" if item.find("url/ref") is None else item.find("url/ref").text + "url_id": "No url id" if item.find("url/ref") is None else item.find("url/ref").text, + "id_adv": "Not info" if item.find("issue-type/ref") is None else item.find("issue-type/ref").text } data_res_req.append(json_res_req) @@ -114,7 +115,7 @@ def get_issue_type(self, tree): "severity": item.attrib.get('severity', None), "cwe": "Not info" if item.find("cme") is None else item.find("cwe").text, "xfid": "Not info" if item.find("xfid") is None else item.find("xfid").text, - "advisory": "Not info" if item.find("advisory/ref") is None else item.find("advisory/ref").text, + "advisory": "Not info" if item.find("advisory/ref") is None else item.find("advisory/ref").text } list_item.append(item_info) @@ -148,6 +149,11 @@ def get_issue_data(self, tree): }, "testTechnicalDescription": "Not info" if adivisory.find("testTechnicalDescription") is None else self.get_parser(adivisory.find("testTechnicalDescription")), + "testTechnicalDescriptionMixed": "Not info" if adivisory.find("testTechnicalDescriptionMixed") is None else + self.get_parser(adivisory.find("testTechnicalDescriptionMixed")), + + "testDescriptionMixed": "Not info" if adivisory.find("testDescriptionMixed") is None else + self.get_parser(adivisory.find("testDescriptionMixed")), "causes": "Not info" if adivisory.find("causes/cause") is None else adivisory.find("causes/cause").text, "securityRisks": "Not info" if adivisory.find("securityRisks/securityRisk") is None else @@ -182,6 +188,28 @@ def get_parser(self, tree): "code": code_join } + elif tree.tag == 'testDescriptionMixed': + + for text_info in tree.findall('p'): + text_join += text_info.text + + for code_info in tree.findall('li'): + text_join += code_info.text + + tech_data = { + "text": text_join, + "items": code_join + } + + elif tree.tag == 'testTechnicalDescriptionMixed': + + for text_info in tree.findall('p'): + text_join += text_info.text + + tech_data = { + "text": text_join, + } + elif tree.tag == 'references': for text_info in tree.findall('text'): text_join += "no info " if text_info.text is None else text_info.text @@ -307,21 +335,24 @@ def parseOutputString(self, output): elif operating_system == 'SAST': for info_loc_source in issues: - location = info_loc_source['location'] source_file = info_loc_source['source_file'] - line = info_loc_source["line"] host_id = self.createAndAddHost(source_file, os=operating_system) - service_id = self.createAndAddServiceToHost(host_id, location, ports=line) - for vulnserv in name_scan: - for sev in item: - if sev['id'] == vulnserv['id']: - info_severity = sev['severity_id'] - - self.createAndAddVulnToService(host_id=host_id, service_id=service_id, name=vulnserv['name'], - desc=vulnserv['description'], severity=info_severity, - resolution=vulnserv['fixRecommendations'], run_date=None, - data=f'xfix: {vulnserv["xfid"]} cme: {vulnserv["cwe"]}') - + ref = f'{info_loc_source["location"]} - {info_loc_source["line"]}' + for vuln_data in name_scan: + if vuln_data['id'] == info_loc_source["id_adv"]: + desc = f'desc: {vuln_data["description"]} DescMix {vuln_data["testDescriptionMixed"]}' + resolution = f'Fix Recomendarion {vuln_data["fixRecommendations"]}' \ + f' - TestTecnical {vuln_data["testTechnicalDescriptionMixed"]}' + + self.createAndAddVulnToHost(host_id=host_id, + name=vuln_data['name'], + desc=desc, + ref=[ref], + severity=info_loc_source['severity'], + resolution=resolution, + data=f'xfix: {vuln_data["xfid"]} cme: {vuln_data["cwe"]}', + run_date=None, + ) else: host_id = self.createAndAddHost(layout['name'], os=operating_system) for vulnserv in name_scan: From 2f93c83b714c58b606295859e115b3277c5cfec4 Mon Sep 17 00:00:00 2001 From: Blas Date: Wed, 12 Aug 2020 18:54:27 -0300 Subject: [PATCH 117/698] cobalt master --- faraday_plugins/plugins/repo/cobalt/plugin.py | 1 - 1 file changed, 1 deletion(-) diff --git a/faraday_plugins/plugins/repo/cobalt/plugin.py b/faraday_plugins/plugins/repo/cobalt/plugin.py index 08d28710..e2c089fc 100644 --- a/faraday_plugins/plugins/repo/cobalt/plugin.py +++ b/faraday_plugins/plugins/repo/cobalt/plugin.py @@ -104,4 +104,3 @@ def parseOutputString(self, output): def createPlugin(): return CobaltPlugin() - From 3f5665dc43c23ee9ae2f5aa193539a70374b85f9 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Thu, 13 Aug 2020 20:28:03 -0300 Subject: [PATCH 118/698] add tenableio support --- CHANGELOG/current/add_tenableio_support.md | 1 + faraday_plugins/plugins/repo/nessus/plugin.py | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 CHANGELOG/current/add_tenableio_support.md diff --git a/CHANGELOG/current/add_tenableio_support.md b/CHANGELOG/current/add_tenableio_support.md new file mode 100644 index 00000000..188c5260 --- /dev/null +++ b/CHANGELOG/current/add_tenableio_support.md @@ -0,0 +1 @@ +Add support for tenable io \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/nessus/plugin.py b/faraday_plugins/plugins/repo/nessus/plugin.py index d7b8edbb..af2b6cd3 100644 --- a/faraday_plugins/plugins/repo/nessus/plugin.py +++ b/faraday_plugins/plugins/repo/nessus/plugin.py @@ -45,7 +45,10 @@ def __init__(self, output): def getPolicy(self, tree): policy_tree = tree.find('Policy') - return Policy(policy_tree) + if policy_tree: + return Policy(policy_tree) + else: + return None def getReport(self, tree): report_tree = tree.find('Report') @@ -191,7 +194,8 @@ def parseOutputString(self, output): """ try: parser = NessusParser(output) - except: + except Exception as e: + print(e) return None if parser.report.report_json is not None: From 630618d4235824339ffa5ee56e9fcd466453acc4 Mon Sep 17 00:00:00 2001 From: Blas Date: Mon, 17 Aug 2020 15:42:04 -0300 Subject: [PATCH 119/698] add ncrack plugin --- CHANGELOG/current/add_ncrack.md | 1 + .../plugins/repo/ncrack/__init__.py | 0 faraday_plugins/plugins/repo/ncrack/plugin.py | 125 ++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 CHANGELOG/current/add_ncrack.md create mode 100644 faraday_plugins/plugins/repo/ncrack/__init__.py create mode 100644 faraday_plugins/plugins/repo/ncrack/plugin.py diff --git a/CHANGELOG/current/add_ncrack.md b/CHANGELOG/current/add_ncrack.md new file mode 100644 index 00000000..d6829fb2 --- /dev/null +++ b/CHANGELOG/current/add_ncrack.md @@ -0,0 +1 @@ +ADD plugin ncrack \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/ncrack/__init__.py b/faraday_plugins/plugins/repo/ncrack/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/faraday_plugins/plugins/repo/ncrack/plugin.py b/faraday_plugins/plugins/repo/ncrack/plugin.py new file mode 100644 index 00000000..aaa7542a --- /dev/null +++ b/faraday_plugins/plugins/repo/ncrack/plugin.py @@ -0,0 +1,125 @@ +""" +Faraday Penetration Test IDE +Copyright (C) 2020 Infobyte LLC (http://www.infobytesec.com/) +See the file 'doc/LICENSE' for the license information + +""" + +from faraday_plugins.plugins.plugin import PluginXMLFormat +try: + import xml.etree.cElementTree as ET +except ImportError: + import xml.etree.ElementTree as ET + + +__author__ = "Blas Moyano" +__copyright__ = "Copyright (c) 2020, Infobyte LLC" +__credits__ = ["Blas Moyano"] +__license__ = "" +__version__ = "1.0" +__maintainer__ = "Blas Moyano" +__status__ = "Development" + + +class NcrackParser: + def __init__(self, xml_output): + self.tree = self.parse_xml(xml_output) + if self.tree: + scanner = self.tree.attrib.get('scanner', None) + args = self.tree.attrib.get('args', None) + start = self.tree.attrib.get('start', None) + start_str = self.tree.attrib.get('start_str', None) + service_data = None if self.tree.find('service') is None else \ + self.get_service(self.tree.findall('service')) + self.ncrack_info = { + "scanner_name": scanner, + "args": args, + "date": start, + "date_str": start_str, + "info_service": service_data + } + else: + self.tree = None + + def parse_xml(self, xml_output): + try: + tree = ET.fromstring(xml_output) + except SyntaxError as err: + print('SyntaxError In xml: %s. %s' % (err, xml_output)) + return None + return tree + + def get_service(self, tree): + list_service_info = [] + for service in tree: + address = service.find('address') + port = service.find('port') + credential = service.find('credentials') + if address is not None: + addr = address.attrib.get('addr', None) + addr_type = address.attrib.get('addrtype', None) + else: + addr = None + addr_type = None + + if port is not None: + protocol = port.attrib.get('protocol', None) + port_number = port.attrib.get('portid', None) + port_name = port.attrib.get('name', None) + else: + protocol = None + port_number = None + port_name = None + + if credential is not None: + user = credential.attrib.get('username', None) + passw = credential.attrib.get('password', None) + else: + user = None + passw = None + + service_info = { + "addr": addr, + "addr_type": addr_type, + "protocol": protocol, + "port_number": port_number, + "port_name": port_name, + "user": user, + "passw": passw + } + list_service_info.append(service_info) + return list_service_info + + +class NcrackPlugin(PluginXMLFormat): + def __init__(self): + super().__init__() + self.identifier_tag = "ncrackrun" + self.id = 'ncrack' + self.name = 'ncrack XML Plugin' + self.plugin_version = '0.0.1' + self.version = '1.0.0' + self.framework_version = '1.0.0' + + def parseOutputString(self, output): + parser = NcrackParser(output) + data = parser.ncrack_info + + for service_vuln in data['info_service']: + host_id = self.createAndAddHost(service_vuln['addr'], + description=f"{data['scanner_name']} - args: {data['args']}") + + service_id = self.createAndAddServiceToHost(host_id, + service_vuln['addr'], + ports=service_vuln['port_number'], + protocol=service_vuln['protocol'], + description=service_vuln['port_name']) + if service_vuln['user'] is not None or service_vuln['passw'] is not None: + self.createAndAddCredToService(host_id, + service_id, + username=service_vuln['user'], + password=service_vuln['passw']) + + +def createPlugin(): + return NcrackPlugin() From 24d7c12086faf2fb45b06259b29ba72f6fe31a5e Mon Sep 17 00:00:00 2001 From: Blas Date: Wed, 19 Aug 2020 22:40:13 -0300 Subject: [PATCH 120/698] FIX whois parser data --- CHANGELOG/current/fix_whois.md | 1 + faraday_plugins/plugins/repo/whois/plugin.py | 27 ++++++++++++++------ 2 files changed, 20 insertions(+), 8 deletions(-) create mode 100644 CHANGELOG/current/fix_whois.md diff --git a/CHANGELOG/current/fix_whois.md b/CHANGELOG/current/fix_whois.md new file mode 100644 index 00000000..2ef301db --- /dev/null +++ b/CHANGELOG/current/fix_whois.md @@ -0,0 +1 @@ +FIX whois. command whois IP not parse data \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/whois/plugin.py b/faraday_plugins/plugins/repo/whois/plugin.py index 33191de7..7d8b2316 100644 --- a/faraday_plugins/plugins/repo/whois/plugin.py +++ b/faraday_plugins/plugins/repo/whois/plugin.py @@ -68,19 +68,30 @@ def __init__(self): "--version": "output version information and exit", } - + def processCommandString(self, username, current_path, command_string): + self.command_string = command_string + super(CmdWhoisPlugin, self).processCommandString(username, current_path, command_string) def parseOutputString(self, output): matches = re.findall("Name Server:\s*(.*)\s*", output) - for m in matches: - m = m.strip() - ip = resolve_hostname(m) - h_id = self.createAndAddHost(ip, "os unknown", hostnames=[m]) + if not matches: + ip = re.findall(r'[0-9]+(?:\.[0-9]+){3}', self.command_string) + matches_descr = re.findall("descr:\s*(.*)\s*", output) + for md in matches_descr: + desc = md.strip() + h_id = self.createAndAddHost(ip[0], "os unknown", description=desc) + else: + for m in matches: + m = m.strip() + ip = resolve_hostname(m) + h_id = self.createAndAddHost(ip, "os unknown", hostnames=[m]) + matches_domain = re.findall("Domain Name:\s*(.*)\s*", output) + for md in matches_domain: + md = md.strip() + ip = resolve_hostname(md) + h_id = self.createAndAddHost(ip, "os unknown", hostnames=[md]) return True - def createPlugin(): return CmdWhoisPlugin() - -# I'm Py3 From cdcd4c0d3b26761331894b31ab96c1207e64fec0 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Fri, 21 Aug 2020 15:10:11 -0300 Subject: [PATCH 121/698] add default plugin_version --- CHANGELOG/current/add_default_plugin_version.md | 1 + faraday_plugins/plugins/plugin.py | 1 + 2 files changed, 2 insertions(+) create mode 100644 CHANGELOG/current/add_default_plugin_version.md diff --git a/CHANGELOG/current/add_default_plugin_version.md b/CHANGELOG/current/add_default_plugin_version.md new file mode 100644 index 00000000..acf11059 --- /dev/null +++ b/CHANGELOG/current/add_default_plugin_version.md @@ -0,0 +1 @@ +add a default value to plugin_version \ No newline at end of file diff --git a/faraday_plugins/plugins/plugin.py b/faraday_plugins/plugins/plugin.py index cdf23b84..d4adb960 100644 --- a/faraday_plugins/plugins/plugin.py +++ b/faraday_plugins/plugins/plugin.py @@ -57,6 +57,7 @@ def __init__(self): self.start_date = datetime.now() self.logger = logger.getChild(self.__class__.__name__) self.open_options = {"mode": "r", "encoding": "utf-8"} + self.plugin_version = "0.0" self.vulns_data = {"hosts": [], "command": {"tool": "", "command": "", "params": "", From 1c77a94569d2b992bb891b0e9e44d76ece72fed8 Mon Sep 17 00:00:00 2001 From: Blas Date: Sat, 22 Aug 2020 18:07:49 -0300 Subject: [PATCH 122/698] ADD plugin Whatweb --- CHANGELOG/current/add_whatweb.md | 1 + .../plugins/repo/whatweb/__init__.py | 0 .../plugins/repo/whatweb/plugin.py | 90 +++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 CHANGELOG/current/add_whatweb.md create mode 100644 faraday_plugins/plugins/repo/whatweb/__init__.py create mode 100644 faraday_plugins/plugins/repo/whatweb/plugin.py diff --git a/CHANGELOG/current/add_whatweb.md b/CHANGELOG/current/add_whatweb.md new file mode 100644 index 00000000..d6464f3d --- /dev/null +++ b/CHANGELOG/current/add_whatweb.md @@ -0,0 +1 @@ +ADD plugin WhatWeb \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/whatweb/__init__.py b/faraday_plugins/plugins/repo/whatweb/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/faraday_plugins/plugins/repo/whatweb/plugin.py b/faraday_plugins/plugins/repo/whatweb/plugin.py new file mode 100644 index 00000000..d538b3b1 --- /dev/null +++ b/faraday_plugins/plugins/repo/whatweb/plugin.py @@ -0,0 +1,90 @@ +""" +Faraday Penetration Test IDE +Copyright (C) 2020 Infobyte LLC (http://www.infobytesec.com/) +See the file 'doc/LICENSE' for the license information + +""" +import json +from faraday_plugins.plugins.plugin import PluginJsonFormat + +__author__ = "Blas Moyano" +__copyright__ = "Copyright (c) 2020, Infobyte LLC" +__credits__ = ["Blas Moyano"] +__license__ = "" +__version__ = "0.0.1" +__maintainer__ = "Blas Moyano" +__email__ = "bmoyano@infobytesec.com" +__status__ = "Development" + + +class WhatWebJsonParser: + + def __init__(self, json_output): + list_data = json.loads(json_output) + self.host_whatweb = [] + for info in list_data: + try: + server_info = info['plugins']['HTTPServer'] + except KeyError: + server_info = {} + + try: + ip_info = info['plugins']['IP'] + except KeyError: + ip_info = {} + + try: + country_info = info['plugins']['Country'] + except KeyError: + country_info = {} + + whatweb_data = { + "url": info.get('target', None), + "os": None if not server_info else server_info.get('os', None), + "os_detail": "Unknown" if not server_info else server_info.get('string', 'Unknown'), + "ip": ['0.0.0.0'] if ip_info is None else ip_info.get('string', None), + "country": "" if country_info is None else country_info.get('string', "") + } + self.host_whatweb.append(whatweb_data) + + +class WhatWebPlugin(PluginJsonFormat): + + def __init__(self): + super().__init__() + self.id = "whatweb" + self.name = "WhatWebPlugin" + self.plugin_version = "0.1" + self.version = "0.0.1" + self.json_keys = set() + + def report_belongs_to(self, **kwargs): + result = False + if super().report_belongs_to(**kwargs): + report_path = kwargs.get("report_path", "") + with open(report_path) as f: + output = f.readlines() + for line in output: + check_target = line.find('"target":') + check = line.find('"plugins":') + if check > 0 and check_target > 0: + result = True + return result + + def parseOutputString(self, output): + parser = WhatWebJsonParser(output) + for whatweb_data in parser.host_whatweb: + desc = f"{whatweb_data['os_detail']} - {whatweb_data['country']}" + if whatweb_data['os'] is None: + datail_os = "Unknown" + else: + datail_os = whatweb_data['os'][0] + + self.createAndAddHost(whatweb_data['ip'][0], + os=datail_os, + hostnames=whatweb_data['url'], + description=desc) + + +def createPlugin(): + return WhatWebPlugin() From f040aa766c405f7347a336869a54333539575820 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Tue, 25 Aug 2020 13:40:32 -0300 Subject: [PATCH 123/698] fix desc variable --- faraday_plugins/plugins/repo/whois/plugin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/faraday_plugins/plugins/repo/whois/plugin.py b/faraday_plugins/plugins/repo/whois/plugin.py index 7d8b2316..91772435 100644 --- a/faraday_plugins/plugins/repo/whois/plugin.py +++ b/faraday_plugins/plugins/repo/whois/plugin.py @@ -77,6 +77,7 @@ def parseOutputString(self, output): if not matches: ip = re.findall(r'[0-9]+(?:\.[0-9]+){3}', self.command_string) matches_descr = re.findall("descr:\s*(.*)\s*", output) + desc = "" for md in matches_descr: desc = md.strip() h_id = self.createAndAddHost(ip[0], "os unknown", description=desc) From eb90e049de75374e88525452f06eb0d53b5a5519 Mon Sep 17 00:00:00 2001 From: Leonardo Lazzaro Date: Wed, 2 Sep 2020 17:54:46 -0300 Subject: [PATCH 124/698] new plugins version --- faraday_plugins/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faraday_plugins/__init__.py b/faraday_plugins/__init__.py index 5a5df3be..19b4f1d6 100644 --- a/faraday_plugins/__init__.py +++ b/faraday_plugins/__init__.py @@ -1 +1 @@ -__version__ = '1.2.3' +__version__ = '1.3.0' From aabd1df2f22342eba02beb3ab27d4fc64000158c Mon Sep 17 00:00:00 2001 From: Leonardo Lazzaro Date: Wed, 2 Sep 2020 18:02:49 -0300 Subject: [PATCH 125/698] add changelog --- CHANGELOG/1.3.0/add_appspider.md | 1 + CHANGELOG/1.3.0/add_cli_tests.md | 1 + CHANGELOG/1.3.0/add_default_plugin_version.md | 1 + ..._output_file_to_faraday-plugins_command.md | 1 + CHANGELOG/1.3.0/add_prowler.md | 1 + CHANGELOG/1.3.0/add_ssl_labs.md | 1 + CHANGELOG/1.3.0/add_tenableio_support.md | 1 + CHANGELOG/1.3.0/delete_old_methods.md | 1 + CHANGELOG/1.3.0/fix_Arachni.md | 1 + CHANGELOG/1.3.0/fix_Openvas.md | 1 + CHANGELOG/1.3.0/fix_QualysWebapp.md | 1 + CHANGELOG/1.3.0/fix_hydra_to_resolve_ip.md | 1 + CHANGELOG/1.3.0/fix_nessus.md | 1 + CHANGELOG/1.3.0/fix_prowler.md | 1 + CHANGELOG/1.3.0/fix_xml_nmap.md | 1 + CHANGELOG/1.3.0/new_rdpscan_plugin.md | 1 + CHANGELOG/1.3.0/update_appscan.md | 1 + CHANGELOG/1.3.0/update_readme.md | 1 + CHANGELOG/1.3.0/update_zap.md | 1 + CHANGELOG/RELEASE.md | 22 +++++++++++++++++++ CHANGELOG/current/.keep | 0 RELEASE.md | 22 +++++++++++++++++++ 22 files changed, 63 insertions(+) create mode 100644 CHANGELOG/1.3.0/add_appspider.md create mode 100644 CHANGELOG/1.3.0/add_cli_tests.md create mode 100644 CHANGELOG/1.3.0/add_default_plugin_version.md create mode 100644 CHANGELOG/1.3.0/add_output_file_to_faraday-plugins_command.md create mode 100644 CHANGELOG/1.3.0/add_prowler.md create mode 100644 CHANGELOG/1.3.0/add_ssl_labs.md create mode 100644 CHANGELOG/1.3.0/add_tenableio_support.md create mode 100644 CHANGELOG/1.3.0/delete_old_methods.md create mode 100644 CHANGELOG/1.3.0/fix_Arachni.md create mode 100644 CHANGELOG/1.3.0/fix_Openvas.md create mode 100644 CHANGELOG/1.3.0/fix_QualysWebapp.md create mode 100644 CHANGELOG/1.3.0/fix_hydra_to_resolve_ip.md create mode 100644 CHANGELOG/1.3.0/fix_nessus.md create mode 100644 CHANGELOG/1.3.0/fix_prowler.md create mode 100644 CHANGELOG/1.3.0/fix_xml_nmap.md create mode 100644 CHANGELOG/1.3.0/new_rdpscan_plugin.md create mode 100644 CHANGELOG/1.3.0/update_appscan.md create mode 100644 CHANGELOG/1.3.0/update_readme.md create mode 100644 CHANGELOG/1.3.0/update_zap.md create mode 100644 CHANGELOG/RELEASE.md create mode 100644 CHANGELOG/current/.keep create mode 100644 RELEASE.md diff --git a/CHANGELOG/1.3.0/add_appspider.md b/CHANGELOG/1.3.0/add_appspider.md new file mode 100644 index 00000000..a2dabc6e --- /dev/null +++ b/CHANGELOG/1.3.0/add_appspider.md @@ -0,0 +1 @@ +ADD plugin AppSpider diff --git a/CHANGELOG/1.3.0/add_cli_tests.md b/CHANGELOG/1.3.0/add_cli_tests.md new file mode 100644 index 00000000..9d2aa581 --- /dev/null +++ b/CHANGELOG/1.3.0/add_cli_tests.md @@ -0,0 +1 @@ +Add tests to faraday-plugins cli \ No newline at end of file diff --git a/CHANGELOG/1.3.0/add_default_plugin_version.md b/CHANGELOG/1.3.0/add_default_plugin_version.md new file mode 100644 index 00000000..acf11059 --- /dev/null +++ b/CHANGELOG/1.3.0/add_default_plugin_version.md @@ -0,0 +1 @@ +add a default value to plugin_version \ No newline at end of file diff --git a/CHANGELOG/1.3.0/add_output_file_to_faraday-plugins_command.md b/CHANGELOG/1.3.0/add_output_file_to_faraday-plugins_command.md new file mode 100644 index 00000000..ee950889 --- /dev/null +++ b/CHANGELOG/1.3.0/add_output_file_to_faraday-plugins_command.md @@ -0,0 +1 @@ +Add --output-file parameter to faraday-plugins process command \ No newline at end of file diff --git a/CHANGELOG/1.3.0/add_prowler.md b/CHANGELOG/1.3.0/add_prowler.md new file mode 100644 index 00000000..b4d6355d --- /dev/null +++ b/CHANGELOG/1.3.0/add_prowler.md @@ -0,0 +1 @@ +Add plugins prowler \ No newline at end of file diff --git a/CHANGELOG/1.3.0/add_ssl_labs.md b/CHANGELOG/1.3.0/add_ssl_labs.md new file mode 100644 index 00000000..2491ffe3 --- /dev/null +++ b/CHANGELOG/1.3.0/add_ssl_labs.md @@ -0,0 +1 @@ +Add plugins ssl labs \ No newline at end of file diff --git a/CHANGELOG/1.3.0/add_tenableio_support.md b/CHANGELOG/1.3.0/add_tenableio_support.md new file mode 100644 index 00000000..188c5260 --- /dev/null +++ b/CHANGELOG/1.3.0/add_tenableio_support.md @@ -0,0 +1 @@ +Add support for tenable io \ No newline at end of file diff --git a/CHANGELOG/1.3.0/delete_old_methods.md b/CHANGELOG/1.3.0/delete_old_methods.md new file mode 100644 index 00000000..f36561a1 --- /dev/null +++ b/CHANGELOG/1.3.0/delete_old_methods.md @@ -0,0 +1 @@ +delete old deprecated methods \ No newline at end of file diff --git a/CHANGELOG/1.3.0/fix_Arachni.md b/CHANGELOG/1.3.0/fix_Arachni.md new file mode 100644 index 00000000..a4d02d23 --- /dev/null +++ b/CHANGELOG/1.3.0/fix_Arachni.md @@ -0,0 +1 @@ +Bug fix: Arachni Plugin 'NoneType' object has no attribute 'find' diff --git a/CHANGELOG/1.3.0/fix_Openvas.md b/CHANGELOG/1.3.0/fix_Openvas.md new file mode 100644 index 00000000..8b574928 --- /dev/null +++ b/CHANGELOG/1.3.0/fix_Openvas.md @@ -0,0 +1 @@ +Bug fix: Openvas Plugin - Import xml from OpenVas doesnt work diff --git a/CHANGELOG/1.3.0/fix_QualysWebapp.md b/CHANGELOG/1.3.0/fix_QualysWebapp.md new file mode 100644 index 00000000..d0887885 --- /dev/null +++ b/CHANGELOG/1.3.0/fix_QualysWebapp.md @@ -0,0 +1 @@ +Bug fix: QualysWebApp Plugin, error in get info OPERATING_SYSTEM diff --git a/CHANGELOG/1.3.0/fix_hydra_to_resolve_ip.md b/CHANGELOG/1.3.0/fix_hydra_to_resolve_ip.md new file mode 100644 index 00000000..8a5fe528 --- /dev/null +++ b/CHANGELOG/1.3.0/fix_hydra_to_resolve_ip.md @@ -0,0 +1 @@ +Fix Hydra plugin to resolve ip address \ No newline at end of file diff --git a/CHANGELOG/1.3.0/fix_nessus.md b/CHANGELOG/1.3.0/fix_nessus.md new file mode 100644 index 00000000..50c470c6 --- /dev/null +++ b/CHANGELOG/1.3.0/fix_nessus.md @@ -0,0 +1 @@ +Fix Nessus mod severity HIGH for Low \ No newline at end of file diff --git a/CHANGELOG/1.3.0/fix_prowler.md b/CHANGELOG/1.3.0/fix_prowler.md new file mode 100644 index 00000000..f28eeaea --- /dev/null +++ b/CHANGELOG/1.3.0/fix_prowler.md @@ -0,0 +1 @@ +Bug Fix: Detect plugins AWS Prowler diff --git a/CHANGELOG/1.3.0/fix_xml_nmap.md b/CHANGELOG/1.3.0/fix_xml_nmap.md new file mode 100644 index 00000000..a7c4cf8c --- /dev/null +++ b/CHANGELOG/1.3.0/fix_xml_nmap.md @@ -0,0 +1 @@ +Fix broken xml on nmap plugin diff --git a/CHANGELOG/1.3.0/new_rdpscan_plugin.md b/CHANGELOG/1.3.0/new_rdpscan_plugin.md new file mode 100644 index 00000000..8d65222c --- /dev/null +++ b/CHANGELOG/1.3.0/new_rdpscan_plugin.md @@ -0,0 +1 @@ +Add new rdpscan plugin diff --git a/CHANGELOG/1.3.0/update_appscan.md b/CHANGELOG/1.3.0/update_appscan.md new file mode 100644 index 00000000..0b95a040 --- /dev/null +++ b/CHANGELOG/1.3.0/update_appscan.md @@ -0,0 +1 @@ +UPDATE xml report to appscan \ No newline at end of file diff --git a/CHANGELOG/1.3.0/update_readme.md b/CHANGELOG/1.3.0/update_readme.md new file mode 100644 index 00000000..4cfa6d9c --- /dev/null +++ b/CHANGELOG/1.3.0/update_readme.md @@ -0,0 +1 @@ +Update Readme \ No newline at end of file diff --git a/CHANGELOG/1.3.0/update_zap.md b/CHANGELOG/1.3.0/update_zap.md new file mode 100644 index 00000000..1fd14e86 --- /dev/null +++ b/CHANGELOG/1.3.0/update_zap.md @@ -0,0 +1 @@ +Fix how ZAP genereate vulns \ No newline at end of file diff --git a/CHANGELOG/RELEASE.md b/CHANGELOG/RELEASE.md new file mode 100644 index 00000000..4b0ee7be --- /dev/null +++ b/CHANGELOG/RELEASE.md @@ -0,0 +1,22 @@ +1.3.0: +--- + * ADD plugin AppSpider + * Add tests to faraday-plugins cli + * add a default value to plugin_version + * Add --output-file parameter to faraday-plugins process command + * Add plugins prowler + * Add plugins ssl labs + * Add support for tenable io + * delete old deprecated methods + * Bug fix: Arachni Plugin 'NoneType' object has no attribute 'find' + * Bug fix: Openvas Plugin - Import xml from OpenVas doesnt work + * Bug fix: QualysWebApp Plugin, error in get info OPERATING_SYSTEM + * Fix Hydra plugin to resolve ip address + * Fix Nessus mod severity HIGH for Low + * Bug Fix: Detect plugins AWS Prowler + * Fix broken xml on nmap plugin + * Add new rdpscan plugin + * UPDATE xml report to appscan + * Update Readme + * Fix how ZAP genereate vulns + diff --git a/CHANGELOG/current/.keep b/CHANGELOG/current/.keep new file mode 100644 index 00000000..e69de29b diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 00000000..4b0ee7be --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,22 @@ +1.3.0: +--- + * ADD plugin AppSpider + * Add tests to faraday-plugins cli + * add a default value to plugin_version + * Add --output-file parameter to faraday-plugins process command + * Add plugins prowler + * Add plugins ssl labs + * Add support for tenable io + * delete old deprecated methods + * Bug fix: Arachni Plugin 'NoneType' object has no attribute 'find' + * Bug fix: Openvas Plugin - Import xml from OpenVas doesnt work + * Bug fix: QualysWebApp Plugin, error in get info OPERATING_SYSTEM + * Fix Hydra plugin to resolve ip address + * Fix Nessus mod severity HIGH for Low + * Bug Fix: Detect plugins AWS Prowler + * Fix broken xml on nmap plugin + * Add new rdpscan plugin + * UPDATE xml report to appscan + * Update Readme + * Fix how ZAP genereate vulns + From 801ddfa5a8a355c2cc50a179ddcb956c34f1a99c Mon Sep 17 00:00:00 2001 From: Blas Date: Sat, 5 Sep 2020 14:53:15 -0300 Subject: [PATCH 126/698] ADD name os --- faraday_plugins/plugins/repo/whois/plugin.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/faraday_plugins/plugins/repo/whois/plugin.py b/faraday_plugins/plugins/repo/whois/plugin.py index 91772435..e3daf963 100644 --- a/faraday_plugins/plugins/repo/whois/plugin.py +++ b/faraday_plugins/plugins/repo/whois/plugin.py @@ -77,20 +77,25 @@ def parseOutputString(self, output): if not matches: ip = re.findall(r'[0-9]+(?:\.[0-9]+){3}', self.command_string) matches_descr = re.findall("descr:\s*(.*)\s*", output) + matches_netname = re.findall("NetName:\s*(.*)\s*", output) desc = "" + os_name = "os unknown" for md in matches_descr: desc = md.strip() - h_id = self.createAndAddHost(ip[0], "os unknown", description=desc) + + for osname in matches_netname: + os_name = osname.strip() + self.createAndAddHost(ip[0], os_name, description=desc) else: for m in matches: m = m.strip() ip = resolve_hostname(m) - h_id = self.createAndAddHost(ip, "os unknown", hostnames=[m]) + self.createAndAddHost(ip, "os unknown", hostnames=[m]) matches_domain = re.findall("Domain Name:\s*(.*)\s*", output) for md in matches_domain: md = md.strip() ip = resolve_hostname(md) - h_id = self.createAndAddHost(ip, "os unknown", hostnames=[md]) + self.createAndAddHost(ip, "os unknown", hostnames=[md]) return True From ef4f7aea02c1b53942492e3d37553040b9425e8a Mon Sep 17 00:00:00 2001 From: Blas Date: Mon, 7 Sep 2020 22:49:37 -0300 Subject: [PATCH 127/698] ADD info parser. DEL string os info --- faraday_plugins/plugins/repo/whois/plugin.py | 28 +++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/faraday_plugins/plugins/repo/whois/plugin.py b/faraday_plugins/plugins/repo/whois/plugin.py index e3daf963..3db5eb34 100644 --- a/faraday_plugins/plugins/repo/whois/plugin.py +++ b/faraday_plugins/plugins/repo/whois/plugin.py @@ -77,25 +77,45 @@ def parseOutputString(self, output): if not matches: ip = re.findall(r'[0-9]+(?:\.[0-9]+){3}', self.command_string) matches_descr = re.findall("descr:\s*(.*)\s*", output) + matches_netname = re.findall("NetName:\s*(.*)\s*", output) + if not matches_netname: + matches_netname = re.findall("netname:\s*(.*)\s*", output) + matches_ref = re.findall("Ref:\s*(.*)\s*", output) desc = "" - os_name = "os unknown" + ref = [] + os_name = "unknown" + for md in matches_descr: desc = md.strip() + for mr in matches_ref: + ref.append(mr.strip()) + for osname in matches_netname: os_name = osname.strip() - self.createAndAddHost(ip[0], os_name, description=desc) + self.createAndAddHost( + ip[0], + os_name, + hostnames=[ref], + description=desc + ) else: for m in matches: m = m.strip() ip = resolve_hostname(m) - self.createAndAddHost(ip, "os unknown", hostnames=[m]) + self.createAndAddHost( + ip, + hostnames=[m] + ) matches_domain = re.findall("Domain Name:\s*(.*)\s*", output) for md in matches_domain: md = md.strip() ip = resolve_hostname(md) - self.createAndAddHost(ip, "os unknown", hostnames=[md]) + self.createAndAddHost( + ip, + hostnames=[md] + ) return True From 09751fadae52d1c8a8ed8580f8d302c13f77f22c Mon Sep 17 00:00:00 2001 From: Blas Date: Tue, 8 Sep 2020 15:17:46 -0300 Subject: [PATCH 128/698] ADD nserver match --- faraday_plugins/plugins/repo/whois/plugin.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/faraday_plugins/plugins/repo/whois/plugin.py b/faraday_plugins/plugins/repo/whois/plugin.py index 3db5eb34..ba759069 100644 --- a/faraday_plugins/plugins/repo/whois/plugin.py +++ b/faraday_plugins/plugins/repo/whois/plugin.py @@ -74,8 +74,14 @@ def processCommandString(self, username, current_path, command_string): def parseOutputString(self, output): matches = re.findall("Name Server:\s*(.*)\s*", output) + if not matches: + matches = re.findall("nserver:\s*(.*)\s*", output) + if not matches: ip = re.findall(r'[0-9]+(?:\.[0-9]+){3}', self.command_string) + if not ip: + url = self.command_string.replace('whois ', '') + ip = [resolve_hostname(url)] matches_descr = re.findall("descr:\s*(.*)\s*", output) matches_netname = re.findall("NetName:\s*(.*)\s*", output) @@ -103,7 +109,8 @@ def parseOutputString(self, output): else: for m in matches: m = m.strip() - ip = resolve_hostname(m) + url = re.findall(r'https?://[^\s<>"]+|.[^\s<>"]+', str(m)) + ip = resolve_hostname(url[0]) self.createAndAddHost( ip, hostnames=[m] From 26d7b641e419af1f5f1935880e4ab0b83fd93759 Mon Sep 17 00:00:00 2001 From: Blas Date: Thu, 10 Sep 2020 11:39:45 -0300 Subject: [PATCH 129/698] ADD plugin nextnet --- CHANGELOG/current/nextnet.md | 1 + .../plugins/repo/nextnet/__init__.py | 0 .../plugins/repo/nextnet/plugin.py | 61 +++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 CHANGELOG/current/nextnet.md create mode 100644 faraday_plugins/plugins/repo/nextnet/__init__.py create mode 100644 faraday_plugins/plugins/repo/nextnet/plugin.py diff --git a/CHANGELOG/current/nextnet.md b/CHANGELOG/current/nextnet.md new file mode 100644 index 00000000..084e69a1 --- /dev/null +++ b/CHANGELOG/current/nextnet.md @@ -0,0 +1 @@ +ADD plugin nextnet \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/nextnet/__init__.py b/faraday_plugins/plugins/repo/nextnet/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/faraday_plugins/plugins/repo/nextnet/plugin.py b/faraday_plugins/plugins/repo/nextnet/plugin.py new file mode 100644 index 00000000..6352a807 --- /dev/null +++ b/faraday_plugins/plugins/repo/nextnet/plugin.py @@ -0,0 +1,61 @@ +""" +Faraday Penetration Test IDE +Copyright (C) 2020 Infobyte LLC (http://www.infobytesec.com/) +See the file 'doc/LICENSE' for the license information + +""" +import re +import os +import json +from faraday_plugins.plugins.plugin import PluginBase +from faraday_plugins.plugins.plugins_utils import resolve_hostname + + +__author__ = "Blas Moyano" +__copyright__ = "Copyright (c) 2020, Infobyte LLC" +__credits__ = ["Blas Moyano"] +__license__ = "" +__version__ = "1.0.0" +__maintainer__ = "Blas Moyano" +__email__ = "bmoyano@infobytesec.com" +__status__ = "Development" + + +class CmdNextNetin(PluginBase): + def __init__(self): + super().__init__() + self.id = "nextnet" + self.name = "nextnet" + self.plugin_version = "0.0.1" + self.version = "5.0.20" + self.framework_version = "1.0.0" + self.options = None + self._current_output = None + self._command_regex = re.compile(r'^[.]*?[/]*?nextnet\s+.*?') + self._host_ip = None + self._info = 0 + + def parseOutputString(self, output): + output_lines = output.split('\n') + output_lines = output_lines[:-1] + for line in output_lines: + json_line = json.loads(line) + h_id = self.createAndAddHost( + json_line.get("host", "0.0.0.0"), + os=json_line.get("name", "unknown"), + hostnames=json_line.get("nets", "unknown") + ) + desc = f'Probe Tag: {json_line.get("probe", "Not tag probe")}' \ + f'Info Tag: {json_line.get("info", "Not tag info")}' + self.createAndAddServiceToHost( + h_id, + name=json_line.get("host", "0.0.0.0"), + protocol=json_line.get("proto", "tcp"), + ports=json_line.get("port", None), + description=desc + ) + return True + + +def createPlugin(): + return CmdNextNetin() From 56c129b2e42dbc312ef303c7676f5176c37f1810 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Fri, 11 Sep 2020 15:55:21 -0300 Subject: [PATCH 130/698] Change the way we detect json reports when they are lists of dictionaries --- .../current/modify_json_reports_detection.md | 1 + faraday_plugins/plugins/manager.py | 6 +++++- faraday_plugins/plugins/repo/ssl_labs/plugin.py | 15 ++------------- faraday_plugins/plugins/repo/whatweb/plugin.py | 16 ++-------------- 4 files changed, 10 insertions(+), 28 deletions(-) create mode 100644 CHANGELOG/current/modify_json_reports_detection.md diff --git a/CHANGELOG/current/modify_json_reports_detection.md b/CHANGELOG/current/modify_json_reports_detection.md new file mode 100644 index 00000000..3a685769 --- /dev/null +++ b/CHANGELOG/current/modify_json_reports_detection.md @@ -0,0 +1 @@ +Change the way we detect json reports when they are lists of dictionaries \ No newline at end of file diff --git a/faraday_plugins/plugins/manager.py b/faraday_plugins/plugins/manager.py index 2edbcae5..337e2202 100644 --- a/faraday_plugins/plugins/manager.py +++ b/faraday_plugins/plugins/manager.py @@ -89,7 +89,11 @@ def _get_plugin_by_file_type(self, report_path): try: report_file.seek(0) json_data = json.load(report_file) - file_json_keys = set(json_data.keys()) + if isinstance(json_data, list): + if len(json_data) > 0: + file_json_keys = set(json_data[0].keys()) + else: + file_json_keys = set(json_data.keys()) logger.debug("Found JSON content on file: %s - Keys: %s", report_path, file_json_keys) except Exception as e: logger.debug("Non JSON content [%s] - %s", report_path, e) diff --git a/faraday_plugins/plugins/repo/ssl_labs/plugin.py b/faraday_plugins/plugins/repo/ssl_labs/plugin.py index f3b9112a..53fa3ce1 100644 --- a/faraday_plugins/plugins/repo/ssl_labs/plugin.py +++ b/faraday_plugins/plugins/repo/ssl_labs/plugin.py @@ -73,19 +73,8 @@ def __init__(self): self.name = "SSL Labs" self.plugin_version = "0.1" self.version = "3.4.5" - self.json_keys = set() - - def report_belongs_to(self, **kwargs): - result = False - if super().report_belongs_to(**kwargs): - report_path = kwargs.get("report_path", "") - with open(report_path) as f: - output = f.readlines() - for line in output: - check = line.find('"criteriaVersion":') - if check > 0: - result = True - return result + self.json_keys = {'engineVersion', 'criteriaVersion', 'endpoints'} + def parseOutputString(self, output): parser = SslLabsJsonParser(output) diff --git a/faraday_plugins/plugins/repo/whatweb/plugin.py b/faraday_plugins/plugins/repo/whatweb/plugin.py index d538b3b1..05ece3a9 100644 --- a/faraday_plugins/plugins/repo/whatweb/plugin.py +++ b/faraday_plugins/plugins/repo/whatweb/plugin.py @@ -56,20 +56,8 @@ def __init__(self): self.name = "WhatWebPlugin" self.plugin_version = "0.1" self.version = "0.0.1" - self.json_keys = set() - - def report_belongs_to(self, **kwargs): - result = False - if super().report_belongs_to(**kwargs): - report_path = kwargs.get("report_path", "") - with open(report_path) as f: - output = f.readlines() - for line in output: - check_target = line.find('"target":') - check = line.find('"plugins":') - if check > 0 and check_target > 0: - result = True - return result + self.json_keys = {'target', 'http_status', 'plugins'} + def parseOutputString(self, output): parser = WhatWebJsonParser(output) From 42c40aa6a3da9fc40a83bfbfb816fcd7cc21f1ff Mon Sep 17 00:00:00 2001 From: Blas Date: Tue, 15 Sep 2020 11:36:28 -0300 Subject: [PATCH 131/698] ADD plugin openscap --- CHANGELOG/current/add_openscap.md | 1 + .../plugins/repo/openscap/__init__.py | 0 .../plugins/repo/openscap/plugin.py | 195 ++++++++++++++++++ 3 files changed, 196 insertions(+) create mode 100644 CHANGELOG/current/add_openscap.md create mode 100644 faraday_plugins/plugins/repo/openscap/__init__.py create mode 100644 faraday_plugins/plugins/repo/openscap/plugin.py diff --git a/CHANGELOG/current/add_openscap.md b/CHANGELOG/current/add_openscap.md new file mode 100644 index 00000000..75b76944 --- /dev/null +++ b/CHANGELOG/current/add_openscap.md @@ -0,0 +1 @@ +ADD plungin openscap \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/openscap/__init__.py b/faraday_plugins/plugins/repo/openscap/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/faraday_plugins/plugins/repo/openscap/plugin.py b/faraday_plugins/plugins/repo/openscap/plugin.py new file mode 100644 index 00000000..a2b38085 --- /dev/null +++ b/faraday_plugins/plugins/repo/openscap/plugin.py @@ -0,0 +1,195 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Faraday Penetration Test IDE +Copyright (C) 2020 Infobyte LLC (http://www.infobytesec.com/) +See the file 'doc/LICENSE' for the license information +""" +from faraday_plugins.plugins.plugin import PluginXMLFormat +from datetime import datetime +from lxml import etree + +try: + import xml.etree.cElementTree as ET +except ImportError: + import xml.etree.ElementTree as ET + +__author__ = 'Blas Moyano' +__copyright__ = 'Copyright 2020, Faraday Project' +__credits__ = ['Blas Moyano'] +__license__ = '' +__version__ = '1.0.0' +__status__ = 'Development' + + +class OpenScapParser: + def __init__(self, xml_output): + self.tree = self.parse_xml(xml_output) + + if self.tree is not None: + self.rule_date = self.get_parser_rule(self.tree.findall('Rule', self.tree.nsmap)) + self.result_data = self.get_parser_result(self.tree.findall('TestResult', self.tree.nsmap)) + self.tree = None + + def parse_xml(self, xml_output): + try: + parser = etree.XMLParser(recover=True) + tree = etree.fromstring(xml_output, parser=parser) + except SyntaxError as err: + print('SyntaxError In xml: %s. %s' % (err, xml_output)) + return None + return tree + + def get_parser_rule(self, tree): + list_rules = [] + for rule in tree: + title = rule.find('title', self.tree.nsmap) + ident = rule.find('ident', self.tree.nsmap) + check = rule.find('check', self.tree.nsmap) + check_ref = rule.find('check/check-content-ref', self.tree.nsmap) + try: + ident_result = ident.text + except AttributeError: + ident_result = "" + json_rule = { + "rule_id": rule.attrib.get('id', None), + "rule_sev": rule.attrib.get('severity', None), + "rule_title": title.text, + "rule_ident": ident_result, + "rule_check": check.attrib.get('system', None), + "rule_ref_name": check_ref.attrib.get('name', None), + "rule_ref_href": check_ref.attrib.get('href', None) + } + list_rules.append(json_rule) + return list_rules + + def get_parser_result(self, tree): + list_result = [] + list_ip = [] + list_mac = [] + list_data = [] + for result in tree: + title = result.find('title', self.tree.nsmap) + target = result.find('target', self.tree.nsmap) + ips = result.findall('target-address', self.tree.nsmap) + target_facts = result.findall('target-facts/fact', self.tree.nsmap) + rule_result = result.findall('rule-result', self.tree.nsmap) + + for ip in ips: + list_ip.append(ip.text) + + for mac in target_facts: + fact_name = mac.attrib.get('name', None) + if fact_name == 'urn:xccdf:fact:ethernet:MAC': + list_mac.append(mac.text) + + for data in rule_result: + list_ident = [] + idents = data.findall('ident', self.tree.nsmap) + check = data.find('check', self.tree.nsmap) + check_ref = data.find('check/check-content-ref', self.tree.nsmap) + + for ident in idents: + json_ident = { + "system": data.attrib.get('system', None), + "text": ident.text + } + list_ident.append(json_ident) + + json_data = { + "id": data.attrib.get('idref', None), + "time": data.attrib.get('time', None), + "severity": data.attrib.get('severity', None), + "ident": list_ident, + "check": check.attrib.get('system', None), + "ref_name": check_ref.attrib.get('name', None), + "ref_href": check_ref.attrib.get('href', None) + } + + status = data.find('result', self.tree.nsmap) + if status.text == 'fail': + list_data.append(json_data) + + json_result = { + "id": result.attrib.get('id', None), + "start_time": result.attrib.get('start-time', None), + "end_time": result.attrib.get('end-time', None), + "result_title": title.text, + "target": target.text, + "ips": list_ip, + "mac": list_mac, + "rule_result": list_data + } + list_result.append(json_result) + return list_result + + +class OpenScapPlugin(PluginXMLFormat): + def __init__(self): + super().__init__() + self.identifier_tag = ["Benchmark"] + self.id = 'OpenScap' + self.name = 'OpenScap XML Output Plugin' + self.plugin_version = '1.0.0' + self.version = '1.0.0' + self.framework_version = '1.0.0' + self.options = None + self.protocol = None + self.port = '80' + self.address = None + + def report_belongs_to(self, main_tag="", **kwargs): + match = False + if not super().report_belongs_to(**kwargs): + if type(self.identifier_tag) == list: + if main_tag.find(self.identifier_tag[0]) >= 0: + match = True + return match + + def parseOutputString(self, output): + + parser = OpenScapParser(output) + host_id = self.createAndAddHost( + name=parser.result_data[0]['target'], + hostnames=parser.result_data[0]['ips'], + description=parser.result_data[0]['result_title'], + mac=str(parser.result_data[0]['mac'])) + + rules_fail = parser.result_data[0]['rule_result'] + if rules_fail: + info_rules = parser.rule_date + severity = 0 + + for rule in rules_fail: + vuln_run_date = datetime.strptime( + rule['time'].replace('T', ' '), + '%Y-%m-%d %H:%M:%S') + + if rule['severity'] == 'low': + severity = 1 + elif rule['severity'] == 'medium': + severity = 2 + elif rule['severity'] == 'high': + severity = 3 + + desc = f'name: {rule["ref_name"]} - link: {rule["ref_href"]}' + + for info in info_rules: + if rule['id'] == info['rule_id']: + vuln_name = info['rule_title'] + vuln_data = info['rule_check'] + vuln_ref = info['rule_ident'] + + self.createAndAddVulnToHost( + host_id, + vuln_name, + desc=desc, + ref=vuln_ref, + severity=severity, + data=vuln_data, + external_id=rule['id'], + run_date=vuln_run_date) + + +def createPlugin(): + return OpenScapPlugin() From 72cd05220fa7ef03f6b3753e42d1220e48941fe9 Mon Sep 17 00:00:00 2001 From: Blas Date: Wed, 16 Sep 2020 14:39:23 -0300 Subject: [PATCH 132/698] FIX type ref --- faraday_plugins/plugins/repo/openscap/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faraday_plugins/plugins/repo/openscap/plugin.py b/faraday_plugins/plugins/repo/openscap/plugin.py index a2b38085..1047b7a3 100644 --- a/faraday_plugins/plugins/repo/openscap/plugin.py +++ b/faraday_plugins/plugins/repo/openscap/plugin.py @@ -184,7 +184,7 @@ def parseOutputString(self, output): host_id, vuln_name, desc=desc, - ref=vuln_ref, + ref=[vuln_ref], severity=severity, data=vuln_data, external_id=rule['id'], From ed360623d956928c7b87fca8e85c0f3c72bd9fbe Mon Sep 17 00:00:00 2001 From: Blas Date: Sun, 20 Sep 2020 23:10:02 -0300 Subject: [PATCH 133/698] UPD parser info in MBSA --- faraday_plugins/plugins/repo/mbsa/plugin.py | 69 +++++++++++++++++++-- 1 file changed, 63 insertions(+), 6 deletions(-) diff --git a/faraday_plugins/plugins/repo/mbsa/plugin.py b/faraday_plugins/plugins/repo/mbsa/plugin.py index 39ebc6f8..bc4497e1 100644 --- a/faraday_plugins/plugins/repo/mbsa/plugin.py +++ b/faraday_plugins/plugins/repo/mbsa/plugin.py @@ -6,6 +6,7 @@ from faraday_plugins.plugins.plugin import PluginByExtension import re import os +from datetime import datetime __author__ = "Blas Moyano" __copyright__ = "Copyright (c) 2020, Infobyte LLC" @@ -17,11 +18,11 @@ class MbsaParser: - def __init__(self, xml_output): - self.tree = self.parse_xml(xml_output) + def __init__(self, log_output): + pass -class MaltegoPlugin(PluginByExtension): +class MbsaPlugin(PluginByExtension): def __init__(self): super().__init__() self.id = "MBSA" @@ -32,10 +33,66 @@ def __init__(self): self.extension = ".log" def parseOutputString(self, output): - print(type(output.find())) - #parser = MbsaParser(output) + computer_name = re.search('(Computer name:) (.*[A-Z])', output) + ip = re.search('(IP address:) ([0-9]+(?:\.[0-9]+){3})', output) + scan_date = re.search('(Scan date:) (.*[0-9])', output) + issues = re.findall(r'Issue: .*', output) + score = re.findall(r'Score: .*', output) + result = re.findall(r'Result: .*', output) + detail = '' + i = 0 + issues_top = len(issues) + + host_id = self.createAndAddHost( + ip.group(2), + 'Windows', + hostnames=[computer_name.group(2)]) + + for issue in issues: + + test = re.search(issues[i], output) + + if i+1 != issues_top: + test_issue = re.search(issues[i+1], output) + else: + end = None + try: + start = test.end() + end = test_issue.start() + except: + start = None + + if start is not None: + if end is None: + result_info = output[start:] + else: + result_info = output[start:end] + result_info.rstrip('\n') + result_info = result_info.replace(score[i], '') + result_info = result_info.replace(result[i], '') + result_info = result_info.strip() + if result_info: + print("ntro") + detail = re.search('(Detail:)', result_info) + if not None: + detail = result_info + result_info = result[i] + + else: + detail = '' + result_info = result[i] + + self.createAndAddVulnToHost(host_id, + issue.replace('Issue: ', ''), + desc=score[i].replace('Score: ', ''), + ref=None, + resolution=result_info.replace('Result: ', ''), + data=detail, + run_date=datetime.strptime(scan_date.group(2), '%Y/%m/%d %H:%M')) + + i += 1 def createPlugin(): - return MaltegoPlugin() + return MbsaPlugin() From 0b33810fed9c1803d5b6571d1aa8c474ef7da103 Mon Sep 17 00:00:00 2001 From: Blas Date: Sat, 26 Sep 2020 14:20:14 -0300 Subject: [PATCH 134/698] UPD get info in parser --- faraday_plugins/plugins/repo/mbsa/plugin.py | 41 ++++++++++----------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/faraday_plugins/plugins/repo/mbsa/plugin.py b/faraday_plugins/plugins/repo/mbsa/plugin.py index bc4497e1..5129cafd 100644 --- a/faraday_plugins/plugins/repo/mbsa/plugin.py +++ b/faraday_plugins/plugins/repo/mbsa/plugin.py @@ -5,7 +5,6 @@ """ from faraday_plugins.plugins.plugin import PluginByExtension import re -import os from datetime import datetime __author__ = "Blas Moyano" @@ -19,7 +18,12 @@ class MbsaParser: def __init__(self, log_output): - pass + self.computer_name = re.search('(Computer name:) (.*[A-Z])', log_output) + self.ip = re.search('(IP address:) ([0-9]+(?:\.[0-9]+){3})', log_output) + self.scan_date = re.search('(Scan date:) (.*[0-9])', log_output) + self.issues = re.findall(r'Issue: .*', log_output) + self.score = re.findall(r'Score: .*', log_output) + self.result = re.findall(r'Result: .*', log_output) class MbsaPlugin(PluginByExtension): @@ -33,28 +37,22 @@ def __init__(self): self.extension = ".log" def parseOutputString(self, output): - - computer_name = re.search('(Computer name:) (.*[A-Z])', output) - ip = re.search('(IP address:) ([0-9]+(?:\.[0-9]+){3})', output) - scan_date = re.search('(Scan date:) (.*[0-9])', output) - issues = re.findall(r'Issue: .*', output) - score = re.findall(r'Score: .*', output) - result = re.findall(r'Result: .*', output) + parser = MbsaParser(output) detail = '' i = 0 - issues_top = len(issues) + issues_top = len(parser.issues) host_id = self.createAndAddHost( - ip.group(2), + parser.ip.group(2), 'Windows', - hostnames=[computer_name.group(2)]) + hostnames=[parser.computer_name.group(2)]) - for issue in issues: + for issue in parser.issues: - test = re.search(issues[i], output) + test = re.search(parser.issues[i], output) if i+1 != issues_top: - test_issue = re.search(issues[i+1], output) + test_issue = re.search(parser.issues[i+1], output) else: end = None try: @@ -69,27 +67,26 @@ def parseOutputString(self, output): else: result_info = output[start:end] result_info.rstrip('\n') - result_info = result_info.replace(score[i], '') - result_info = result_info.replace(result[i], '') + result_info = result_info.replace(parser.score[i], '') + result_info = result_info.replace(parser.result[i], '') result_info = result_info.strip() if result_info: - print("ntro") detail = re.search('(Detail:)', result_info) if not None: detail = result_info - result_info = result[i] + result_info = parser.result[i] else: detail = '' - result_info = result[i] + result_info = parser.result[i] self.createAndAddVulnToHost(host_id, issue.replace('Issue: ', ''), - desc=score[i].replace('Score: ', ''), + desc=parser.score[i].replace('Score: ', ''), ref=None, resolution=result_info.replace('Result: ', ''), data=detail, - run_date=datetime.strptime(scan_date.group(2), '%Y/%m/%d %H:%M')) + run_date=datetime.strptime(parser.scan_date.group(2), '%Y/%m/%d %H:%M')) i += 1 From 12b4cef0eea3837f5dabbd718557429a21a2fdf4 Mon Sep 17 00:00:00 2001 From: Blas Date: Tue, 29 Sep 2020 14:05:16 -0300 Subject: [PATCH 135/698] check is none in ip, hostname and rundate --- faraday_plugins/plugins/repo/mbsa/plugin.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/faraday_plugins/plugins/repo/mbsa/plugin.py b/faraday_plugins/plugins/repo/mbsa/plugin.py index 5129cafd..2c0ab36a 100644 --- a/faraday_plugins/plugins/repo/mbsa/plugin.py +++ b/faraday_plugins/plugins/repo/mbsa/plugin.py @@ -41,11 +41,21 @@ def parseOutputString(self, output): detail = '' i = 0 issues_top = len(parser.issues) + ip = '0.0.0.0' + hostname = [] + run_date = None + + if parser.ip is not None: + ip = parser.ip.group(2) + if parser.computer_name is not None: + hostname.append(parser.computer_name.group(2)) + if parser.scan_date is not None: + run_date = datetime.strptime(parser.scan_date.group(2), '%Y/%m/%d %H:%M') host_id = self.createAndAddHost( - parser.ip.group(2), + ip, 'Windows', - hostnames=[parser.computer_name.group(2)]) + hostnames=hostname) for issue in parser.issues: @@ -86,7 +96,7 @@ def parseOutputString(self, output): ref=None, resolution=result_info.replace('Result: ', ''), data=detail, - run_date=datetime.strptime(parser.scan_date.group(2), '%Y/%m/%d %H:%M')) + run_date=run_date) i += 1 From 9500e9ec6af1ec9e3b7f1bbfe793bc20bdc3013f Mon Sep 17 00:00:00 2001 From: Blas Date: Fri, 2 Oct 2020 12:09:23 -0300 Subject: [PATCH 136/698] FIX resolution check key in dict --- .../plugins/repo/appscan/plugin.py | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/faraday_plugins/plugins/repo/appscan/plugin.py b/faraday_plugins/plugins/repo/appscan/plugin.py index 363bd79d..c42eecec 100644 --- a/faraday_plugins/plugins/repo/appscan/plugin.py +++ b/faraday_plugins/plugins/repo/appscan/plugin.py @@ -310,8 +310,14 @@ def parseOutputString(self, output): if info['id'] == issue['advisory']: vuln_name = info['name'] vuln_desc = info['description'] - resolution = f'Text: {info["fixRecommendations"]["text"]}. ' \ - f'Link: {info["fixRecommendations"]["link"]}' + + text_info = info['fixRecommendations']['text'] \ + if 'text' in info['fixRecommendations'] else "Not Text" + + link_info = info['fixRecommendations']['link'] \ + if 'link' in info['fixRecommendations'] else "Not Info" + + resolution = f"Text:{text_info}. Link: {link_info}." vuln_data = f'xfix: {info["xfid"]} cme: {info["cwe"]}' for url in urls: @@ -341,6 +347,7 @@ def parseOutputString(self, output): for vuln_data in name_scan: if vuln_data['id'] == info_loc_source["id_adv"]: desc = f'desc: {vuln_data["description"]} DescMix {vuln_data["testDescriptionMixed"]}' + resolution = f'Fix Recomendarion {vuln_data["fixRecommendations"]}' \ f' - TestTecnical {vuln_data["testTechnicalDescriptionMixed"]}' @@ -364,7 +371,14 @@ def parseOutputString(self, output): else: desc = vulnserv['description'] - resolution = f"Text:{vulnserv['fixRecommendations']['text']}. Link: {vulnserv['fixRecommendations']['link']}." + text_info = vulnserv['fixRecommendations']['text'] \ + if 'text' in vulnserv['fixRecommendations'] else "Not Text" + + link_info = vulnserv['fixRecommendations']['link'] \ + if 'link' in vulnserv['fixRecommendations'] else "Not Info" + + resolution = f"Text:{text_info}. Link: {link_info}." + self.createAndAddVulnToHost(host_id=host_id, name=vulnserv['name'], desc=desc, severity=info_severity, resolution=resolution, data=f'xfix: {vulnserv["xfid"]} cme: {vulnserv["cwe"]}', run_date=None) From e711a2064699e4a39e1b7fc1b17859249fa00b98 Mon Sep 17 00:00:00 2001 From: Blas Date: Wed, 14 Oct 2020 22:40:51 -0300 Subject: [PATCH 137/698] UPD name vuln change for title tag. If title is none type tag is a name vuln --- faraday_plugins/plugins/repo/netsparker/plugin.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/faraday_plugins/plugins/repo/netsparker/plugin.py b/faraday_plugins/plugins/repo/netsparker/plugin.py index b0397213..7fdd1403 100644 --- a/faraday_plugins/plugins/repo/netsparker/plugin.py +++ b/faraday_plugins/plugins/repo/netsparker/plugin.py @@ -110,6 +110,7 @@ def __init__(self, item_node, encoding="ascii"): self.port = host.group(11) self.name = self.get_text_from_subnode("type") + self.name_title = self.get_text_from_subnode("title") self.desc = self.get_text_from_subnode("description") self.severity = self.re_map_severity(self.get_text_from_subnode("severity")) self.certainty = self.get_text_from_subnode("certainty") @@ -216,8 +217,11 @@ def parseOutputString(self, output): desc = BeautifulSoup(i.desc, "lxml").text else: desc = "" - - v_id = self.createAndAddVulnWebToService(h_id, s_id, i.name, ref=i.ref, website=i.hostname, + if i.name_title is None: + name = i.name + else: + name = i.name_title + v_id = self.createAndAddVulnWebToService(h_id, s_id, name, ref=i.ref, website=i.hostname, severity=i.severity, desc=desc, path=i.url, method=i.method, request=i.request, response=i.response, resolution=resolution, pname=i.param, data=i.data) From 36a3cb9bfd5e2cbf7e07d0d1556400904a209c38 Mon Sep 17 00:00:00 2001 From: Blas Date: Sun, 18 Oct 2020 22:32:37 -0300 Subject: [PATCH 138/698] ADD changelog --- CHANGELOG/current/fix_netsparker.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 CHANGELOG/current/fix_netsparker.md diff --git a/CHANGELOG/current/fix_netsparker.md b/CHANGELOG/current/fix_netsparker.md new file mode 100644 index 00000000..77fec880 --- /dev/null +++ b/CHANGELOG/current/fix_netsparker.md @@ -0,0 +1 @@ +FIX Netsparker change name vuln \ No newline at end of file From 68ee17eb124f7e2b9199f190c31d28d0df2ec312 Mon Sep 17 00:00:00 2001 From: Blas Date: Sun, 18 Oct 2020 22:36:21 -0300 Subject: [PATCH 139/698] ADD changelog --- CHANGELOG/current/fix_redlink.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 CHANGELOG/current/fix_redlink.md diff --git a/CHANGELOG/current/fix_redlink.md b/CHANGELOG/current/fix_redlink.md new file mode 100644 index 00000000..ca0e9cb3 --- /dev/null +++ b/CHANGELOG/current/fix_redlink.md @@ -0,0 +1 @@ +FIX resolution check key in dict \ No newline at end of file From 63d44ebc3d3d6b2c56850a3fd1d53c3a6dde8910 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Fri, 23 Oct 2020 11:34:06 -0300 Subject: [PATCH 140/698] Add new plugin base class, for multi line json --- CHANGELOG/current/add_multilinejson_format.md | 1 + faraday_plugins/plugins/manager.py | 4 +-- faraday_plugins/plugins/plugin.py | 25 +++++++++++++++++++ .../plugins/repo/awsprowler/plugin.py | 22 +++------------- 4 files changed, 31 insertions(+), 21 deletions(-) create mode 100644 CHANGELOG/current/add_multilinejson_format.md diff --git a/CHANGELOG/current/add_multilinejson_format.md b/CHANGELOG/current/add_multilinejson_format.md new file mode 100644 index 00000000..68710fe3 --- /dev/null +++ b/CHANGELOG/current/add_multilinejson_format.md @@ -0,0 +1 @@ +Add new plugin base class, for multi line json \ No newline at end of file diff --git a/faraday_plugins/plugins/manager.py b/faraday_plugins/plugins/manager.py index 337e2202..9472c7dc 100644 --- a/faraday_plugins/plugins/manager.py +++ b/faraday_plugins/plugins/manager.py @@ -102,9 +102,9 @@ def _get_plugin_by_file_type(self, report_path): reader_file_string = StringIO(report_file.read().decode('utf-8')) reader = csv.DictReader(reader_file_string) file_csv_headers = set(reader.fieldnames) - logger.debug("Found JSON content on file: %s - Keys: %s", report_path, file_json_keys) + logger.debug("Found CSV content on file: %s - Keys: %s", report_path, file_json_keys) except Exception as e: - logger.debug("Non JSON content [%s] - %s", report_path, e) + logger.debug("Non CSV content [%s] - %s", report_path, e) try: file_zip = zipfile.ZipFile(report_path, "r") files_in_zip = set(file_zip.namelist()) diff --git a/faraday_plugins/plugins/plugin.py b/faraday_plugins/plugins/plugin.py index d4adb960..97272e0a 100644 --- a/faraday_plugins/plugins/plugin.py +++ b/faraday_plugins/plugins/plugin.py @@ -595,6 +595,31 @@ def report_belongs_to(self, file_json_keys=None, **kwargs): return match +class PluginMultiLineJsonFormat(PluginByExtension): + + def __init__(self): + super().__init__() + self.json_keys = set() + self.extension = ".json" + + def report_belongs_to(self, file_json_keys=None, **kwargs): + match = False + report_path = kwargs.get("report_path", "") + if super().report_belongs_to(**kwargs): + with open(report_path) as f: + try: + json_lines = list(map(lambda x: json.loads(x), f.readlines())) + if len(json_lines) > 0: + matched_lines = list(filter(lambda json_line: self.json_keys.issubset(json_line.keys()), + json_lines)) + match = len(matched_lines) == len(json_lines) + self.logger.debug("Json Keys Match: [%s =/in %s] -> %s", json_lines[0].keys(), self.json_keys, + match) + except ValueError: + return False + return match + + class PluginCSVFormat(PluginByExtension): def __init__(self): diff --git a/faraday_plugins/plugins/repo/awsprowler/plugin.py b/faraday_plugins/plugins/repo/awsprowler/plugin.py index ff84068a..8444467a 100644 --- a/faraday_plugins/plugins/repo/awsprowler/plugin.py +++ b/faraday_plugins/plugins/repo/awsprowler/plugin.py @@ -8,7 +8,7 @@ import json from datetime import datetime import re -from faraday_plugins.plugins.plugin import PluginJsonFormat +from faraday_plugins.plugins.plugin import PluginMultiLineJsonFormat __author__ = "Blas Moyano" __copyright__ = "Copyright (c) 2020, Infobyte LLC" @@ -28,7 +28,7 @@ def __init__(self, json_output): self.report_aws = string_manipulate.split("#") -class AwsProwlerPlugin(PluginJsonFormat): +class AwsProwlerPlugin(PluginMultiLineJsonFormat): """ Handle the AWS Prowler tool. Detects the output of the tool and adds the information to Faraday. """ @@ -39,24 +39,8 @@ def __init__(self): self.name = "AWS Prowler" self.plugin_version = "0.1" self.version = "0.0.1" - self.json_keys = set() + self.json_keys = {"Profile", "Account Number"} - def report_belongs_to(self, **kwargs): - if super().report_belongs_to(**kwargs): - report_path = kwargs.get("report_path", "") - with open(report_path) as f: - output = f.readlines() - try: - for line in output: - check_line = json.loads(line) - if check_line.keys() >= {"Profile", "Account Number"}: - pass - else: - return False - except ValueError: - return False - return True - return False def parseOutputString(self, output, debug=False): parser = AwsProwlerJsonParser(output) From 49ed39d53dbf59fc899cc0a22afc640ebd12bb2a Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Tue, 27 Oct 2020 12:48:10 -0300 Subject: [PATCH 141/698] fix missing ip in arachni --- CHANGELOG/current/fix_arachni_ip_missing.md | 1 + faraday_plugins/plugins/repo/arachni/plugin.py | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 CHANGELOG/current/fix_arachni_ip_missing.md diff --git a/CHANGELOG/current/fix_arachni_ip_missing.md b/CHANGELOG/current/fix_arachni_ip_missing.md new file mode 100644 index 00000000..73d7d58c --- /dev/null +++ b/CHANGELOG/current/fix_arachni_ip_missing.md @@ -0,0 +1 @@ +Fix missing ip in some arachni reports \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/arachni/plugin.py b/faraday_plugins/plugins/repo/arachni/plugin.py index 8142820a..217199d1 100755 --- a/faraday_plugins/plugins/repo/arachni/plugin.py +++ b/faraday_plugins/plugins/repo/arachni/plugin.py @@ -257,7 +257,7 @@ def __init__(self, plugins_node): self.ip = plugins_node.find('resolver').find('results') \ .find('hostname').get('ipaddress') except Exception: - self.ip = '0.0.0.0' + self.ip = None def getHealthmap(self): @@ -394,7 +394,10 @@ def parseOutputString(self, output): return self.hostname = self.getHostname(parser.system.url) - self.address = resolve_hostname(parser.plugins.ip) + if parser.plugins.ip: + self.address = resolve_hostname(parser.plugins.ip) + else: + self.address = self.hostname # Create host and interface host_id = self.createAndAddHost(self.address, hostnames=[self.hostname]) From 9234260cbdef8ca8b1f687009307fcb1ea469564 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Tue, 27 Oct 2020 16:33:52 -0300 Subject: [PATCH 142/698] fix resolv name in arachni --- faraday_plugins/plugins/repo/arachni/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faraday_plugins/plugins/repo/arachni/plugin.py b/faraday_plugins/plugins/repo/arachni/plugin.py index 217199d1..5b7dd838 100755 --- a/faraday_plugins/plugins/repo/arachni/plugin.py +++ b/faraday_plugins/plugins/repo/arachni/plugin.py @@ -397,7 +397,7 @@ def parseOutputString(self, output): if parser.plugins.ip: self.address = resolve_hostname(parser.plugins.ip) else: - self.address = self.hostname + self.address = resolve_hostname(self.hostname) # Create host and interface host_id = self.createAndAddHost(self.address, hostnames=[self.hostname]) From e359a024c2c067281c02daab070764e59f7b7be6 Mon Sep 17 00:00:00 2001 From: Blas Date: Wed, 28 Oct 2020 12:05:31 -0300 Subject: [PATCH 143/698] UPD fixRecommendations in DAST --- faraday_plugins/plugins/repo/appscan/plugin.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/faraday_plugins/plugins/repo/appscan/plugin.py b/faraday_plugins/plugins/repo/appscan/plugin.py index c42eecec..572c61d9 100644 --- a/faraday_plugins/plugins/repo/appscan/plugin.py +++ b/faraday_plugins/plugins/repo/appscan/plugin.py @@ -310,14 +310,12 @@ def parseOutputString(self, output): if info['id'] == issue['advisory']: vuln_name = info['name'] vuln_desc = info['description'] + resolution = "" + if 'text' in info['fixRecommendations']: + resolution += info['fixRecommendations']['text'] + if 'link' in info['fixRecommendations']: + resolution += info['fixRecommendations']['link'] - text_info = info['fixRecommendations']['text'] \ - if 'text' in info['fixRecommendations'] else "Not Text" - - link_info = info['fixRecommendations']['link'] \ - if 'link' in info['fixRecommendations'] else "Not Info" - - resolution = f"Text:{text_info}. Link: {link_info}." vuln_data = f'xfix: {info["xfid"]} cme: {info["cwe"]}' for url in urls: From 91e26d864999dc8f056873c7294ea27e5b84c107 Mon Sep 17 00:00:00 2001 From: Blas Date: Tue, 3 Nov 2020 16:11:16 -0300 Subject: [PATCH 144/698] ADD plugin Nuclei --- CHANGELOG/current/add_nuclei_md | 1 + .../plugins/repo/nuclei/__init__.py | 0 faraday_plugins/plugins/repo/nuclei/plugin.py | 98 +++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 CHANGELOG/current/add_nuclei_md create mode 100644 faraday_plugins/plugins/repo/nuclei/__init__.py create mode 100644 faraday_plugins/plugins/repo/nuclei/plugin.py diff --git a/CHANGELOG/current/add_nuclei_md b/CHANGELOG/current/add_nuclei_md new file mode 100644 index 00000000..a4431b8f --- /dev/null +++ b/CHANGELOG/current/add_nuclei_md @@ -0,0 +1 @@ +add plugin nuclei \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/nuclei/__init__.py b/faraday_plugins/plugins/repo/nuclei/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/faraday_plugins/plugins/repo/nuclei/plugin.py b/faraday_plugins/plugins/repo/nuclei/plugin.py new file mode 100644 index 00000000..58b93cb2 --- /dev/null +++ b/faraday_plugins/plugins/repo/nuclei/plugin.py @@ -0,0 +1,98 @@ +""" +Faraday Penetration Test IDE +Copyright (C) 2020 Infobyte LLC (http://www.infobytesec.com/) +See the file 'doc/LICENSE' for the license information + +""" +import socket +import json +from urllib.parse import urlparse +from faraday_plugins.plugins.plugin import PluginMultiLineJsonFormat +from faraday_plugins.plugins.plugins_utils import resolve_hostname + +__author__ = "Blas Moyano" +__copyright__ = "Copyright (c) 2020, Infobyte LLC" +__credits__ = ["Blas Moyano"] +__license__ = "" +__version__ = "0.0.1" +__maintainer__ = "Blas Moyano" +__email__ = "bmoyano@infobytesec.com" +__status__ = "Development" + + +class NucleiJsonParser: + + def __init__(self, json_output): + self.list_to_vulns = json_output.split("\n") + + +class NucleiPlugin(PluginMultiLineJsonFormat): + """ Handle the Nuclei tool. Detects the output of the tool + and adds the information to Faraday. + """ + + def __init__(self): + super().__init__() + self.id = "nuclei" + self.name = "Nuclei" + self.plugin_version = "0.1" + self.version = "0.0.1" + self.json_keys = {"matched", "template"} + + def parseOutputString(self, output, debug=False): + parser = NucleiJsonParser(output) + matched_list = [] + matched_json = {} + for vuln in parser.list_to_vulns: + if vuln != '': + json_vuln = json.loads(vuln) + matched = json_vuln.get('matched', None) + url = urlparse(matched) + url_scheme = f'{url.scheme}://{url.hostname}' + + if url_scheme in matched_list: + matched_json[url_scheme].append(json_vuln) + else: + matched_list.append(url_scheme) + matched_json[url_scheme] = [json_vuln] + + for host in matched_list: + url_data = urlparse(host) + url_name = url_data.hostname + url_protocol = url_data.scheme + ip = resolve_hostname(host) + host_id = self.createAndAddHost( + name=ip, + hostnames=[host], + description="Nuclei") + + service_id = self.createAndAddServiceToHost( + host_id, + name=url_name, + protocol=url_protocol, + status='open', + version='', + description='') + + for info_vuln in matched_json[host]: + desc = f'{info_vuln.get("template", None)} - {info_vuln.get("author", None)}' + + self.createAndAddVulnWebToService( + host_id, + service_id, + name=info_vuln.get('matcher_name', "Nuclei"), + desc=desc, + ref=None, + severity=info_vuln.get('severity', ""), + website=host, + request=info_vuln.get('request', None), + response=info_vuln.get('response', None), + method=info_vuln.get('type', None), + data=info_vuln.get('name', None)) + + +def createPlugin(): + return NucleiPlugin() + + + From 510c99265062679ee4e120404c591c31dfd76c96 Mon Sep 17 00:00:00 2001 From: Blas Date: Tue, 3 Nov 2020 16:22:41 -0300 Subject: [PATCH 145/698] ADD changelog --- CHANGELOG/current/{add_nuclei_md => add_nuclei.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename CHANGELOG/current/{add_nuclei_md => add_nuclei.md} (100%) diff --git a/CHANGELOG/current/add_nuclei_md b/CHANGELOG/current/add_nuclei.md similarity index 100% rename from CHANGELOG/current/add_nuclei_md rename to CHANGELOG/current/add_nuclei.md From b07d8ee6717a5c384948aee114b3eadf3095f0ea Mon Sep 17 00:00:00 2001 From: Blas Date: Thu, 5 Nov 2020 11:54:55 -0300 Subject: [PATCH 146/698] FIX add port in createAndAddServiceToHost --- faraday_plugins/plugins/repo/nuclei/plugin.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/faraday_plugins/plugins/repo/nuclei/plugin.py b/faraday_plugins/plugins/repo/nuclei/plugin.py index 58b93cb2..49848fc5 100644 --- a/faraday_plugins/plugins/repo/nuclei/plugin.py +++ b/faraday_plugins/plugins/repo/nuclei/plugin.py @@ -65,10 +65,14 @@ def parseOutputString(self, output, debug=False): name=ip, hostnames=[host], description="Nuclei") + port = 80 + if url.scheme == 'https': + port = 443 service_id = self.createAndAddServiceToHost( host_id, name=url_name, + ports=port, protocol=url_protocol, status='open', version='', From a0277b0420782d20d4805f661c27836ca19b5994 Mon Sep 17 00:00:00 2001 From: Blas Date: Thu, 12 Nov 2020 15:08:49 -0300 Subject: [PATCH 147/698] ADD plugins sslyze json --- CHANGELOG/current/add_sslyze_json.md | 1 + .../plugins/repo/sslyzejson/__init__.py | 1 + .../plugins/repo/sslyzejson/plugin.py | 246 ++++++++++++++++++ 3 files changed, 248 insertions(+) create mode 100644 CHANGELOG/current/add_sslyze_json.md create mode 100644 faraday_plugins/plugins/repo/sslyzejson/__init__.py create mode 100644 faraday_plugins/plugins/repo/sslyzejson/plugin.py diff --git a/CHANGELOG/current/add_sslyze_json.md b/CHANGELOG/current/add_sslyze_json.md new file mode 100644 index 00000000..fe128111 --- /dev/null +++ b/CHANGELOG/current/add_sslyze_json.md @@ -0,0 +1 @@ +ADD plugins sslyze for json \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/sslyzejson/__init__.py b/faraday_plugins/plugins/repo/sslyzejson/__init__.py new file mode 100644 index 00000000..308ccd2c --- /dev/null +++ b/faraday_plugins/plugins/repo/sslyzejson/__init__.py @@ -0,0 +1 @@ +# I'm Py3 \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/sslyzejson/plugin.py b/faraday_plugins/plugins/repo/sslyzejson/plugin.py new file mode 100644 index 00000000..798f1703 --- /dev/null +++ b/faraday_plugins/plugins/repo/sslyzejson/plugin.py @@ -0,0 +1,246 @@ +""" +Faraday Penetration Test IDE +Copyright (C) 2020 Infobyte LLC (http://www.infobytesec.com/) +See the file 'doc/LICENSE' for the license information + +""" +import re +import json +from faraday_plugins.plugins.plugin import PluginJsonFormat + +__author__ = "Blas Moyano" +__copyright__ = "Copyright (c) 2020, Infobyte LLC" +__credits__ = ["Blas Moyano"] +__license__ = "" +__version__ = "0.0.1" +__maintainer__ = "Blas Moyano" +__email__ = "bmoyano@infobytesec.com" +__status__ = "Development" + + +class SslyzeJsonParser: + + def __init__(self, json_output): + json_sslyze = json.loads(json_output) + scan_result = json_sslyze.get('server_scan_results') + self.list_vul = self.get_vuln(scan_result) + + def get_vuln(self, scan_result): + list_vuln = [] + if scan_result: + for scan in scan_result: + try: + host = self.get_host(scan['server_info']['server_location']) + except KeyError: + host = {} + + try: + certif = self.get_certification(scan['scan_commands_results']['certificate_info']) + except KeyError: + certif = {} + + if not scan['scan_commands']: + ciphers = {} + else: + commands = [] + for command in scan['scan_commands']: + if command.find("cipher") >= 0: + commands.append(command) + ciphers = self.get_cipher(scan['scan_commands_results'], commands) + + try: + heartbleed = self.get_heartbleed(scan['scan_commands_results']['heartbleed']) + except KeyError: + heartbleed = {} + + try: + openssl_ccs = self.get_openssl_ccs(scan['scan_commands_results']['openssl_ccs_injection']) + except KeyError: + openssl_ccs = {} + + json_vuln = { + "host_info": host, + "certification": certif, + "ciphers": ciphers, + "heartbleed": heartbleed, + "openssl_ccs":openssl_ccs + } + + list_vuln.append(json_vuln) + return list_vuln + + def get_host(self, server_location): + port = server_location.get('port', None) + protocol = '' + if port is not None: + if port == 443: + protocol = 'https' + else: + protocol = 'http' + + json_host = { + "url": server_location.get('hostname', None), + "ip": server_location.get('ip_address', '0.0.0.0'), + "port": port, + "protocol": protocol + } + + return json_host + + def get_certification(self, certificate): + certif_deploy = certificate['certificate_deployments'] + send_certif = certif_deploy[0].get('leaf_certificate_subject_matches_hostname', True) == False + if send_certif: + json_certif = { + "name": "Certificate mismatch", + "desc": f"Certificate does not match server hostname {certificate.get('hostname_used_for_server_name_indication', 'Not hostname')}", + "severity": "info" + } + else: + json_certif = {} + return json_certif + + def get_cipher(self, scan_result, list_commands): + weak_cipher_list = [ + "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", + "TLS_RSA_WITH_AES_128_CBC_SHA", + "TLS_RSA_WITH_AES_128_CBC_SHA256", + "TLS_RSA_WITH_AES_128_GCM_SHA256", + "TLS_RSA_WITH_AES_256_CBC_SHA", + "TLS_RSA_WITH_AES_256_CBC_SHA256", + "TLS_RSA_WITH_AES_256_GCM_SHA384", + "TLS_RSA_WITH_3DES_EDE_CBC_SHA", + "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA", + "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA" + ] + weak_cipher = {} + for command in list_commands: + weak_cipher[command] = [] + try: + if scan_result[command]['accepted_cipher_suites']: + for cipher_suite in scan_result[command]['accepted_cipher_suites']: + name_cipher = cipher_suite['cipher_suite'].get('name') + if name_cipher in weak_cipher_list: + if not name_cipher in weak_cipher[command]: + weak_cipher[command].append(name_cipher) + except KeyError: + pass + + try: + if scan_result[command]['cipher_suite_preferred_by_server'] is not None: + for cipher_suite in scan_result[command]['accepted_cipher_suites']: + name_cipher = cipher_suite['cipher_suite'].get('name') + if name_cipher in weak_cipher_list: + if not name_cipher in weak_cipher[command]: + weak_cipher[command].append(name_cipher) + except KeyError: + pass + + return weak_cipher + + def get_heartbleed(self, heartbleed): + json_heartbleed = {} + if heartbleed.get('is_vulnerable_to_heartbleed', False): + json_heartbleed = { + "name": "OpenSSL Heartbleed", + "desc": "OpenSSL Heartbleed is vulnerable", + "severity": "critical" + } + return json_heartbleed + + def get_openssl_ccs(self, openssl_ccs): + json_openssl_ccs = {} + if openssl_ccs.get('is_vulnerable_to_ccs_injection', False): + json_openssl_ccs = { + "name": "OpenSSL CCS Injection", + "desc": "OpenSSL CCS Injection is vulnerable", + "severity": "medium" + } + return json_openssl_ccs + + +class SslyzePlugin(PluginJsonFormat): + + def __init__(self): + super().__init__() + self.id = "sslyzejson" + self.name = "Sslyze Json" + self.plugin_version = "0.1" + self.version = "3.4.5" + self.json_keys = {'server_scan_results', 'sslyze_url'} + self._command_regex = re.compile(r'^(sudo sslyze|sslyze|\.\/sslyze)\s+.*?') + self.json_arg_re = re.compile(r"^.*(--json_out\s*[^\s]+).*$") + + def parseOutputString(self, output): + parser = SslyzeJsonParser(output) + + for info_sslyze in parser.list_vul: + info_sslyze['host_info'].get('url') + host_id = self.createAndAddHost( + info_sslyze['host_info'].get('ip'), + os="unknown", + hostnames=[ + info_sslyze['host_info'].get('url') + ] + ) + service_id = self.createAndAddServiceToHost( + host_id, + name=info_sslyze['host_info'].get('protocol'), + protocol=info_sslyze['host_info'].get('protocol'), + ports=[ + info_sslyze['host_info'].get('port') + ] + ) + + if info_sslyze['certification']: + self.createAndAddVulnToService( + host_id, + service_id, + name=info_sslyze['certification'].get('name'), + desc=info_sslyze['certification'].get('desc'), + severity=info_sslyze['certification'].get('info')) + + if info_sslyze['ciphers']: + for k, v in info_sslyze['ciphers'].items(): + if len(v) != 0: + for ciphers in v: + key = k.replace('_cipher_suites', '') + self.createAndAddVulnToService( + host_id, + service_id, + name=ciphers, + desc=f"In protocol [{key}], weak cipher suite: {ciphers}", + severity="low") + + if info_sslyze['heartbleed']: + self.createAndAddVulnToService( + host_id, + service_id, + name=info_sslyze['heartbleed'].get('name'), + desc=info_sslyze['heartbleed'].get('desc'), + severity=info_sslyze['heartbleed'].get('severity')) + + if info_sslyze['openssl_ccs']: + self.createAndAddVulnToService( + host_id, + service_id, + name=info_sslyze['openssl_ccs'].get('name'), + desc=info_sslyze['openssl_ccs'].get('desc'), + severity=info_sslyze['openssl_ccs'].get('severity')) + + def processCommandString(self, username, current_path, command_string): + super().processCommandString(username, current_path, command_string) + arg_match = self.json_arg_re.match(command_string) + if arg_match is None: + return re.sub(r"(^.*?sslyze)", + r"\1 --json_out %s" % self._output_file_path, + command_string) + else: + return re.sub(arg_match.group(1), + r"--json_out %s" % self._output_file_path, + command_string) + + +def createPlugin(): + return SslyzePlugin() + From 20850090829fd8865cdfe46397a9da7601169e80 Mon Sep 17 00:00:00 2001 From: Blas Date: Thu, 12 Nov 2020 23:18:40 -0300 Subject: [PATCH 148/698] UPD change name host por url and fix IP --- faraday_plugins/plugins/repo/nuclei/plugin.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/faraday_plugins/plugins/repo/nuclei/plugin.py b/faraday_plugins/plugins/repo/nuclei/plugin.py index 49848fc5..beff7c41 100644 --- a/faraday_plugins/plugins/repo/nuclei/plugin.py +++ b/faraday_plugins/plugins/repo/nuclei/plugin.py @@ -47,8 +47,8 @@ def parseOutputString(self, output, debug=False): if vuln != '': json_vuln = json.loads(vuln) matched = json_vuln.get('matched', None) - url = urlparse(matched) - url_scheme = f'{url.scheme}://{url.hostname}' + url_parser = urlparse(matched) + url_scheme = f'{url_parser.scheme}://{url_parser.hostname}' if url_scheme in matched_list: matched_json[url_scheme].append(json_vuln) @@ -56,17 +56,16 @@ def parseOutputString(self, output, debug=False): matched_list.append(url_scheme) matched_json[url_scheme] = [json_vuln] - for host in matched_list: - url_data = urlparse(host) + for url in matched_list: + url_data = urlparse(url) url_name = url_data.hostname url_protocol = url_data.scheme - ip = resolve_hostname(host) + ip = resolve_hostname(url_name) host_id = self.createAndAddHost( name=ip, - hostnames=[host], - description="Nuclei") + hostnames=[url_name]) port = 80 - if url.scheme == 'https': + if url_parser.scheme == 'https': port = 443 service_id = self.createAndAddServiceToHost( @@ -78,7 +77,7 @@ def parseOutputString(self, output, debug=False): version='', description='') - for info_vuln in matched_json[host]: + for info_vuln in matched_json[url]: desc = f'{info_vuln.get("template", None)} - {info_vuln.get("author", None)}' self.createAndAddVulnWebToService( @@ -88,7 +87,7 @@ def parseOutputString(self, output, debug=False): desc=desc, ref=None, severity=info_vuln.get('severity', ""), - website=host, + website=url, request=info_vuln.get('request', None), response=info_vuln.get('response', None), method=info_vuln.get('type', None), From 3a5ba9f1dbb67785b79328636b502b1b6177eedb Mon Sep 17 00:00:00 2001 From: Blas Date: Mon, 16 Nov 2020 12:29:46 -0300 Subject: [PATCH 149/698] DEL command in sslyze XML , UPD fix flake in sslyze json --- faraday_plugins/plugins/repo/sslyze/plugin.py | 77 ++++++++----------- .../plugins/repo/sslyzejson/plugin.py | 11 +-- 2 files changed, 36 insertions(+), 52 deletions(-) diff --git a/faraday_plugins/plugins/repo/sslyze/plugin.py b/faraday_plugins/plugins/repo/sslyze/plugin.py index e01ce70c..5c621006 100644 --- a/faraday_plugins/plugins/repo/sslyze/plugin.py +++ b/faraday_plugins/plugins/repo/sslyze/plugin.py @@ -6,7 +6,6 @@ except ImportError: import xml.etree.ElementTree as ET - WEAK_CIPHER_LIST = [ "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA", @@ -15,9 +14,9 @@ "TLS_RSA_WITH_AES_256_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA256", "TLS_RSA_WITH_AES_256_GCM_SHA384", - "TLS_RSA_WITH_3DES_EDE_CBC_SHA", + "TLS_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA", - "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA" + "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA" ] @@ -31,7 +30,7 @@ def __init__(self, xml_output): self.heart_bleed = self.get_heartbleed(self.parser) self.open_ssl_ccs = self.get_openssl_ccs(self.parser) - def parse_xml(self, xml_output): + def parse_xml(self, xml_output): try: tree = ET.fromstring(xml_output) return tree @@ -41,7 +40,7 @@ def parse_xml(self, xml_output): def get_target(self, tree): return tree.xpath('//target') - + def get_hostname_validation(self, tree): return tree.xpath('//hostnameValidation') @@ -73,7 +72,7 @@ def get_weak_cipher_suite(self, tree): if cipher.attrib['name'] in WEAK_CIPHER_LIST: if not cipher.attrib['name'] in weak_cipher[protocol.tag]: weak_cipher[protocol.tag].append(cipher.attrib['name']) - + return weak_cipher def get_heartbleed(self, tree): @@ -88,15 +87,13 @@ class SslyzePlugin(PluginXMLFormat): def __init__(self): super().__init__() self.identifier_tag = "document" - self.id = "Sslyze" + self.id = "Sslyze XML" self.name = "Sslyze Plugin" self.plugin_version = "0.0.1" self.version = "2.0.6" self.framework_version = "1.0.0" self.options = None self._current_output = None - self._command_regex = re.compile(r'^(sudo sslyze|sslyze|\.\/sslyze)\s+.*?') - self.xml_arg_re = re.compile(r"^.*(--xml_output\s*[^\s]+).*$") self._use_temp_file = True self._temp_file_extension = "xml" @@ -115,75 +112,61 @@ def parseOutputString(self, output): port = parser.target[0].attrib['port'] protocol = parser.target[0].attrib['tlsWrappedProtocol'] cipher = parser.cipher_suite - + # Creating host host_id = self.createAndAddHost(ip) - # Creating service CHANGE NAME + # Creating service CHANGE NAME service_id = self.createAndAddServiceToHost( - host_id, + host_id, name=protocol, - protocol=protocol, + protocol=protocol, ports=[port], - ) - + ) + # Checking if certificate matches certificate = parser.certificate[0].attrib['certificateMatchesServerHostname'] server_hostname = parser.certificate[0].attrib['serverHostname'] if certificate.lower() == 'false': self.createAndAddVulnToService( - host_id, - service_id, - name="Certificate mismatch", - desc="Certificate does not match server hostname {}".format(server_hostname), + host_id, + service_id, + name="Certificate mismatch", + desc="Certificate does not match server hostname {}".format(server_hostname), severity="info") - #Ciphers + # Ciphers cipher = parser.cipher_suite for key in cipher: for value in cipher[key]: self.createAndAddVulnToService( - host_id, - service_id, + host_id, + service_id, name=value, - desc="In protocol [{}], weak cipher suite: {}".format(key, value), + desc="In protocol [{}], weak cipher suite: {}".format(key, value), severity="low") - - #Heartbleed + + # Heartbleed heartbleed = parser.heart_bleed if heartbleed[0][0].attrib['isVulnerable'].lower() == 'true': self.createAndAddVulnToService( - host_id, - service_id, + host_id, + service_id, name="OpenSSL Heartbleed", - desc="OpenSSL Heartbleed is vulnerable", + desc="OpenSSL Heartbleed is vulnerable", severity="critical") - - #OpenSsl CCS Injection + + # OpenSsl CCS Injection openssl_ccs = parser.open_ssl_ccs if openssl_ccs[0][0].attrib['isVulnerable'].lower() == 'true': self.createAndAddVulnToService( - host_id, - service_id, + host_id, + service_id, name="OpenSSL CCS Injection", - desc="OpenSSL CCS Injection is vulnerable", + desc="OpenSSL CCS Injection is vulnerable", severity="medium") - def processCommandString(self, username, current_path, command_string): - super().processCommandString(username, current_path, command_string) - arg_match = self.xml_arg_re.match(command_string) - if arg_match is None: - return re.sub(r"(^.*?sslyze)", - r"\1 --xml_out %s" % self._output_file_path, - command_string) - else: - return re.sub(arg_match.group(1), - r"--xml_out %s" % self._output_file_path, - command_string) - def createPlugin(): return SslyzePlugin() - -# I'm Py3 diff --git a/faraday_plugins/plugins/repo/sslyzejson/plugin.py b/faraday_plugins/plugins/repo/sslyzejson/plugin.py index 798f1703..1f5adb42 100644 --- a/faraday_plugins/plugins/repo/sslyzejson/plugin.py +++ b/faraday_plugins/plugins/repo/sslyzejson/plugin.py @@ -89,8 +89,9 @@ def get_host(self, server_location): def get_certification(self, certificate): certif_deploy = certificate['certificate_deployments'] - send_certif = certif_deploy[0].get('leaf_certificate_subject_matches_hostname', True) == False - if send_certif: + send_certif = certif_deploy[0].get('leaf_certificate_subject_matches_hostname', True) + + if not send_certif: json_certif = { "name": "Certificate mismatch", "desc": f"Certificate does not match server hostname {certificate.get('hostname_used_for_server_name_indication', 'Not hostname')}", @@ -121,7 +122,7 @@ def get_cipher(self, scan_result, list_commands): for cipher_suite in scan_result[command]['accepted_cipher_suites']: name_cipher = cipher_suite['cipher_suite'].get('name') if name_cipher in weak_cipher_list: - if not name_cipher in weak_cipher[command]: + if name_cipher not in weak_cipher[command]: weak_cipher[command].append(name_cipher) except KeyError: pass @@ -131,7 +132,7 @@ def get_cipher(self, scan_result, list_commands): for cipher_suite in scan_result[command]['accepted_cipher_suites']: name_cipher = cipher_suite['cipher_suite'].get('name') if name_cipher in weak_cipher_list: - if not name_cipher in weak_cipher[command]: + if name_cipher not in weak_cipher[command]: weak_cipher[command].append(name_cipher) except KeyError: pass @@ -163,7 +164,7 @@ class SslyzePlugin(PluginJsonFormat): def __init__(self): super().__init__() - self.id = "sslyzejson" + self.id = "Sslyze JSON" self.name = "Sslyze Json" self.plugin_version = "0.1" self.version = "3.4.5" From 69561a3eefbacb58afe9b03eb309b451c7da7f73 Mon Sep 17 00:00:00 2001 From: Blas Date: Tue, 17 Nov 2020 15:32:36 -0300 Subject: [PATCH 150/698] FIX matched is None --- faraday_plugins/plugins/repo/nuclei/plugin.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/faraday_plugins/plugins/repo/nuclei/plugin.py b/faraday_plugins/plugins/repo/nuclei/plugin.py index beff7c41..57c021ee 100644 --- a/faraday_plugins/plugins/repo/nuclei/plugin.py +++ b/faraday_plugins/plugins/repo/nuclei/plugin.py @@ -47,14 +47,16 @@ def parseOutputString(self, output, debug=False): if vuln != '': json_vuln = json.loads(vuln) matched = json_vuln.get('matched', None) - url_parser = urlparse(matched) - url_scheme = f'{url_parser.scheme}://{url_parser.hostname}' - - if url_scheme in matched_list: - matched_json[url_scheme].append(json_vuln) - else: - matched_list.append(url_scheme) - matched_json[url_scheme] = [json_vuln] + + if matched is not None: + url_parser = urlparse(matched) + url_scheme = f'{url_parser.scheme}://{url_parser.hostname}' + + if url_scheme in matched_list: + matched_json[url_scheme].append(json_vuln) + else: + matched_list.append(url_scheme) + matched_json[url_scheme] = [json_vuln] for url in matched_list: url_data = urlparse(url) From 5e4db2403133c158ebe3ec82488c4029832a1bf0 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Fri, 4 Dec 2020 19:35:06 -0300 Subject: [PATCH 151/698] remove namespace from main_tag --- faraday_plugins/plugins/manager.py | 6 +++++- faraday_plugins/plugins/repo/openscap/plugin.py | 12 ++---------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/faraday_plugins/plugins/manager.py b/faraday_plugins/plugins/manager.py index 9472c7dc..50a00d46 100644 --- a/faraday_plugins/plugins/manager.py +++ b/faraday_plugins/plugins/manager.py @@ -81,7 +81,11 @@ def _get_plugin_by_file_type(self, report_path): else: try: for event, elem in ET.iterparse(report_file, ('start',)): - main_tag = elem.tag + prefix, has_namespace, postfix = elem.tag.partition("}") + if has_namespace: + main_tag = postfix + else: + main_tag = elem.tag break logger.debug("Found XML content on file: %s - Main tag: %s", report_path, main_tag) except Exception as e: diff --git a/faraday_plugins/plugins/repo/openscap/plugin.py b/faraday_plugins/plugins/repo/openscap/plugin.py index 1047b7a3..02ff3a72 100644 --- a/faraday_plugins/plugins/repo/openscap/plugin.py +++ b/faraday_plugins/plugins/repo/openscap/plugin.py @@ -127,7 +127,7 @@ def get_parser_result(self, tree): class OpenScapPlugin(PluginXMLFormat): def __init__(self): super().__init__() - self.identifier_tag = ["Benchmark"] + self.identifier_tag = "Benchmark" self.id = 'OpenScap' self.name = 'OpenScap XML Output Plugin' self.plugin_version = '1.0.0' @@ -136,15 +136,7 @@ def __init__(self): self.options = None self.protocol = None self.port = '80' - self.address = None - - def report_belongs_to(self, main_tag="", **kwargs): - match = False - if not super().report_belongs_to(**kwargs): - if type(self.identifier_tag) == list: - if main_tag.find(self.identifier_tag[0]) >= 0: - match = True - return match + def parseOutputString(self, output): From 0522905dd0212f30ba50f14570e429539b25917b Mon Sep 17 00:00:00 2001 From: Eric Horvat Date: Mon, 14 Dec 2020 11:26:43 -0300 Subject: [PATCH 152/698] [MOD] Prepare 1.4.0(beta) Changelog --- .../{current => 1.4.0}/add_multilinejson_format.md | 0 CHANGELOG/{current => 1.4.0}/add_ncrack.md | 0 CHANGELOG/{current => 1.4.0}/add_nuclei.md | 0 CHANGELOG/{current => 1.4.0}/add_sslyze_json.md | 0 CHANGELOG/{current => 1.4.0}/add_whatweb.md | 0 .../{current => 1.4.0}/fix_arachni_ip_missing.md | 0 CHANGELOG/{current => 1.4.0}/fix_netsparker.md | 0 CHANGELOG/{current => 1.4.0}/fix_whois.md | 0 .../modify_json_reports_detection.md | 0 CHANGELOG/RELEASE.md | 12 ++++++++++++ RELEASE.md | 12 ++++++++++++ 11 files changed, 24 insertions(+) rename CHANGELOG/{current => 1.4.0}/add_multilinejson_format.md (100%) rename CHANGELOG/{current => 1.4.0}/add_ncrack.md (100%) rename CHANGELOG/{current => 1.4.0}/add_nuclei.md (100%) rename CHANGELOG/{current => 1.4.0}/add_sslyze_json.md (100%) rename CHANGELOG/{current => 1.4.0}/add_whatweb.md (100%) rename CHANGELOG/{current => 1.4.0}/fix_arachni_ip_missing.md (100%) rename CHANGELOG/{current => 1.4.0}/fix_netsparker.md (100%) rename CHANGELOG/{current => 1.4.0}/fix_whois.md (100%) rename CHANGELOG/{current => 1.4.0}/modify_json_reports_detection.md (100%) diff --git a/CHANGELOG/current/add_multilinejson_format.md b/CHANGELOG/1.4.0/add_multilinejson_format.md similarity index 100% rename from CHANGELOG/current/add_multilinejson_format.md rename to CHANGELOG/1.4.0/add_multilinejson_format.md diff --git a/CHANGELOG/current/add_ncrack.md b/CHANGELOG/1.4.0/add_ncrack.md similarity index 100% rename from CHANGELOG/current/add_ncrack.md rename to CHANGELOG/1.4.0/add_ncrack.md diff --git a/CHANGELOG/current/add_nuclei.md b/CHANGELOG/1.4.0/add_nuclei.md similarity index 100% rename from CHANGELOG/current/add_nuclei.md rename to CHANGELOG/1.4.0/add_nuclei.md diff --git a/CHANGELOG/current/add_sslyze_json.md b/CHANGELOG/1.4.0/add_sslyze_json.md similarity index 100% rename from CHANGELOG/current/add_sslyze_json.md rename to CHANGELOG/1.4.0/add_sslyze_json.md diff --git a/CHANGELOG/current/add_whatweb.md b/CHANGELOG/1.4.0/add_whatweb.md similarity index 100% rename from CHANGELOG/current/add_whatweb.md rename to CHANGELOG/1.4.0/add_whatweb.md diff --git a/CHANGELOG/current/fix_arachni_ip_missing.md b/CHANGELOG/1.4.0/fix_arachni_ip_missing.md similarity index 100% rename from CHANGELOG/current/fix_arachni_ip_missing.md rename to CHANGELOG/1.4.0/fix_arachni_ip_missing.md diff --git a/CHANGELOG/current/fix_netsparker.md b/CHANGELOG/1.4.0/fix_netsparker.md similarity index 100% rename from CHANGELOG/current/fix_netsparker.md rename to CHANGELOG/1.4.0/fix_netsparker.md diff --git a/CHANGELOG/current/fix_whois.md b/CHANGELOG/1.4.0/fix_whois.md similarity index 100% rename from CHANGELOG/current/fix_whois.md rename to CHANGELOG/1.4.0/fix_whois.md diff --git a/CHANGELOG/current/modify_json_reports_detection.md b/CHANGELOG/1.4.0/modify_json_reports_detection.md similarity index 100% rename from CHANGELOG/current/modify_json_reports_detection.md rename to CHANGELOG/1.4.0/modify_json_reports_detection.md diff --git a/CHANGELOG/RELEASE.md b/CHANGELOG/RELEASE.md index 4b0ee7be..ac3e8582 100644 --- a/CHANGELOG/RELEASE.md +++ b/CHANGELOG/RELEASE.md @@ -1,3 +1,15 @@ +1.4.0: +--- + * Add new plugin base class, for multi line json + * New ncrack plugin + * New nuclei plugin + * New sslyze json plugin + * New WhatWeb plugin + * Fix missing ip in some arachni reports + * Fix change name vuln in Netsparker plugin + * Fix whois plugin, command whois IP not parse data + * Change the way we detect json reports when they are lists of dictionaries + 1.3.0: --- * ADD plugin AppSpider diff --git a/RELEASE.md b/RELEASE.md index 4b0ee7be..ac3e8582 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,3 +1,15 @@ +1.4.0: +--- + * Add new plugin base class, for multi line json + * New ncrack plugin + * New nuclei plugin + * New sslyze json plugin + * New WhatWeb plugin + * Fix missing ip in some arachni reports + * Fix change name vuln in Netsparker plugin + * Fix whois plugin, command whois IP not parse data + * Change the way we detect json reports when they are lists of dictionaries + 1.3.0: --- * ADD plugin AppSpider From d463fe81c6aa8031fa272a1a1f2fbdb78ec5c92f Mon Sep 17 00:00:00 2001 From: Eric Horvat Date: Mon, 14 Dec 2020 12:00:50 -0300 Subject: [PATCH 153/698] [MOD] Last references 1.4.0b1 --- CHANGELOG/1.3.0/date.md | 1 + CHANGELOG/{1.4.0 => 1.4.0b1}/add_multilinejson_format.md | 0 CHANGELOG/{1.4.0 => 1.4.0b1}/add_ncrack.md | 0 CHANGELOG/{1.4.0 => 1.4.0b1}/add_nuclei.md | 0 CHANGELOG/{1.4.0 => 1.4.0b1}/add_sslyze_json.md | 0 CHANGELOG/{1.4.0 => 1.4.0b1}/add_whatweb.md | 0 CHANGELOG/{1.4.0 => 1.4.0b1}/fix_arachni_ip_missing.md | 0 CHANGELOG/{1.4.0 => 1.4.0b1}/fix_netsparker.md | 0 CHANGELOG/{1.4.0 => 1.4.0b1}/fix_whois.md | 0 CHANGELOG/{1.4.0 => 1.4.0b1}/modify_json_reports_detection.md | 0 CHANGELOG/RELEASE.md | 4 ++-- faraday_plugins/__init__.py | 2 +- 12 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 CHANGELOG/1.3.0/date.md rename CHANGELOG/{1.4.0 => 1.4.0b1}/add_multilinejson_format.md (100%) rename CHANGELOG/{1.4.0 => 1.4.0b1}/add_ncrack.md (100%) rename CHANGELOG/{1.4.0 => 1.4.0b1}/add_nuclei.md (100%) rename CHANGELOG/{1.4.0 => 1.4.0b1}/add_sslyze_json.md (100%) rename CHANGELOG/{1.4.0 => 1.4.0b1}/add_whatweb.md (100%) rename CHANGELOG/{1.4.0 => 1.4.0b1}/fix_arachni_ip_missing.md (100%) rename CHANGELOG/{1.4.0 => 1.4.0b1}/fix_netsparker.md (100%) rename CHANGELOG/{1.4.0 => 1.4.0b1}/fix_whois.md (100%) rename CHANGELOG/{1.4.0 => 1.4.0b1}/modify_json_reports_detection.md (100%) diff --git a/CHANGELOG/1.3.0/date.md b/CHANGELOG/1.3.0/date.md new file mode 100644 index 00000000..ca52a58b --- /dev/null +++ b/CHANGELOG/1.3.0/date.md @@ -0,0 +1 @@ +Sep 2nd, 2020 \ No newline at end of file diff --git a/CHANGELOG/1.4.0/add_multilinejson_format.md b/CHANGELOG/1.4.0b1/add_multilinejson_format.md similarity index 100% rename from CHANGELOG/1.4.0/add_multilinejson_format.md rename to CHANGELOG/1.4.0b1/add_multilinejson_format.md diff --git a/CHANGELOG/1.4.0/add_ncrack.md b/CHANGELOG/1.4.0b1/add_ncrack.md similarity index 100% rename from CHANGELOG/1.4.0/add_ncrack.md rename to CHANGELOG/1.4.0b1/add_ncrack.md diff --git a/CHANGELOG/1.4.0/add_nuclei.md b/CHANGELOG/1.4.0b1/add_nuclei.md similarity index 100% rename from CHANGELOG/1.4.0/add_nuclei.md rename to CHANGELOG/1.4.0b1/add_nuclei.md diff --git a/CHANGELOG/1.4.0/add_sslyze_json.md b/CHANGELOG/1.4.0b1/add_sslyze_json.md similarity index 100% rename from CHANGELOG/1.4.0/add_sslyze_json.md rename to CHANGELOG/1.4.0b1/add_sslyze_json.md diff --git a/CHANGELOG/1.4.0/add_whatweb.md b/CHANGELOG/1.4.0b1/add_whatweb.md similarity index 100% rename from CHANGELOG/1.4.0/add_whatweb.md rename to CHANGELOG/1.4.0b1/add_whatweb.md diff --git a/CHANGELOG/1.4.0/fix_arachni_ip_missing.md b/CHANGELOG/1.4.0b1/fix_arachni_ip_missing.md similarity index 100% rename from CHANGELOG/1.4.0/fix_arachni_ip_missing.md rename to CHANGELOG/1.4.0b1/fix_arachni_ip_missing.md diff --git a/CHANGELOG/1.4.0/fix_netsparker.md b/CHANGELOG/1.4.0b1/fix_netsparker.md similarity index 100% rename from CHANGELOG/1.4.0/fix_netsparker.md rename to CHANGELOG/1.4.0b1/fix_netsparker.md diff --git a/CHANGELOG/1.4.0/fix_whois.md b/CHANGELOG/1.4.0b1/fix_whois.md similarity index 100% rename from CHANGELOG/1.4.0/fix_whois.md rename to CHANGELOG/1.4.0b1/fix_whois.md diff --git a/CHANGELOG/1.4.0/modify_json_reports_detection.md b/CHANGELOG/1.4.0b1/modify_json_reports_detection.md similarity index 100% rename from CHANGELOG/1.4.0/modify_json_reports_detection.md rename to CHANGELOG/1.4.0b1/modify_json_reports_detection.md diff --git a/CHANGELOG/RELEASE.md b/CHANGELOG/RELEASE.md index ac3e8582..b69fb53f 100644 --- a/CHANGELOG/RELEASE.md +++ b/CHANGELOG/RELEASE.md @@ -1,4 +1,4 @@ -1.4.0: +1.4.0b1: --- * Add new plugin base class, for multi line json * New ncrack plugin @@ -10,7 +10,7 @@ * Fix whois plugin, command whois IP not parse data * Change the way we detect json reports when they are lists of dictionaries -1.3.0: +1.3.0 [Sep 2nd, 2020]: --- * ADD plugin AppSpider * Add tests to faraday-plugins cli diff --git a/faraday_plugins/__init__.py b/faraday_plugins/__init__.py index 19b4f1d6..0e092e7a 100644 --- a/faraday_plugins/__init__.py +++ b/faraday_plugins/__init__.py @@ -1 +1 @@ -__version__ = '1.3.0' +__version__ = '1.4.0b1' From 1effc96a094423d1e8f624c52b120332f54fb1f5 Mon Sep 17 00:00:00 2001 From: Eric Horvat Date: Mon, 14 Dec 2020 12:11:21 -0300 Subject: [PATCH 154/698] [MOD] "typo" update of changelog file --- RELEASE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index ac3e8582..b69fb53f 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,4 +1,4 @@ -1.4.0: +1.4.0b1: --- * Add new plugin base class, for multi line json * New ncrack plugin @@ -10,7 +10,7 @@ * Fix whois plugin, command whois IP not parse data * Change the way we detect json reports when they are lists of dictionaries -1.3.0: +1.3.0 [Sep 2nd, 2020]: --- * ADD plugin AppSpider * Add tests to faraday-plugins cli From 7a7d5964d3058bb0cae73188f6cf76b4cb33a9fe Mon Sep 17 00:00:00 2001 From: Blas Date: Tue, 15 Dec 2020 11:55:04 -0300 Subject: [PATCH 155/698] FIX url none --- CHANGELOG/current/fix_nuclei.md | 1 + faraday_plugins/plugins/repo/nuclei/plugin.py | 22 ++++++++----------- 2 files changed, 10 insertions(+), 13 deletions(-) create mode 100644 CHANGELOG/current/fix_nuclei.md diff --git a/CHANGELOG/current/fix_nuclei.md b/CHANGELOG/current/fix_nuclei.md new file mode 100644 index 00000000..b161e113 --- /dev/null +++ b/CHANGELOG/current/fix_nuclei.md @@ -0,0 +1 @@ +FIX nuclei url none \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/nuclei/plugin.py b/faraday_plugins/plugins/repo/nuclei/plugin.py index 57c021ee..f4ee2619 100644 --- a/faraday_plugins/plugins/repo/nuclei/plugin.py +++ b/faraday_plugins/plugins/repo/nuclei/plugin.py @@ -47,17 +47,15 @@ def parseOutputString(self, output, debug=False): if vuln != '': json_vuln = json.loads(vuln) matched = json_vuln.get('matched', None) - if matched is not None: url_parser = urlparse(matched) - url_scheme = f'{url_parser.scheme}://{url_parser.hostname}' - - if url_scheme in matched_list: - matched_json[url_scheme].append(json_vuln) - else: - matched_list.append(url_scheme) - matched_json[url_scheme] = [json_vuln] - + if url_parser.hostname is not None: + url_scheme = f'{url_parser.scheme}://{url_parser.hostname}' + if url_scheme in matched_list: + matched_json[url_scheme].append(json_vuln) + else: + matched_list.append(url_scheme) + matched_json[url_scheme] = [json_vuln] for url in matched_list: url_data = urlparse(url) url_name = url_data.hostname @@ -65,7 +63,8 @@ def parseOutputString(self, output, debug=False): ip = resolve_hostname(url_name) host_id = self.createAndAddHost( name=ip, - hostnames=[url_name]) + hostnames=[url_name] + ) port = 80 if url_parser.scheme == 'https': port = 443 @@ -98,6 +97,3 @@ def parseOutputString(self, output, debug=False): def createPlugin(): return NucleiPlugin() - - - From 05614df1a53262be1b985c2565dde410a8c3fb12 Mon Sep 17 00:00:00 2001 From: Eric Horvat Date: Tue, 15 Dec 2020 14:19:29 -0300 Subject: [PATCH 156/698] [MOD] Changelogs for 1.4.0b2 + version file --- CHANGELOG/1.4.0b1/date.md | 1 + CHANGELOG/1.4.0b2/date.md | 1 + CHANGELOG/1.4.0b2/fix_nuclei.md | 1 + CHANGELOG/RELEASE.md | 6 +++++- CHANGELOG/current/fix_nuclei.md | 1 - RELEASE.md | 6 +++++- faraday_plugins/__init__.py | 2 +- 7 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 CHANGELOG/1.4.0b1/date.md create mode 100644 CHANGELOG/1.4.0b2/date.md create mode 100644 CHANGELOG/1.4.0b2/fix_nuclei.md delete mode 100644 CHANGELOG/current/fix_nuclei.md diff --git a/CHANGELOG/1.4.0b1/date.md b/CHANGELOG/1.4.0b1/date.md new file mode 100644 index 00000000..c691eb27 --- /dev/null +++ b/CHANGELOG/1.4.0b1/date.md @@ -0,0 +1 @@ +Dec 14th, 2020 \ No newline at end of file diff --git a/CHANGELOG/1.4.0b2/date.md b/CHANGELOG/1.4.0b2/date.md new file mode 100644 index 00000000..585afaf5 --- /dev/null +++ b/CHANGELOG/1.4.0b2/date.md @@ -0,0 +1 @@ +Dec 15th, 2020 \ No newline at end of file diff --git a/CHANGELOG/1.4.0b2/fix_nuclei.md b/CHANGELOG/1.4.0b2/fix_nuclei.md new file mode 100644 index 00000000..ef0a22eb --- /dev/null +++ b/CHANGELOG/1.4.0b2/fix_nuclei.md @@ -0,0 +1 @@ +Fix nuclei plugin bug when url is None \ No newline at end of file diff --git a/CHANGELOG/RELEASE.md b/CHANGELOG/RELEASE.md index b69fb53f..ea150430 100644 --- a/CHANGELOG/RELEASE.md +++ b/CHANGELOG/RELEASE.md @@ -1,4 +1,8 @@ -1.4.0b1: +1.4.0b2 [Dec 15th, 2020]: +--- + * Fix nuclei plugin bug when url is None + +1.4.0b1 [Dec 14th, 2020]: --- * Add new plugin base class, for multi line json * New ncrack plugin diff --git a/CHANGELOG/current/fix_nuclei.md b/CHANGELOG/current/fix_nuclei.md deleted file mode 100644 index b161e113..00000000 --- a/CHANGELOG/current/fix_nuclei.md +++ /dev/null @@ -1 +0,0 @@ -FIX nuclei url none \ No newline at end of file diff --git a/RELEASE.md b/RELEASE.md index b69fb53f..ea150430 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,4 +1,8 @@ -1.4.0b1: +1.4.0b2 [Dec 15th, 2020]: +--- + * Fix nuclei plugin bug when url is None + +1.4.0b1 [Dec 14th, 2020]: --- * Add new plugin base class, for multi line json * New ncrack plugin diff --git a/faraday_plugins/__init__.py b/faraday_plugins/__init__.py index 0e092e7a..3983595e 100644 --- a/faraday_plugins/__init__.py +++ b/faraday_plugins/__init__.py @@ -1 +1 @@ -__version__ = '1.4.0b1' +__version__ = '1.4.0b2' From de0cca1d79e5ed5bb5b4588049a0b8f9edff4647 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Mon, 21 Dec 2020 20:17:48 -0300 Subject: [PATCH 157/698] update nuclei vuln fields --- CHANGELOG/current/update_nuclei_fields.md | 1 + faraday_plugins/plugins/repo/nuclei/plugin.py | 18 +++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 CHANGELOG/current/update_nuclei_fields.md diff --git a/CHANGELOG/current/update_nuclei_fields.md b/CHANGELOG/current/update_nuclei_fields.md new file mode 100644 index 00000000..9d67a341 --- /dev/null +++ b/CHANGELOG/current/update_nuclei_fields.md @@ -0,0 +1 @@ +Update the fields of the nuclei output used to create a vuln \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/nuclei/plugin.py b/faraday_plugins/plugins/repo/nuclei/plugin.py index 57c021ee..f80cd39e 100644 --- a/faraday_plugins/plugins/repo/nuclei/plugin.py +++ b/faraday_plugins/plugins/repo/nuclei/plugin.py @@ -72,28 +72,32 @@ def parseOutputString(self, output, debug=False): service_id = self.createAndAddServiceToHost( host_id, - name=url_name, + name=url_parser.scheme, ports=port, - protocol=url_protocol, + protocol="tcp", status='open', version='', description='') for info_vuln in matched_json[url]: desc = f'{info_vuln.get("template", None)} - {info_vuln.get("author", None)}' - + if info_vuln.get("author", None): + ref = [f"author: {info_vuln.get('author', None)}"] + else: + ref = None self.createAndAddVulnWebToService( host_id, service_id, - name=info_vuln.get('matcher_name', "Nuclei"), - desc=desc, - ref=None, + name=info_vuln.get('template', ""), + desc=info_vuln.get('description', info_vuln.get('name', None)), + ref=ref, severity=info_vuln.get('severity', ""), website=url, request=info_vuln.get('request', None), response=info_vuln.get('response', None), method=info_vuln.get('type', None), - data=info_vuln.get('name', None)) + data=info_vuln.get('matcher_name', info_vuln.get('name', None)), + external_id=info_vuln.get('template', "")) def createPlugin(): From a87108bf714a4abf60f5ebce2e3cac3d11893cc2 Mon Sep 17 00:00:00 2001 From: Eric Horvat Date: Tue, 22 Dec 2020 21:45:16 -0300 Subject: [PATCH 158/698] [MOD] Changelog to 1.4.0 --- CHANGELOG/1.4.0/date.md | 1 + CHANGELOG/{current => 1.4.0}/update_nuclei_fields.md | 0 CHANGELOG/RELEASE.md | 4 ++++ CHANGELOG/current/add_appspider.md | 1 - CHANGELOG/current/add_cli_tests.md | 1 - CHANGELOG/current/add_default_plugin_version.md | 1 - CHANGELOG/current/add_multilinejson_format.md | 1 - CHANGELOG/current/add_ncrack.md | 1 - CHANGELOG/current/add_nuclei.md | 1 - .../current/add_output_file_to_faraday-plugins_command.md | 1 - CHANGELOG/current/add_prowler.md | 1 - CHANGELOG/current/add_ssl_labs.md | 1 - CHANGELOG/current/add_sslyze_json.md | 1 - CHANGELOG/current/add_tenableio_support.md | 1 - CHANGELOG/current/add_whatweb.md | 1 - CHANGELOG/current/delete_old_methods.md | 1 - CHANGELOG/current/fix_Arachni.md | 1 - CHANGELOG/current/fix_Openvas.md | 1 - CHANGELOG/current/fix_QualysWebapp.md | 1 - CHANGELOG/current/fix_arachni_ip_missing.md | 1 - CHANGELOG/current/fix_hydra_to_resolve_ip.md | 1 - CHANGELOG/current/fix_nessus.md | 1 - CHANGELOG/current/fix_netsparker.md | 1 - CHANGELOG/current/fix_prowler.md | 1 - CHANGELOG/current/fix_redlink.md | 1 - CHANGELOG/current/fix_whois.md | 1 - CHANGELOG/current/fix_xml_nmap.md | 1 - CHANGELOG/current/modify_json_reports_detection.md | 1 - CHANGELOG/current/new_rdpscan_plugin.md | 1 - CHANGELOG/current/update_appscan.md | 1 - CHANGELOG/current/update_readme.md | 1 - CHANGELOG/current/update_zap.md | 1 - RELEASE.md | 4 ++++ faraday_plugins/__init__.py | 2 +- 34 files changed, 10 insertions(+), 30 deletions(-) create mode 100644 CHANGELOG/1.4.0/date.md rename CHANGELOG/{current => 1.4.0}/update_nuclei_fields.md (100%) delete mode 100644 CHANGELOG/current/add_appspider.md delete mode 100644 CHANGELOG/current/add_cli_tests.md delete mode 100644 CHANGELOG/current/add_default_plugin_version.md delete mode 100644 CHANGELOG/current/add_multilinejson_format.md delete mode 100644 CHANGELOG/current/add_ncrack.md delete mode 100644 CHANGELOG/current/add_nuclei.md delete mode 100644 CHANGELOG/current/add_output_file_to_faraday-plugins_command.md delete mode 100644 CHANGELOG/current/add_prowler.md delete mode 100644 CHANGELOG/current/add_ssl_labs.md delete mode 100644 CHANGELOG/current/add_sslyze_json.md delete mode 100644 CHANGELOG/current/add_tenableio_support.md delete mode 100644 CHANGELOG/current/add_whatweb.md delete mode 100644 CHANGELOG/current/delete_old_methods.md delete mode 100644 CHANGELOG/current/fix_Arachni.md delete mode 100644 CHANGELOG/current/fix_Openvas.md delete mode 100644 CHANGELOG/current/fix_QualysWebapp.md delete mode 100644 CHANGELOG/current/fix_arachni_ip_missing.md delete mode 100644 CHANGELOG/current/fix_hydra_to_resolve_ip.md delete mode 100644 CHANGELOG/current/fix_nessus.md delete mode 100644 CHANGELOG/current/fix_netsparker.md delete mode 100644 CHANGELOG/current/fix_prowler.md delete mode 100644 CHANGELOG/current/fix_redlink.md delete mode 100644 CHANGELOG/current/fix_whois.md delete mode 100644 CHANGELOG/current/fix_xml_nmap.md delete mode 100644 CHANGELOG/current/modify_json_reports_detection.md delete mode 100644 CHANGELOG/current/new_rdpscan_plugin.md delete mode 100644 CHANGELOG/current/update_appscan.md delete mode 100644 CHANGELOG/current/update_readme.md delete mode 100644 CHANGELOG/current/update_zap.md diff --git a/CHANGELOG/1.4.0/date.md b/CHANGELOG/1.4.0/date.md new file mode 100644 index 00000000..70af2e91 --- /dev/null +++ b/CHANGELOG/1.4.0/date.md @@ -0,0 +1 @@ +Dec 23rd, 2020 diff --git a/CHANGELOG/current/update_nuclei_fields.md b/CHANGELOG/1.4.0/update_nuclei_fields.md similarity index 100% rename from CHANGELOG/current/update_nuclei_fields.md rename to CHANGELOG/1.4.0/update_nuclei_fields.md diff --git a/CHANGELOG/RELEASE.md b/CHANGELOG/RELEASE.md index ea150430..82de3bd0 100644 --- a/CHANGELOG/RELEASE.md +++ b/CHANGELOG/RELEASE.md @@ -1,3 +1,7 @@ +1.4.0 [Dec 23rd, 2020]: +--- + * Update the fields of the nuclei output used to create a vuln + 1.4.0b2 [Dec 15th, 2020]: --- * Fix nuclei plugin bug when url is None diff --git a/CHANGELOG/current/add_appspider.md b/CHANGELOG/current/add_appspider.md deleted file mode 100644 index a2dabc6e..00000000 --- a/CHANGELOG/current/add_appspider.md +++ /dev/null @@ -1 +0,0 @@ -ADD plugin AppSpider diff --git a/CHANGELOG/current/add_cli_tests.md b/CHANGELOG/current/add_cli_tests.md deleted file mode 100644 index 9d2aa581..00000000 --- a/CHANGELOG/current/add_cli_tests.md +++ /dev/null @@ -1 +0,0 @@ -Add tests to faraday-plugins cli \ No newline at end of file diff --git a/CHANGELOG/current/add_default_plugin_version.md b/CHANGELOG/current/add_default_plugin_version.md deleted file mode 100644 index acf11059..00000000 --- a/CHANGELOG/current/add_default_plugin_version.md +++ /dev/null @@ -1 +0,0 @@ -add a default value to plugin_version \ No newline at end of file diff --git a/CHANGELOG/current/add_multilinejson_format.md b/CHANGELOG/current/add_multilinejson_format.md deleted file mode 100644 index 68710fe3..00000000 --- a/CHANGELOG/current/add_multilinejson_format.md +++ /dev/null @@ -1 +0,0 @@ -Add new plugin base class, for multi line json \ No newline at end of file diff --git a/CHANGELOG/current/add_ncrack.md b/CHANGELOG/current/add_ncrack.md deleted file mode 100644 index d6829fb2..00000000 --- a/CHANGELOG/current/add_ncrack.md +++ /dev/null @@ -1 +0,0 @@ -ADD plugin ncrack \ No newline at end of file diff --git a/CHANGELOG/current/add_nuclei.md b/CHANGELOG/current/add_nuclei.md deleted file mode 100644 index a4431b8f..00000000 --- a/CHANGELOG/current/add_nuclei.md +++ /dev/null @@ -1 +0,0 @@ -add plugin nuclei \ No newline at end of file diff --git a/CHANGELOG/current/add_output_file_to_faraday-plugins_command.md b/CHANGELOG/current/add_output_file_to_faraday-plugins_command.md deleted file mode 100644 index ee950889..00000000 --- a/CHANGELOG/current/add_output_file_to_faraday-plugins_command.md +++ /dev/null @@ -1 +0,0 @@ -Add --output-file parameter to faraday-plugins process command \ No newline at end of file diff --git a/CHANGELOG/current/add_prowler.md b/CHANGELOG/current/add_prowler.md deleted file mode 100644 index b4d6355d..00000000 --- a/CHANGELOG/current/add_prowler.md +++ /dev/null @@ -1 +0,0 @@ -Add plugins prowler \ No newline at end of file diff --git a/CHANGELOG/current/add_ssl_labs.md b/CHANGELOG/current/add_ssl_labs.md deleted file mode 100644 index 2491ffe3..00000000 --- a/CHANGELOG/current/add_ssl_labs.md +++ /dev/null @@ -1 +0,0 @@ -Add plugins ssl labs \ No newline at end of file diff --git a/CHANGELOG/current/add_sslyze_json.md b/CHANGELOG/current/add_sslyze_json.md deleted file mode 100644 index fe128111..00000000 --- a/CHANGELOG/current/add_sslyze_json.md +++ /dev/null @@ -1 +0,0 @@ -ADD plugins sslyze for json \ No newline at end of file diff --git a/CHANGELOG/current/add_tenableio_support.md b/CHANGELOG/current/add_tenableio_support.md deleted file mode 100644 index 188c5260..00000000 --- a/CHANGELOG/current/add_tenableio_support.md +++ /dev/null @@ -1 +0,0 @@ -Add support for tenable io \ No newline at end of file diff --git a/CHANGELOG/current/add_whatweb.md b/CHANGELOG/current/add_whatweb.md deleted file mode 100644 index d6464f3d..00000000 --- a/CHANGELOG/current/add_whatweb.md +++ /dev/null @@ -1 +0,0 @@ -ADD plugin WhatWeb \ No newline at end of file diff --git a/CHANGELOG/current/delete_old_methods.md b/CHANGELOG/current/delete_old_methods.md deleted file mode 100644 index f36561a1..00000000 --- a/CHANGELOG/current/delete_old_methods.md +++ /dev/null @@ -1 +0,0 @@ -delete old deprecated methods \ No newline at end of file diff --git a/CHANGELOG/current/fix_Arachni.md b/CHANGELOG/current/fix_Arachni.md deleted file mode 100644 index 3a812d06..00000000 --- a/CHANGELOG/current/fix_Arachni.md +++ /dev/null @@ -1 +0,0 @@ -* Bug fix: Arachni Plugin 'NoneType' object has no attribute 'find' diff --git a/CHANGELOG/current/fix_Openvas.md b/CHANGELOG/current/fix_Openvas.md deleted file mode 100644 index ce3f6e02..00000000 --- a/CHANGELOG/current/fix_Openvas.md +++ /dev/null @@ -1 +0,0 @@ -* Bug fix: Openvas Plugin - Import xml from OpenVas doesnt work diff --git a/CHANGELOG/current/fix_QualysWebapp.md b/CHANGELOG/current/fix_QualysWebapp.md deleted file mode 100644 index 97a2b0d9..00000000 --- a/CHANGELOG/current/fix_QualysWebapp.md +++ /dev/null @@ -1 +0,0 @@ -* Bug fix: QualysWebApp Plugin, error in get info OPERATING_SYSTEM diff --git a/CHANGELOG/current/fix_arachni_ip_missing.md b/CHANGELOG/current/fix_arachni_ip_missing.md deleted file mode 100644 index 73d7d58c..00000000 --- a/CHANGELOG/current/fix_arachni_ip_missing.md +++ /dev/null @@ -1 +0,0 @@ -Fix missing ip in some arachni reports \ No newline at end of file diff --git a/CHANGELOG/current/fix_hydra_to_resolve_ip.md b/CHANGELOG/current/fix_hydra_to_resolve_ip.md deleted file mode 100644 index 8a5fe528..00000000 --- a/CHANGELOG/current/fix_hydra_to_resolve_ip.md +++ /dev/null @@ -1 +0,0 @@ -Fix Hydra plugin to resolve ip address \ No newline at end of file diff --git a/CHANGELOG/current/fix_nessus.md b/CHANGELOG/current/fix_nessus.md deleted file mode 100644 index 50c470c6..00000000 --- a/CHANGELOG/current/fix_nessus.md +++ /dev/null @@ -1 +0,0 @@ -Fix Nessus mod severity HIGH for Low \ No newline at end of file diff --git a/CHANGELOG/current/fix_netsparker.md b/CHANGELOG/current/fix_netsparker.md deleted file mode 100644 index 77fec880..00000000 --- a/CHANGELOG/current/fix_netsparker.md +++ /dev/null @@ -1 +0,0 @@ -FIX Netsparker change name vuln \ No newline at end of file diff --git a/CHANGELOG/current/fix_prowler.md b/CHANGELOG/current/fix_prowler.md deleted file mode 100644 index 2608bd7d..00000000 --- a/CHANGELOG/current/fix_prowler.md +++ /dev/null @@ -1 +0,0 @@ -* Bug Fix: Detect plugins AWS Prowler diff --git a/CHANGELOG/current/fix_redlink.md b/CHANGELOG/current/fix_redlink.md deleted file mode 100644 index ca0e9cb3..00000000 --- a/CHANGELOG/current/fix_redlink.md +++ /dev/null @@ -1 +0,0 @@ -FIX resolution check key in dict \ No newline at end of file diff --git a/CHANGELOG/current/fix_whois.md b/CHANGELOG/current/fix_whois.md deleted file mode 100644 index 2ef301db..00000000 --- a/CHANGELOG/current/fix_whois.md +++ /dev/null @@ -1 +0,0 @@ -FIX whois. command whois IP not parse data \ No newline at end of file diff --git a/CHANGELOG/current/fix_xml_nmap.md b/CHANGELOG/current/fix_xml_nmap.md deleted file mode 100644 index bba79048..00000000 --- a/CHANGELOG/current/fix_xml_nmap.md +++ /dev/null @@ -1 +0,0 @@ -* Fix broken xml on nmap plugin diff --git a/CHANGELOG/current/modify_json_reports_detection.md b/CHANGELOG/current/modify_json_reports_detection.md deleted file mode 100644 index 3a685769..00000000 --- a/CHANGELOG/current/modify_json_reports_detection.md +++ /dev/null @@ -1 +0,0 @@ -Change the way we detect json reports when they are lists of dictionaries \ No newline at end of file diff --git a/CHANGELOG/current/new_rdpscan_plugin.md b/CHANGELOG/current/new_rdpscan_plugin.md deleted file mode 100644 index 65802044..00000000 --- a/CHANGELOG/current/new_rdpscan_plugin.md +++ /dev/null @@ -1 +0,0 @@ -* Add new rdpscan plugin diff --git a/CHANGELOG/current/update_appscan.md b/CHANGELOG/current/update_appscan.md deleted file mode 100644 index 0b95a040..00000000 --- a/CHANGELOG/current/update_appscan.md +++ /dev/null @@ -1 +0,0 @@ -UPDATE xml report to appscan \ No newline at end of file diff --git a/CHANGELOG/current/update_readme.md b/CHANGELOG/current/update_readme.md deleted file mode 100644 index 4cfa6d9c..00000000 --- a/CHANGELOG/current/update_readme.md +++ /dev/null @@ -1 +0,0 @@ -Update Readme \ No newline at end of file diff --git a/CHANGELOG/current/update_zap.md b/CHANGELOG/current/update_zap.md deleted file mode 100644 index 1fd14e86..00000000 --- a/CHANGELOG/current/update_zap.md +++ /dev/null @@ -1 +0,0 @@ -Fix how ZAP genereate vulns \ No newline at end of file diff --git a/RELEASE.md b/RELEASE.md index ea150430..82de3bd0 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,3 +1,7 @@ +1.4.0 [Dec 23rd, 2020]: +--- + * Update the fields of the nuclei output used to create a vuln + 1.4.0b2 [Dec 15th, 2020]: --- * Fix nuclei plugin bug when url is None diff --git a/faraday_plugins/__init__.py b/faraday_plugins/__init__.py index 3983595e..96e3ce8d 100644 --- a/faraday_plugins/__init__.py +++ b/faraday_plugins/__init__.py @@ -1 +1 @@ -__version__ = '1.4.0b2' +__version__ = '1.4.0' From f744ebb6673e5a2ad6f2c9847253c1bea18ac468 Mon Sep 17 00:00:00 2001 From: Eric Horvat Date: Wed, 23 Dec 2020 17:02:43 -0300 Subject: [PATCH 159/698] [FIX] Merge with \n diff conflict --- faraday_plugins/plugins/repo/appscan/plugin.py | 4 ---- faraday_plugins/plugins/repo/ssl_labs/plugin.py | 3 --- faraday_plugins/plugins/repo/whois/plugin.py | 4 ---- 3 files changed, 11 deletions(-) diff --git a/faraday_plugins/plugins/repo/appscan/plugin.py b/faraday_plugins/plugins/repo/appscan/plugin.py index f9950fb1..572c61d9 100644 --- a/faraday_plugins/plugins/repo/appscan/plugin.py +++ b/faraday_plugins/plugins/repo/appscan/plugin.py @@ -346,10 +346,6 @@ def parseOutputString(self, output): if vuln_data['id'] == info_loc_source["id_adv"]: desc = f'desc: {vuln_data["description"]} DescMix {vuln_data["testDescriptionMixed"]}' -<<<<<<< HEAD - -======= ->>>>>>> a87108bf714a4abf60f5ebce2e3cac3d11893cc2 resolution = f'Fix Recomendarion {vuln_data["fixRecommendations"]}' \ f' - TestTecnical {vuln_data["testTechnicalDescriptionMixed"]}' diff --git a/faraday_plugins/plugins/repo/ssl_labs/plugin.py b/faraday_plugins/plugins/repo/ssl_labs/plugin.py index 6d91197b..53fa3ce1 100644 --- a/faraday_plugins/plugins/repo/ssl_labs/plugin.py +++ b/faraday_plugins/plugins/repo/ssl_labs/plugin.py @@ -75,10 +75,7 @@ def __init__(self): self.version = "3.4.5" self.json_keys = {'engineVersion', 'criteriaVersion', 'endpoints'} -<<<<<<< HEAD -======= ->>>>>>> a87108bf714a4abf60f5ebce2e3cac3d11893cc2 def parseOutputString(self, output): parser = SslLabsJsonParser(output) host = parser.host_info(parser.json_data) diff --git a/faraday_plugins/plugins/repo/whois/plugin.py b/faraday_plugins/plugins/repo/whois/plugin.py index 1b469bca..ba759069 100644 --- a/faraday_plugins/plugins/repo/whois/plugin.py +++ b/faraday_plugins/plugins/repo/whois/plugin.py @@ -72,10 +72,6 @@ def processCommandString(self, username, current_path, command_string): self.command_string = command_string super(CmdWhoisPlugin, self).processCommandString(username, current_path, command_string) -<<<<<<< HEAD - -======= ->>>>>>> a87108bf714a4abf60f5ebce2e3cac3d11893cc2 def parseOutputString(self, output): matches = re.findall("Name Server:\s*(.*)\s*", output) if not matches: From efd3203428fe3e09a6b130120ca4dd324aa38535 Mon Sep 17 00:00:00 2001 From: Blas Date: Mon, 25 Jan 2021 11:58:15 -0300 Subject: [PATCH 160/698] UPD severity in vuln --- faraday_plugins/plugins/repo/mbsa/plugin.py | 28 +++++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/faraday_plugins/plugins/repo/mbsa/plugin.py b/faraday_plugins/plugins/repo/mbsa/plugin.py index 2c0ab36a..bb65c165 100644 --- a/faraday_plugins/plugins/repo/mbsa/plugin.py +++ b/faraday_plugins/plugins/repo/mbsa/plugin.py @@ -89,14 +89,26 @@ def parseOutputString(self, output): else: detail = '' result_info = parser.result[i] - - self.createAndAddVulnToHost(host_id, - issue.replace('Issue: ', ''), - desc=parser.score[i].replace('Score: ', ''), - ref=None, - resolution=result_info.replace('Result: ', ''), - data=detail, - run_date=run_date) + score = parser.score[i].replace('Score: ', '').strip() + if score != 'Check passed': + if score == 'Best practice' or score == 'Unable to scan': + severity = "info" + elif score == 'Check failed (non-critical)': + severity = 'med' + elif score == 'Check failed': + severity = 'high' + else: + severity = 'info' + + self.createAndAddVulnToHost( + host_id, + issue.replace('Issue: ', '').strip(), + desc=result_info.replace('Result: ', '').strip(), + ref=None, + severity=severity, + data=detail, + run_date=run_date + ) i += 1 From fbf2b350a8e1f75bb5303eb9e72e3f0c899ffd95 Mon Sep 17 00:00:00 2001 From: Blas Date: Mon, 25 Jan 2021 15:21:39 -0300 Subject: [PATCH 161/698] FIX ip and hostnames --- .../plugins/repo/openscap/plugin.py | 39 ++++++++++++++++--- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/faraday_plugins/plugins/repo/openscap/plugin.py b/faraday_plugins/plugins/repo/openscap/plugin.py index 02ff3a72..71e6ec50 100644 --- a/faraday_plugins/plugins/repo/openscap/plugin.py +++ b/faraday_plugins/plugins/repo/openscap/plugin.py @@ -8,6 +8,7 @@ from faraday_plugins.plugins.plugin import PluginXMLFormat from datetime import datetime from lxml import etree +import ipaddress try: import xml.etree.cElementTree as ET @@ -137,15 +138,41 @@ def __init__(self): self.protocol = None self.port = '80' - def parseOutputString(self, output): - parser = OpenScapParser(output) + ips = [] + + for ip in parser.result_data[0]['ips']: + len_start_port = ip.find(":") + if len_start_port > -1: + ip = ip[:len_start_port] + try: + ipaddress.ip_address(ip) + ips.append(ip) + except ValueError: + pass + for ip in ips: + if ip != '127.0.0.1': + ip = ip + ips.remove(ip) + break + + list_mac = parser.result_data[0]['mac'] + for mac in list_mac: + if mac != '00:00:00:00:00:00': + mac_address = mac + list_mac.remove(mac_address) + break + + description = f'Title: {parser.result_data[0]["result_title"]} ' \ + f'Ips: {ips} ' \ + f'Macs: {list_mac}' host_id = self.createAndAddHost( - name=parser.result_data[0]['target'], - hostnames=parser.result_data[0]['ips'], - description=parser.result_data[0]['result_title'], - mac=str(parser.result_data[0]['mac'])) + name=ip, + hostnames=[parser.result_data[0]['target']], + description=description, + mac=mac_address + ) rules_fail = parser.result_data[0]['rule_result'] if rules_fail: From 73129e1cb52a2121712f91de79766a5ce99a8b9c Mon Sep 17 00:00:00 2001 From: Blas Date: Mon, 25 Jan 2021 16:04:59 -0300 Subject: [PATCH 162/698] DEL print. FIX name service --- faraday_plugins/plugins/repo/nextnet/plugin.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/faraday_plugins/plugins/repo/nextnet/plugin.py b/faraday_plugins/plugins/repo/nextnet/plugin.py index 83aa4bc2..9320c52e 100644 --- a/faraday_plugins/plugins/repo/nextnet/plugin.py +++ b/faraday_plugins/plugins/repo/nextnet/plugin.py @@ -36,7 +36,6 @@ def __init__(self): self._info = 0 def parseOutputString(self, output): - print(output) output_lines = output.split('\n') output_lines = output_lines[:-1] @@ -57,7 +56,7 @@ def parseOutputString(self, output): ) self.createAndAddServiceToHost( h_id, - name=f'Probe Tag: {json_line.get("probe", "unknown")}', + name=json_line.get("probe", "unknown"), protocol=json_line.get("proto", "tcp"), ports=json_line.get("port", None), description=desc From fe54b04b8ce740443b42822e66566dbe937706d3 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Mon, 22 Feb 2021 12:26:31 -0300 Subject: [PATCH 163/698] Fix bugs in Nessus plugins with old versions --- CHANGELOG/current/fix_nessus_plugin.md | 1 + faraday_plugins/plugins/repo/nessus/plugin.py | 245 +++++++----------- 2 files changed, 101 insertions(+), 145 deletions(-) create mode 100644 CHANGELOG/current/fix_nessus_plugin.md diff --git a/CHANGELOG/current/fix_nessus_plugin.md b/CHANGELOG/current/fix_nessus_plugin.md new file mode 100644 index 00000000..f93bab03 --- /dev/null +++ b/CHANGELOG/current/fix_nessus_plugin.md @@ -0,0 +1 @@ +Fix bugs in Nessus plugins with old versions diff --git a/faraday_plugins/plugins/repo/nessus/plugin.py b/faraday_plugins/plugins/repo/nessus/plugin.py index af2b6cd3..798f97eb 100644 --- a/faraday_plugins/plugins/repo/nessus/plugin.py +++ b/faraday_plugins/plugins/repo/nessus/plugin.py @@ -5,6 +5,7 @@ """ import dateutil +from collections import namedtuple from faraday_plugins.plugins.plugin import PluginXMLFormat import xml.etree.ElementTree as ET @@ -12,13 +13,15 @@ __author__ = "Blas" __copyright__ = "Copyright (c) 2019, Infobyte LLC" -__credits__ = ["Blas"] +__credits__ = ["Blas", "Nicolas Rebagliati"] __license__ = "" __version__ = "1.0.0" __maintainer__ = "Blas" __email__ = "bmoyano@infobytesec.com" __status__ = "Development" +ReportItem = namedtuple('ReportItem', ['port', 'svc_name', 'protocol', 'severity', 'plugin_id', + 'plugin_name', 'plugin_family', 'description', 'plugin_output', 'info']) class NessusParser: """ @@ -54,6 +57,13 @@ def getReport(self, tree): report_tree = tree.find('Report') return Report(report_tree) + def parse_compliance_data(self, data: dict): + compliance_data = {} + for key, value in data.items(): + if 'compliance-' in key: + compliance_name = key.split("}")[-1] + compliance_data[compliance_name] = value + return compliance_data class Policy(): def __init__(self, policy_node): @@ -101,7 +111,6 @@ def getIndividualPluginSelection(self, individual): plugin_status)) return item_plugin - class Report(): def __init__(self, report_node): self.node = report_node @@ -113,47 +122,46 @@ def __init__(self, report_node): self.report_json = {} if self.report_host is not None: for x in self.node: - self.report_host_ip = x.attrib.get('name') - self.host_properties = self.gethosttag(x.find('HostProperties')) - self.report_item = self.getreportitems(x.findall('ReportItem')) - self.report_ip.append(self.report_host_ip) - self.report_desc.append(self.host_properties) - self.report_serv.append(self.report_item) + report_host_ip = x.attrib.get('name') + host_properties = self.gethosttag(x.find('HostProperties')) + report_items = self.getreportitems(x.findall('ReportItem')) + self.report_ip.append(report_host_ip) + self.report_desc.append(host_properties) + self.report_serv.append(report_items) self.report_json['ip'] = self.report_ip self.report_json['desc'] = self.report_desc self.report_json['serv'] = self.report_serv - self.report_json['host_end'] = self.host_properties.get('HOST_END') + self.report_json['host_end'] = host_properties.get('HOST_END') else: self.report_host_ip = None self.host_properties = None - self.report_item = None + self.report_items = None self.report_json = None def getreportitems(self, items): - result_item = [] + report_items = [] for item in items: - self.port = item.attrib.get('port') - self.svc_name = item.attrib.get('svc_name') - self.protocol = item.attrib.get('protocol') - self.severity = item.attrib.get('severity') - self.plugin_id = item.attrib.get('pluginID') - self.plugin_name = item.attrib.get('pluginName') - self.plugin_family = item.attrib.get('pluginFamily') + port = item.attrib.get('port') + svc_name = item.attrib.get('svc_name') + protocol = item.attrib.get('protocol') + severity = item.attrib.get('severity') + plugin_id = item.attrib.get('pluginID') + plugin_name = item.attrib.get('pluginName') + plugin_family = item.attrib.get('pluginFamily') if item.find('plugin_output') is not None: - self.plugin_output = item.find('plugin_output').text + plugin_output = item.find('plugin_output').text else: - self.plugin_output = "Not Description" + plugin_output = "Not Description" if item.find('description') is not None: - self.description = item.find('description').text + description = item.find('description').text else: - self.description = "Not Description" - - self.info = self.getinfoitem(item) - result_item.append((self.port, self.svc_name, self.protocol, self.severity, self.plugin_id, - self.plugin_name, self.plugin_family, self.description, self.plugin_output, self.info)) - return result_item + description = "Not Description" + info = self.getinfoitem(item) + report_items.append(ReportItem(*[port, svc_name, protocol, severity, plugin_id, + plugin_name, plugin_family, description, plugin_output, info])) + return report_items def getinfoitem(self, item): item_tags = {} @@ -167,7 +175,6 @@ def gethosttag(self, tags): host_tags.setdefault(t.attrib.get('name'), t.text) return host_tags - class NessusPlugin(PluginXMLFormat): """ Example plugin to parse nessus output. @@ -195,7 +202,7 @@ def parseOutputString(self, output): try: parser = NessusParser(output) except Exception as e: - print(e) + self.logger.error(str(e)) return None if parser.report.report_json is not None: @@ -203,127 +210,80 @@ def parseOutputString(self, output): if run_date: run_date = dateutil.parser.parse(run_date) for set_info, ip in enumerate(parser.report.report_json['ip'], start=1): - if 'mac-address' in parser.report.report_json['desc'][set_info - 1]: - mac = parser.report.report_json['desc'][set_info - 1]['mac-address'] - else: - mac = '' - if 'operating-system' in parser.report.report_json['desc'][set_info - 1]: - os = parser.report.report_json['desc'][set_info - 1]['operating-system'] - else: - os = None - - if 'host-ip' in parser.report.report_json['desc'][set_info - 1]: - ip_host = parser.report.report_json['desc'][set_info - 1]['host-ip'] - else: - ip_host = "0.0.0.0" - if 'host-fqdn' in parser.report.report_json['desc'][set_info - 1]: - website = parser.report.report_json['desc'][set_info - 1]['host-fqdn'] - host_name = [] - host_name.append(parser.report.report_json['desc'][set_info - 1]['host-fqdn']) - else: - website = None - host_name = None - + website = None + mac = parser.report.report_json['desc'][set_info - 1].get('mac-address', '') + os = parser.report.report_json['desc'][set_info - 1].get('operating-system', None) + ip_host = parser.report.report_json['desc'][set_info - 1].get('host-ip', ip) + host_name = parser.report.report_json['desc'][set_info - 1].get('host-fqdn', None) + if host_name: + website = host_name host_id = self.createAndAddHost(ip_host, os=os, hostnames=host_name, mac=mac) - cve = [] - for serv in parser.report.report_json['serv'][set_info -1]: - serv_name = serv[1] - serv_port = serv[0] - serv_protocol = serv[2] - serv_status = serv[3] - external_id = serv[4] - serv_description = serv[7] - cve.append(serv[8]) - severity = serv[3] - desc = serv[8] - - if serv_name == 'general': - ref = [] - vulnerability_name = serv[5] - data = serv[9] - if not data: - continue - if 'description' in data: - desc = data['description'] - else: - desc = "No description" - if 'solution' in data: - resolution = data['solution'] - else: - resolution = "No Solution" - if 'plugin_output' in data: - data_po = data['plugin_output'] - else: - data_po = "Not data" - - risk_factor = "unclassified" - if 'risk_factor' in data: - risk_factor = data['risk_factor'] - if risk_factor == 'None': - risk_factor = "info" # I checked several external id and most of them were info + for report_item in parser.report.report_json['serv'][set_info -1]: + vulnerability_name = report_item.plugin_name + if not vulnerability_name: + continue + item_name = report_item.svc_name + item_port = report_item.port + item_protocol = report_item.protocol + item_severity = report_item.severity + external_id = report_item.plugin_id + serv_description = report_item.description + #cve.append(report_item.plugin_output) + description = report_item.plugin_output + data = report_item.info + risk_factor = data.get('risk_factor', None) + cve = [] + ref = [] + if risk_factor == 'None' or risk_factor is None: + risk_factor = item_severity # I checked several external id and most of them were info + if item_name == 'general': + description = data.get('description', '') + resolution = data.get('solution', '') + data_pluin_ouput = data.get('plugin_output', '') if 'cvss_base_score' in data: - cvss_base_score = "CVSS :{}".format(data['cvss_base_score']) + cvss_base_score = f"CVSS:{data['cvss_base_score']}" ref.append(cvss_base_score) - else: - ref = [] - policyviolations = [] - tags_info = None - if serv[6] == 'Policy Compliance': + if report_item.plugin_family == 'Policy Compliance': # This condition was added to support CIS Benchmark in policy violation field. - risk_factor = 'info' - tags_info = "Passed Checks" - bis_benchmark_data = serv[7].split('\n') - policy_item = bis_benchmark_data[0] - + bis_benchmark_data = report_item.description.split('\n') + compliance_data = parser.parse_compliance_data(data) + compliance_info = compliance_data.get('compliance-info', '') + if compliance_info and not description: + description = compliance_info + compliance_reference = compliance_data.get('compliance-reference', '').replace('|', ':').split(',') + compliance_result = compliance_data.get('compliance-result', '') + for reference in compliance_reference: + ref.append(reference) + compliance_check_name = compliance_data.get('compliance-check-name', '') + compliance_solution = compliance_data.get('compliance-solution', '') + if compliance_solution and not resolution: + resolution = compliance_solution + policy_item = f'{compliance_check_name} - {compliance_result}' for policy_check_data in bis_benchmark_data: if 'ref.' in policy_check_data: ref.append(policy_check_data) - - if 'FAILED' in policy_item: - risk_factor = 'low' - tags_info = "Failed checks" - policyviolations.append(policy_item) - - vulnerability_name = f'{serv[6]} {vulnerability_name} {policy_item}' + if 'compliance-see-also' in compliance_data: + ref.append(compliance_data.get('compliance-see-also')) + # We used this info from tenable: https://community.tenable.com/s/article/Compliance-checks-in-SecurityCenter + policyviolations.append(policy_item) + vulnerability_name = f'{vulnerability_name}: {policy_item}' self.createAndAddVulnToHost(host_id, vulnerability_name, - desc=desc, + desc=description, severity=risk_factor, resolution=resolution, - data=data_po, + data=data_pluin_ouput, ref=ref, policyviolations=policyviolations, external_id=external_id, - run_date=run_date, - tags=tags_info) + run_date=run_date) else: - data = serv[9] - if not data: - continue - ref = [] - vulnerability_name = serv[5] - if 'description' in data: - desc = data['description'] - else: - desc = "No description" - if 'solution' in data: - resolution = data['solution'] - else: - resolution = "No Solution" - if 'plugin_output' in data: - data_po = data['plugin_output'] - else: - data_po = "Not data" - - risk_factor = "info" - if 'risk_factor' in data: - risk_factor = data['risk_factor'] - - if risk_factor == 'None': - risk_factor = 'info' - + vulnerability_name = report_item.plugin_name + description = data.get('description', '') + resolution = data.get('solution', '') + data_pluin_ouput = data.get('plugin_output', '') if 'cvss_base_score' in data: cvss_base_score = f"CVSS:{data['cvss_base_score']}" ref.append(cvss_base_score) @@ -337,15 +297,15 @@ def parseOutputString(self, output): if 'xref' in data: ref.append(data['xref']) - service_id = self.createAndAddServiceToHost(host_id, name=serv_name, protocol=serv_protocol, - ports=serv_port) + service_id = self.createAndAddServiceToHost(host_id, name=item_name, protocol=item_protocol, + ports=item_port) - if serv_name == 'www' or serv_name == 'http': + if item_name == 'www' or item_name == 'http': self.createAndAddVulnWebToService(host_id, service_id, name=vulnerability_name, - desc=desc, - data=data_po, + desc=description, + data=data_pluin_ouput, severity=risk_factor, resolution=resolution, ref=ref, @@ -357,17 +317,12 @@ def parseOutputString(self, output): service_id, name=vulnerability_name, severity=risk_factor, - desc=desc, + desc=description, ref=ref, - data=data_po, + data=data_pluin_ouput, external_id=external_id, resolution=resolution, run_date=run_date) - else: - ip = '0.0.0.0' - host_id = self.createAndAddHost(ip, hostnames=None) - service_id = self.createAndAddServiceToHost(host_id,name="Not Information") - self.createAndAddVulnToService(host_id, service_id, name=parser.policy.policy_name, desc="No Description") def createPlugin(): From 6e43c025bf4f7580265e49c183771a759730b9c6 Mon Sep 17 00:00:00 2001 From: Blas Date: Mon, 22 Feb 2021 14:36:43 -0300 Subject: [PATCH 164/698] change id --- CHANGELOG/current/fix_sslyze_plugin.md | 1 + faraday_plugins/plugins/repo/sslyze/plugin.py | 2 +- faraday_plugins/plugins/repo/sslyzejson/plugin.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 CHANGELOG/current/fix_sslyze_plugin.md diff --git a/CHANGELOG/current/fix_sslyze_plugin.md b/CHANGELOG/current/fix_sslyze_plugin.md new file mode 100644 index 00000000..36cd2cc4 --- /dev/null +++ b/CHANGELOG/current/fix_sslyze_plugin.md @@ -0,0 +1 @@ +FIX change id sslyze for JSON/XML diff --git a/faraday_plugins/plugins/repo/sslyze/plugin.py b/faraday_plugins/plugins/repo/sslyze/plugin.py index 5c621006..2db05c00 100644 --- a/faraday_plugins/plugins/repo/sslyze/plugin.py +++ b/faraday_plugins/plugins/repo/sslyze/plugin.py @@ -87,7 +87,7 @@ class SslyzePlugin(PluginXMLFormat): def __init__(self): super().__init__() self.identifier_tag = "document" - self.id = "Sslyze XML" + self.id = "Sslyze_XML" self.name = "Sslyze Plugin" self.plugin_version = "0.0.1" self.version = "2.0.6" diff --git a/faraday_plugins/plugins/repo/sslyzejson/plugin.py b/faraday_plugins/plugins/repo/sslyzejson/plugin.py index 1f5adb42..bb4dec17 100644 --- a/faraday_plugins/plugins/repo/sslyzejson/plugin.py +++ b/faraday_plugins/plugins/repo/sslyzejson/plugin.py @@ -164,7 +164,7 @@ class SslyzePlugin(PluginJsonFormat): def __init__(self): super().__init__() - self.id = "Sslyze JSON" + self.id = "Sslyze_JSON" self.name = "Sslyze Json" self.plugin_version = "0.1" self.version = "3.4.5" From 484a32f4118f08219a946bd5874822a1f385d795 Mon Sep 17 00:00:00 2001 From: Eric Horvat Date: Fri, 26 Feb 2021 11:42:59 -0300 Subject: [PATCH 165/698] [MOD] Ready for 1.4.1 --- CHANGELOG/1.4.1/add_microsoft_baseline.md | 1 + CHANGELOG/1.4.1/add_nextnet.md | 1 + CHANGELOG/1.4.1/add_openscap.md | 1 + CHANGELOG/1.4.1/date.md | 1 + CHANGELOG/1.4.1/fix_nessus_plugin.md | 1 + CHANGELOG/RELEASE.md | 7 +++++++ CHANGELOG/current/add_microsoft_baseline.md | 1 - CHANGELOG/current/add_openscap.md | 1 - CHANGELOG/current/fix_nessus_plugin.md | 1 - CHANGELOG/current/nextnet.md | 1 - RELEASE.md | 7 +++++++ faraday_plugins/__init__.py | 2 +- 12 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 CHANGELOG/1.4.1/add_microsoft_baseline.md create mode 100644 CHANGELOG/1.4.1/add_nextnet.md create mode 100644 CHANGELOG/1.4.1/add_openscap.md create mode 100644 CHANGELOG/1.4.1/date.md create mode 100644 CHANGELOG/1.4.1/fix_nessus_plugin.md delete mode 100644 CHANGELOG/current/add_microsoft_baseline.md delete mode 100644 CHANGELOG/current/add_openscap.md delete mode 100644 CHANGELOG/current/fix_nessus_plugin.md delete mode 100644 CHANGELOG/current/nextnet.md diff --git a/CHANGELOG/1.4.1/add_microsoft_baseline.md b/CHANGELOG/1.4.1/add_microsoft_baseline.md new file mode 100644 index 00000000..bf729f6a --- /dev/null +++ b/CHANGELOG/1.4.1/add_microsoft_baseline.md @@ -0,0 +1 @@ +ADD microsoft baseline security analyzer plugin diff --git a/CHANGELOG/1.4.1/add_nextnet.md b/CHANGELOG/1.4.1/add_nextnet.md new file mode 100644 index 00000000..b9f53277 --- /dev/null +++ b/CHANGELOG/1.4.1/add_nextnet.md @@ -0,0 +1 @@ +ADD nextnet plugin diff --git a/CHANGELOG/1.4.1/add_openscap.md b/CHANGELOG/1.4.1/add_openscap.md new file mode 100644 index 00000000..4cfac92f --- /dev/null +++ b/CHANGELOG/1.4.1/add_openscap.md @@ -0,0 +1 @@ +ADD openscap plugin diff --git a/CHANGELOG/1.4.1/date.md b/CHANGELOG/1.4.1/date.md new file mode 100644 index 00000000..1c7356eb --- /dev/null +++ b/CHANGELOG/1.4.1/date.md @@ -0,0 +1 @@ +Feb 26th, 2021 diff --git a/CHANGELOG/1.4.1/fix_nessus_plugin.md b/CHANGELOG/1.4.1/fix_nessus_plugin.md new file mode 100644 index 00000000..34dba3ab --- /dev/null +++ b/CHANGELOG/1.4.1/fix_nessus_plugin.md @@ -0,0 +1 @@ +FIX old versions of Nessus plugins bugs diff --git a/CHANGELOG/RELEASE.md b/CHANGELOG/RELEASE.md index 82de3bd0..d6a2086a 100644 --- a/CHANGELOG/RELEASE.md +++ b/CHANGELOG/RELEASE.md @@ -1,3 +1,10 @@ +1.4.1 [Feb 26th, 2021]: +--- + * ADD microsoft baseline security analyzer plugin + * ADD nextnet plugin + * ADD openscap plugin + * FIX old versions of Nessus plugins bugs + 1.4.0 [Dec 23rd, 2020]: --- * Update the fields of the nuclei output used to create a vuln diff --git a/CHANGELOG/current/add_microsoft_baseline.md b/CHANGELOG/current/add_microsoft_baseline.md deleted file mode 100644 index a35a029a..00000000 --- a/CHANGELOG/current/add_microsoft_baseline.md +++ /dev/null @@ -1 +0,0 @@ -Add microsoft baseline security analyzer diff --git a/CHANGELOG/current/add_openscap.md b/CHANGELOG/current/add_openscap.md deleted file mode 100644 index 75b76944..00000000 --- a/CHANGELOG/current/add_openscap.md +++ /dev/null @@ -1 +0,0 @@ -ADD plungin openscap \ No newline at end of file diff --git a/CHANGELOG/current/fix_nessus_plugin.md b/CHANGELOG/current/fix_nessus_plugin.md deleted file mode 100644 index f93bab03..00000000 --- a/CHANGELOG/current/fix_nessus_plugin.md +++ /dev/null @@ -1 +0,0 @@ -Fix bugs in Nessus plugins with old versions diff --git a/CHANGELOG/current/nextnet.md b/CHANGELOG/current/nextnet.md deleted file mode 100644 index 084e69a1..00000000 --- a/CHANGELOG/current/nextnet.md +++ /dev/null @@ -1 +0,0 @@ -ADD plugin nextnet \ No newline at end of file diff --git a/RELEASE.md b/RELEASE.md index 82de3bd0..d6a2086a 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,3 +1,10 @@ +1.4.1 [Feb 26th, 2021]: +--- + * ADD microsoft baseline security analyzer plugin + * ADD nextnet plugin + * ADD openscap plugin + * FIX old versions of Nessus plugins bugs + 1.4.0 [Dec 23rd, 2020]: --- * Update the fields of the nuclei output used to create a vuln diff --git a/faraday_plugins/__init__.py b/faraday_plugins/__init__.py index bdbb22b7..8e3c933c 100644 --- a/faraday_plugins/__init__.py +++ b/faraday_plugins/__init__.py @@ -1 +1 @@ -__version__ = '1.4.0' \ No newline at end of file +__version__ = '1.4.1' From 7ef062a89aa9ce0ed10ecc340cf4e576248994f8 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Mar 2021 12:22:37 -0300 Subject: [PATCH 166/698] fix sslyze output file --- CHANGELOG/current/fix_bug_in_sslyze_output_file.md | 1 + faraday_plugins/plugins/repo/sslyzejson/plugin.py | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 CHANGELOG/current/fix_bug_in_sslyze_output_file.md diff --git a/CHANGELOG/current/fix_bug_in_sslyze_output_file.md b/CHANGELOG/current/fix_bug_in_sslyze_output_file.md new file mode 100644 index 00000000..ce00a3c1 --- /dev/null +++ b/CHANGELOG/current/fix_bug_in_sslyze_output_file.md @@ -0,0 +1 @@ +Fix bug with sslyze output file diff --git a/faraday_plugins/plugins/repo/sslyzejson/plugin.py b/faraday_plugins/plugins/repo/sslyzejson/plugin.py index bb4dec17..c1cb60bb 100644 --- a/faraday_plugins/plugins/repo/sslyzejson/plugin.py +++ b/faraday_plugins/plugins/repo/sslyzejson/plugin.py @@ -171,6 +171,8 @@ def __init__(self): self.json_keys = {'server_scan_results', 'sslyze_url'} self._command_regex = re.compile(r'^(sudo sslyze|sslyze|\.\/sslyze)\s+.*?') self.json_arg_re = re.compile(r"^.*(--json_out\s*[^\s]+).*$") + self._use_temp_file = True + self._temp_file_extension = "json" def parseOutputString(self, output): parser = SslyzeJsonParser(output) From 71a27b544ea456b5c8a0cb929e49a92cffb168ec Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Mar 2021 12:45:13 -0300 Subject: [PATCH 167/698] ready for release 1.4.2 --- CHANGELOG/1.4.2/date.md | 1 + .../fix_bug_in_sslyze_output_file.md | 0 .../{current => 1.4.2}/fix_sslyze_plugin.md | 0 CHANGELOG/RELEASE.md | 49 ------------------- RELEASE.md | 5 ++ 5 files changed, 6 insertions(+), 49 deletions(-) create mode 100644 CHANGELOG/1.4.2/date.md rename CHANGELOG/{current => 1.4.2}/fix_bug_in_sslyze_output_file.md (100%) rename CHANGELOG/{current => 1.4.2}/fix_sslyze_plugin.md (100%) delete mode 100644 CHANGELOG/RELEASE.md diff --git a/CHANGELOG/1.4.2/date.md b/CHANGELOG/1.4.2/date.md new file mode 100644 index 00000000..45d9b329 --- /dev/null +++ b/CHANGELOG/1.4.2/date.md @@ -0,0 +1 @@ +Mar 10th, 2021 diff --git a/CHANGELOG/current/fix_bug_in_sslyze_output_file.md b/CHANGELOG/1.4.2/fix_bug_in_sslyze_output_file.md similarity index 100% rename from CHANGELOG/current/fix_bug_in_sslyze_output_file.md rename to CHANGELOG/1.4.2/fix_bug_in_sslyze_output_file.md diff --git a/CHANGELOG/current/fix_sslyze_plugin.md b/CHANGELOG/1.4.2/fix_sslyze_plugin.md similarity index 100% rename from CHANGELOG/current/fix_sslyze_plugin.md rename to CHANGELOG/1.4.2/fix_sslyze_plugin.md diff --git a/CHANGELOG/RELEASE.md b/CHANGELOG/RELEASE.md deleted file mode 100644 index d6a2086a..00000000 --- a/CHANGELOG/RELEASE.md +++ /dev/null @@ -1,49 +0,0 @@ -1.4.1 [Feb 26th, 2021]: ---- - * ADD microsoft baseline security analyzer plugin - * ADD nextnet plugin - * ADD openscap plugin - * FIX old versions of Nessus plugins bugs - -1.4.0 [Dec 23rd, 2020]: ---- - * Update the fields of the nuclei output used to create a vuln - -1.4.0b2 [Dec 15th, 2020]: ---- - * Fix nuclei plugin bug when url is None - -1.4.0b1 [Dec 14th, 2020]: ---- - * Add new plugin base class, for multi line json - * New ncrack plugin - * New nuclei plugin - * New sslyze json plugin - * New WhatWeb plugin - * Fix missing ip in some arachni reports - * Fix change name vuln in Netsparker plugin - * Fix whois plugin, command whois IP not parse data - * Change the way we detect json reports when they are lists of dictionaries - -1.3.0 [Sep 2nd, 2020]: ---- - * ADD plugin AppSpider - * Add tests to faraday-plugins cli - * add a default value to plugin_version - * Add --output-file parameter to faraday-plugins process command - * Add plugins prowler - * Add plugins ssl labs - * Add support for tenable io - * delete old deprecated methods - * Bug fix: Arachni Plugin 'NoneType' object has no attribute 'find' - * Bug fix: Openvas Plugin - Import xml from OpenVas doesnt work - * Bug fix: QualysWebApp Plugin, error in get info OPERATING_SYSTEM - * Fix Hydra plugin to resolve ip address - * Fix Nessus mod severity HIGH for Low - * Bug Fix: Detect plugins AWS Prowler - * Fix broken xml on nmap plugin - * Add new rdpscan plugin - * UPDATE xml report to appscan - * Update Readme - * Fix how ZAP genereate vulns - diff --git a/RELEASE.md b/RELEASE.md index d6a2086a..b75b6b3b 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,3 +1,8 @@ +1.4.2 [Mar 10th, 2021]: +--- + * Fix bug with sslyze output file + * FIX change id sslyze for JSON/XML + 1.4.1 [Feb 26th, 2021]: --- * ADD microsoft baseline security analyzer plugin From ff52cb9f6caa2290bc2c05678fdd0310f1413e2f Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 10 Mar 2021 12:52:21 -0300 Subject: [PATCH 168/698] update version --- faraday_plugins/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faraday_plugins/__init__.py b/faraday_plugins/__init__.py index 8e3c933c..98d186be 100644 --- a/faraday_plugins/__init__.py +++ b/faraday_plugins/__init__.py @@ -1 +1 @@ -__version__ = '1.4.1' +__version__ = '1.4.2' From 6998eea3988155cac659e1c93c6da37e17dc9b68 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Fri, 12 Mar 2021 17:46:44 -0300 Subject: [PATCH 169/698] implementar ignore_info --- faraday_plugins/commands.py | 5 +- faraday_plugins/plugins/manager.py | 7 +- faraday_plugins/plugins/plugin.py | 65 ++++++++++--------- .../plugins/repo/acunetix/plugin.py | 8 +-- faraday_plugins/plugins/repo/amap/plugin.py | 8 +-- .../plugins/repo/appscan/plugin.py | 9 +-- .../plugins/repo/appspider/plugin.py | 9 +-- .../plugins/repo/arachni/plugin.py | 8 +-- .../plugins/repo/arp_scan/plugin.py | 8 +-- .../plugins/repo/awsprowler/plugin.py | 8 +-- faraday_plugins/plugins/repo/beef/plugin.py | 8 +-- .../plugins/repo/brutexss/plugin.py | 8 +-- faraday_plugins/plugins/repo/burp/plugin.py | 8 +-- .../plugins/repo/checkmarx/plugin.py | 9 +-- faraday_plugins/plugins/repo/cobalt/plugin.py | 8 +-- faraday_plugins/plugins/repo/dig/plugin.py | 16 ++--- faraday_plugins/plugins/repo/dirb/plugin.py | 8 +-- .../plugins/repo/dirsearch/plugin.py | 10 +-- .../plugins/repo/dnsenum/plugin.py | 8 +-- faraday_plugins/plugins/repo/dnsmap/plugin.py | 8 +-- .../plugins/repo/dnsrecon/plugin.py | 8 +-- .../plugins/repo/dnswalk/plugin.py | 8 +-- .../plugins/repo/faraday_csv/plugin.py | 9 +-- faraday_plugins/plugins/repo/fierce/plugin.py | 8 +-- .../plugins/repo/fortify/plugin.py | 8 +-- .../plugins/repo/fruitywifi/plugin.py | 8 +-- faraday_plugins/plugins/repo/ftp/plugin.py | 8 +-- .../plugins/repo/goohost/plugin.py | 8 +-- faraday_plugins/plugins/repo/hping3/plugin.py | 8 +-- faraday_plugins/plugins/repo/hydra/plugin.py | 8 +-- faraday_plugins/plugins/repo/impact/plugin.py | 8 +-- faraday_plugins/plugins/repo/ip360/plugin.py | 8 +-- faraday_plugins/plugins/repo/junit/plugin.py | 8 +-- faraday_plugins/plugins/repo/lynis/plugin.py | 8 +-- .../plugins/repo/maltego/plugin.py | 8 +-- faraday_plugins/plugins/repo/mbsa/plugin.py | 9 +-- faraday_plugins/plugins/repo/medusa/plugin.py | 8 +-- .../plugins/repo/metasploit/plugin.py | 8 +-- faraday_plugins/plugins/repo/ncrack/plugin.py | 9 +-- faraday_plugins/plugins/repo/ndiff/plugin.py | 8 +-- faraday_plugins/plugins/repo/nessus/plugin.py | 8 +-- .../plugins/repo/netdiscover/plugin.py | 8 +-- .../plugins/repo/netsparker/plugin.py | 8 +-- .../plugins/repo/netsparkercloud/plugin.py | 8 +-- .../plugins/repo/nexpose_full/plugin.py | 8 +-- .../plugins/repo/nextnet/plugin.py | 9 +-- faraday_plugins/plugins/repo/nikto/plugin.py | 10 +-- faraday_plugins/plugins/repo/nmap/plugin.py | 8 +-- faraday_plugins/plugins/repo/nuclei/plugin.py | 8 +-- .../plugins/repo/openscap/plugin.py | 9 +-- .../plugins/repo/openvas/plugin.py | 8 +-- .../plugins/repo/pasteanalyzer/plugin.py | 8 +-- .../plugins/repo/peepingtom/plugin.py | 8 +-- faraday_plugins/plugins/repo/ping/plugin.py | 8 +-- .../plugins/repo/propecia/plugin.py | 8 +-- .../plugins/repo/qualysguard/plugin.py | 8 +-- .../plugins/repo/qualyswebapp/plugin.py | 9 +-- .../plugins/repo/rdpscan/plugin.py | 8 +-- .../plugins/repo/reconng/plugin.py | 8 +-- faraday_plugins/plugins/repo/retina/plugin.py | 8 +-- .../plugins/repo/reverseraider/plugin.py | 8 +-- .../plugins/repo/skipfish/plugin.py | 8 +-- .../plugins/repo/sourceclear/plugin.py | 8 +-- .../plugins/repo/sshdefaultscan/plugin.py | 8 +-- .../plugins/repo/ssl_labs/plugin.py | 8 +-- faraday_plugins/plugins/repo/sslyze/plugin.py | 8 +-- .../plugins/repo/sslyzejson/plugin.py | 8 +-- faraday_plugins/plugins/repo/telnet/plugin.py | 8 +-- .../plugins/repo/theharvester/plugin.py | 8 +-- .../plugins/repo/traceroute/plugin.py | 8 +-- faraday_plugins/plugins/repo/w3af/plugin.py | 8 +-- faraday_plugins/plugins/repo/wapiti/plugin.py | 8 +-- faraday_plugins/plugins/repo/wcscan/plugin.py | 8 +-- .../plugins/repo/webfuzzer/plugin.py | 8 +-- .../plugins/repo/webinspect/plugin.py | 10 ++- faraday_plugins/plugins/repo/wfuzz/plugin.py | 8 +-- .../plugins/repo/whatweb/plugin.py | 8 +-- .../plugins/repo/whitesource/plugin.py | 12 ++-- faraday_plugins/plugins/repo/whois/plugin.py | 8 +-- faraday_plugins/plugins/repo/wpscan/plugin.py | 8 +-- faraday_plugins/plugins/repo/x1/plugin.py | 8 +-- .../plugins/repo/xsssniper/plugin.py | 8 +-- faraday_plugins/plugins/repo/zap/plugin.py | 8 +-- 83 files changed, 379 insertions(+), 365 deletions(-) diff --git a/faraday_plugins/commands.py b/faraday_plugins/commands.py index c4fc1cc7..ab85245c 100644 --- a/faraday_plugins/commands.py +++ b/faraday_plugins/commands.py @@ -52,11 +52,12 @@ def list_plugins(custom_plugins_folder): @click.option('-cpf', '--custom-plugins-folder', type=str) @click.option('--summary', is_flag=True) @click.option('-o', '--output-file', type=click.Path(exists=False)) -def process_report(report_file, plugin_id, custom_plugins_folder, summary, output_file): +@click.option('--ignore-info', is_flag=True, help="Ignore information vulnerabilities") +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) + plugins_manager = PluginsManager(custom_plugins_folder, ignore_info) analyzer = ReportAnalyzer(plugins_manager) if plugin_id: plugin = plugins_manager.get_plugin(plugin_id) diff --git a/faraday_plugins/plugins/manager.py b/faraday_plugins/plugins/manager.py index 50a00d46..66069896 100644 --- a/faraday_plugins/plugins/manager.py +++ b/faraday_plugins/plugins/manager.py @@ -151,7 +151,8 @@ def get_plugin(self, command_string): class PluginsManager: - def __init__(self, custom_plugins_folder=None): + def __init__(self, custom_plugins_folder=None, ignore_info = False): + self.ignore_info = ignore_info self.plugins = {} self.plugin_modules = {} self._load_plugins(custom_plugins_folder) @@ -214,7 +215,7 @@ def get_plugin(self, plugin_id): plugin = None plugin_id = plugin_id.lower() if plugin_id in self.plugin_modules: - plugin = self.plugin_modules[plugin_id].createPlugin() + plugin = self.plugin_modules[plugin_id].createPlugin(self.ignore_info) else: logger.debug("Unknown Plugin: %s", plugin_id) return plugin @@ -222,4 +223,4 @@ def get_plugin(self, plugin_id): def get_plugins(self): for plugin_id, plugin_module in self.plugin_modules.items(): logger.debug("Instance Plugin: %s", plugin_id) - yield plugin_id, plugin_module.createPlugin() + yield plugin_id, plugin_module.createPlugin(self.ignore_info) diff --git a/faraday_plugins/plugins/plugin.py b/faraday_plugins/plugins/plugin.py index 97272e0a..7e353ed3 100644 --- a/faraday_plugins/plugins/plugin.py +++ b/faraday_plugins/plugins/plugin.py @@ -29,10 +29,11 @@ class PluginBase: # TODO: Add class generic identifier class_signature = "PluginBase" - def __init__(self): + def __init__(self, ignore_info=False): # Must be unique. Check that there is not # an existant plugin with the same id. # TODO: Make script that list current ids. + self.ignore_info = ignore_info self.id = None self.auto_load = True self._rid = id(self) @@ -138,26 +139,32 @@ def save_service_cache(self, host_id, service): return obj_uuid def save_service_vuln_cache(self, host_id, service_id, vuln): - cache_id = self.get_service_vuln_cache_id(host_id, service_id, vuln) - if cache_id not in self._vulns_cache: - obj_uuid = self.save_cache(vuln) - service = self.get_from_cache(service_id) - service["vulnerabilities"].append(vuln) - self._vulns_cache[cache_id] = obj_uuid + if self.ignore_info and vuln['severity'] == 'info': + return None else: - obj_uuid = self._vulns_cache[cache_id] - return obj_uuid + cache_id = self.get_service_vuln_cache_id(host_id, service_id, vuln) + if cache_id not in self._vulns_cache: + obj_uuid = self.save_cache(vuln) + service = self.get_from_cache(service_id) + service["vulnerabilities"].append(vuln) + self._vulns_cache[cache_id] = obj_uuid + else: + obj_uuid = self._vulns_cache[cache_id] + return obj_uuid def save_host_vuln_cache(self, host_id, vuln): - cache_id = self.get_host_vuln_cache_id(host_id, vuln) - if cache_id not in self._vulns_cache: - obj_uuid = self.save_cache(vuln) - host = self.get_from_cache(host_id) - host["vulnerabilities"].append(vuln) - self._vulns_cache[cache_id] = obj_uuid + if self.ignore_info and vuln['severity'] == 'info': + return None else: - obj_uuid = self._vulns_cache[cache_id] - return obj_uuid + cache_id = self.get_host_vuln_cache_id(host_id, vuln) + if cache_id not in self._vulns_cache: + obj_uuid = self.save_cache(vuln) + host = self.get_from_cache(host_id) + host["vulnerabilities"].append(vuln) + self._vulns_cache[cache_id] = obj_uuid + else: + obj_uuid = self._vulns_cache[cache_id] + return obj_uuid @staticmethod def _get_dict_hash(d, keys): @@ -545,8 +552,8 @@ def processOutput(self, term_output): class PluginByExtension(PluginBase): - def __init__(self): - super().__init__() + def __init__(self, ignore_info=False): + super().__init__(ignore_info) self.extension = [] def report_belongs_to(self, extension="", **kwargs): @@ -561,8 +568,8 @@ def report_belongs_to(self, extension="", **kwargs): class PluginXMLFormat(PluginByExtension): - def __init__(self): - super().__init__() + def __init__(self, ignore_info=False): + super().__init__(ignore_info) self.identifier_tag = [] self.extension = ".xml" self.open_options = {"mode": "rb"} @@ -580,8 +587,8 @@ def report_belongs_to(self, main_tag="", **kwargs): class PluginJsonFormat(PluginByExtension): - def __init__(self): - super().__init__() + def __init__(self, ignore_info=False): + super().__init__(ignore_info) self.json_keys = set() self.extension = ".json" @@ -597,8 +604,8 @@ def report_belongs_to(self, file_json_keys=None, **kwargs): class PluginMultiLineJsonFormat(PluginByExtension): - def __init__(self): - super().__init__() + def __init__(self, ignore_info=False): + super().__init__(ignore_info) self.json_keys = set() self.extension = ".json" @@ -622,8 +629,8 @@ def report_belongs_to(self, file_json_keys=None, **kwargs): class PluginCSVFormat(PluginByExtension): - def __init__(self): - super().__init__() + def __init__(self, ignore_info=False): + super().__init__(ignore_info) self.extension = ".csv" self.csv_headers = set() @@ -642,8 +649,8 @@ def report_belongs_to(self, file_csv_headers=None, **kwargs): class PluginZipFormat(PluginByExtension): - def __init__(self): - super().__init__() + def __init__(self, ignore_info=False): + super().__init__(ignore_info) self.extension = ".zip" self.files_list = set() diff --git a/faraday_plugins/plugins/repo/acunetix/plugin.py b/faraday_plugins/plugins/repo/acunetix/plugin.py index 644850da..6c8004df 100644 --- a/faraday_plugins/plugins/repo/acunetix/plugin.py +++ b/faraday_plugins/plugins/repo/acunetix/plugin.py @@ -217,8 +217,8 @@ class AcunetixPlugin(PluginXMLFormat): Example plugin to parse acunetix output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = "ScanGroup" self.id = "Acunetix" self.name = "Acunetix XML Output Plugin" @@ -291,5 +291,5 @@ def setHost(self): pass -def createPlugin(): - return AcunetixPlugin() \ No newline at end of file +def createPlugin(ignore_info=False): + return AcunetixPlugin(ignore_info=ignore_info) \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/amap/plugin.py b/faraday_plugins/plugins/repo/amap/plugin.py index abd01f47..0da8c98b 100644 --- a/faraday_plugins/plugins/repo/amap/plugin.py +++ b/faraday_plugins/plugins/repo/amap/plugin.py @@ -20,8 +20,8 @@ class AmapPlugin(PluginBase): """ Example plugin to parse amap output.""" - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Amap" self.name = "Amap Output Plugin" self.plugin_version = "0.0.3" @@ -147,7 +147,7 @@ def processCommandString(self, username, current_path, command_string): return final -def createPlugin(): - return AmapPlugin() +def createPlugin(ignore_info=False): + return AmapPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/appscan/plugin.py b/faraday_plugins/plugins/repo/appscan/plugin.py index 572c61d9..f55794f2 100644 --- a/faraday_plugins/plugins/repo/appscan/plugin.py +++ b/faraday_plugins/plugins/repo/appscan/plugin.py @@ -262,8 +262,9 @@ def get_scan_conf_data(self, host_info): class AppScanPlugin(PluginXMLFormat): - def __init__(self): - super().__init__() + + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = "xml-report" self.id = 'Appscan' self.name = 'Appscan XML Plugin' @@ -382,5 +383,5 @@ def parseOutputString(self, output): data=f'xfix: {vulnserv["xfid"]} cme: {vulnserv["cwe"]}', run_date=None) -def createPlugin(): - return AppScanPlugin() +def createPlugin(ignore_info=False): + return AppScanPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/appspider/plugin.py b/faraday_plugins/plugins/repo/appspider/plugin.py index d3ebd48a..e1f98c8a 100644 --- a/faraday_plugins/plugins/repo/appspider/plugin.py +++ b/faraday_plugins/plugins/repo/appspider/plugin.py @@ -39,8 +39,9 @@ def parse_xml(self, xml_output): class AppSpiderPlugin(PluginXMLFormat): - def __init__(self): - super().__init__() + + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = ["VulnSummary"] self.id = 'AppSpider' self.name = 'AppSpider XML Output Plugin' @@ -113,5 +114,5 @@ def parseOutputString(self, output): external_id=vuln_external_id, data=str_data) -def createPlugin(): - return AppSpiderPlugin() +def createPlugin(ignore_info=False): + return AppSpiderPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/arachni/plugin.py b/faraday_plugins/plugins/repo/arachni/plugin.py index 5b7dd838..2d9dfd38 100755 --- a/faraday_plugins/plugins/repo/arachni/plugin.py +++ b/faraday_plugins/plugins/repo/arachni/plugin.py @@ -335,8 +335,8 @@ class ArachniPlugin(PluginXMLFormat): # Plugin that parses Arachni's XML report files. - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = ["report", "arachni_report"] self.id = 'Arachni' self.name = 'Arachni XML Output Plugin' @@ -491,7 +491,7 @@ def getHostname(self, url): return self.hostname -def createPlugin(): - return ArachniPlugin() +def createPlugin(ignore_info=False): + return ArachniPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/arp_scan/plugin.py b/faraday_plugins/plugins/repo/arp_scan/plugin.py index e955acb9..4d5de3ec 100644 --- a/faraday_plugins/plugins/repo/arp_scan/plugin.py +++ b/faraday_plugins/plugins/repo/arp_scan/plugin.py @@ -22,8 +22,8 @@ class CmdArpScanPlugin(PluginBase): Basically inserts into the tree the ouput of this tool """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "arp-scan" self.name = "arp-scan network scanner" self.plugin_version = "0.0.2" @@ -60,6 +60,6 @@ def parseOutputString(self, output): -def createPlugin(): - return CmdArpScanPlugin() +def createPlugin(ignore_info=False): + return CmdArpScanPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/awsprowler/plugin.py b/faraday_plugins/plugins/repo/awsprowler/plugin.py index 8444467a..7b37db19 100644 --- a/faraday_plugins/plugins/repo/awsprowler/plugin.py +++ b/faraday_plugins/plugins/repo/awsprowler/plugin.py @@ -33,8 +33,8 @@ class AwsProwlerPlugin(PluginMultiLineJsonFormat): and adds the information to Faraday. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "awsprowler" self.name = "AWS Prowler" self.plugin_version = "0.1" @@ -67,5 +67,5 @@ def parseOutputString(self, output, debug=False): external_id=vuln_external_id, policyviolations=[vuln_policy]) -def createPlugin(): - return AwsProwlerPlugin() +def createPlugin(ignore_info=False): + return AwsProwlerPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/beef/plugin.py b/faraday_plugins/plugins/repo/beef/plugin.py index b4cc400a..f84fbcb8 100644 --- a/faraday_plugins/plugins/repo/beef/plugin.py +++ b/faraday_plugins/plugins/repo/beef/plugin.py @@ -23,8 +23,8 @@ class BeefPlugin(PluginBase): Example plugin to parse beef output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Beef" self.name = "BeEF Online Service Plugin" self.plugin_version = "0.0.1" @@ -99,6 +99,6 @@ def setHost(self): pass -def createPlugin(): - return BeefPlugin() +def createPlugin(ignore_info=False): + return BeefPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/brutexss/plugin.py b/faraday_plugins/plugins/repo/brutexss/plugin.py index 59cacef6..6b809cc0 100644 --- a/faraday_plugins/plugins/repo/brutexss/plugin.py +++ b/faraday_plugins/plugins/repo/brutexss/plugin.py @@ -17,8 +17,8 @@ class brutexss (PluginBase): - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "brutexss" self.name = "brutexss" self.plugin_version = "0.0.2" @@ -57,7 +57,7 @@ def parseOutputString(self, output): -def createPlugin(): - return brutexss() +def createPlugin(ignore_info=False): + return brutexss(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/burp/plugin.py b/faraday_plugins/plugins/repo/burp/plugin.py index 1b5b195e..4347a523 100644 --- a/faraday_plugins/plugins/repo/burp/plugin.py +++ b/faraday_plugins/plugins/repo/burp/plugin.py @@ -210,8 +210,8 @@ class BurpPlugin(PluginXMLFormat): Example plugin to parse burp output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = "issues" self.id = "Burp" self.name = "Burp XML Output Plugin" @@ -289,7 +289,7 @@ def setHost(self): pass -def createPlugin(): - return BurpPlugin() +def createPlugin(ignore_info=False): + return BurpPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/checkmarx/plugin.py b/faraday_plugins/plugins/repo/checkmarx/plugin.py index fbcf549d..ef7c0b76 100755 --- a/faraday_plugins/plugins/repo/checkmarx/plugin.py +++ b/faraday_plugins/plugins/repo/checkmarx/plugin.py @@ -79,8 +79,9 @@ def get_path_node_info(self, path_node): class CheckmarxPlugin(PluginXMLFormat): - def __init__(self): - super().__init__() + + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = ["CxXMLResults"] self.id = 'Checkmarx' self.name = 'Checkmarx XML Output Plugin' @@ -137,6 +138,6 @@ def parseOutputString(self, output): resolution=data, ref=refs) -def createPlugin(): - return CheckmarxPlugin() +def createPlugin(ignore_info=False): + return CheckmarxPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/cobalt/plugin.py b/faraday_plugins/plugins/repo/cobalt/plugin.py index e2c089fc..a367199a 100644 --- a/faraday_plugins/plugins/repo/cobalt/plugin.py +++ b/faraday_plugins/plugins/repo/cobalt/plugin.py @@ -51,8 +51,8 @@ class CobaltPlugin(PluginCSVFormat): Example plugin to parse Cobalt output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.csv_headers = [{'Token'}, {'Tag'}] self.id = "Cobalt" self.name = "Cobalt CSV Output Plugin" @@ -102,5 +102,5 @@ def parseOutputString(self, output): data=row['StepsToReproduce'], external_id=row['Tag'], run_date=run_date) -def createPlugin(): - return CobaltPlugin() +def createPlugin(ignore_info=False): + return CobaltPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/dig/plugin.py b/faraday_plugins/plugins/repo/dig/plugin.py index e5c43424..53d4d437 100644 --- a/faraday_plugins/plugins/repo/dig/plugin.py +++ b/faraday_plugins/plugins/repo/dig/plugin.py @@ -25,12 +25,12 @@ class DigPlugin(PluginBase): Handle DiG (http://linux.die.net/man/1/dig) output """ - def __init__(self): - super().__init__() - self.id = u"dig" - self.name = u"DiG" - self.plugin_version = u"0.0.1" - self.version = u"9.9.5-3" + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) + self.id = "dig" + self.name = "DiG" + self.plugin_version = "0.0.1" + self.version = "9.9.5-3" self._command_regex = re.compile(r'^(dig)\s+.*?') def parseOutputString(self, output): @@ -141,7 +141,7 @@ def parseOutputString(self, output): return True -def createPlugin(): - return DigPlugin() +def createPlugin(ignore_info=False): + return DigPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/dirb/plugin.py b/faraday_plugins/plugins/repo/dirb/plugin.py index 2aa305d6..c9207b5d 100644 --- a/faraday_plugins/plugins/repo/dirb/plugin.py +++ b/faraday_plugins/plugins/repo/dirb/plugin.py @@ -19,8 +19,8 @@ class dirbPlugin(PluginBase): - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "dirb" self.name = "Dirb" self.plugin_version = "0.0.1" @@ -116,7 +116,7 @@ def processCommandString(self, username, current_path, command_string): return "%s%s" % (command_string, extra_arg) -def createPlugin(): - return dirbPlugin() +def createPlugin(ignore_info=False): + return dirbPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/dirsearch/plugin.py b/faraday_plugins/plugins/repo/dirsearch/plugin.py index c53cd108..196e372f 100644 --- a/faraday_plugins/plugins/repo/dirsearch/plugin.py +++ b/faraday_plugins/plugins/repo/dirsearch/plugin.py @@ -52,8 +52,9 @@ class DirsearchPlugin(PluginBase): - def __init__(self): - super().__init__() + + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "dirsearch" self.name = "dirsearch" self.plugin_version = "0.0.1" @@ -132,7 +133,6 @@ def processCommandString(self, username, current_path, command_string): return '{} --json-report {}'.format(command_string, self._output_file_path) -def createPlugin(): - return DirsearchPlugin() +def createPlugin(ignore_info=False): + return DirsearchPlugin(ignore_info=ignore_info) -# I'm Py3 diff --git a/faraday_plugins/plugins/repo/dnsenum/plugin.py b/faraday_plugins/plugins/repo/dnsenum/plugin.py index 9fba1611..1b2ee15a 100644 --- a/faraday_plugins/plugins/repo/dnsenum/plugin.py +++ b/faraday_plugins/plugins/repo/dnsenum/plugin.py @@ -150,8 +150,8 @@ class DnsenumPlugin(PluginBase): Example plugin to parse dnsenum output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Dnsenum" self.name = "Dnsenum XML Output Plugin" self.plugin_version = "0.0.1" @@ -197,7 +197,7 @@ def setHost(self): pass -def createPlugin(): - return DnsenumPlugin() +def createPlugin(ignore_info=False): + return DnsenumPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/dnsmap/plugin.py b/faraday_plugins/plugins/repo/dnsmap/plugin.py index 4ceebf98..ddfdc052 100644 --- a/faraday_plugins/plugins/repo/dnsmap/plugin.py +++ b/faraday_plugins/plugins/repo/dnsmap/plugin.py @@ -91,8 +91,8 @@ def add_host_info_to_items(self, ip_address, hostname): class DnsmapPlugin(PluginBase): """Example plugin to parse dnsmap output.""" - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Dnsmap" self.name = "Dnsmap Output Plugin" self.plugin_version = "0.3" @@ -137,7 +137,7 @@ def processCommandString(self, username, current_path, command_string): command_string) -def createPlugin(): - return DnsmapPlugin() +def createPlugin(ignore_info=False): + return DnsmapPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/dnsrecon/plugin.py b/faraday_plugins/plugins/repo/dnsrecon/plugin.py index fd5a3c07..c89b732c 100644 --- a/faraday_plugins/plugins/repo/dnsrecon/plugin.py +++ b/faraday_plugins/plugins/repo/dnsrecon/plugin.py @@ -156,8 +156,8 @@ class DnsreconPlugin(PluginBase): Example plugin to parse dnsrecon output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Dnsrecon" self.name = "Dnsrecon XML Output Plugin" self.plugin_version = "0.0.2" @@ -243,7 +243,7 @@ def setHost(self): pass -def createPlugin(): - return DnsreconPlugin() +def createPlugin(ignore_info=False): + return DnsreconPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/dnswalk/plugin.py b/faraday_plugins/plugins/repo/dnswalk/plugin.py index 8ae73dc5..795f3d11 100644 --- a/faraday_plugins/plugins/repo/dnswalk/plugin.py +++ b/faraday_plugins/plugins/repo/dnswalk/plugin.py @@ -69,8 +69,8 @@ class DnswalkPlugin(PluginBase): Example plugin to parse dnswalk output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Dnswalk" self.name = "Dnswalk XML Output Plugin" self.plugin_version = "0.0.1" @@ -113,7 +113,7 @@ def parseOutputString(self, output): return True -def createPlugin(): - return DnswalkPlugin() +def createPlugin(ignore_info=False): + return DnswalkPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/faraday_csv/plugin.py b/faraday_plugins/plugins/repo/faraday_csv/plugin.py index 934313d7..2ea3eea4 100644 --- a/faraday_plugins/plugins/repo/faraday_csv/plugin.py +++ b/faraday_plugins/plugins/repo/faraday_csv/plugin.py @@ -248,8 +248,9 @@ def parse_custom_fields(self, row, custom_fields_names): class FaradayCSVPlugin(PluginCSVFormat): - def __init__(self): - super().__init__() + + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "faraday_csv" self.name = "Faraday CSV Plugin" self.plugin_version = "1.0" @@ -351,5 +352,5 @@ def parseOutputString(self, output): ) -def createPlugin(): - return FaradayCSVPlugin() +def createPlugin(ignore_info=False): + return FaradayCSVPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/fierce/plugin.py b/faraday_plugins/plugins/repo/fierce/plugin.py index 25a7adfa..71bbae2a 100644 --- a/faraday_plugins/plugins/repo/fierce/plugin.py +++ b/faraday_plugins/plugins/repo/fierce/plugin.py @@ -101,8 +101,8 @@ class FiercePlugin(PluginBase): Example plugin to parse fierce output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Fierce" self.name = "Fierce Output Plugin" self.plugin_version = "0.0.1" @@ -176,7 +176,7 @@ def parseOutputString(self, output): -def createPlugin(): - return FiercePlugin() +def createPlugin(ignore_info=False): + return FiercePlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/fortify/plugin.py b/faraday_plugins/plugins/repo/fortify/plugin.py index 6da3afae..9ab59f90 100644 --- a/faraday_plugins/plugins/repo/fortify/plugin.py +++ b/faraday_plugins/plugins/repo/fortify/plugin.py @@ -14,8 +14,8 @@ class FortifyPlugin(PluginByExtension): Example plugin to parse nmap output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Fortify" self.name = "Fortify XML Output Plugin" self.plugin_version = "0.0.1" @@ -392,6 +392,6 @@ def format_description(self, vulnID): return text -def createPlugin(): - return FortifyPlugin() +def createPlugin(ignore_info=False): + return FortifyPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/fruitywifi/plugin.py b/faraday_plugins/plugins/repo/fruitywifi/plugin.py index 86b6bfcb..bd174b71 100644 --- a/faraday_plugins/plugins/repo/fruitywifi/plugin.py +++ b/faraday_plugins/plugins/repo/fruitywifi/plugin.py @@ -24,8 +24,8 @@ class FruityWiFiPlugin(PluginBase): This plugin handles FruityWiFi clients. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "fruitywifi" self.name = "FruityWiFi" self.plugin_version = "0.0.1" @@ -127,7 +127,7 @@ def processCommandString(self, username, current_path, command_string): -def createPlugin(): - return FruityWiFiPlugin() +def createPlugin(ignore_info=False): + return FruityWiFiPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/ftp/plugin.py b/faraday_plugins/plugins/repo/ftp/plugin.py index 81faf91e..b09fdd71 100644 --- a/faraday_plugins/plugins/repo/ftp/plugin.py +++ b/faraday_plugins/plugins/repo/ftp/plugin.py @@ -27,8 +27,8 @@ class CmdFtpPlugin(PluginBase): Basically detects if user was able to connect to a device """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "ftp" self.name = "Ftp" self.plugin_version = "0.0.1" @@ -72,7 +72,7 @@ def processCommandString(self, username, current_path, command_string): self._port = count_args[c - 1] -def createPlugin(): - return CmdFtpPlugin() +def createPlugin(ignore_info=False): + return CmdFtpPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/goohost/plugin.py b/faraday_plugins/plugins/repo/goohost/plugin.py index 4a1ac738..51cc46ea 100644 --- a/faraday_plugins/plugins/repo/goohost/plugin.py +++ b/faraday_plugins/plugins/repo/goohost/plugin.py @@ -65,8 +65,8 @@ class GoohostPlugin(PluginBase): Example plugin to parse goohost output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Goohost" self.name = "Goohost XML Output Plugin" self.plugin_version = "0.0.1" @@ -129,6 +129,6 @@ def processOutput(self, command_output): self.parseOutputString(command_output) -def createPlugin(): - return GoohostPlugin() +def createPlugin(ignore_info=False): + return GoohostPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/hping3/plugin.py b/faraday_plugins/plugins/repo/hping3/plugin.py index 6ba684e9..25cb4ac8 100644 --- a/faraday_plugins/plugins/repo/hping3/plugin.py +++ b/faraday_plugins/plugins/repo/hping3/plugin.py @@ -14,8 +14,8 @@ class hping3(PluginBase): - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Hping3" self.name = "hping3" self.plugin_version = "0.0.1" @@ -68,7 +68,7 @@ def parseOutputString(self, output): host_id, service, protocol="tcp", ports=port, status="open") -def createPlugin(): - return hping3() +def createPlugin(ignore_info=False): + return hping3(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/hydra/plugin.py b/faraday_plugins/plugins/repo/hydra/plugin.py index 3e8ca486..89a4bd10 100644 --- a/faraday_plugins/plugins/repo/hydra/plugin.py +++ b/faraday_plugins/plugins/repo/hydra/plugin.py @@ -50,8 +50,8 @@ class HydraPlugin(PluginBase): Example plugin to parse hydra output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Hydra" self.name = "Hydra XML Output Plugin" self.plugin_version = "0.0.1" @@ -131,7 +131,7 @@ def setHost(self): pass -def createPlugin(): - return HydraPlugin() +def createPlugin(ignore_info=False): + return HydraPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/impact/plugin.py b/faraday_plugins/plugins/repo/impact/plugin.py index ddf72d90..663b4859 100644 --- a/faraday_plugins/plugins/repo/impact/plugin.py +++ b/faraday_plugins/plugins/repo/impact/plugin.py @@ -213,8 +213,8 @@ class ImpactPlugin(PluginXMLFormat): Example plugin to parse impact output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = "entities" self.id = "CoreImpact" self.name = "Core Impact XML Output Plugin" @@ -286,7 +286,7 @@ def setHost(self): pass -def createPlugin(): - return ImpactPlugin() +def createPlugin(ignore_info=False): + return ImpactPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/ip360/plugin.py b/faraday_plugins/plugins/repo/ip360/plugin.py index 3df01e6a..dc3339bc 100644 --- a/faraday_plugins/plugins/repo/ip360/plugin.py +++ b/faraday_plugins/plugins/repo/ip360/plugin.py @@ -68,8 +68,8 @@ class Ip360Plugin(PluginBase): Example plugin to parse Ip360 output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Ip360" self.name = "Ip360 CSV Output Plugin" self.plugin_version = "0.0.1" @@ -103,7 +103,7 @@ def parseOutputString(self, output): ref=vulnerability.get("ref")) -def createPlugin(): - return Ip360Plugin() +def createPlugin(ignore_info=False): + return Ip360Plugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/junit/plugin.py b/faraday_plugins/plugins/repo/junit/plugin.py index 958383ff..fe9b2721 100644 --- a/faraday_plugins/plugins/repo/junit/plugin.py +++ b/faraday_plugins/plugins/repo/junit/plugin.py @@ -122,8 +122,8 @@ class JunitPlugin(PluginXMLFormat): Example plugin to parse junit output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Junit" self.name = "Junit XML Output Plugin" self.plugin_version = "0.0.1" @@ -141,5 +141,5 @@ def parseOutputString(self, output): del parser -def createPlugin(): - return JunitPlugin() +def createPlugin(ignore_info=False): + return JunitPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/lynis/plugin.py b/faraday_plugins/plugins/repo/lynis/plugin.py index cf8c6efa..a7ee102e 100644 --- a/faraday_plugins/plugins/repo/lynis/plugin.py +++ b/faraday_plugins/plugins/repo/lynis/plugin.py @@ -221,8 +221,8 @@ def parse_warnings(self): class LynisPlugin(PluginByExtension): """ Simple example plugin to parse lynis' lynis-report.dat file.""" - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Lynis" self.name = "Lynis DAT Output Plugin" self.plugin_version = "0.4" @@ -324,7 +324,7 @@ def processOutput(self, command_output): self._parse_filename(file_path) -def createPlugin(): - return LynisPlugin() +def createPlugin(ignore_info=False): + return LynisPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/maltego/plugin.py b/faraday_plugins/plugins/repo/maltego/plugin.py index b1d2113e..5c55d140 100755 --- a/faraday_plugins/plugins/repo/maltego/plugin.py +++ b/faraday_plugins/plugins/repo/maltego/plugin.py @@ -370,8 +370,8 @@ def getInfoMtgl(self, xml, name): class MaltegoPlugin(PluginZipFormat): - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = "maltego" self.id = "Maltego" self.name = "Maltego MTGX & MTGL Output Plugin" @@ -512,5 +512,5 @@ def parseOutputString(self, output): -def createPlugin(): - return MaltegoPlugin() +def createPlugin(ignore_info=False): + return MaltegoPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/mbsa/plugin.py b/faraday_plugins/plugins/repo/mbsa/plugin.py index bb65c165..a9a5ecab 100644 --- a/faraday_plugins/plugins/repo/mbsa/plugin.py +++ b/faraday_plugins/plugins/repo/mbsa/plugin.py @@ -27,8 +27,9 @@ def __init__(self, log_output): class MbsaPlugin(PluginByExtension): - def __init__(self): - super().__init__() + + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "MBSA" self.name = "Microsoft Baseline Security Analyzer" self.plugin_version = "1.0.1" @@ -113,5 +114,5 @@ def parseOutputString(self, output): i += 1 -def createPlugin(): - return MbsaPlugin() +def createPlugin(ignore_info=False): + return MbsaPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/medusa/plugin.py b/faraday_plugins/plugins/repo/medusa/plugin.py index 7aa69d62..dae0e390 100644 --- a/faraday_plugins/plugins/repo/medusa/plugin.py +++ b/faraday_plugins/plugins/repo/medusa/plugin.py @@ -59,8 +59,8 @@ class MedusaPlugin(PluginBase): Example plugin to parse medusa output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Medusa" self.name = "Medusa Output Plugin" self.plugin_version = "0.0.1" @@ -134,5 +134,5 @@ def setHost(self): pass -def createPlugin(): - return MedusaPlugin() +def createPlugin(ignore_info=False): + return MedusaPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/metasploit/plugin.py b/faraday_plugins/plugins/repo/metasploit/plugin.py index 914d8238..5cd755ab 100644 --- a/faraday_plugins/plugins/repo/metasploit/plugin.py +++ b/faraday_plugins/plugins/repo/metasploit/plugin.py @@ -325,8 +325,8 @@ class MetasploitPlugin(PluginXMLFormat): Example plugin to parse metasploit output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = ["MetasploitV4", "MetasploitV5"] self.id = "Metasploit" self.name = "Metasploit XML Output Plugin" @@ -403,7 +403,7 @@ def setHost(self): pass -def createPlugin(): - return MetasploitPlugin() +def createPlugin(ignore_info=False): + return MetasploitPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/ncrack/plugin.py b/faraday_plugins/plugins/repo/ncrack/plugin.py index aaa7542a..3b194e16 100644 --- a/faraday_plugins/plugins/repo/ncrack/plugin.py +++ b/faraday_plugins/plugins/repo/ncrack/plugin.py @@ -92,8 +92,9 @@ def get_service(self, tree): class NcrackPlugin(PluginXMLFormat): - def __init__(self): - super().__init__() + + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = "ncrackrun" self.id = 'ncrack' self.name = 'ncrack XML Plugin' @@ -121,5 +122,5 @@ def parseOutputString(self, output): password=service_vuln['passw']) -def createPlugin(): - return NcrackPlugin() +def createPlugin(ignore_info=False): + return NcrackPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/ndiff/plugin.py b/faraday_plugins/plugins/repo/ndiff/plugin.py index f7263331..93472b09 100644 --- a/faraday_plugins/plugins/repo/ndiff/plugin.py +++ b/faraday_plugins/plugins/repo/ndiff/plugin.py @@ -109,8 +109,8 @@ class CmdNdiffPlugin(PluginBase): Add a new vuln INFO if detect a new host or a new port .. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Ndiff" self.name = "ndiff" self.plugin_version = "0.0.1" @@ -156,7 +156,7 @@ def processCommandString(self, username, current_path, command_string): return f"{command_string} --xml " -def createPlugin(): - return CmdNdiffPlugin() +def createPlugin(ignore_info=False): + return CmdNdiffPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/nessus/plugin.py b/faraday_plugins/plugins/repo/nessus/plugin.py index 798f97eb..88c5116b 100644 --- a/faraday_plugins/plugins/repo/nessus/plugin.py +++ b/faraday_plugins/plugins/repo/nessus/plugin.py @@ -180,8 +180,8 @@ class NessusPlugin(PluginXMLFormat): Example plugin to parse nessus output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.extension = ".nessus" self.identifier_tag = "NessusClientData_v2" self.id = "Nessus" @@ -325,5 +325,5 @@ def parseOutputString(self, output): run_date=run_date) -def createPlugin(): - return NessusPlugin() +def createPlugin(ignore_info=False): + return NessusPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/netdiscover/plugin.py b/faraday_plugins/plugins/repo/netdiscover/plugin.py index b87e7a17..5bd0c27d 100644 --- a/faraday_plugins/plugins/repo/netdiscover/plugin.py +++ b/faraday_plugins/plugins/repo/netdiscover/plugin.py @@ -16,8 +16,8 @@ class NetdiscoverPlugin(PluginBase): - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Netdiscover" self.name = "netdiscover" self.plugin_version = "0.0.1" @@ -39,7 +39,7 @@ def parseOutputString(self, output): -def createPlugin(): - return NetdiscoverPlugin() +def createPlugin(ignore_info=False): + return NetdiscoverPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/netsparker/plugin.py b/faraday_plugins/plugins/repo/netsparker/plugin.py index 7fdd1403..0635cb35 100644 --- a/faraday_plugins/plugins/repo/netsparker/plugin.py +++ b/faraday_plugins/plugins/repo/netsparker/plugin.py @@ -185,8 +185,8 @@ class NetsparkerPlugin(PluginXMLFormat): Example plugin to parse netsparker output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = "netsparker" self.id = "Netsparker" self.name = "Netsparker XML Output Plugin" @@ -229,7 +229,7 @@ def parseOutputString(self, output): del parser -def createPlugin(): - return NetsparkerPlugin() +def createPlugin(ignore_info=False): + return NetsparkerPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/netsparkercloud/plugin.py b/faraday_plugins/plugins/repo/netsparkercloud/plugin.py index ce85c6b4..4ce6e33f 100644 --- a/faraday_plugins/plugins/repo/netsparkercloud/plugin.py +++ b/faraday_plugins/plugins/repo/netsparkercloud/plugin.py @@ -180,8 +180,8 @@ class NetsparkerCloudPlugin(PluginXMLFormat): Example plugin to parse netsparkercloud output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = "netsparker-cloud" self.id = "NetsparkerCloud" self.name = "NetsparkerCloud XML Output Plugin" @@ -210,5 +210,5 @@ def setHost(self): pass -def createPlugin(): - return NetsparkerCloudPlugin() +def createPlugin(ignore_info=False): + return NetsparkerCloudPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/nexpose_full/plugin.py b/faraday_plugins/plugins/repo/nexpose_full/plugin.py index c565809e..4cea3ffc 100644 --- a/faraday_plugins/plugins/repo/nexpose_full/plugin.py +++ b/faraday_plugins/plugins/repo/nexpose_full/plugin.py @@ -249,8 +249,8 @@ class NexposeFullPlugin(PluginXMLFormat): Example plugin to parse nexpose output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = "NexposeReport" self.id = "NexposeFull" self.name = "Nexpose XML 2.0 Report Plugin" @@ -325,7 +325,7 @@ def setHost(self): pass -def createPlugin(): - return NexposeFullPlugin() +def createPlugin(ignore_info=False): + return NexposeFullPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/nextnet/plugin.py b/faraday_plugins/plugins/repo/nextnet/plugin.py index 9320c52e..6eb07194 100644 --- a/faraday_plugins/plugins/repo/nextnet/plugin.py +++ b/faraday_plugins/plugins/repo/nextnet/plugin.py @@ -22,8 +22,9 @@ class CmdNextNetin(PluginBase): - def __init__(self): - super().__init__() + + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "nextnet" self.name = "nextnet" self.plugin_version = "0.0.1" @@ -64,5 +65,5 @@ def parseOutputString(self, output): return True -def createPlugin(): - return CmdNextNetin() +def createPlugin(ignore_info=False): + return CmdNextNetin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/nikto/plugin.py b/faraday_plugins/plugins/repo/nikto/plugin.py index ee556abf..1d60115a 100644 --- a/faraday_plugins/plugins/repo/nikto/plugin.py +++ b/faraday_plugins/plugins/repo/nikto/plugin.py @@ -247,8 +247,8 @@ class NiktoPlugin(PluginXMLFormat): Example plugin to parse nikto output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = "niktoscan" self.id = "Nikto" self.name = "Nikto XML Output Plugin" @@ -258,7 +258,7 @@ def __init__(self): self.parent = None self._use_temp_file = True self._temp_file_extension = "xml" - self.xml_arg_re = re.compile(r"^.*(-output\s*[^\s]+).*$") + self.xml_alrg_re = re.compile(r"^.*(-output\s*[^\s]+).*$") self._command_regex = re.compile( r'^(sudo nikto|nikto|sudo nikto\.pl|nikto\.pl|perl nikto\.pl|\.\/nikto\.pl|\.\/nikto)\s+.*?') self._completition = { @@ -364,7 +364,7 @@ def setHost(self): pass -def createPlugin(): - return NiktoPlugin() +def createPlugin(ignore_info=False): + return NiktoPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/nmap/plugin.py b/faraday_plugins/plugins/repo/nmap/plugin.py index 0c493b56..f9d8d1d4 100644 --- a/faraday_plugins/plugins/repo/nmap/plugin.py +++ b/faraday_plugins/plugins/repo/nmap/plugin.py @@ -431,8 +431,8 @@ class NmapPlugin(PluginXMLFormat): Example plugin to parse nmap output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = "nmaprun" self.id = "Nmap" self.name = "Nmap XML Output Plugin" @@ -550,7 +550,7 @@ def processCommandString(self, username, current_path, command_string): r"-oX %s" % self._output_file_path, command_string) -def createPlugin(): - return NmapPlugin() +def createPlugin(ignore_info=False): + return NmapPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/nuclei/plugin.py b/faraday_plugins/plugins/repo/nuclei/plugin.py index dd8d576a..01e32134 100644 --- a/faraday_plugins/plugins/repo/nuclei/plugin.py +++ b/faraday_plugins/plugins/repo/nuclei/plugin.py @@ -31,8 +31,8 @@ class NucleiPlugin(PluginMultiLineJsonFormat): and adds the information to Faraday. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "nuclei" self.name = "Nuclei" self.plugin_version = "0.1" @@ -100,7 +100,7 @@ def parseOutputString(self, output, debug=False): external_id=info_vuln.get('template', "")) -def createPlugin(): - return NucleiPlugin() +def createPlugin(ignore_info=False): + return NucleiPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/openscap/plugin.py b/faraday_plugins/plugins/repo/openscap/plugin.py index 71e6ec50..437ba2ad 100644 --- a/faraday_plugins/plugins/repo/openscap/plugin.py +++ b/faraday_plugins/plugins/repo/openscap/plugin.py @@ -126,8 +126,9 @@ def get_parser_result(self, tree): class OpenScapPlugin(PluginXMLFormat): - def __init__(self): - super().__init__() + + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = "Benchmark" self.id = 'OpenScap' self.name = 'OpenScap XML Output Plugin' @@ -210,5 +211,5 @@ def parseOutputString(self, output): run_date=vuln_run_date) -def createPlugin(): - return OpenScapPlugin() +def createPlugin(ignore_info=False): + return OpenScapPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/openvas/plugin.py b/faraday_plugins/plugins/repo/openvas/plugin.py index ebbd768c..918faad9 100644 --- a/faraday_plugins/plugins/repo/openvas/plugin.py +++ b/faraday_plugins/plugins/repo/openvas/plugin.py @@ -320,8 +320,8 @@ class OpenvasPlugin(PluginXMLFormat): Example plugin to parse openvas output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = ["report", "get_results_response"] self.id = "Openvas" self.name = "Openvas XML Output Plugin" @@ -447,7 +447,7 @@ def setHost(self): pass -def createPlugin(): - return OpenvasPlugin() +def createPlugin(ignore_info=False): + return OpenvasPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/pasteanalyzer/plugin.py b/faraday_plugins/plugins/repo/pasteanalyzer/plugin.py index 1e7fd647..3c47c291 100644 --- a/faraday_plugins/plugins/repo/pasteanalyzer/plugin.py +++ b/faraday_plugins/plugins/repo/pasteanalyzer/plugin.py @@ -21,8 +21,8 @@ class pasteAnalyzerPlugin(PluginBase): - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "pasteAnalyzer" self.name = "pasteAnalyzer JSON Output Plugin" self.plugin_version = "1.0.0" @@ -86,7 +86,7 @@ def processCommandString(self, username, current_path, command_string): return command_string -def createPlugin(): - return pasteAnalyzerPlugin() +def createPlugin(ignore_info=False): + return pasteAnalyzerPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/peepingtom/plugin.py b/faraday_plugins/plugins/repo/peepingtom/plugin.py index cc50f3fd..e1e02927 100644 --- a/faraday_plugins/plugins/repo/peepingtom/plugin.py +++ b/faraday_plugins/plugins/repo/peepingtom/plugin.py @@ -25,8 +25,8 @@ class PeepingTomPlugin(PluginBase): Handle PeepingTom (https://bitbucket.org/LaNMaSteR53/peepingtom) output """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "peepingtom" self.name = "PeepingTom" self.plugin_version = "0.0.1" @@ -71,7 +71,7 @@ def processCommandString(self, username, current_path, command_string): self._path = current_path -def createPlugin(): - return PeepingTomPlugin() +def createPlugin(ignore_info=False): + return PeepingTomPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/ping/plugin.py b/faraday_plugins/plugins/repo/ping/plugin.py index 89bb6216..365ed2bd 100644 --- a/faraday_plugins/plugins/repo/ping/plugin.py +++ b/faraday_plugins/plugins/repo/ping/plugin.py @@ -23,8 +23,8 @@ class CmdPingPlugin(PluginBase): Basically detects if user was able to connect to a device """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "ping" self.name = "Ping" self.plugin_version = "0.0.1" @@ -49,8 +49,8 @@ def _isIPV4(self, ip): -def createPlugin(): - return CmdPingPlugin() +def createPlugin(ignore_info=False): + return CmdPingPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/propecia/plugin.py b/faraday_plugins/plugins/repo/propecia/plugin.py index b762c62f..75f7e687 100644 --- a/faraday_plugins/plugins/repo/propecia/plugin.py +++ b/faraday_plugins/plugins/repo/propecia/plugin.py @@ -24,8 +24,8 @@ class CmdPropeciaPlugin(PluginBase): Basically inserts into the tree the ouput of this tool """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "propecia" self.name = "propecia port scanner" self.plugin_version = "0.0.1" @@ -61,7 +61,7 @@ def processCommandString(self, username, current_path, command_string): self._port = count_args[2] -def createPlugin(): - return CmdPropeciaPlugin() +def createPlugin(ignore_info=False): + return CmdPropeciaPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/qualysguard/plugin.py b/faraday_plugins/plugins/repo/qualysguard/plugin.py index 46658a8c..f84bce52 100644 --- a/faraday_plugins/plugins/repo/qualysguard/plugin.py +++ b/faraday_plugins/plugins/repo/qualysguard/plugin.py @@ -335,8 +335,8 @@ class QualysguardPlugin(PluginXMLFormat): Example plugin to parse qualysguard output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = ["ASSET_DATA_REPORT", "SCAN"] self.id = 'Qualysguard' self.name = 'Qualysguard XML Output Plugin' @@ -419,7 +419,7 @@ def setHost(self): pass -def createPlugin(): - return QualysguardPlugin() +def createPlugin(ignore_info=False): + return QualysguardPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/qualyswebapp/plugin.py b/faraday_plugins/plugins/repo/qualyswebapp/plugin.py index 76eae4de..298ed048 100644 --- a/faraday_plugins/plugins/repo/qualyswebapp/plugin.py +++ b/faraday_plugins/plugins/repo/qualyswebapp/plugin.py @@ -101,8 +101,9 @@ def get_qid_list(self, vul_list_tags): class QualysWebappPlugin(PluginXMLFormat): - def __init__(self): - super().__init__() + + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = ["WAS_SCAN_REPORT"] self.id = 'QualysWebapp' self.name = 'QualysWebapp XML Output Plugin' @@ -175,5 +176,5 @@ def parseOutputString(self, output): external_id=vuln_scan_id, data=vuln_data_add) -def createPlugin(): - return QualysWebappPlugin() +def createPlugin(ignore_info=False): + return QualysWebappPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/rdpscan/plugin.py b/faraday_plugins/plugins/repo/rdpscan/plugin.py index 473ead5a..0ddcf22f 100644 --- a/faraday_plugins/plugins/repo/rdpscan/plugin.py +++ b/faraday_plugins/plugins/repo/rdpscan/plugin.py @@ -7,8 +7,8 @@ class RDPScanPlugin(PluginBase): - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = "rdpscan" self.id = "rdpscan" self.name = "rdpscan" @@ -43,5 +43,5 @@ def parseOutputString(self, output): ) -def createPlugin(): - return RDPScanPlugin() +def createPlugin(ignore_info=False): + return RDPScanPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/reconng/plugin.py b/faraday_plugins/plugins/repo/reconng/plugin.py index 04042fea..4e74df9b 100644 --- a/faraday_plugins/plugins/repo/reconng/plugin.py +++ b/faraday_plugins/plugins/repo/reconng/plugin.py @@ -128,8 +128,8 @@ class ReconngPlugin(PluginXMLFormat): Example plugin to parse qualysguard output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = "reconng" self.id = 'Reconng' self.name = 'Reconng XML Output Plugin' @@ -171,7 +171,7 @@ def parseOutputString(self, output): -def createPlugin(): - return ReconngPlugin() +def createPlugin(ignore_info=False): + return ReconngPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/retina/plugin.py b/faraday_plugins/plugins/repo/retina/plugin.py index ff196cc5..e0e0a530 100644 --- a/faraday_plugins/plugins/repo/retina/plugin.py +++ b/faraday_plugins/plugins/repo/retina/plugin.py @@ -172,8 +172,8 @@ class RetinaPlugin(PluginXMLFormat): Example plugin to parse retina output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = "scanJob" self.id = "Retina" self.name = "Retina XML Output Plugin" @@ -227,7 +227,7 @@ def setHost(self): pass -def createPlugin(): - return RetinaPlugin() +def createPlugin(ignore_info=False): + return RetinaPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/reverseraider/plugin.py b/faraday_plugins/plugins/repo/reverseraider/plugin.py index decad09c..206f31fa 100644 --- a/faraday_plugins/plugins/repo/reverseraider/plugin.py +++ b/faraday_plugins/plugins/repo/reverseraider/plugin.py @@ -49,8 +49,8 @@ class ReverseraiderPlugin(PluginBase): Example plugin to parse reverseraider output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Reverseraider" self.name = "Reverseraider XML Output Plugin" self.plugin_version = "0.0.1" @@ -78,7 +78,7 @@ def parseOutputString(self, output): -def createPlugin(): - return ReverseraiderPlugin() +def createPlugin(ignore_info=False): + return ReverseraiderPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/skipfish/plugin.py b/faraday_plugins/plugins/repo/skipfish/plugin.py index e1cd78c8..8821bad2 100644 --- a/faraday_plugins/plugins/repo/skipfish/plugin.py +++ b/faraday_plugins/plugins/repo/skipfish/plugin.py @@ -111,8 +111,8 @@ class SkipfishPlugin(PluginBase): Example plugin to parse skipfish output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Skipfish" self.name = "Skipfish Output Plugin" self.plugin_version = "0.0.2" @@ -218,7 +218,7 @@ def setHost(self): pass -def createPlugin(): - return SkipfishPlugin() +def createPlugin(ignore_info=False): + return SkipfishPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/sourceclear/plugin.py b/faraday_plugins/plugins/repo/sourceclear/plugin.py index f61c3287..0b4e3351 100644 --- a/faraday_plugins/plugins/repo/sourceclear/plugin.py +++ b/faraday_plugins/plugins/repo/sourceclear/plugin.py @@ -45,8 +45,8 @@ class SourceclearPlugin(PluginJsonFormat): and adds the information to Faraday. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "sourceclear" self.name = "Sourceclear" self.plugin_version = "0.1" @@ -82,5 +82,5 @@ def parseOutputString(self, output, debug=False): website=v_website) -def createPlugin(): - return SourceclearPlugin() +def createPlugin(ignore_info=False): + return SourceclearPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/sshdefaultscan/plugin.py b/faraday_plugins/plugins/repo/sshdefaultscan/plugin.py index 2b5699af..a8a7ee91 100644 --- a/faraday_plugins/plugins/repo/sshdefaultscan/plugin.py +++ b/faraday_plugins/plugins/repo/sshdefaultscan/plugin.py @@ -22,8 +22,8 @@ class SSHDefaultScanPlugin(PluginBase): using --batch and --batch-template; supports --username and --password """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "sshdefaultscan" self.name = "sshdefaultscan" self.plugin_version = "0.0.1" @@ -66,7 +66,7 @@ def processCommandString(self, username, current_path, command_string): return None -def createPlugin(): - return SSHDefaultScanPlugin() +def createPlugin(ignore_info=False): + return SSHDefaultScanPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/ssl_labs/plugin.py b/faraday_plugins/plugins/repo/ssl_labs/plugin.py index 53fa3ce1..070183fd 100644 --- a/faraday_plugins/plugins/repo/ssl_labs/plugin.py +++ b/faraday_plugins/plugins/repo/ssl_labs/plugin.py @@ -67,8 +67,8 @@ class SslLabsPlugin(PluginJsonFormat): and adds the information to Faraday. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "ssllabs" self.name = "SSL Labs" self.plugin_version = "0.1" @@ -110,5 +110,5 @@ def parseOutputString(self, output): data=vuln['data']) -def createPlugin(): - return SslLabsPlugin() +def createPlugin(ignore_info=False): + return SslLabsPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/sslyze/plugin.py b/faraday_plugins/plugins/repo/sslyze/plugin.py index 2db05c00..5070513d 100644 --- a/faraday_plugins/plugins/repo/sslyze/plugin.py +++ b/faraday_plugins/plugins/repo/sslyze/plugin.py @@ -84,8 +84,8 @@ def get_openssl_ccs(self, tree): class SslyzePlugin(PluginXMLFormat): - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = "document" self.id = "Sslyze_XML" self.name = "Sslyze Plugin" @@ -168,5 +168,5 @@ def parseOutputString(self, output): severity="medium") -def createPlugin(): - return SslyzePlugin() +def createPlugin(ignore_info=False): + return SslyzePlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/sslyzejson/plugin.py b/faraday_plugins/plugins/repo/sslyzejson/plugin.py index c1cb60bb..33d05f2c 100644 --- a/faraday_plugins/plugins/repo/sslyzejson/plugin.py +++ b/faraday_plugins/plugins/repo/sslyzejson/plugin.py @@ -162,8 +162,8 @@ def get_openssl_ccs(self, openssl_ccs): class SslyzePlugin(PluginJsonFormat): - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Sslyze_JSON" self.name = "Sslyze Json" self.plugin_version = "0.1" @@ -244,6 +244,6 @@ def processCommandString(self, username, current_path, command_string): command_string) -def createPlugin(): - return SslyzePlugin() +def createPlugin(ignore_info=False): + return SslyzePlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/telnet/plugin.py b/faraday_plugins/plugins/repo/telnet/plugin.py index 47f270e2..3a0f542a 100644 --- a/faraday_plugins/plugins/repo/telnet/plugin.py +++ b/faraday_plugins/plugins/repo/telnet/plugin.py @@ -24,8 +24,8 @@ class TelnetRouterPlugin(PluginBase): Basically detects if user was able to connect to a device """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Telnet" self.name = "Telnet" self.plugin_version = "0.0.1" @@ -77,7 +77,7 @@ def processCommandString(self, username, current_path, command_string): self._port = count_args[c - 1] -def createPlugin(): - return TelnetRouterPlugin() +def createPlugin(ignore_info=False): + return TelnetRouterPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/theharvester/plugin.py b/faraday_plugins/plugins/repo/theharvester/plugin.py index bd88e57f..6d9254c2 100644 --- a/faraday_plugins/plugins/repo/theharvester/plugin.py +++ b/faraday_plugins/plugins/repo/theharvester/plugin.py @@ -73,8 +73,8 @@ class TheharvesterPlugin(PluginBase): Example plugin to parse theharvester output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Theharvester" self.name = "Theharvester XML Output Plugin" self.plugin_version = "0.0.1" @@ -115,8 +115,8 @@ def parseOutputString(self, output): -def createPlugin(): - return TheharvesterPlugin() +def createPlugin(ignore_info=False): + return TheharvesterPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/traceroute/plugin.py b/faraday_plugins/plugins/repo/traceroute/plugin.py index a2de5cd8..3e02a085 100644 --- a/faraday_plugins/plugins/repo/traceroute/plugin.py +++ b/faraday_plugins/plugins/repo/traceroute/plugin.py @@ -16,8 +16,8 @@ class traceroutePlugin(PluginBase): - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Traceroute" self.name = "Traceroute" self.plugin_version = "1.0.0" @@ -56,7 +56,7 @@ def processCommandString(self, username, current_path, command_string): return None -def createPlugin(): - return traceroutePlugin() +def createPlugin(ignore_info=False): + return traceroutePlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/w3af/plugin.py b/faraday_plugins/plugins/repo/w3af/plugin.py index 77c4c03d..6108fe6f 100644 --- a/faraday_plugins/plugins/repo/w3af/plugin.py +++ b/faraday_plugins/plugins/repo/w3af/plugin.py @@ -208,8 +208,8 @@ class W3afPlugin(PluginXMLFormat): Example plugin to parse w3af output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = ["w3af-run", "w3afrun"] self.id = "W3af" self.name = "W3af XML Output Plugin" @@ -241,7 +241,7 @@ def parseOutputString(self, output): -def createPlugin(): - return W3afPlugin() +def createPlugin(ignore_info=False): + return W3afPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/wapiti/plugin.py b/faraday_plugins/plugins/repo/wapiti/plugin.py index 02c84599..5d266d8b 100644 --- a/faraday_plugins/plugins/repo/wapiti/plugin.py +++ b/faraday_plugins/plugins/repo/wapiti/plugin.py @@ -224,8 +224,8 @@ class WapitiPlugin(PluginXMLFormat): Example plugin to parse wapiti output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = "report" self.id = "Wapiti" self.name = "Wapiti XML Output Plugin" @@ -346,7 +346,7 @@ def setHost(self): pass -def createPlugin(): - return WapitiPlugin() +def createPlugin(ignore_info=False): + return WapitiPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/wcscan/plugin.py b/faraday_plugins/plugins/repo/wcscan/plugin.py index db7981eb..bd759294 100644 --- a/faraday_plugins/plugins/repo/wcscan/plugin.py +++ b/faraday_plugins/plugins/repo/wcscan/plugin.py @@ -70,8 +70,8 @@ class WcscanPlugin(PluginBase): Example plugin to parse wcscan output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Wcscan" self.name = "Wcscan XML Output Plugin" self.plugin_version = "0.0.2" @@ -133,7 +133,7 @@ def processCommandString(self, username, current_path, command_string): return re.sub(arg_match.group(1), r"-xml %s" % self._output_file_path, command_string) -def createPlugin(): - return WcscanPlugin() +def createPlugin(ignore_info=False): + return WcscanPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/webfuzzer/plugin.py b/faraday_plugins/plugins/repo/webfuzzer/plugin.py index eb575f6d..2131c87d 100644 --- a/faraday_plugins/plugins/repo/webfuzzer/plugin.py +++ b/faraday_plugins/plugins/repo/webfuzzer/plugin.py @@ -73,8 +73,8 @@ class WebfuzzerPlugin(PluginBase): Example plugin to parse webfuzzer output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Webfuzzer" self.name = "Webfuzzer Output Plugin" self.plugin_version = "0.0.2" @@ -135,7 +135,7 @@ def processCommandString(self, username, current_path, command_string): self._output_path = current_path + "/" + self.host + ".txt" -def createPlugin(): - return WebfuzzerPlugin() +def createPlugin(ignore_info=False): + return WebfuzzerPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/webinspect/plugin.py b/faraday_plugins/plugins/repo/webinspect/plugin.py index 65428d1e..2ab7d1f1 100644 --- a/faraday_plugins/plugins/repo/webinspect/plugin.py +++ b/faraday_plugins/plugins/repo/webinspect/plugin.py @@ -117,8 +117,8 @@ class WebInspectPlugin(PluginXMLFormat): This plugin handles WebInspect reports. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Webinspect" self.name = "Webinspect" self.plugin_version = "0.0.1" @@ -153,8 +153,6 @@ def parseOutputString(self, output): ) - - -def createPlugin(): - return WebInspectPlugin() +def createPlugin(ignore_info=False): + return WebInspectPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/wfuzz/plugin.py b/faraday_plugins/plugins/repo/wfuzz/plugin.py index 5eb8c819..5362ae59 100644 --- a/faraday_plugins/plugins/repo/wfuzz/plugin.py +++ b/faraday_plugins/plugins/repo/wfuzz/plugin.py @@ -7,8 +7,8 @@ class WfuzzPlugin(PluginBase): - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "Wfuzz" self.name = "Wfuzz Plugin" self.plugin_version = "0.0.1" @@ -84,7 +84,7 @@ def parseOutputString(self, output): path=path) -def createPlugin(): - return WfuzzPlugin() +def createPlugin(ignore_info=False): + return WfuzzPlugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/whatweb/plugin.py b/faraday_plugins/plugins/repo/whatweb/plugin.py index 05ece3a9..6f8f1686 100644 --- a/faraday_plugins/plugins/repo/whatweb/plugin.py +++ b/faraday_plugins/plugins/repo/whatweb/plugin.py @@ -50,8 +50,8 @@ def __init__(self, json_output): class WhatWebPlugin(PluginJsonFormat): - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "whatweb" self.name = "WhatWebPlugin" self.plugin_version = "0.1" @@ -74,5 +74,5 @@ def parseOutputString(self, output): description=desc) -def createPlugin(): - return WhatWebPlugin() +def createPlugin(ignore_info=False): + return WhatWebPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/whitesource/plugin.py b/faraday_plugins/plugins/repo/whitesource/plugin.py index 39fae1e5..900b64e1 100644 --- a/faraday_plugins/plugins/repo/whitesource/plugin.py +++ b/faraday_plugins/plugins/repo/whitesource/plugin.py @@ -22,8 +22,9 @@ class WhitesourcePlugin(PluginJsonFormat): - def __init__(self): - super().__init__() + + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "whitesource" self.name = "whitesource" self.plugin_version = "0.1" @@ -93,8 +94,5 @@ def parseOutputString(self, output): ) - - - -def createPlugin(): - return WhitesourcePlugin() +def createPlugin(ignore_info=False): + return WhitesourcePlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/whois/plugin.py b/faraday_plugins/plugins/repo/whois/plugin.py index ba759069..dbb8bae5 100644 --- a/faraday_plugins/plugins/repo/whois/plugin.py +++ b/faraday_plugins/plugins/repo/whois/plugin.py @@ -27,8 +27,8 @@ class CmdWhoisPlugin(PluginBase): Basically detects if user was able to connect to a device """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "whois" self.name = "Whois" self.plugin_version = "0.0.1" @@ -126,5 +126,5 @@ def parseOutputString(self, output): return True -def createPlugin(): - return CmdWhoisPlugin() +def createPlugin(ignore_info=False): + return CmdWhoisPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/wpscan/plugin.py b/faraday_plugins/plugins/repo/wpscan/plugin.py index 07e8de8c..15da849c 100644 --- a/faraday_plugins/plugins/repo/wpscan/plugin.py +++ b/faraday_plugins/plugins/repo/wpscan/plugin.py @@ -49,8 +49,8 @@ class WPScanPlugin(PluginJsonFormat): and adds the information to Faraday. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "wpscan" self.name = "WPscan" self.plugin_version = "0.2" @@ -91,5 +91,5 @@ def parseOutputString(self, output): severity='unclassified') -def createPlugin(): - return WPScanPlugin() +def createPlugin(ignore_info=False): + return WPScanPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/x1/plugin.py b/faraday_plugins/plugins/repo/x1/plugin.py index e506d1a4..f57ea8fa 100644 --- a/faraday_plugins/plugins/repo/x1/plugin.py +++ b/faraday_plugins/plugins/repo/x1/plugin.py @@ -155,8 +155,8 @@ class X1Plugin(PluginXMLFormat): Example plugin to parse x1 output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = ["session", "landscapePolicy"] self.id = "X1" self.name = "Onapsis X1 XML Output Plugin" @@ -193,7 +193,7 @@ def setHost(self): pass -def createPlugin(): - return X1Plugin() +def createPlugin(ignore_info=False): + return X1Plugin(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/xsssniper/plugin.py b/faraday_plugins/plugins/repo/xsssniper/plugin.py index 5afe36e8..08f26a51 100644 --- a/faraday_plugins/plugins/repo/xsssniper/plugin.py +++ b/faraday_plugins/plugins/repo/xsssniper/plugin.py @@ -16,8 +16,8 @@ class xsssniper(PluginBase): - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.id = "xsssniper" self.name = "xsssniper" self.plugin_version = "0.0.1" @@ -55,7 +55,7 @@ def parseOutputString(self, output): params=''.join(parametro), request='', response='') -def createPlugin(): - return xsssniper() +def createPlugin(ignore_info=False): + return xsssniper(ignore_info=ignore_info) # I'm Py3 diff --git a/faraday_plugins/plugins/repo/zap/plugin.py b/faraday_plugins/plugins/repo/zap/plugin.py index 187de0be..56170720 100644 --- a/faraday_plugins/plugins/repo/zap/plugin.py +++ b/faraday_plugins/plugins/repo/zap/plugin.py @@ -234,8 +234,8 @@ class ZapPlugin(PluginXMLFormat): Example plugin to parse zap output. """ - def __init__(self): - super().__init__() + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) self.identifier_tag = "OWASPZAPReport" self.id = "Zap" self.name = "Zap XML Output Plugin" @@ -287,5 +287,5 @@ def setHost(self): pass -def createPlugin(): - return ZapPlugin() +def createPlugin(ignore_info=False): + return ZapPlugin(ignore_info=ignore_info) From 4d9b492de8217a60f78453b89b7536c38fc77f2e Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Fri, 12 Mar 2021 17:57:37 -0300 Subject: [PATCH 170/698] add changelog --- CHANGELOG/current/new_ignore_info_option.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 CHANGELOG/current/new_ignore_info_option.md diff --git a/CHANGELOG/current/new_ignore_info_option.md b/CHANGELOG/current/new_ignore_info_option.md new file mode 100644 index 00000000..64a23214 --- /dev/null +++ b/CHANGELOG/current/new_ignore_info_option.md @@ -0,0 +1 @@ +Add Ignore information vulnerabilities option From 56cb9fcfad3d83426011e9a57d420af495dfd642 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Fri, 12 Mar 2021 18:24:59 -0300 Subject: [PATCH 171/698] remove I'm Py3 footer --- faraday_plugins/plugins/repo/acunetix/__init__.py | 2 +- faraday_plugins/plugins/repo/amap/__init__.py | 2 +- faraday_plugins/plugins/repo/amap/plugin.py | 2 +- faraday_plugins/plugins/repo/appscan/__init__.py | 2 +- faraday_plugins/plugins/repo/arachni/__init__.py | 2 +- faraday_plugins/plugins/repo/arachni/plugin.py | 2 +- faraday_plugins/plugins/repo/arp_scan/__init__.py | 2 +- faraday_plugins/plugins/repo/beef/__init__.py | 2 +- faraday_plugins/plugins/repo/brutexss/__init__.py | 2 +- faraday_plugins/plugins/repo/brutexss/plugin.py | 2 +- faraday_plugins/plugins/repo/burp/__init__.py | 2 +- faraday_plugins/plugins/repo/burp/plugin.py | 2 +- faraday_plugins/plugins/repo/checkmarx/__init__.py | 2 +- faraday_plugins/plugins/repo/cobalt/__init__.py | 2 +- faraday_plugins/plugins/repo/dig/__init__.py | 2 +- faraday_plugins/plugins/repo/dig/plugin.py | 2 +- faraday_plugins/plugins/repo/dirb/__init__.py | 2 +- faraday_plugins/plugins/repo/dirb/plugin.py | 2 +- faraday_plugins/plugins/repo/dirsearch/__init__.py | 2 +- faraday_plugins/plugins/repo/dnsenum/__init__.py | 2 +- faraday_plugins/plugins/repo/dnsenum/plugin.py | 2 +- faraday_plugins/plugins/repo/dnsmap/__init__.py | 2 +- faraday_plugins/plugins/repo/dnsmap/plugin.py | 2 +- faraday_plugins/plugins/repo/dnsrecon/__init__.py | 2 +- faraday_plugins/plugins/repo/dnsrecon/plugin.py | 2 +- faraday_plugins/plugins/repo/dnswalk/__init__.py | 2 +- faraday_plugins/plugins/repo/dnswalk/plugin.py | 2 +- faraday_plugins/plugins/repo/faraday_csv/__init__.py | 2 +- faraday_plugins/plugins/repo/fierce/__init__.py | 2 +- faraday_plugins/plugins/repo/fierce/plugin.py | 2 +- faraday_plugins/plugins/repo/fruitywifi/__init__.py | 2 +- faraday_plugins/plugins/repo/fruitywifi/fruitywifi.py | 2 +- faraday_plugins/plugins/repo/fruitywifi/plugin.py | 2 +- faraday_plugins/plugins/repo/ftp/__init__.py | 2 +- faraday_plugins/plugins/repo/ftp/plugin.py | 2 +- faraday_plugins/plugins/repo/goohost/__init__.py | 2 +- faraday_plugins/plugins/repo/hping3/__init__.py | 2 +- faraday_plugins/plugins/repo/hping3/plugin.py | 2 +- faraday_plugins/plugins/repo/hydra/__init__.py | 2 +- faraday_plugins/plugins/repo/hydra/plugin.py | 2 +- faraday_plugins/plugins/repo/impact/__init__.py | 2 +- faraday_plugins/plugins/repo/ip360/__init__.py | 2 +- faraday_plugins/plugins/repo/ip360/plugin.py | 2 +- faraday_plugins/plugins/repo/junit/__init__.py | 2 +- faraday_plugins/plugins/repo/lynis/__init__.py | 2 +- faraday_plugins/plugins/repo/maltego/__init__.py | 2 +- faraday_plugins/plugins/repo/medusa/__init__.py | 2 +- faraday_plugins/plugins/repo/metasploit/__init__.py | 2 +- faraday_plugins/plugins/repo/metasploit/plugin.py | 2 +- faraday_plugins/plugins/repo/ndiff/__init__.py | 2 +- faraday_plugins/plugins/repo/ndiff/plugin.py | 2 +- faraday_plugins/plugins/repo/nessus/__init__.py | 2 +- faraday_plugins/plugins/repo/netdiscover/__init__.py | 2 +- faraday_plugins/plugins/repo/netdiscover/plugin.py | 2 +- faraday_plugins/plugins/repo/netsparker/__init__.py | 2 +- faraday_plugins/plugins/repo/netsparker/plugin.py | 2 +- faraday_plugins/plugins/repo/netsparkercloud/__init__.py | 2 +- faraday_plugins/plugins/repo/nexpose_full/__init__.py | 2 +- faraday_plugins/plugins/repo/nexpose_full/plugin.py | 2 +- faraday_plugins/plugins/repo/nikto/__init__.py | 2 +- faraday_plugins/plugins/repo/nikto/plugin.py | 2 +- faraday_plugins/plugins/repo/nmap/__init__.py | 2 +- faraday_plugins/plugins/repo/nmap/plugin.py | 2 +- faraday_plugins/plugins/repo/openvas/__init__.py | 2 +- faraday_plugins/plugins/repo/openvas/plugin.py | 2 +- faraday_plugins/plugins/repo/pasteanalyzer/__init__.py | 2 +- faraday_plugins/plugins/repo/pasteanalyzer/plugin.py | 2 +- faraday_plugins/plugins/repo/peepingtom/__init__.py | 2 +- faraday_plugins/plugins/repo/peepingtom/plugin.py | 2 +- faraday_plugins/plugins/repo/ping/__init__.py | 2 +- faraday_plugins/plugins/repo/ping/plugin.py | 2 +- faraday_plugins/plugins/repo/propecia/__init__.py | 2 +- faraday_plugins/plugins/repo/propecia/plugin.py | 2 +- faraday_plugins/plugins/repo/qualysguard/__init__.py | 2 +- faraday_plugins/plugins/repo/reconng/__init__.py | 2 +- faraday_plugins/plugins/repo/reconng/plugin.py | 2 +- faraday_plugins/plugins/repo/retina/__init__.py | 2 +- faraday_plugins/plugins/repo/retina/plugin.py | 2 +- faraday_plugins/plugins/repo/reverseraider/__init__.py | 2 +- faraday_plugins/plugins/repo/reverseraider/plugin.py | 2 +- faraday_plugins/plugins/repo/skipfish/__init__.py | 2 +- faraday_plugins/plugins/repo/skipfish/plugin.py | 2 +- faraday_plugins/plugins/repo/sourceclear/__init__.py | 2 +- faraday_plugins/plugins/repo/sshdefaultscan/__init__.py | 2 +- faraday_plugins/plugins/repo/sshdefaultscan/plugin.py | 2 +- faraday_plugins/plugins/repo/sslyze/__init__.py | 2 +- faraday_plugins/plugins/repo/sslyzejson/__init__.py | 2 +- faraday_plugins/plugins/repo/telnet/__init__.py | 2 +- faraday_plugins/plugins/repo/telnet/plugin.py | 2 +- faraday_plugins/plugins/repo/theharvester/__init__.py | 2 +- faraday_plugins/plugins/repo/theharvester/plugin.py | 2 +- faraday_plugins/plugins/repo/traceroute/__init__.py | 2 +- faraday_plugins/plugins/repo/traceroute/plugin.py | 2 +- faraday_plugins/plugins/repo/w3af/__init__.py | 2 +- faraday_plugins/plugins/repo/w3af/plugin.py | 2 +- faraday_plugins/plugins/repo/wapiti/__init__.py | 2 +- faraday_plugins/plugins/repo/wapiti/plugin.py | 2 +- faraday_plugins/plugins/repo/wcscan/__init__.py | 2 +- faraday_plugins/plugins/repo/wcscan/plugin.py | 2 +- faraday_plugins/plugins/repo/webfuzzer/__init__.py | 2 +- faraday_plugins/plugins/repo/webfuzzer/plugin.py | 2 +- faraday_plugins/plugins/repo/wfuzz/__init__.py | 2 +- faraday_plugins/plugins/repo/wfuzz/plugin.py | 2 +- faraday_plugins/plugins/repo/whois/__init__.py | 2 +- faraday_plugins/plugins/repo/wpscan/__init__.py | 2 +- faraday_plugins/plugins/repo/x1/__init__.py | 2 +- faraday_plugins/plugins/repo/x1/plugin.py | 2 +- faraday_plugins/plugins/repo/xsssniper/__init__.py | 2 +- faraday_plugins/plugins/repo/xsssniper/plugin.py | 2 +- 109 files changed, 109 insertions(+), 109 deletions(-) diff --git a/faraday_plugins/plugins/repo/acunetix/__init__.py b/faraday_plugins/plugins/repo/acunetix/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/acunetix/__init__.py +++ b/faraday_plugins/plugins/repo/acunetix/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/amap/__init__.py b/faraday_plugins/plugins/repo/amap/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/amap/__init__.py +++ b/faraday_plugins/plugins/repo/amap/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/amap/plugin.py b/faraday_plugins/plugins/repo/amap/plugin.py index 0da8c98b..54714eaa 100644 --- a/faraday_plugins/plugins/repo/amap/plugin.py +++ b/faraday_plugins/plugins/repo/amap/plugin.py @@ -150,4 +150,4 @@ def processCommandString(self, username, current_path, command_string): def createPlugin(ignore_info=False): return AmapPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/appscan/__init__.py b/faraday_plugins/plugins/repo/appscan/__init__.py index 00dc0fca..d417d2e7 100644 --- a/faraday_plugins/plugins/repo/appscan/__init__.py +++ b/faraday_plugins/plugins/repo/appscan/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/arachni/__init__.py b/faraday_plugins/plugins/repo/arachni/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/arachni/__init__.py +++ b/faraday_plugins/plugins/repo/arachni/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/arachni/plugin.py b/faraday_plugins/plugins/repo/arachni/plugin.py index 2d9dfd38..4db7d7b8 100755 --- a/faraday_plugins/plugins/repo/arachni/plugin.py +++ b/faraday_plugins/plugins/repo/arachni/plugin.py @@ -494,4 +494,4 @@ def getHostname(self, url): def createPlugin(ignore_info=False): return ArachniPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/arp_scan/__init__.py b/faraday_plugins/plugins/repo/arp_scan/__init__.py index ea531e17..625a6e25 100755 --- a/faraday_plugins/plugins/repo/arp_scan/__init__.py +++ b/faraday_plugins/plugins/repo/arp_scan/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/beef/__init__.py b/faraday_plugins/plugins/repo/beef/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/beef/__init__.py +++ b/faraday_plugins/plugins/repo/beef/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/brutexss/__init__.py b/faraday_plugins/plugins/repo/brutexss/__init__.py index 454b1c0a..729fe446 100644 --- a/faraday_plugins/plugins/repo/brutexss/__init__.py +++ b/faraday_plugins/plugins/repo/brutexss/__init__.py @@ -3,4 +3,4 @@ Copyright (C) 2018 Infobyte LLC (http://www.infobytesec.com/) See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/brutexss/plugin.py b/faraday_plugins/plugins/repo/brutexss/plugin.py index 6b809cc0..6e3d9406 100644 --- a/faraday_plugins/plugins/repo/brutexss/plugin.py +++ b/faraday_plugins/plugins/repo/brutexss/plugin.py @@ -60,4 +60,4 @@ def parseOutputString(self, output): def createPlugin(ignore_info=False): return brutexss(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/burp/__init__.py b/faraday_plugins/plugins/repo/burp/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/burp/__init__.py +++ b/faraday_plugins/plugins/repo/burp/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/burp/plugin.py b/faraday_plugins/plugins/repo/burp/plugin.py index 4347a523..986048f2 100644 --- a/faraday_plugins/plugins/repo/burp/plugin.py +++ b/faraday_plugins/plugins/repo/burp/plugin.py @@ -292,4 +292,4 @@ def setHost(self): def createPlugin(ignore_info=False): return BurpPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/checkmarx/__init__.py b/faraday_plugins/plugins/repo/checkmarx/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/checkmarx/__init__.py +++ b/faraday_plugins/plugins/repo/checkmarx/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/cobalt/__init__.py b/faraday_plugins/plugins/repo/cobalt/__init__.py index 81e2e0d9..cef3c4e2 100644 --- a/faraday_plugins/plugins/repo/cobalt/__init__.py +++ b/faraday_plugins/plugins/repo/cobalt/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/dig/__init__.py b/faraday_plugins/plugins/repo/dig/__init__.py index f55478ec..4c2d40a8 100644 --- a/faraday_plugins/plugins/repo/dig/__init__.py +++ b/faraday_plugins/plugins/repo/dig/__init__.py @@ -3,4 +3,4 @@ Copyright (C) 2013 Infobyte LLC (http://www.infobytesec.com/) See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/dig/plugin.py b/faraday_plugins/plugins/repo/dig/plugin.py index 53d4d437..d0519353 100644 --- a/faraday_plugins/plugins/repo/dig/plugin.py +++ b/faraday_plugins/plugins/repo/dig/plugin.py @@ -144,4 +144,4 @@ def parseOutputString(self, output): def createPlugin(ignore_info=False): return DigPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/dirb/__init__.py b/faraday_plugins/plugins/repo/dirb/__init__.py index 0c98f519..fd94db9c 100644 --- a/faraday_plugins/plugins/repo/dirb/__init__.py +++ b/faraday_plugins/plugins/repo/dirb/__init__.py @@ -3,4 +3,4 @@ Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/) See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/dirb/plugin.py b/faraday_plugins/plugins/repo/dirb/plugin.py index c9207b5d..5de14209 100644 --- a/faraday_plugins/plugins/repo/dirb/plugin.py +++ b/faraday_plugins/plugins/repo/dirb/plugin.py @@ -119,4 +119,4 @@ def processCommandString(self, username, current_path, command_string): def createPlugin(ignore_info=False): return dirbPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/dirsearch/__init__.py b/faraday_plugins/plugins/repo/dirsearch/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/dirsearch/__init__.py +++ b/faraday_plugins/plugins/repo/dirsearch/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/dnsenum/__init__.py b/faraday_plugins/plugins/repo/dnsenum/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/dnsenum/__init__.py +++ b/faraday_plugins/plugins/repo/dnsenum/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/dnsenum/plugin.py b/faraday_plugins/plugins/repo/dnsenum/plugin.py index 1b2ee15a..bff14665 100644 --- a/faraday_plugins/plugins/repo/dnsenum/plugin.py +++ b/faraday_plugins/plugins/repo/dnsenum/plugin.py @@ -200,4 +200,4 @@ def setHost(self): def createPlugin(ignore_info=False): return DnsenumPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/dnsmap/__init__.py b/faraday_plugins/plugins/repo/dnsmap/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/dnsmap/__init__.py +++ b/faraday_plugins/plugins/repo/dnsmap/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/dnsmap/plugin.py b/faraday_plugins/plugins/repo/dnsmap/plugin.py index ddfdc052..6fe6352b 100644 --- a/faraday_plugins/plugins/repo/dnsmap/plugin.py +++ b/faraday_plugins/plugins/repo/dnsmap/plugin.py @@ -140,4 +140,4 @@ def processCommandString(self, username, current_path, command_string): def createPlugin(ignore_info=False): return DnsmapPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/dnsrecon/__init__.py b/faraday_plugins/plugins/repo/dnsrecon/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/dnsrecon/__init__.py +++ b/faraday_plugins/plugins/repo/dnsrecon/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/dnsrecon/plugin.py b/faraday_plugins/plugins/repo/dnsrecon/plugin.py index c89b732c..08a63463 100644 --- a/faraday_plugins/plugins/repo/dnsrecon/plugin.py +++ b/faraday_plugins/plugins/repo/dnsrecon/plugin.py @@ -246,4 +246,4 @@ def setHost(self): def createPlugin(ignore_info=False): return DnsreconPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/dnswalk/__init__.py b/faraday_plugins/plugins/repo/dnswalk/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/dnswalk/__init__.py +++ b/faraday_plugins/plugins/repo/dnswalk/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/dnswalk/plugin.py b/faraday_plugins/plugins/repo/dnswalk/plugin.py index 795f3d11..4851d7a4 100644 --- a/faraday_plugins/plugins/repo/dnswalk/plugin.py +++ b/faraday_plugins/plugins/repo/dnswalk/plugin.py @@ -116,4 +116,4 @@ def parseOutputString(self, output): def createPlugin(ignore_info=False): return DnswalkPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/faraday_csv/__init__.py b/faraday_plugins/plugins/repo/faraday_csv/__init__.py index f55478ec..4c2d40a8 100644 --- a/faraday_plugins/plugins/repo/faraday_csv/__init__.py +++ b/faraday_plugins/plugins/repo/faraday_csv/__init__.py @@ -3,4 +3,4 @@ Copyright (C) 2013 Infobyte LLC (http://www.infobytesec.com/) See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/fierce/__init__.py b/faraday_plugins/plugins/repo/fierce/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/fierce/__init__.py +++ b/faraday_plugins/plugins/repo/fierce/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/fierce/plugin.py b/faraday_plugins/plugins/repo/fierce/plugin.py index 71bbae2a..fa3476ce 100644 --- a/faraday_plugins/plugins/repo/fierce/plugin.py +++ b/faraday_plugins/plugins/repo/fierce/plugin.py @@ -179,4 +179,4 @@ def parseOutputString(self, output): def createPlugin(ignore_info=False): return FiercePlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/fruitywifi/__init__.py b/faraday_plugins/plugins/repo/fruitywifi/__init__.py index ea531e17..625a6e25 100755 --- a/faraday_plugins/plugins/repo/fruitywifi/__init__.py +++ b/faraday_plugins/plugins/repo/fruitywifi/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/fruitywifi/fruitywifi.py b/faraday_plugins/plugins/repo/fruitywifi/fruitywifi.py index 93a16dd4..3247d106 100755 --- a/faraday_plugins/plugins/repo/fruitywifi/fruitywifi.py +++ b/faraday_plugins/plugins/repo/fruitywifi/fruitywifi.py @@ -147,4 +147,4 @@ def submitGet(self, data): print(json.dumps("No clients connected")) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/fruitywifi/plugin.py b/faraday_plugins/plugins/repo/fruitywifi/plugin.py index bd174b71..001ac700 100644 --- a/faraday_plugins/plugins/repo/fruitywifi/plugin.py +++ b/faraday_plugins/plugins/repo/fruitywifi/plugin.py @@ -130,4 +130,4 @@ def processCommandString(self, username, current_path, command_string): def createPlugin(ignore_info=False): return FruityWiFiPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/ftp/__init__.py b/faraday_plugins/plugins/repo/ftp/__init__.py index ea531e17..625a6e25 100755 --- a/faraday_plugins/plugins/repo/ftp/__init__.py +++ b/faraday_plugins/plugins/repo/ftp/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/ftp/plugin.py b/faraday_plugins/plugins/repo/ftp/plugin.py index b09fdd71..978caaae 100644 --- a/faraday_plugins/plugins/repo/ftp/plugin.py +++ b/faraday_plugins/plugins/repo/ftp/plugin.py @@ -75,4 +75,4 @@ def processCommandString(self, username, current_path, command_string): def createPlugin(ignore_info=False): return CmdFtpPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/goohost/__init__.py b/faraday_plugins/plugins/repo/goohost/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/goohost/__init__.py +++ b/faraday_plugins/plugins/repo/goohost/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/hping3/__init__.py b/faraday_plugins/plugins/repo/hping3/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/hping3/__init__.py +++ b/faraday_plugins/plugins/repo/hping3/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/hping3/plugin.py b/faraday_plugins/plugins/repo/hping3/plugin.py index 25cb4ac8..03004fcd 100644 --- a/faraday_plugins/plugins/repo/hping3/plugin.py +++ b/faraday_plugins/plugins/repo/hping3/plugin.py @@ -71,4 +71,4 @@ def parseOutputString(self, output): def createPlugin(ignore_info=False): return hping3(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/hydra/__init__.py b/faraday_plugins/plugins/repo/hydra/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/hydra/__init__.py +++ b/faraday_plugins/plugins/repo/hydra/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/hydra/plugin.py b/faraday_plugins/plugins/repo/hydra/plugin.py index 89a4bd10..841077d5 100644 --- a/faraday_plugins/plugins/repo/hydra/plugin.py +++ b/faraday_plugins/plugins/repo/hydra/plugin.py @@ -134,4 +134,4 @@ def setHost(self): def createPlugin(ignore_info=False): return HydraPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/impact/__init__.py b/faraday_plugins/plugins/repo/impact/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/impact/__init__.py +++ b/faraday_plugins/plugins/repo/impact/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/ip360/__init__.py b/faraday_plugins/plugins/repo/ip360/__init__.py index 454b1c0a..729fe446 100644 --- a/faraday_plugins/plugins/repo/ip360/__init__.py +++ b/faraday_plugins/plugins/repo/ip360/__init__.py @@ -3,4 +3,4 @@ Copyright (C) 2018 Infobyte LLC (http://www.infobytesec.com/) See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/ip360/plugin.py b/faraday_plugins/plugins/repo/ip360/plugin.py index dc3339bc..c066759e 100644 --- a/faraday_plugins/plugins/repo/ip360/plugin.py +++ b/faraday_plugins/plugins/repo/ip360/plugin.py @@ -106,4 +106,4 @@ def parseOutputString(self, output): def createPlugin(ignore_info=False): return Ip360Plugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/junit/__init__.py b/faraday_plugins/plugins/repo/junit/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/junit/__init__.py +++ b/faraday_plugins/plugins/repo/junit/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/lynis/__init__.py b/faraday_plugins/plugins/repo/lynis/__init__.py index 00dc0fca..d417d2e7 100644 --- a/faraday_plugins/plugins/repo/lynis/__init__.py +++ b/faraday_plugins/plugins/repo/lynis/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/maltego/__init__.py b/faraday_plugins/plugins/repo/maltego/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/maltego/__init__.py +++ b/faraday_plugins/plugins/repo/maltego/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/medusa/__init__.py b/faraday_plugins/plugins/repo/medusa/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/medusa/__init__.py +++ b/faraday_plugins/plugins/repo/medusa/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/metasploit/__init__.py b/faraday_plugins/plugins/repo/metasploit/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/metasploit/__init__.py +++ b/faraday_plugins/plugins/repo/metasploit/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/metasploit/plugin.py b/faraday_plugins/plugins/repo/metasploit/plugin.py index 5cd755ab..8d6d0372 100644 --- a/faraday_plugins/plugins/repo/metasploit/plugin.py +++ b/faraday_plugins/plugins/repo/metasploit/plugin.py @@ -406,4 +406,4 @@ def setHost(self): def createPlugin(ignore_info=False): return MetasploitPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/ndiff/__init__.py b/faraday_plugins/plugins/repo/ndiff/__init__.py index 81e2e0d9..cef3c4e2 100644 --- a/faraday_plugins/plugins/repo/ndiff/__init__.py +++ b/faraday_plugins/plugins/repo/ndiff/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/ndiff/plugin.py b/faraday_plugins/plugins/repo/ndiff/plugin.py index 93472b09..6419dc34 100644 --- a/faraday_plugins/plugins/repo/ndiff/plugin.py +++ b/faraday_plugins/plugins/repo/ndiff/plugin.py @@ -159,4 +159,4 @@ def processCommandString(self, username, current_path, command_string): def createPlugin(ignore_info=False): return CmdNdiffPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/nessus/__init__.py b/faraday_plugins/plugins/repo/nessus/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/nessus/__init__.py +++ b/faraday_plugins/plugins/repo/nessus/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/netdiscover/__init__.py b/faraday_plugins/plugins/repo/netdiscover/__init__.py index 0c98f519..fd94db9c 100644 --- a/faraday_plugins/plugins/repo/netdiscover/__init__.py +++ b/faraday_plugins/plugins/repo/netdiscover/__init__.py @@ -3,4 +3,4 @@ Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/) See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/netdiscover/plugin.py b/faraday_plugins/plugins/repo/netdiscover/plugin.py index 5bd0c27d..e1072cb9 100644 --- a/faraday_plugins/plugins/repo/netdiscover/plugin.py +++ b/faraday_plugins/plugins/repo/netdiscover/plugin.py @@ -42,4 +42,4 @@ def parseOutputString(self, output): def createPlugin(ignore_info=False): return NetdiscoverPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/netsparker/__init__.py b/faraday_plugins/plugins/repo/netsparker/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/netsparker/__init__.py +++ b/faraday_plugins/plugins/repo/netsparker/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/netsparker/plugin.py b/faraday_plugins/plugins/repo/netsparker/plugin.py index 0635cb35..e4fb5947 100644 --- a/faraday_plugins/plugins/repo/netsparker/plugin.py +++ b/faraday_plugins/plugins/repo/netsparker/plugin.py @@ -232,4 +232,4 @@ def parseOutputString(self, output): def createPlugin(ignore_info=False): return NetsparkerPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/netsparkercloud/__init__.py b/faraday_plugins/plugins/repo/netsparkercloud/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/netsparkercloud/__init__.py +++ b/faraday_plugins/plugins/repo/netsparkercloud/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/nexpose_full/__init__.py b/faraday_plugins/plugins/repo/nexpose_full/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/nexpose_full/__init__.py +++ b/faraday_plugins/plugins/repo/nexpose_full/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/nexpose_full/plugin.py b/faraday_plugins/plugins/repo/nexpose_full/plugin.py index 4cea3ffc..3cfad5da 100644 --- a/faraday_plugins/plugins/repo/nexpose_full/plugin.py +++ b/faraday_plugins/plugins/repo/nexpose_full/plugin.py @@ -328,4 +328,4 @@ def setHost(self): def createPlugin(ignore_info=False): return NexposeFullPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/nikto/__init__.py b/faraday_plugins/plugins/repo/nikto/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/nikto/__init__.py +++ b/faraday_plugins/plugins/repo/nikto/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/nikto/plugin.py b/faraday_plugins/plugins/repo/nikto/plugin.py index 1d60115a..9a3d2949 100644 --- a/faraday_plugins/plugins/repo/nikto/plugin.py +++ b/faraday_plugins/plugins/repo/nikto/plugin.py @@ -367,4 +367,4 @@ def setHost(self): def createPlugin(ignore_info=False): return NiktoPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/nmap/__init__.py b/faraday_plugins/plugins/repo/nmap/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/nmap/__init__.py +++ b/faraday_plugins/plugins/repo/nmap/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/nmap/plugin.py b/faraday_plugins/plugins/repo/nmap/plugin.py index f9d8d1d4..4fc46bc9 100644 --- a/faraday_plugins/plugins/repo/nmap/plugin.py +++ b/faraday_plugins/plugins/repo/nmap/plugin.py @@ -553,4 +553,4 @@ def processCommandString(self, username, current_path, command_string): def createPlugin(ignore_info=False): return NmapPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/openvas/__init__.py b/faraday_plugins/plugins/repo/openvas/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/openvas/__init__.py +++ b/faraday_plugins/plugins/repo/openvas/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/openvas/plugin.py b/faraday_plugins/plugins/repo/openvas/plugin.py index 918faad9..fa66b163 100644 --- a/faraday_plugins/plugins/repo/openvas/plugin.py +++ b/faraday_plugins/plugins/repo/openvas/plugin.py @@ -450,4 +450,4 @@ def setHost(self): def createPlugin(ignore_info=False): return OpenvasPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/pasteanalyzer/__init__.py b/faraday_plugins/plugins/repo/pasteanalyzer/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/pasteanalyzer/__init__.py +++ b/faraday_plugins/plugins/repo/pasteanalyzer/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/pasteanalyzer/plugin.py b/faraday_plugins/plugins/repo/pasteanalyzer/plugin.py index 3c47c291..47aeed69 100644 --- a/faraday_plugins/plugins/repo/pasteanalyzer/plugin.py +++ b/faraday_plugins/plugins/repo/pasteanalyzer/plugin.py @@ -89,4 +89,4 @@ def processCommandString(self, username, current_path, command_string): def createPlugin(ignore_info=False): return pasteAnalyzerPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/peepingtom/__init__.py b/faraday_plugins/plugins/repo/peepingtom/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/peepingtom/__init__.py +++ b/faraday_plugins/plugins/repo/peepingtom/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/peepingtom/plugin.py b/faraday_plugins/plugins/repo/peepingtom/plugin.py index e1e02927..49bc59b8 100644 --- a/faraday_plugins/plugins/repo/peepingtom/plugin.py +++ b/faraday_plugins/plugins/repo/peepingtom/plugin.py @@ -74,4 +74,4 @@ def processCommandString(self, username, current_path, command_string): def createPlugin(ignore_info=False): return PeepingTomPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/ping/__init__.py b/faraday_plugins/plugins/repo/ping/__init__.py index ea531e17..625a6e25 100755 --- a/faraday_plugins/plugins/repo/ping/__init__.py +++ b/faraday_plugins/plugins/repo/ping/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/ping/plugin.py b/faraday_plugins/plugins/repo/ping/plugin.py index 365ed2bd..80ff3a83 100644 --- a/faraday_plugins/plugins/repo/ping/plugin.py +++ b/faraday_plugins/plugins/repo/ping/plugin.py @@ -53,4 +53,4 @@ def createPlugin(ignore_info=False): return CmdPingPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/propecia/__init__.py b/faraday_plugins/plugins/repo/propecia/__init__.py index ea531e17..625a6e25 100755 --- a/faraday_plugins/plugins/repo/propecia/__init__.py +++ b/faraday_plugins/plugins/repo/propecia/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/propecia/plugin.py b/faraday_plugins/plugins/repo/propecia/plugin.py index 75f7e687..453d0521 100644 --- a/faraday_plugins/plugins/repo/propecia/plugin.py +++ b/faraday_plugins/plugins/repo/propecia/plugin.py @@ -64,4 +64,4 @@ def processCommandString(self, username, current_path, command_string): def createPlugin(ignore_info=False): return CmdPropeciaPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/qualysguard/__init__.py b/faraday_plugins/plugins/repo/qualysguard/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/qualysguard/__init__.py +++ b/faraday_plugins/plugins/repo/qualysguard/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/reconng/__init__.py b/faraday_plugins/plugins/repo/reconng/__init__.py index 308ccd2c..8b137891 100644 --- a/faraday_plugins/plugins/repo/reconng/__init__.py +++ b/faraday_plugins/plugins/repo/reconng/__init__.py @@ -1 +1 @@ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/reconng/plugin.py b/faraday_plugins/plugins/repo/reconng/plugin.py index 4e74df9b..5d152227 100644 --- a/faraday_plugins/plugins/repo/reconng/plugin.py +++ b/faraday_plugins/plugins/repo/reconng/plugin.py @@ -174,4 +174,4 @@ def parseOutputString(self, output): def createPlugin(ignore_info=False): return ReconngPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/retina/__init__.py b/faraday_plugins/plugins/repo/retina/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/retina/__init__.py +++ b/faraday_plugins/plugins/repo/retina/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/retina/plugin.py b/faraday_plugins/plugins/repo/retina/plugin.py index e0e0a530..83aec976 100644 --- a/faraday_plugins/plugins/repo/retina/plugin.py +++ b/faraday_plugins/plugins/repo/retina/plugin.py @@ -230,4 +230,4 @@ def setHost(self): def createPlugin(ignore_info=False): return RetinaPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/reverseraider/__init__.py b/faraday_plugins/plugins/repo/reverseraider/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/reverseraider/__init__.py +++ b/faraday_plugins/plugins/repo/reverseraider/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/reverseraider/plugin.py b/faraday_plugins/plugins/repo/reverseraider/plugin.py index 206f31fa..d7b18e9c 100644 --- a/faraday_plugins/plugins/repo/reverseraider/plugin.py +++ b/faraday_plugins/plugins/repo/reverseraider/plugin.py @@ -81,4 +81,4 @@ def parseOutputString(self, output): def createPlugin(ignore_info=False): return ReverseraiderPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/skipfish/__init__.py b/faraday_plugins/plugins/repo/skipfish/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/skipfish/__init__.py +++ b/faraday_plugins/plugins/repo/skipfish/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/skipfish/plugin.py b/faraday_plugins/plugins/repo/skipfish/plugin.py index 8821bad2..871da865 100644 --- a/faraday_plugins/plugins/repo/skipfish/plugin.py +++ b/faraday_plugins/plugins/repo/skipfish/plugin.py @@ -221,4 +221,4 @@ def setHost(self): def createPlugin(ignore_info=False): return SkipfishPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/sourceclear/__init__.py b/faraday_plugins/plugins/repo/sourceclear/__init__.py index 7c43e3cb..fbeb92a8 100644 --- a/faraday_plugins/plugins/repo/sourceclear/__init__.py +++ b/faraday_plugins/plugins/repo/sourceclear/__init__.py @@ -5,4 +5,4 @@ """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/sshdefaultscan/__init__.py b/faraday_plugins/plugins/repo/sshdefaultscan/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/sshdefaultscan/__init__.py +++ b/faraday_plugins/plugins/repo/sshdefaultscan/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/sshdefaultscan/plugin.py b/faraday_plugins/plugins/repo/sshdefaultscan/plugin.py index a8a7ee91..3a3959f7 100644 --- a/faraday_plugins/plugins/repo/sshdefaultscan/plugin.py +++ b/faraday_plugins/plugins/repo/sshdefaultscan/plugin.py @@ -69,4 +69,4 @@ def processCommandString(self, username, current_path, command_string): def createPlugin(ignore_info=False): return SSHDefaultScanPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/sslyze/__init__.py b/faraday_plugins/plugins/repo/sslyze/__init__.py index 308ccd2c..8b137891 100644 --- a/faraday_plugins/plugins/repo/sslyze/__init__.py +++ b/faraday_plugins/plugins/repo/sslyze/__init__.py @@ -1 +1 @@ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/sslyzejson/__init__.py b/faraday_plugins/plugins/repo/sslyzejson/__init__.py index 308ccd2c..8b137891 100644 --- a/faraday_plugins/plugins/repo/sslyzejson/__init__.py +++ b/faraday_plugins/plugins/repo/sslyzejson/__init__.py @@ -1 +1 @@ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/telnet/__init__.py b/faraday_plugins/plugins/repo/telnet/__init__.py index ea531e17..625a6e25 100755 --- a/faraday_plugins/plugins/repo/telnet/__init__.py +++ b/faraday_plugins/plugins/repo/telnet/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/telnet/plugin.py b/faraday_plugins/plugins/repo/telnet/plugin.py index 3a0f542a..be79af23 100644 --- a/faraday_plugins/plugins/repo/telnet/plugin.py +++ b/faraday_plugins/plugins/repo/telnet/plugin.py @@ -80,4 +80,4 @@ def processCommandString(self, username, current_path, command_string): def createPlugin(ignore_info=False): return TelnetRouterPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/theharvester/__init__.py b/faraday_plugins/plugins/repo/theharvester/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/theharvester/__init__.py +++ b/faraday_plugins/plugins/repo/theharvester/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/theharvester/plugin.py b/faraday_plugins/plugins/repo/theharvester/plugin.py index 6d9254c2..300b545b 100644 --- a/faraday_plugins/plugins/repo/theharvester/plugin.py +++ b/faraday_plugins/plugins/repo/theharvester/plugin.py @@ -119,4 +119,4 @@ def createPlugin(ignore_info=False): return TheharvesterPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/traceroute/__init__.py b/faraday_plugins/plugins/repo/traceroute/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/traceroute/__init__.py +++ b/faraday_plugins/plugins/repo/traceroute/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/traceroute/plugin.py b/faraday_plugins/plugins/repo/traceroute/plugin.py index 3e02a085..e0551d1f 100644 --- a/faraday_plugins/plugins/repo/traceroute/plugin.py +++ b/faraday_plugins/plugins/repo/traceroute/plugin.py @@ -59,4 +59,4 @@ def processCommandString(self, username, current_path, command_string): def createPlugin(ignore_info=False): return traceroutePlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/w3af/__init__.py b/faraday_plugins/plugins/repo/w3af/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/w3af/__init__.py +++ b/faraday_plugins/plugins/repo/w3af/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/w3af/plugin.py b/faraday_plugins/plugins/repo/w3af/plugin.py index 6108fe6f..bd75216b 100644 --- a/faraday_plugins/plugins/repo/w3af/plugin.py +++ b/faraday_plugins/plugins/repo/w3af/plugin.py @@ -244,4 +244,4 @@ def parseOutputString(self, output): def createPlugin(ignore_info=False): return W3afPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/wapiti/__init__.py b/faraday_plugins/plugins/repo/wapiti/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/wapiti/__init__.py +++ b/faraday_plugins/plugins/repo/wapiti/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/wapiti/plugin.py b/faraday_plugins/plugins/repo/wapiti/plugin.py index 5d266d8b..b9602a3f 100644 --- a/faraday_plugins/plugins/repo/wapiti/plugin.py +++ b/faraday_plugins/plugins/repo/wapiti/plugin.py @@ -349,4 +349,4 @@ def setHost(self): def createPlugin(ignore_info=False): return WapitiPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/wcscan/__init__.py b/faraday_plugins/plugins/repo/wcscan/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/wcscan/__init__.py +++ b/faraday_plugins/plugins/repo/wcscan/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/wcscan/plugin.py b/faraday_plugins/plugins/repo/wcscan/plugin.py index bd759294..ef26f659 100644 --- a/faraday_plugins/plugins/repo/wcscan/plugin.py +++ b/faraday_plugins/plugins/repo/wcscan/plugin.py @@ -136,4 +136,4 @@ def processCommandString(self, username, current_path, command_string): def createPlugin(ignore_info=False): return WcscanPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/webfuzzer/__init__.py b/faraday_plugins/plugins/repo/webfuzzer/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/webfuzzer/__init__.py +++ b/faraday_plugins/plugins/repo/webfuzzer/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/webfuzzer/plugin.py b/faraday_plugins/plugins/repo/webfuzzer/plugin.py index 2131c87d..53d7a1a5 100644 --- a/faraday_plugins/plugins/repo/webfuzzer/plugin.py +++ b/faraday_plugins/plugins/repo/webfuzzer/plugin.py @@ -138,4 +138,4 @@ def processCommandString(self, username, current_path, command_string): def createPlugin(ignore_info=False): return WebfuzzerPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/wfuzz/__init__.py b/faraday_plugins/plugins/repo/wfuzz/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/wfuzz/__init__.py +++ b/faraday_plugins/plugins/repo/wfuzz/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/wfuzz/plugin.py b/faraday_plugins/plugins/repo/wfuzz/plugin.py index 5362ae59..ea16eebf 100644 --- a/faraday_plugins/plugins/repo/wfuzz/plugin.py +++ b/faraday_plugins/plugins/repo/wfuzz/plugin.py @@ -87,4 +87,4 @@ def parseOutputString(self, output): def createPlugin(ignore_info=False): return WfuzzPlugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/whois/__init__.py b/faraday_plugins/plugins/repo/whois/__init__.py index ea531e17..625a6e25 100755 --- a/faraday_plugins/plugins/repo/whois/__init__.py +++ b/faraday_plugins/plugins/repo/whois/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/wpscan/__init__.py b/faraday_plugins/plugins/repo/wpscan/__init__.py index 7c43e3cb..fbeb92a8 100644 --- a/faraday_plugins/plugins/repo/wpscan/__init__.py +++ b/faraday_plugins/plugins/repo/wpscan/__init__.py @@ -5,4 +5,4 @@ """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/x1/__init__.py b/faraday_plugins/plugins/repo/x1/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/x1/__init__.py +++ b/faraday_plugins/plugins/repo/x1/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/x1/plugin.py b/faraday_plugins/plugins/repo/x1/plugin.py index f57ea8fa..044e51b0 100644 --- a/faraday_plugins/plugins/repo/x1/plugin.py +++ b/faraday_plugins/plugins/repo/x1/plugin.py @@ -196,4 +196,4 @@ def setHost(self): def createPlugin(ignore_info=False): return X1Plugin(ignore_info=ignore_info) -# I'm Py3 + diff --git a/faraday_plugins/plugins/repo/xsssniper/__init__.py b/faraday_plugins/plugins/repo/xsssniper/__init__.py index ea531e17..625a6e25 100644 --- a/faraday_plugins/plugins/repo/xsssniper/__init__.py +++ b/faraday_plugins/plugins/repo/xsssniper/__init__.py @@ -4,4 +4,4 @@ See the file 'doc/LICENSE' for the license information """ -# I'm Py3 \ No newline at end of file + diff --git a/faraday_plugins/plugins/repo/xsssniper/plugin.py b/faraday_plugins/plugins/repo/xsssniper/plugin.py index 08f26a51..cf68cf36 100644 --- a/faraday_plugins/plugins/repo/xsssniper/plugin.py +++ b/faraday_plugins/plugins/repo/xsssniper/plugin.py @@ -58,4 +58,4 @@ def parseOutputString(self, output): def createPlugin(ignore_info=False): return xsssniper(ignore_info=ignore_info) -# I'm Py3 + From 9d2886365ffbbefd397733205f08efb6a843db38 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Mon, 15 Mar 2021 13:13:14 -0300 Subject: [PATCH 172/698] update ignore_info --- faraday_plugins/commands.py | 8 +++++--- faraday_plugins/plugins/plugin.py | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/faraday_plugins/commands.py b/faraday_plugins/commands.py index ab85245c..a498fa31 100644 --- a/faraday_plugins/commands.py +++ b/faraday_plugins/commands.py @@ -57,7 +57,7 @@ def process_report(report_file, plugin_id, custom_plugins_folder, summary, outpu 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) + plugins_manager = PluginsManager(custom_plugins_folder, ignore_info=ignore_info) analyzer = ReportAnalyzer(plugins_manager) if plugin_id: plugin = plugins_manager.get_plugin(plugin_id) @@ -88,8 +88,10 @@ def process_report(report_file, plugin_id, custom_plugins_folder, summary, outpu @click.option('--summary', is_flag=True) @click.option('-o', '--output-file', type=click.Path(exists=False)) @click.option('-sh', '--show-output', is_flag=True) -def process_command(command, plugin_id, custom_plugins_folder, dont_run, summary, output_file, show_output): - plugins_manager = PluginsManager(custom_plugins_folder) +@click.option('--ignore-info', is_flag=True, help="Ignore information vulnerabilities") +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) diff --git a/faraday_plugins/plugins/plugin.py b/faraday_plugins/plugins/plugin.py index 7e353ed3..c9670323 100644 --- a/faraday_plugins/plugins/plugin.py +++ b/faraday_plugins/plugins/plugin.py @@ -303,7 +303,7 @@ def _parse_filename(self, filename): def processReport(self, filepath, user="faraday"): if os.path.isfile(filepath): - self.vulns_data["command"]["params"] = filepath + self.vulns_data["command"]["params"] = filepath if not self.ignore_info else f"{filepath} (Info ignored)" self.vulns_data["command"]["user"] = user self.vulns_data["command"]["import_source"] = "report" self._parse_filename(filepath) From edd8522af6861a7e2236a2deefe3ae61986128fc Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 17 Mar 2021 14:53:35 -0300 Subject: [PATCH 173/698] ready for release 1.4.3 --- CHANGELOG/1.4.3/date.md | 1 + CHANGELOG/{current => 1.4.3}/new_ignore_info_option.md | 0 2 files changed, 1 insertion(+) create mode 100644 CHANGELOG/1.4.3/date.md rename CHANGELOG/{current => 1.4.3}/new_ignore_info_option.md (100%) diff --git a/CHANGELOG/1.4.3/date.md b/CHANGELOG/1.4.3/date.md new file mode 100644 index 00000000..8886c2b5 --- /dev/null +++ b/CHANGELOG/1.4.3/date.md @@ -0,0 +1 @@ +Mar 17th, 2021 diff --git a/CHANGELOG/current/new_ignore_info_option.md b/CHANGELOG/1.4.3/new_ignore_info_option.md similarity index 100% rename from CHANGELOG/current/new_ignore_info_option.md rename to CHANGELOG/1.4.3/new_ignore_info_option.md From a54290dab97bff7f7141c2f34812ee487b2ceb32 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 17 Mar 2021 14:53:47 -0300 Subject: [PATCH 174/698] ready for release 1.4.3 --- RELEASE.md | 4 ++++ faraday_plugins/__init__.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/RELEASE.md b/RELEASE.md index b75b6b3b..d815e44d 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,3 +1,7 @@ +1.4.3 [Mar 17th, 2021]: +--- + * Add Ignore information vulnerabilities option + 1.4.2 [Mar 10th, 2021]: --- * Fix bug with sslyze output file diff --git a/faraday_plugins/__init__.py b/faraday_plugins/__init__.py index 98d186be..4e7c72a5 100644 --- a/faraday_plugins/__init__.py +++ b/faraday_plugins/__init__.py @@ -1 +1 @@ -__version__ = '1.4.2' +__version__ = '1.4.3' From 5c029761d0e985bb12db45537605fa2a9dd70141 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Fri, 26 Mar 2021 11:26:05 -0300 Subject: [PATCH 175/698] csv plugin dont consider ignore_info --- CHANGELOG/current/csv_plugin_dont_user_ignore_info.md | 1 + faraday_plugins/plugins/repo/faraday_csv/plugin.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 CHANGELOG/current/csv_plugin_dont_user_ignore_info.md diff --git a/CHANGELOG/current/csv_plugin_dont_user_ignore_info.md b/CHANGELOG/current/csv_plugin_dont_user_ignore_info.md new file mode 100644 index 00000000..78c8492c --- /dev/null +++ b/CHANGELOG/current/csv_plugin_dont_user_ignore_info.md @@ -0,0 +1 @@ +Faraday CSV Plugin do not consider ignore_info diff --git a/faraday_plugins/plugins/repo/faraday_csv/plugin.py b/faraday_plugins/plugins/repo/faraday_csv/plugin.py index 2ea3eea4..faaa63b2 100644 --- a/faraday_plugins/plugins/repo/faraday_csv/plugin.py +++ b/faraday_plugins/plugins/repo/faraday_csv/plugin.py @@ -353,4 +353,4 @@ def parseOutputString(self, output): def createPlugin(ignore_info=False): - return FaradayCSVPlugin(ignore_info=ignore_info) + return FaradayCSVPlugin(ignore_info=False) From 05c6820aea72bbe48fbd1a499757dfda7205199e Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Mon, 29 Mar 2021 12:41:24 -0300 Subject: [PATCH 176/698] change burp fields --- CHANGELOG/current/change_burp_fields.md | 1 + faraday_plugins/plugins/repo/burp/plugin.py | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 CHANGELOG/current/change_burp_fields.md diff --git a/CHANGELOG/current/change_burp_fields.md b/CHANGELOG/current/change_burp_fields.md new file mode 100644 index 00000000..63529a11 --- /dev/null +++ b/CHANGELOG/current/change_burp_fields.md @@ -0,0 +1 @@ +Use background for description and detail for data en Burp plugin. diff --git a/faraday_plugins/plugins/repo/burp/plugin.py b/faraday_plugins/plugins/repo/burp/plugin.py index 986048f2..52927343 100644 --- a/faraday_plugins/plugins/repo/burp/plugin.py +++ b/faraday_plugins/plugins/repo/burp/plugin.py @@ -236,10 +236,16 @@ def parseOutputString(self, output): ports=[str(item.port)], status="open") - desc = "Detail\n" + item.detail if item.background: - desc += "\nBackground\n" + item.background + desc = item.background + else: + desc = "" desc = self.removeHtml(desc) + if item.detail: + data = item.detail + else: + data = "" + data = self.removeHtml(data) resolution = self.removeHtml(item.remediation) if item.remediation else "" v_id = self.createAndAddVulnWebToService( @@ -247,6 +253,7 @@ def parseOutputString(self, output): s_id, item.name, desc=desc, + data=data, severity=item.severity, website=item.host, path=item.path, From 541b46bb61a74b93fcc0263249a6706baaa2b4a4 Mon Sep 17 00:00:00 2001 From: Manuel Jose Sotomayor Torrealba Date: Mon, 29 Mar 2021 16:11:29 -0300 Subject: [PATCH 177/698] I just changed a validation to get The Method Correctly, with findtext --- faraday_plugins/plugins/repo/zap/plugin.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/faraday_plugins/plugins/repo/zap/plugin.py b/faraday_plugins/plugins/repo/zap/plugin.py index 56170720..616776bb 100644 --- a/faraday_plugins/plugins/repo/zap/plugin.py +++ b/faraday_plugins/plugins/repo/zap/plugin.py @@ -5,19 +5,21 @@ """ import re from urllib.parse import urlparse + from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import resolve_hostname try: import xml.etree.cElementTree as ET + ETREE_VERSION = ET.VERSION except ImportError: import xml.etree.ElementTree as ET + ETREE_VERSION = ET.VERSION ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] - __author__ = "Francisco Amato" __copyright__ = "Copyright (c) 2013, Infobyte LLC" __credits__ = ["Francisco Amato"] @@ -28,7 +30,6 @@ __status__ = "Development" - class ZapXmlParser: """ The objective of this class is to parse an xml @@ -72,7 +73,8 @@ def parse_xml(self, xml_output): return tree - def get_items(self, tree): + @staticmethod + def get_items(tree): """ @return items A list of Host instances """ @@ -144,7 +146,6 @@ def get_text_from_subnode(self, subnode_xpath_expr): return None - class Item: """ An abstract representation of a Item @@ -168,7 +169,7 @@ def __init__(self, item_node): if self.get_text_from_subnode('reference'): self.desc += '\nReference: ' + \ - self.get_text_from_subnode('reference') + self.get_text_from_subnode('reference') self.ref = [] if self.get_text_from_subnode('cweid'): @@ -183,11 +184,7 @@ def __init__(self, item_node): for elem in arr: uri = elem.find('uri').text - method_element = elem.find('method') - if method_element: - method = elem.find('method').text - else: - method = "" + method = elem.findtext('method', "") self.parse_uri(uri, method) def parse_uri(self, uri, method): @@ -244,7 +241,6 @@ def __init__(self, *arg, **kwargs): self.framework_version = "1.0.0" self.options = None - def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it @@ -282,7 +278,6 @@ def parseOutputString(self, output): del parser - def setHost(self): pass From 63cb8f75ed711624f29882d05656700d25feca92 Mon Sep 17 00:00:00 2001 From: Manuel Jose Sotomayor Torrealba Date: Mon, 29 Mar 2021 16:40:05 -0300 Subject: [PATCH 178/698] changing ref from CWE- to CWE: --- faraday_plugins/plugins/repo/zap/plugin.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/faraday_plugins/plugins/repo/zap/plugin.py b/faraday_plugins/plugins/repo/zap/plugin.py index 616776bb..f919400f 100644 --- a/faraday_plugins/plugins/repo/zap/plugin.py +++ b/faraday_plugins/plugins/repo/zap/plugin.py @@ -53,7 +53,8 @@ def __init__(self, xml_output): else: self.sites = [] - def parse_xml(self, xml_output): + @staticmethod + def parse_xml(xml_output): """ Open and parse an xml file. @@ -169,11 +170,11 @@ def __init__(self, item_node): if self.get_text_from_subnode('reference'): self.desc += '\nReference: ' + \ - self.get_text_from_subnode('reference') + self.get_text_from_subnode('reference') self.ref = [] if self.get_text_from_subnode('cweid'): - self.ref.append("CWE-" + self.get_text_from_subnode('cweid')) + self.ref.append("CWE:" + self.get_text_from_subnode('cweid')) self.items = [] From 1970839508a32e3dd1eadf86401f5d3d5a467995 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Tue, 30 Mar 2021 12:37:13 -0300 Subject: [PATCH 179/698] ready for release 1.4.4 --- .../{current => 1.4.4}/csv_plugin_dont_user_ignore_info.md | 0 CHANGELOG/1.4.4/date.md | 1 + RELEASE.md | 4 ++++ 3 files changed, 5 insertions(+) rename CHANGELOG/{current => 1.4.4}/csv_plugin_dont_user_ignore_info.md (100%) create mode 100644 CHANGELOG/1.4.4/date.md diff --git a/CHANGELOG/current/csv_plugin_dont_user_ignore_info.md b/CHANGELOG/1.4.4/csv_plugin_dont_user_ignore_info.md similarity index 100% rename from CHANGELOG/current/csv_plugin_dont_user_ignore_info.md rename to CHANGELOG/1.4.4/csv_plugin_dont_user_ignore_info.md diff --git a/CHANGELOG/1.4.4/date.md b/CHANGELOG/1.4.4/date.md new file mode 100644 index 00000000..2bf6cb08 --- /dev/null +++ b/CHANGELOG/1.4.4/date.md @@ -0,0 +1 @@ +Mar 30th, 2021 diff --git a/RELEASE.md b/RELEASE.md index d815e44d..92c37222 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,3 +1,7 @@ +1.4.4 [Mar 30th, 2021]: +--- + * Faraday CSV Plugin do not consider ignore_info option + 1.4.3 [Mar 17th, 2021]: --- * Add Ignore information vulnerabilities option From 5aa7c9414651857e673cebba8677730de4d5ebf6 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Tue, 30 Mar 2021 12:47:40 -0300 Subject: [PATCH 180/698] update version --- faraday_plugins/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faraday_plugins/__init__.py b/faraday_plugins/__init__.py index 4e7c72a5..9e0feee7 100644 --- a/faraday_plugins/__init__.py +++ b/faraday_plugins/__init__.py @@ -1 +1 @@ -__version__ = '1.4.3' +__version__ = '1.4.4' From 61ae2bf849a4f68fdc123ca95f5e2a27c09c217c Mon Sep 17 00:00:00 2001 From: Manuel Jose Sotomayor Torrealba Date: Tue, 30 Mar 2021 23:11:23 -0300 Subject: [PATCH 181/698] upload improvement more info in data, and changing the extraction of params --- faraday_plugins/plugins/repo/zap/plugin.py | 36 ++++++++++++++-------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/faraday_plugins/plugins/repo/zap/plugin.py b/faraday_plugins/plugins/repo/zap/plugin.py index f919400f..5d7c30c8 100644 --- a/faraday_plugins/plugins/repo/zap/plugin.py +++ b/faraday_plugins/plugins/repo/zap/plugin.py @@ -186,22 +186,26 @@ def __init__(self, item_node): for elem in arr: uri = elem.find('uri').text method = elem.findtext('method', "") - self.parse_uri(uri, method) + item = self.parse_uri(uri, method) - def parse_uri(self, uri, method): + param = elem.findtext("param", "") + attack = elem.findtext("attack", "") + if attack and param: + item["data"] = f"Payload:\n {param} = {attack}" + + item["pname"] = elem.findtext("param", "") + + self.items.append(item) + + def parse_uri(self, uri, method) -> dict: parsed_url = urlparse(uri) protocol = parsed_url.scheme host = parsed_url.netloc port = parsed_url.port + params = self.extract_params_from_uri(uri) - try: - params = [i.split('=')[0] - for i in uri.split('?')[1].split('&')] - except Exception as e: - params = '' - - item = { + return { 'uri': uri, 'params': ', '.join(params), 'host': host, @@ -210,9 +214,14 @@ def parse_uri(self, uri, method): 'port': port, 'method': method, 'path': parsed_url.path, - 'query': parsed_url.query + 'query': parsed_url.query, + 'data': "" } - self.items.append(item) + + @staticmethod + def extract_params_from_uri(uri): + params = re.findall("(\w+)=", uri) + return params if params else '' def get_text_from_subnode(self, subnode_xpath_expr): """ @@ -262,6 +271,7 @@ def parseOutputString(self, output): for item in site.items: for instance in item.items: + self.createAndAddVulnWebToService( h_id, s_id, @@ -274,7 +284,9 @@ def parseOutputString(self, output): params=instance['params'], method=instance['method'], ref=item.ref, - resolution=item.resolution + resolution=item.resolution, + data=instance["data"], + pname=instance["pname"] ) del parser From 7f9f347eab6d78c2ea06457aec0d6da7b4d79aac Mon Sep 17 00:00:00 2001 From: Manuel Jose Sotomayor Torrealba Date: Wed, 31 Mar 2021 10:20:28 -0300 Subject: [PATCH 182/698] adding change log --- ...rt_reports_of_owasp_and_zap_we_might_get_more_data.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 CHANGELOG/current/when_import_reports_of_owasp_and_zap_we_might_get_more_data.md diff --git a/CHANGELOG/current/when_import_reports_of_owasp_and_zap_we_might_get_more_data.md b/CHANGELOG/current/when_import_reports_of_owasp_and_zap_we_might_get_more_data.md new file mode 100644 index 00000000..027300db --- /dev/null +++ b/CHANGELOG/current/when_import_reports_of_owasp_and_zap_we_might_get_more_data.md @@ -0,0 +1,9 @@ +FIX a validation to get the info "method" from the .xml changing the function from find to findtext + +ADD the info of "attack" and "param" into data to show more info + +CHANGE the structure of the reference CWE from CWE-12 to CWE:12 + +REPAIR some pylint with static_method, removing the try and except + +CHANGE the function to extract params from url with a regex From 0de2fc6726b374c5b9cdf7b5e102dea321997546 Mon Sep 17 00:00:00 2001 From: Luca Truffarelli Date: Wed, 7 Apr 2021 11:47:45 +0200 Subject: [PATCH 183/698] Implementation of vulners script output --- faraday_plugins/plugins/plugins_utils.py | 19 +++++- faraday_plugins/plugins/repo/nmap/plugin.py | 66 ++++++++++++++++++--- 2 files changed, 76 insertions(+), 9 deletions(-) diff --git a/faraday_plugins/plugins/plugins_utils.py b/faraday_plugins/plugins/plugins_utils.py index 628ecd3a..81f21c41 100644 --- a/faraday_plugins/plugins/plugins_utils.py +++ b/faraday_plugins/plugins/plugins_utils.py @@ -109,4 +109,21 @@ def resolve_hostname(hostname): except Exception as e: return hostname else: - return ip_address \ No newline at end of file + return ip_address + +def get_severity_from_cvss(cvss): + try: + if type(cvss) != float: + cvss = float(cvss) + + cvss_ranges = [(0.0, 0.1, 'info'), + (0.1, 4.0, 'low'), + (4.0, 7.0, 'med'), + (7.0, 9.0, 'high'), + (9.0, 10.1, 'critical')] + for (lower, upper, severity) in cvss_ranges: + if lower <= cvss < upper: + return severity + except ValueError: + return 'unclassified' + diff --git a/faraday_plugins/plugins/repo/nmap/plugin.py b/faraday_plugins/plugins/repo/nmap/plugin.py index 4fc46bc9..f727851b 100644 --- a/faraday_plugins/plugins/repo/nmap/plugin.py +++ b/faraday_plugins/plugins/repo/nmap/plugin.py @@ -19,6 +19,7 @@ from lxml import etree from lxml.etree import XMLParser from faraday_plugins.plugins.plugin import PluginXMLFormat +from faraday_plugins.plugins.plugins_utils import get_severity_from_cvss ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] current_path = os.path.abspath(os.getcwd()) @@ -345,12 +346,56 @@ def get_scripts(self): Expects to find a scripts in the node. """ for s in self.node.findall('script'): - yield Script(s) + if s.get("id") == 'vulners': + for service_table in s.findall('table'): + for vulnerability_table in service_table.findall('table'): + yield ScriptVulners(s, service_table, vulnerability_table) + else: + yield Script(s) def __str__(self): return "%s, %s, Service: %s" % (self.number, self.state, self.service) +class ScriptVulners: + """ + An abstract representation of a script table when script is 'vulners'. + https://nmap.org/nsedoc/scripts/vulners.html + + '' + + @param script_node The reference to the node of the 'vulners' script + @param service_table The outer table taken from an nmap 'vulners' script xml tree + @param vulnerability_table The inner table taken from an nmap 'vulners' script xml tree + """ + + def __init__(self, script_node, service_table, vulnerability_table): + self.node = script_node + self.table = {} + for e in vulnerability_table.findall('elem'): + self.table[e.get("key")] = str(e.text) + + self.name = self.table["id"] + + self.desc = script_node.get("id") + "-" + self.table["id"] + if self.table["is_exploit"] == 'true': + self.desc += " *EXPLOIT*" + + self.refs = ["https://vulners.com/" + self.table["type"] + "/" + self.table["id"]] + self.response = "" + self.web = "" + self.severity = get_severity_from_cvss(self.table["cvss"]) + + def __str__(self): + return "%s, %s, %s" % (self.name, self.product, self.version) + + class Script: """ An abstract representation of a Script. @@ -502,16 +547,21 @@ def parseOutputString(self, output): description=srvname) for v in port.vulns: - severity = "info" + desc = v.desc refs = v.refs - if re.search(r"(? Date: Sat, 10 Apr 2021 09:40:28 +0200 Subject: [PATCH 184/698] Added CVSS to refs --- faraday_plugins/plugins/repo/nmap/plugin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/faraday_plugins/plugins/repo/nmap/plugin.py b/faraday_plugins/plugins/repo/nmap/plugin.py index f727851b..61e4e33f 100644 --- a/faraday_plugins/plugins/repo/nmap/plugin.py +++ b/faraday_plugins/plugins/repo/nmap/plugin.py @@ -388,6 +388,7 @@ def __init__(self, script_node, service_table, vulnerability_table): self.desc += " *EXPLOIT*" self.refs = ["https://vulners.com/" + self.table["type"] + "/" + self.table["id"]] + self.refs.append("CVSS: " + self.table["cvss"]) self.response = "" self.web = "" self.severity = get_severity_from_cvss(self.table["cvss"]) From 97e7f6e51b75964533bb802e6ca0aaa46d3cca90 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Mon, 12 Apr 2021 10:34:10 -0300 Subject: [PATCH 185/698] add bandit plugin --- CHANGELOG/current/add_bandit_plugin.md | 1 + .../plugins/repo/bandit/__init__.py | 0 faraday_plugins/plugins/repo/bandit/plugin.py | 72 +++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 CHANGELOG/current/add_bandit_plugin.md create mode 100644 faraday_plugins/plugins/repo/bandit/__init__.py create mode 100644 faraday_plugins/plugins/repo/bandit/plugin.py diff --git a/CHANGELOG/current/add_bandit_plugin.md b/CHANGELOG/current/add_bandit_plugin.md new file mode 100644 index 00000000..32347321 --- /dev/null +++ b/CHANGELOG/current/add_bandit_plugin.md @@ -0,0 +1 @@ +Add Bandit plugin diff --git a/faraday_plugins/plugins/repo/bandit/__init__.py b/faraday_plugins/plugins/repo/bandit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/faraday_plugins/plugins/repo/bandit/plugin.py b/faraday_plugins/plugins/repo/bandit/plugin.py new file mode 100644 index 00000000..98f53edb --- /dev/null +++ b/faraday_plugins/plugins/repo/bandit/plugin.py @@ -0,0 +1,72 @@ +from faraday_plugins.plugins.plugin import PluginXMLFormat +import xml.etree.ElementTree as ET +import re + +class BanditPlugin(PluginXMLFormat): + """ + Example plugin to parse bandit output. + """ + + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) + self.identifier_tag = 'testsuite' + self.extension = ".xml" + self.id = "Bandit" + self.name = "Bandit XML Output Plugin" + self.plugin_version = "0.0.1" + + def report_belongs_to(self, **kwargs): + if super().report_belongs_to(**kwargs): + report_path = kwargs.get("report_path", "") + with open(report_path) as f: + output = f.read() + return re.search("testsuite name=\"bandit\"", output) is not None + return False + + def parseOutputString(self, output): + bp = BanditParser(output) + + for vuln in bp.vulns: + host_id = self.createAndAddHost(vuln['path']) + + self.createAndAddVulnToHost( + host_id=host_id, + name=vuln['name'], + desc=vuln['issue_text'], + ref=vuln['references'], + severity=vuln['severity'], + ) + + return True + + +class BanditParser: + """ + Parser for bandit on demand + """ + + def __init__(self, xml_output): + self.vulns = self._parse_xml(xml_output) + + + def _parse_xml(self, xml_output): + vulns = [] + tree = ET.fromstring(xml_output) + testcases = tree.findall('testcase') + + for testcase in testcases: + error = testcase.find('error') + name = testcase.attrib['name'] + path = testcase.attrib['classname'] + severity = error.attrib['type'] + issue_text = error.text + more_info = error.attrib['more_info'] + ref = [more_info] + + vulns.append({'name': name, 'path': path, 'references': ref, 'issue_text': issue_text, 'severity': severity}) + + return vulns + + +def createPlugin(ignore_info=False): + return BanditPlugin(ignore_info=ignore_info) From 183149315808a54fe9031f10fcb3dd14f3645a90 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Mon, 12 Apr 2021 11:27:44 -0300 Subject: [PATCH 186/698] add nmap vulners data --- CHANGELOG/current/parse_nmap_vulnes.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 CHANGELOG/current/parse_nmap_vulnes.md diff --git a/CHANGELOG/current/parse_nmap_vulnes.md b/CHANGELOG/current/parse_nmap_vulnes.md new file mode 100644 index 00000000..6e79a68c --- /dev/null +++ b/CHANGELOG/current/parse_nmap_vulnes.md @@ -0,0 +1 @@ +Parse Nmap vulners script data From 5d865ee9b13599a0255f47980c3ff76c840d8d66 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Thu, 15 Apr 2021 15:08:50 -0300 Subject: [PATCH 187/698] rewrite appscan plugin --- CHANGELOG/current/fix_appscan.md | 1 + faraday_plugins/plugins/plugin.py | 3 +- .../plugins/repo/appscan/plugin.py | 559 +++++++----------- 3 files changed, 228 insertions(+), 335 deletions(-) create mode 100644 CHANGELOG/current/fix_appscan.md diff --git a/CHANGELOG/current/fix_appscan.md b/CHANGELOG/current/fix_appscan.md new file mode 100644 index 00000000..754678a8 --- /dev/null +++ b/CHANGELOG/current/fix_appscan.md @@ -0,0 +1 @@ +Rewrite Appscan Plugin diff --git a/faraday_plugins/plugins/plugin.py b/faraday_plugins/plugins/plugin.py index c9670323..90cd541f 100644 --- a/faraday_plugins/plugins/plugin.py +++ b/faraday_plugins/plugins/plugin.py @@ -383,7 +383,8 @@ def createAndAddVulnToHost(self, host_id, name, desc="", ref=None, tags = [tags] vulnerability = {"name": name, "desc": desc, "severity": self.normalize_severity(severity), "refs": ref, "external_id": external_id, "type": "Vulnerability", "resolution": resolution, "data": data, - "custom_fields": custom_fields, "status": status, "impact": impact, "policyviolations": policyviolations, + "custom_fields": custom_fields, "status": status, "impact": impact, + "policyviolations": policyviolations, "confirmed": confirmed, "easeofresolution": easeofresolution, "tags": tags } if run_date: diff --git a/faraday_plugins/plugins/repo/appscan/plugin.py b/faraday_plugins/plugins/repo/appscan/plugin.py index f55794f2..6edc7d0e 100644 --- a/faraday_plugins/plugins/repo/appscan/plugin.py +++ b/faraday_plugins/plugins/repo/appscan/plugin.py @@ -1,43 +1,39 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import resolve_hostname +import dateutil.parser +from urllib.parse import urlparse try: import xml.etree.cElementTree as ET except ImportError: import xml.etree.ElementTree as ET -__author__ = "Alejando Parodi, Ezequiel Tavella, Blas Moyano" -__copyright__ = "Copyright (c) 2015, Infobyte LLC" -__credits__ = ["Alejando Parodi", "Ezequiel Tavella"] +__author__ = "Nicolas Rebagliati" +__copyright__ = "Copyright (c) 2021, Infobyte LLC" +__credits__ = ["Nicolas Rebagliati"] __license__ = "" __version__ = "1.0" -__maintainer__ = "Ezequiel Tavella" +__maintainer__ = "Nicolas Rebagliati" __status__ = "Development" class AppScanParser: + def __init__(self, xml_output): - self.tree = self.parse_xml(xml_output) - if self.tree: - self.operating_system = self.tree.attrib['technology'] - url_group = [tags.tag for tags in self.tree] - check_url = True if 'url-group' in url_group else False - if check_url: - self.urls = self.get_urls_info(self.tree.find('url-group')) - else: - self.urls = None - self.layout = self.get_layout_info(self.tree.find('layout')) - self.item = self.get_issue_type(self.tree.find('issue-type-group')) - self.name_scan = self.get_issue_data(self.tree.find('advisory-group')) - self.host_data = None if self.tree.find('scan-configuration/scanned-hosts/item') is None else \ - self.get_scan_conf_data(self.tree.find('scan-configuration/scanned-hosts/item')) - self.issue_group = self.get_info_issue_group(self.tree.find("issue-group")) - self.fix_recomendation = self.get_fix_info(self.tree.find('fix-recommendation-group')) + tree = self.parse_xml(xml_output) + if tree: + self.scan_type = tree.attrib['technology'] + self.issue_types = self.get_issue_types(tree.find('issue-type-group')) + if self.scan_type == "SAST": + self.fixes = self.get_fixes(tree.find("fix-group-group")) + self.issues = self.get_sast_issues(tree.find("issue-group")) + elif self.scan_type == "DAST": + self.hosts = self.get_hosts(tree.find('scan-configuration/scanned-hosts')) + self.remediations = self.get_remediations(tree.find('remediation-group')) + self.entities = self.get_entity_groups(tree.find('entity-group')) + self.issues = self.get_dast_issues(tree.find("issue-group")) + - else: - self.tree = None def parse_xml(self, xml_output): try: @@ -47,218 +43,200 @@ def parse_xml(self, xml_output): return None return tree - def get_fix_info(self, tree): - list_fix = [] + def get_fixes(self, tree): + fixes = {} for item in tree: - text_info_join = [] - if item.find("general/fixRecommendation"): - for text_tag in tree.findall('text'): - text_info_join += text_tag.text - info_fix = { - "id": item.attrib.get('id', None), - "text": text_info_join - } - list_fix.append(info_fix) - return list_fix - - def get_info_issue_group(sef,tree): - data_res_req = [] + fix_id = item.attrib['id'] + library = item.find("LibraryName").text + location = item.find("Location").text + fixes[fix_id] = {"library": library, "location": location} + return fixes + + def get_issue_types(self, tree): + issue_types = {} for item in tree: - if item.find("variant-group/item/issue-information"): - resp = item.find("variant-group/item/issue-information").text - else: - resp = "Not Response" - - json_res_req = { - "request": "Not request" if item.find("variant-group/item/test-http-traffic") is None else - item.find("variant-group/item/test-http-traffic").text, - "response": resp, - "location": "Not Location" if item.find("location") is None else item.find("location").text, - "source_file": "0.0.0.0" if item.find("source-file") is None else item.find("source-file").text, - "line": 0 if item.find("line") is None else item.find("line").text, - "id_item": item.attrib.get('id', 'Not id item'), - "severity": 0 if item.find("severity-id") is None else item.find("severity-id").text, - "cvss": "No cvss" if item.find("cvss-score") is None else item.find("cvss-score").text, - "cwe": "No cwe" if item.find("cwe") is None else item.find("cwe").text, - "remediation": "No remedation" if item.find("remediation/ref") is None else item.find( - "remediation/ref").text, - "advisory": "No advisory" if item.find("advisory/ref") is None else item.find("advisory/ref").text, - "url_id": "No url id" if item.find("url/ref") is None else item.find("url/ref").text, - "id_adv": "Not info" if item.find("issue-type/ref") is None else item.find("issue-type/ref").text - } - - data_res_req.append(json_res_req) - return data_res_req + type_id = item.attrib['id'] + name = item.find("name").text + issue_types[type_id] = name + return issue_types - def get_layout_info(self, tree): - info_layout = { - "name": "Not info" if tree.find("application-name") is None else tree.find("application-name").text, - "date": "Not info" if tree.find("report-date") is None else tree.find("report-date").text, - "details": f'Departamento: {"Not info" if tree.find("department") is None else tree.find("department").text}' - f'Compania: {"Not info" if tree.find("company") is None else tree.find("company").text}' - f'Titulo Reporte: {"Not info" if tree.find("title") is None else tree.find("title").text}', - "nro_issues": None if tree.find("total-issues-in-application") is None else tree.find("total-issues-in-application").text, - } - return info_layout - - def get_issue_type(self, tree): - list_item = [] + def get_remediations(self, tree): + remediations = {} for item in tree: - severity = item.attrib.get('severity-id', None) - if severity is None: - severity = item.attrib.get('maxIssueSeverity', None) - - item_info = { - "id": item.attrib.get('id', None), - "name": item.find("name").text, - "severity_id": severity, - "severity": item.attrib.get('severity', None), - "cwe": "Not info" if item.find("cme") is None else item.find("cwe").text, - "xfid": "Not info" if item.find("xfid") is None else item.find("xfid").text, - "advisory": "Not info" if item.find("advisory/ref") is None else item.find("advisory/ref").text - } - list_item.append(item_info) - - return list_item + remediation_id = item.attrib['id'] + name = item.find("name").text + remediations[remediation_id] = name + return remediations - def get_issue_data(self, tree): - list_item_data = [] - item_data = {} + def get_hosts(self, tree): + hosts = {} for item in tree: - for adivisory in item: - if adivisory.find("cwe/link"): - cwe = adivisory.find("cwe/link").text - else: - cwe = "Not Response" - - if adivisory.find("xfid/link"): - xfid = adivisory.find("xfid/link").text - else: - xfid = "Not Response" - - item_data = { - "id": item.attrib.get('id', None), - "name": "Not info" if adivisory.find("name") is None else adivisory.find("name").text, - "description": "Not info" if adivisory.find("testDescription") is None else - adivisory.find("testDescription").text, - "threatClassification": { - "name": "Not info" if adivisory.find("threatClassification/name") is None else - adivisory.find("threatClassification/name").text, - "reference": "Not info" if adivisory.find("threatClassification/reference") is None else - adivisory.find("threatClassification/reference").text, - }, - "testTechnicalDescription": "Not info" if adivisory.find("testTechnicalDescription") is None else - self.get_parser(adivisory.find("testTechnicalDescription")), - "testTechnicalDescriptionMixed": "Not info" if adivisory.find("testTechnicalDescriptionMixed") is None else - self.get_parser(adivisory.find("testTechnicalDescriptionMixed")), - - "testDescriptionMixed": "Not info" if adivisory.find("testDescriptionMixed") is None else - self.get_parser(adivisory.find("testDescriptionMixed")), - "causes": "Not info" if adivisory.find("causes/cause") is None else - adivisory.find("causes/cause").text, - "securityRisks": "Not info" if adivisory.find("securityRisks/securityRisk") is None else - adivisory.find("securityRisks/securityRisk").text, - "affectedProducts": "Not info" if adivisory.find("affectedProducts/affectedProduct") is None else - adivisory.find("affectedProducts/affectedProduct").text, - "cwe": cwe, - "xfid": xfid, - "references": "Not info" if adivisory.find("references") is None else - self.get_parser(adivisory.find("references")), - "fixRecommendations": "Not info" if adivisory.find("fixRecommendations/fixRecommendation") is None else - self.get_parser(adivisory.find("fixRecommendations/fixRecommendation")) - } - list_item_data.append(item_data) - return list_item_data - - def get_parser(self, tree): - text_join = "" - code_join = "" - link_join = "" - - if tree.tag == 'testTechnicalDescription': - - for text_info in tree.findall('text'): - text_join += text_info.text - - for code_info in tree.findall('code'): - text_join += code_info.text - - tech_data = { - "text": text_join, - "code": code_join - } - - elif tree.tag == 'testDescriptionMixed': - - for text_info in tree.findall('p'): - text_join += text_info.text - - for code_info in tree.findall('li'): - text_join += code_info.text - - tech_data = { - "text": text_join, - "items": code_join - } - - elif tree.tag == 'testTechnicalDescriptionMixed': - - for text_info in tree.findall('p'): - text_join += text_info.text - - tech_data = { - "text": text_join, - } - - elif tree.tag == 'references': - for text_info in tree.findall('text'): - text_join += "no info " if text_info.text is None else text_info.text - - for link_info in tree.findall('link'): - link_join += "no info " if link_info.text is None else link_info.text - link_join += link_info.attrib.get('target', 'not target') - - tech_data = { - "text": text_join, - "Link": link_join - } - - elif tree.tag == 'fixRecommendation': - for text_info in tree.findall('text'): - text_join += "no info " if text_info.text is None else text_info.text - - for link_info in tree.findall('link'): - link_join += "no info " if link_info.text is None else link_info.text - link_join += link_info.attrib.get('target', 'not target') - - tech_data = { - "text": text_join, - "link": link_join + host = item.find("host").text + port = item.find("port").text + operating_system = item.find("operating-system").text + if "unknown" in operating_system.lower(): + operating_system = "unknown" + web_server = item.find("web-server").text + application_server = item.find("application-server").text + service_name = f"{web_server} ({application_server})" + host_key = f"{host}-{port}" + hosts[host_key] = {"host": host, "port": port, "os": operating_system, + "service_name": service_name} + return hosts + + def get_entity_groups(self, tree): + entity_groups = {} + for item in tree: + entity_id = item.attrib['id'] + name = item.find("name").text + url = item.find("url-name").text + type = item.find("entity-type").text + url_data = urlparse(url) + website = f"{url_data.scheme}://{url_data.netloc}" + host = url_data.netloc.split(":")[0] + if url_data.port: + port = url_data.port + else: + if url_data.scheme == "http": + port = 80 + elif url_data.scheme == "https": + port = 443 + path = url_data.path + entity_groups[entity_id] = {"name": name, "host": host, "port": port, "url": url, + "type": type, "website": website, "path": path} + return entity_groups + + def get_dast_issues(self, tree): + dast_issues = [] + for item in tree: + entity = self.entities[item.find("entity/ref").text] + host = entity["host"] + port = entity["port"] + name = self.issue_types[item.find("issue-type/ref").text] + severity = 0 if item.find("severity-id") is None else int(item.find("severity-id").text) + resolution = self.remediations[item.find("remediation/ref").text] + description = "" if item.find("variant-group/item/reasoning") is None \ + else item.find("variant-group/item/reasoning").text + request = "" if item.find("variant-group/item/test-http-traffic") is None \ + else item.find("variant-group/item/test-http-traffic").text + response = "" if item.find("variant-group/item/issue-information/testResponseChunk") is None \ + else item.find("variant-group/item/issue-information/testResponseChunk").text + cvss = None if item.find("cvss-score") is None else f"CVSS: {item.find('cvss-score').text}" + cvss_base_vector = None if item.find('cvss-vector/base-vector') is None \ + else f"CVSS-base-vector: {item.find('cvss-vector/base-vector').text}" + cvss_temporal_vector = None if item.find('cvss-vector/temporal-vector') is None \ + else f"CVSS-temporal-vector: {item.find('cvss-vector/temporal-vector').text}" + cvss_environmental_vector = None if item.find('cvss-vector/environmental-vector') is None \ + else f"CVSS-environmental-vector: {item.find('cvss-vector/environmental-vector').text}" + cwe = None if item.find("cwe") is None else item.find('cwe').text + if item.attrib.get("cve"): + cve = None if item.find("variant-group/item/issue-information/display-name") is None \ + else item.find('variant-group/item/issue-information/display-name').text + if "CVE" not in cve: + cve = f"CVE-{cve}" + cve_url = item.attrib["cve"] + else: + cve = None + cve_url = None + host_key = f"{host}-{port}" + issue_data = { + "host": host, + "port": port, + "os": self.hosts[host_key]["os"], + "service_name": self.hosts[host_key]["service_name"], + "name": name, + "severity": severity, + "desc": description, + "ref": [], + "resolution": resolution, + "request": request, + "response": response, + "website": entity['website'], + "path": entity['path'], + "external_id": cve } - - return tech_data - - def get_urls_info(self, tree): - list_url = [] - for url in tree: - url_info = { - "id_item": url.attrib.get('id', 'Not id item'), - "id": "Not info" if url.find("issue-type") is None else url.find("issue-type").text, - "url": "Not info" if url.find("name") is None else url.find("name").text, + if cve: + issue_data["ref"].append(cve) + if cve_url: + issue_data["ref"].append(cve_url) + if cwe: + issue_data["ref"].append(f"CWE: {cwe}") + if cvss: + issue_data["ref"].append(cvss) + if cvss_base_vector: + issue_data["ref"].append(cvss_base_vector) + if cvss_temporal_vector: + issue_data["ref"].append(cvss_temporal_vector) + if cvss_environmental_vector: + issue_data["ref"].append(cvss_environmental_vector) + dast_issues.append(issue_data) + return dast_issues + + def get_sast_issues(self, tree): + sast_issues = [] + for item in tree: + name = self.issue_types[item.find("issue-type/ref").text] + source_file = item.attrib["filename"] + severity = 0 if item.find("severity-id") is None else int(item.find("severity-id").text) + description = item.find("fix/item/general/text").text + resolution = "" if item.find("variant-group/item/issue-information/fix-resolution-text") is None \ + else item.find("variant-group/item/issue-information/fix-resolution-text").text + fix_id = item.attrib.get("fix-group-id") + if fix_id: + fix = self.fixes[fix_id] + resolution = f"{resolution}\nLibrary: {fix['library']}\nLocation: {fix['location']}" + cvss = None if item.find("cvss-score") is None else f"CVSS: {item.find('cvss-score').text}" + cvss_base_vector = None if item.find('cvss-vector/base-vector') is None \ + else f"CVSS-base-vector: {item.find('cvss-vector/base-vector').text}" + cvss_temporal_vector = None if item.find('cvss-vector/temporal-vector') is None \ + else f"CVSS-temporal-vector: {item.find('cvss-vector/temporal-vector').text}" + cvss_environmental_vector = None if item.find('cvss-vector/environmental-vector') is None \ + else f"CVSS-environmental-vector: {item.find('cvss-vector/environmental-vector').text}" + cwe = None if item.find("cwe/ref") is None else item.find('cwe/ref').text + if item.attrib.get("cve"): + cve = None if item.find("variant-group/item/issue-information/display-name") is None \ + else item.find('variant-group/item/issue-information/display-name').text + if "CVE" not in cve: + cve = f"CVE-{cve}" + cve_url = item.attrib["cve"] + else: + cve = None + cve_url = None + issue_data = { + "source_file": source_file, + "name": name, + "severity": severity, + "desc": description, + "ref": [], + "resolution": resolution, + "external_id": cve } - list_url.append(url_info) - - return list_url + if cve: + issue_data["ref"].append(cve) + if cve_url: + issue_data["ref"].append(cve_url) + if cwe: + issue_data["ref"].append(f"CWE: {cwe}") + if cvss: + issue_data["ref"].append(cvss) + if cvss_base_vector: + issue_data["ref"].append(cvss_base_vector) + if cvss_temporal_vector: + issue_data["ref"].append(cvss_temporal_vector) + if cvss_environmental_vector: + issue_data["ref"].append(cvss_environmental_vector) + # Build data + data = [] + if item.attrib.get("caller"): + data.append(f"Caller: {item.attrib.get('caller')}") + if item.find("variant-group/item/issue-information/method-signature") is not None: + data.append(f"Method: {item.find('variant-group/item/issue-information/method-signature').text}") + if item.find("variant-group/item/issue-information/method-signature2") is not None: + data.append(f"Location: {item.find('variant-group/item/issue-information/method-signature2').text}") + issue_data['data'] = "\n".join(data) + sast_issues.append(issue_data) + return sast_issues - def get_scan_conf_data(self, host_info): - info_host = { - "host": "Not info" if host_info.find("host") is None else host_info.find("host").text, - "port": "Not info" if host_info.find("port") is None else host_info.find("port").text, - "os": "Not info" if host_info.find("operating-system") is None else host_info.find("operating-system").text, - "webserver": "Not info" if host_info.find("web-server") is None else host_info.find("web-server").text, - "appserver": "Not info" if host_info.find("application-server") is None else host_info.find("application-server").text, - } - return info_host class AppScanPlugin(PluginXMLFormat): @@ -271,116 +249,29 @@ def __init__(self, *arg, **kwargs): self.plugin_version = '0.0.1' self.version = '1.0.0' self.framework_version = '1.0.0' - self.options = None - self.protocol = None - self.port = '80' - self.address = None + def parseOutputString(self, output): parser = AppScanParser(output) - layout = parser.layout - operating_system = parser.operating_system - host_data = parser.host_data - urls = parser.urls - item = parser.item - name_scan = parser.name_scan - issues = parser.issue_group - recomendation = parser.fix_recomendation - - if operating_system == 'DAST': - host_id = self.createAndAddHost(resolve_hostname(host_data['host']), os=host_data['os'], - hostnames=[host_data['host']], description=layout['details']) - - service_id = self.createAndAddServiceToHost(host_id, host_data['host'], ports=host_data['port'], - protocol="tcp?HTTP", - description=f'{host_data["webserver"]} - {host_data["appserver"]}') - if layout['nro_issues'] is None: - nro_check = True - - else: - nro_check = False - check_issues = [] - - for issue in issues: - id = f"{issue['url_id']}{issue['advisory']}" - if id in check_issues and nro_check is True: - check_issues.append(id) - else: - check_issues.append(id) - for info in name_scan: - if info['id'] == issue['advisory']: - vuln_name = info['name'] - vuln_desc = info['description'] - resolution = "" - if 'text' in info['fixRecommendations']: - resolution += info['fixRecommendations']['text'] - if 'link' in info['fixRecommendations']: - resolution += info['fixRecommendations']['link'] - - vuln_data = f'xfix: {info["xfid"]} cme: {info["cwe"]}' - - for url in urls: - if url['id'] == issue['advisory']: - url_name = url['url'] - elif url['id_item'] == issue['id_item']: - url_name = url['url'] - else: - url_name = None - - for rec in recomendation: - if rec['id'] == issue['advisory']: - vuln_data = f'{vuln_data}, {rec["text"]} ' - - ref = f'cwe: {issue["cwe"]} cvss: {issue["cvss"]} remediation: {issue["remediation"]}' - self.createAndAddVulnWebToService(host_id=host_id, service_id=service_id, name=vuln_name, - desc=vuln_desc, severity=issue['severity'], ref=[ref], - website=host_data['host'], request=issue['request'], - response=issue['response'], method=issue['request'], - resolution=resolution, data=vuln_data, path=url_name) - - elif operating_system == 'SAST': - for info_loc_source in issues: - source_file = info_loc_source['source_file'] - host_id = self.createAndAddHost(source_file, os=operating_system) - ref = f'{info_loc_source["location"]} - {info_loc_source["line"]}' - for vuln_data in name_scan: - if vuln_data['id'] == info_loc_source["id_adv"]: - desc = f'desc: {vuln_data["description"]} DescMix {vuln_data["testDescriptionMixed"]}' - - resolution = f'Fix Recomendarion {vuln_data["fixRecommendations"]}' \ - f' - TestTecnical {vuln_data["testTechnicalDescriptionMixed"]}' - - self.createAndAddVulnToHost(host_id=host_id, - name=vuln_data['name'], - desc=desc, - ref=[ref], - severity=info_loc_source['severity'], - resolution=resolution, - data=f'xfix: {vuln_data["xfid"]} cme: {vuln_data["cwe"]}', - run_date=None, - ) - else: - host_id = self.createAndAddHost(layout['name'], os=operating_system) - for vulnserv in name_scan: - for sev in item: - if sev['id'] == vulnserv['id']: - info_severity = sev['severity_id'] - if vulnserv['description'] is None: - desc = "" - else: - desc = vulnserv['description'] - - text_info = vulnserv['fixRecommendations']['text'] \ - if 'text' in vulnserv['fixRecommendations'] else "Not Text" - - link_info = vulnserv['fixRecommendations']['link'] \ - if 'link' in vulnserv['fixRecommendations'] else "Not Info" - - resolution = f"Text:{text_info}. Link: {link_info}." - - self.createAndAddVulnToHost(host_id=host_id, name=vulnserv['name'], desc=desc, - severity=info_severity, resolution=resolution, - data=f'xfix: {vulnserv["xfid"]} cme: {vulnserv["cwe"]}', run_date=None) + scan_type = parser.scan_type + + + if scan_type == 'DAST': + for issue in parser.issues: + host = issue.pop("host") + port = issue.pop("port") + host_os = issue.pop("os") + service_name = issue.pop("service_name") + ip = resolve_hostname(host) + host_id = self.createAndAddHost(ip, hostnames=host) + service_id = self.createAndAddServiceToHost(host_id, service_name, ports=port) + self.createAndAddVulnWebToService(host_id=host_id, service_id=service_id, **issue) + + elif scan_type == 'SAST': + for issue in parser.issues: + source_file = issue.pop('source_file') + host_id = self.createAndAddHost(source_file) + self.createAndAddVulnToHost(host_id=host_id, **issue) def createPlugin(ignore_info=False): From 6ed81326261d5dab944351b033375454ae9becaf Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Thu, 15 Apr 2021 17:37:41 -0300 Subject: [PATCH 188/698] ready for release 1.4.5 --- CHANGELOG/{current => 1.4.5}/add_bandit_plugin.md | 0 CHANGELOG/{current => 1.4.5}/change_burp_fields.md | 0 CHANGELOG/1.4.5/date.md | 1 + CHANGELOG/{current => 1.4.5}/fix_appscan.md | 0 CHANGELOG/{current => 1.4.5}/parse_nmap_vulnes.md | 0 RELEASE.md | 9 ++++++++- faraday_plugins/__init__.py | 2 +- 7 files changed, 10 insertions(+), 2 deletions(-) rename CHANGELOG/{current => 1.4.5}/add_bandit_plugin.md (100%) rename CHANGELOG/{current => 1.4.5}/change_burp_fields.md (100%) create mode 100644 CHANGELOG/1.4.5/date.md rename CHANGELOG/{current => 1.4.5}/fix_appscan.md (100%) rename CHANGELOG/{current => 1.4.5}/parse_nmap_vulnes.md (100%) diff --git a/CHANGELOG/current/add_bandit_plugin.md b/CHANGELOG/1.4.5/add_bandit_plugin.md similarity index 100% rename from CHANGELOG/current/add_bandit_plugin.md rename to CHANGELOG/1.4.5/add_bandit_plugin.md diff --git a/CHANGELOG/current/change_burp_fields.md b/CHANGELOG/1.4.5/change_burp_fields.md similarity index 100% rename from CHANGELOG/current/change_burp_fields.md rename to CHANGELOG/1.4.5/change_burp_fields.md diff --git a/CHANGELOG/1.4.5/date.md b/CHANGELOG/1.4.5/date.md new file mode 100644 index 00000000..0d5ebf9e --- /dev/null +++ b/CHANGELOG/1.4.5/date.md @@ -0,0 +1 @@ +Apr 15th, 2021 diff --git a/CHANGELOG/current/fix_appscan.md b/CHANGELOG/1.4.5/fix_appscan.md similarity index 100% rename from CHANGELOG/current/fix_appscan.md rename to CHANGELOG/1.4.5/fix_appscan.md diff --git a/CHANGELOG/current/parse_nmap_vulnes.md b/CHANGELOG/1.4.5/parse_nmap_vulnes.md similarity index 100% rename from CHANGELOG/current/parse_nmap_vulnes.md rename to CHANGELOG/1.4.5/parse_nmap_vulnes.md diff --git a/RELEASE.md b/RELEASE.md index 92c37222..7df7467a 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,6 +1,13 @@ +1.4.5 [Apr 15th, 2021]: +--- + * Add Bandit plugin + * Use background for description and detail for data en Burp plugin. + * Rewrite Appscan Plugin + * Parse Nmap vulners script data + 1.4.4 [Mar 30th, 2021]: --- - * Faraday CSV Plugin do not consider ignore_info option + * Faraday CSV Plugin do not consider ignore_info 1.4.3 [Mar 17th, 2021]: --- diff --git a/faraday_plugins/__init__.py b/faraday_plugins/__init__.py index 9e0feee7..5e235ead 100644 --- a/faraday_plugins/__init__.py +++ b/faraday_plugins/__init__.py @@ -1 +1 @@ -__version__ = '1.4.4' +__version__ = '1.4.5' From e720efea21d9c4c4bc538b43068d4c5c0f2b0060 Mon Sep 17 00:00:00 2001 From: Federico Kirschbaum Date: Mon, 19 Apr 2021 02:21:55 -0300 Subject: [PATCH 189/698] enhancement of redability of issues created by this plugin, added a number of items --- ...of_owasp_and_zap_we_might_get_more_data.md | 17 ++++++- faraday_plugins/plugins/repo/zap/plugin.py | 48 ++++++++++++++----- 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/CHANGELOG/current/when_import_reports_of_owasp_and_zap_we_might_get_more_data.md b/CHANGELOG/current/when_import_reports_of_owasp_and_zap_we_might_get_more_data.md index 027300db..d884d48c 100644 --- a/CHANGELOG/current/when_import_reports_of_owasp_and_zap_we_might_get_more_data.md +++ b/CHANGELOG/current/when_import_reports_of_owasp_and_zap_we_might_get_more_data.md @@ -6,4 +6,19 @@ CHANGE the structure of the reference CWE from CWE-12 to CWE:12 REPAIR some pylint with static_method, removing the try and except -CHANGE the function to extract params from url with a regex +CHANGE the function to extract params from url with a regex + +FIX service name was hardcoded, now is set by report information + +FIX references are now added in the proper + +FIX readability of the descriptions, remediation & reference by stripping html tags + +ADD now data includes the affected URL, Evidence & Affected Parameter when possible + +ADD new function to strip html tags + +ADD included information in reference for WASC + +ADD ZAP pluginid into external_id + \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/zap/plugin.py b/faraday_plugins/plugins/repo/zap/plugin.py index 5d7c30c8..5dc754bf 100644 --- a/faraday_plugins/plugins/repo/zap/plugin.py +++ b/faraday_plugins/plugins/repo/zap/plugin.py @@ -120,6 +120,13 @@ def get_attrib_from_subnode(xml_node, subnode_xpath_expr, attrib_name): return None +def strip_tags(data): + """ + Remove html tags from a string + @return Stripped string + """ + clean = re.compile('<.*?>') + return re.sub(clean, '', data) class Site: @@ -130,6 +137,7 @@ def __init__(self, item_node): self.host = self.node.get('host') self.ip = resolve_hostname(self.host) self.port = self.node.get('port') + self.ssl = self.node.get('ssl') self.items = [] for alert in self.node.findall('alerts/alertitem'): @@ -162,20 +170,24 @@ def __init__(self, item_node): self.name = self.get_text_from_subnode('alert') self.severity = self.get_text_from_subnode('riskcode') self.desc = self.get_text_from_subnode('desc') - if self.get_text_from_subnode('solution'): self.resolution = self.get_text_from_subnode('solution') else: self.resolution = '' + self.ref = [] if self.get_text_from_subnode('reference'): - self.desc += '\nReference: ' + \ - self.get_text_from_subnode('reference') + links = self.get_text_from_subnode('reference') + for link in links.split("

"): + if link != "": + self.ref.append(strip_tags(link)) - self.ref = [] if self.get_text_from_subnode('cweid'): self.ref.append("CWE:" + self.get_text_from_subnode('cweid')) + if self.get_text_from_subnode('wascid'): + self.ref.append("WASC:" + self.get_text_from_subnode('wascid')) + self.items = [] if item_node.find('instances'): @@ -191,7 +203,15 @@ def __init__(self, item_node): param = elem.findtext("param", "") attack = elem.findtext("attack", "") if attack and param: - item["data"] = f"Payload:\n {param} = {attack}" + item["data"] = f"URL:\n {uri}\n Payload:\n {param} = {attack}" + else: + item["data"] = f"URL:\n {uri}\n Parameter:\n {param}" + + evidence = elem.findtext("evidence", "") + if evidence: + item["data"] = f"URL:\n {uri}\n Parameter:\n {param}\n Evidence:\n {evidence}" + else: + item["data"] = f"URL:\n {uri}\n" item["pname"] = elem.findtext("param", "") @@ -246,8 +266,8 @@ def __init__(self, *arg, **kwargs): self.identifier_tag = "OWASPZAPReport" self.id = "Zap" self.name = "Zap XML Output Plugin" - self.plugin_version = "0.0.3" - self.version = "2.4.3" + self.plugin_version = "0.0.4" + self.version = "2.10.0" self.framework_version = "1.0.0" self.options = None @@ -264,10 +284,15 @@ def parseOutputString(self, output): host = [] if site.host != site.ip: host = [site.host] + + if site.ssl == "true": + service = "https" + else: + service = "http" h_id = self.createAndAddHost(site.ip, hostnames=host) - s_id = self.createAndAddServiceToHost(h_id, "http", "tcp", ports=[site.port], status='open') + s_id = self.createAndAddServiceToHost(h_id, service, "tcp", ports=[site.port], status='open') for item in site.items: for instance in item.items: @@ -276,7 +301,7 @@ def parseOutputString(self, output): h_id, s_id, item.name, - item.desc, + strip_tags(item.desc), website=instance['website'], query=instance['query'], severity=item.severity, @@ -284,9 +309,10 @@ def parseOutputString(self, output): params=instance['params'], method=instance['method'], ref=item.ref, - resolution=item.resolution, + resolution=strip_tags(item.resolution), data=instance["data"], - pname=instance["pname"] + pname=instance["pname"], + external_id=item.id ) del parser From 8dbed62562e0d0e68194c3faa538d160cc259e35 Mon Sep 17 00:00:00 2001 From: Manuel Jose Sotomayor Torrealba Date: Mon, 19 Apr 2021 16:33:42 -0300 Subject: [PATCH 190/698] CHANGE external_id to the correct Structure ZAP-XXXX --- ...mport_reports_of_owasp_and_zap_we_might_get_more_data.md | 3 ++- faraday_plugins/plugins/repo/zap/plugin.py | 6 ++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/CHANGELOG/current/when_import_reports_of_owasp_and_zap_we_might_get_more_data.md b/CHANGELOG/current/when_import_reports_of_owasp_and_zap_we_might_get_more_data.md index d884d48c..24c06bea 100644 --- a/CHANGELOG/current/when_import_reports_of_owasp_and_zap_we_might_get_more_data.md +++ b/CHANGELOG/current/when_import_reports_of_owasp_and_zap_we_might_get_more_data.md @@ -21,4 +21,5 @@ ADD new function to strip html tags ADD included information in reference for WASC ADD ZAP pluginid into external_id - \ No newline at end of file + +CHANGE external_id to the correct Structure ZAP-XXXX diff --git a/faraday_plugins/plugins/repo/zap/plugin.py b/faraday_plugins/plugins/repo/zap/plugin.py index 5dc754bf..120b86cc 100644 --- a/faraday_plugins/plugins/repo/zap/plugin.py +++ b/faraday_plugins/plugins/repo/zap/plugin.py @@ -179,6 +179,7 @@ def __init__(self, item_node): if self.get_text_from_subnode('reference'): links = self.get_text_from_subnode('reference') for link in links.split("

"): + link = link.strip().replace("\n", "") if link != "": self.ref.append(strip_tags(link)) @@ -312,14 +313,11 @@ def parseOutputString(self, output): resolution=strip_tags(item.resolution), data=instance["data"], pname=instance["pname"], - external_id=item.id + external_id="ZAP-"+str(item.id) ) del parser - def setHost(self): - pass - def createPlugin(ignore_info=False): return ZapPlugin(ignore_info=ignore_info) From dedcfb3259738d2e2cf6d3867e63836defd033ee Mon Sep 17 00:00:00 2001 From: Manuel Jose Sotomayor Torrealba Date: Tue, 20 Apr 2021 11:26:42 -0300 Subject: [PATCH 191/698] Structure change to DTO pattern --- .../plugins/repo/nessus/nessusParser.py | 108 +++++++++++ faraday_plugins/plugins/repo/nessus/plugin.py | 168 +----------------- 2 files changed, 116 insertions(+), 160 deletions(-) create mode 100644 faraday_plugins/plugins/repo/nessus/nessusParser.py diff --git a/faraday_plugins/plugins/repo/nessus/nessusParser.py b/faraday_plugins/plugins/repo/nessus/nessusParser.py new file mode 100644 index 00000000..df537d38 --- /dev/null +++ b/faraday_plugins/plugins/repo/nessus/nessusParser.py @@ -0,0 +1,108 @@ +import xml.etree.ElementTree as ET +from collections import namedtuple + +ReportItem = namedtuple('ReportItem', ['port', 'svc_name', 'protocol', 'severity', 'plugin_id', + 'plugin_name', 'plugin_family', 'description', 'plugin_output', 'info']) + + +class NessusParser: + """ + The objective of this class is to parse an xml file generated by the nessus tool. + + TODO: Handle errors. + TODO: Test nessus output version. Handle what happens if the parser doesn't support it. + TODO: Test cases. + + @param nessus_filepath A proper simple report generated by nessus + """ + + def __init__(self, output): + self.tree = ET.fromstring(output) + self.report = None + + if self.tree: + self.report = self.getReport(self.tree) + + @staticmethod + def getReport(tree): + if tree.find('Report'): + return Report(tree.find('Report')) + else: + return None + + @staticmethod + def parse_compliance_data(data: dict): + compliance_data = {} + for key, value in data.items(): + if 'compliance-' in key: + compliance_name = key.split("}")[-1] + compliance_data[compliance_name] = value + return compliance_data + + +class Report: + def __init__(self, report_node): + self.node = report_node + self.report_name = self.node.attrib.get('name') + self.report_host = self.node.find('ReportHost') + self.report_desc = [] + self.report_ip = [] + self.report_serv = [] + self.report_json = {} + if self.report_host is not None: + for x in self.node: + report_host_ip = x.attrib.get('name') + host_properties = self.gethosttag(x.find('HostProperties')) + report_items = self.getreportitems(x.findall('ReportItem')) + self.report_ip.append(report_host_ip) + self.report_desc.append(host_properties) + self.report_serv.append(report_items) + self.report_json['ip'] = self.report_ip + self.report_json['desc'] = self.report_desc + self.report_json['serv'] = self.report_serv + self.report_json['host_end'] = host_properties.get('HOST_END') + + else: + self.report_host_ip = None + self.host_properties = None + self.report_items = None + self.report_json = None + + def getreportitems(self, items): + report_items = [] + + for item in items: + port = item.attrib.get('port') + svc_name = item.attrib.get('svc_name') + protocol = item.attrib.get('protocol') + severity = item.attrib.get('severity') + plugin_id = item.attrib.get('pluginID') + plugin_name = item.attrib.get('pluginName') + plugin_family = item.attrib.get('pluginFamily') + if item.find('plugin_output') is not None: + plugin_output = item.find('plugin_output').text + else: + plugin_output = "Not Description" + if item.find('description') is not None: + description = item.find('description').text + else: + description = "Not Description" + info = self.getinfoitem(item) + report_items.append(ReportItem(*[port, svc_name, protocol, severity, plugin_id, + plugin_name, plugin_family, description, plugin_output, info])) + return report_items + + @staticmethod + def getinfoitem(item): + item_tags = {} + for i in item: + item_tags.setdefault(i.tag, i.text) + return item_tags + + @staticmethod + def gethosttag(tags): + host_tags = {} + for t in tags: + host_tags.setdefault(t.attrib.get('name'), t.text) + return host_tags + diff --git a/faraday_plugins/plugins/repo/nessus/plugin.py b/faraday_plugins/plugins/repo/nessus/plugin.py index 88c5116b..663f5b97 100644 --- a/faraday_plugins/plugins/repo/nessus/plugin.py +++ b/faraday_plugins/plugins/repo/nessus/plugin.py @@ -4,12 +4,10 @@ See the file 'doc/LICENSE' for the license information """ + import dateutil -from collections import namedtuple from faraday_plugins.plugins.plugin import PluginXMLFormat -import xml.etree.ElementTree as ET - __author__ = "Blas" __copyright__ = "Copyright (c) 2019, Infobyte LLC" @@ -20,160 +18,8 @@ __email__ = "bmoyano@infobytesec.com" __status__ = "Development" -ReportItem = namedtuple('ReportItem', ['port', 'svc_name', 'protocol', 'severity', 'plugin_id', - 'plugin_name', 'plugin_family', 'description', 'plugin_output', 'info']) - -class NessusParser: - """ - The objective of this class is to parse an xml file generated by the nessus tool. - - TODO: Handle errors. - TODO: Test nessus output version. Handle what happens if the parser doesn't support it. - TODO: Test cases. - - @param nessus_filepath A proper simple report generated by nessus - """ - - def __init__(self, output): - self.tree = ET.fromstring(output) - self.tag_control = [] - for x in self.tree: - self.tag_control.append(x) - if self.tree: - self.policy = self.getPolicy(self.tree) - self.report = self.getReport(self.tree) - else: - self.policy = None - self.report = None - - def getPolicy(self, tree): - policy_tree = tree.find('Policy') - if policy_tree: - return Policy(policy_tree) - else: - return None - - def getReport(self, tree): - report_tree = tree.find('Report') - return Report(report_tree) - - def parse_compliance_data(self, data: dict): - compliance_data = {} - for key, value in data.items(): - if 'compliance-' in key: - compliance_name = key.split("}")[-1] - compliance_data[compliance_name] = value - return compliance_data - -class Policy(): - def __init__(self, policy_node): - self.node = policy_node - self.policy_name = self.node.find('policyName').text - self.preferences = self.getPreferences(self.node.find('Preferences')) - self.family_selection = self.getFamilySelection(self.node.find('FamilySelection')) - self.individual_plugin_selection = self.getIndividualPluginSelection( - self.node.find('IndividualPluginSelection')) - - def getPreferences(self, preferences): - server_preferences = preferences.find('ServerPreferences') - plugins_preferences = preferences.find('PluginsPreferences') - server_preferences_all = [] - plugins_preferences_json = {} - plugins_preferences_all = [] - for sp in server_preferences: - sp_value = sp.find('value').text - sp_name = sp.find('name').text - server_preferences_all.append("Server Preferences name: {}, Server Preferences value: {}".format(sp_name, - sp_value)) - for pp in plugins_preferences: - for pp_detail in pp: - plugins_preferences_json.setdefault(pp_detail.tag, pp_detail.text) - plugins_preferences_all.append(plugins_preferences_json) - return server_preferences_all, plugins_preferences_all - - def getFamilySelection(self, family): - family_all = [] - for f in family: - family_name = f.find('FamilyName').text - family_value = f.find('Status').text - family_all.append("Family Name: {}, Family Value: {}".format(family_name, family_value)) - return family_all - - def getIndividualPluginSelection(self, individual): - item_plugin = [] - for i in individual: - plugin_id = i.find('PluginId').text - plugin_name = i.find('PluginName').text - plugin_family = i.find('Family').text - plugin_status = i.find('Status').text - item_plugin.append("Plugin ID: {}, Plugin Name: {}, Family: {}, Status: {}".format(plugin_id, plugin_name, - plugin_family, - plugin_status)) - return item_plugin - -class Report(): - def __init__(self, report_node): - self.node = report_node - self.report_name = self.node.attrib.get('name') - self.report_host = self.node.find('ReportHost') - self.report_desc = [] - self.report_ip = [] - self.report_serv = [] - self.report_json = {} - if self.report_host is not None: - for x in self.node: - report_host_ip = x.attrib.get('name') - host_properties = self.gethosttag(x.find('HostProperties')) - report_items = self.getreportitems(x.findall('ReportItem')) - self.report_ip.append(report_host_ip) - self.report_desc.append(host_properties) - self.report_serv.append(report_items) - self.report_json['ip'] = self.report_ip - self.report_json['desc'] = self.report_desc - self.report_json['serv'] = self.report_serv - self.report_json['host_end'] = host_properties.get('HOST_END') - - else: - self.report_host_ip = None - self.host_properties = None - self.report_items = None - self.report_json = None - - def getreportitems(self, items): - report_items = [] - - for item in items: - port = item.attrib.get('port') - svc_name = item.attrib.get('svc_name') - protocol = item.attrib.get('protocol') - severity = item.attrib.get('severity') - plugin_id = item.attrib.get('pluginID') - plugin_name = item.attrib.get('pluginName') - plugin_family = item.attrib.get('pluginFamily') - if item.find('plugin_output') is not None: - plugin_output = item.find('plugin_output').text - else: - plugin_output = "Not Description" - if item.find('description') is not None: - description = item.find('description').text - else: - description = "Not Description" - info = self.getinfoitem(item) - report_items.append(ReportItem(*[port, svc_name, protocol, severity, plugin_id, - plugin_name, plugin_family, description, plugin_output, info])) - return report_items - - def getinfoitem(self, item): - item_tags = {} - for i in item: - item_tags.setdefault(i.tag, i.text) - return item_tags +from faraday_plugins.plugins.repo.nessus.nessusParser import NessusParser - def gethosttag(self, tags): - host_tags = {} - for t in tags: - host_tags.setdefault(t.attrib.get('name'), t.text) - return host_tags class NessusPlugin(PluginXMLFormat): """ @@ -208,7 +54,7 @@ def parseOutputString(self, output): if parser.report.report_json is not None: run_date = parser.report.report_json.get('host_end') if run_date: - run_date = dateutil.parser.parse(run_date) + run_date = dateutil.paparser.prser.parse(run_date) for set_info, ip in enumerate(parser.report.report_json['ip'], start=1): website = None mac = parser.report.report_json['desc'][set_info - 1].get('mac-address', '') @@ -219,7 +65,7 @@ def parseOutputString(self, output): website = host_name host_id = self.createAndAddHost(ip_host, os=os, hostnames=host_name, mac=mac) - for report_item in parser.report.report_json['serv'][set_info -1]: + for report_item in parser.report.report_json['serv'][set_info - 1]: vulnerability_name = report_item.plugin_name if not vulnerability_name: continue @@ -229,7 +75,7 @@ def parseOutputString(self, output): item_severity = report_item.severity external_id = report_item.plugin_id serv_description = report_item.description - #cve.append(report_item.plugin_output) + # cve.append(report_item.plugin_output) description = report_item.plugin_output data = report_item.info risk_factor = data.get('risk_factor', None) @@ -252,7 +98,9 @@ def parseOutputString(self, output): compliance_info = compliance_data.get('compliance-info', '') if compliance_info and not description: description = compliance_info - compliance_reference = compliance_data.get('compliance-reference', '').replace('|', ':').split(',') + compliance_reference = compliance_data.get('compliance-reference', '').replace('|', + ':').split( + ',') compliance_result = compliance_data.get('compliance-result', '') for reference in compliance_reference: ref.append(reference) From 2fbc384d45e49f5ab5cf4ab7d72df0152225ef58 Mon Sep 17 00:00:00 2001 From: Manuel Jose Sotomayor Torrealba Date: Thu, 22 Apr 2021 10:35:07 -0300 Subject: [PATCH 192/698] cambio de estructura --- faraday_plugins/plugins/repo/nessus/DTO.py | 376 ++++++++++++++++++ .../plugins/repo/nessus/nessusParser.py | 174 ++++---- faraday_plugins/plugins/repo/nessus/plugin.py | 34 +- 3 files changed, 491 insertions(+), 93 deletions(-) create mode 100644 faraday_plugins/plugins/repo/nessus/DTO.py diff --git a/faraday_plugins/plugins/repo/nessus/DTO.py b/faraday_plugins/plugins/repo/nessus/DTO.py new file mode 100644 index 00000000..270d82df --- /dev/null +++ b/faraday_plugins/plugins/repo/nessus/DTO.py @@ -0,0 +1,376 @@ +from typing import List + + +class Attachment: + def __init__(self, node): + self.node = node + + @property + def name_attr(self): + return self.node.get("name") + + @property + def type_attr(self): + return self.node.get("type") + + @property + def text(self): + return self.node.text + + +class ReportItem: + def __init__(self, node): + self.node = node + + @property + def port_attr(self): + return self.node.get("port") + + @property + def svc_name_attr(self): + return self.node.get("svc_name") + + @property + def protocol_attr(self): + return self.node.get("protocol") + + @property + def severity_attr(self): + return self.node.get("severity") + + @property + def plugin_id_attr(self): + return self.node.get("pluginID") + + @property + def plugin_name_attr(self): + return self.node.get("pluginName") + + @property + def plugin_family_attr(self): + return self.node.get("pluginFamily") + @property + def agent(self): + return self.node.findtext("agent") + + @property + def description(self): + return self.node.findtext("description", "Not Description") + + @property + def fname(self): + return self.node.findtext("fname") + + @property + def plugin_modification_date(self): + return self.node.findtext("plugin_modification_date") + + @property + def plugin_name(self): + return self.node.findtext("plugin_name") + + @property + def plugin_publication_date(self): + return self.node.findtext("plugin_publication_date") + + @property + def plugin_type(self): + return self.node.findtext("plugin_type") + + @property + def risk_factor(self): + return self.node.findtext("risk_factor") + + @property + def script_version(self): + return self.node.findtext("script_version") + + @property + def see_also(self): + return self.node.findtext("see_also") + + @property + def solution(self): + return self.node.findtext("solution") + + @property + def synopsis(self): + return self.node.findtext("synopsis") + + @property + def plugin_output(self): + return self.node.findtext("plugin_output", "Not Description") + + @property + def always_run(self): + return self.node.findtext("always_run") + + + @property + def asset_inventory(self): + return self.node.findtext("asset_inventory") + + @property + def canvas_package(self): + return self.node.findtext("canvas_package") + + @property + def cvss3_base_score(self): + return self.node.findtext("cvss3_base_score") + + @property + def cvss3_temporal_score(self): + return self.node.findtext("cvss3_temporal_score") + + @property + def cpe(self): + return self.node.findtext("cpe") + + @property + def cvss3_temporal_vector(self): + return self.node.findtext("cvss3_temporal_vector") + + @property + def cvss3_vector(self): + return self.node.findtext("cvss3_vector") + + @property + def cvss_base_score(self): + return self.node.findtext("cvss_base_score") + + @property + def cvss_score_rationale(self): + return self.node.findtext("cvss_score_rationale") + + @property + def cvss_score_source(self): + return self.node.findtext("cvss_score_source") + + @property + def cvss_temporal_score(self): + return self.node.findtext("cvss_temporal_score") + + @property + def cvss_temporal_vector(self): + return self.node.findtext("cvss_temporal_vector") + + @property + def cvss_vector(self): + return self.node.findtext("cvss_vector") + + @property + def exploit_available(self): + return self.node.findtext("exploit_available") + + @property + def exploit_framework_canvas(self): + return self.node.findtext("exploit_framework_canvas") + + @property + def exploit_framework_core(self): + return self.node.findtext("exploit_framework_core") + + @property + def exploit_framework_d2_elliot(self): + return self.node.findtext("exploit_framework_d2_elliot") + + @property + def exploit_framework_metasploit(self): + return self.node.findtext("exploit_framework_metasploit") + + @property + def exploitability_ease(self): + return self.node.findtext("exploitability_ease") + + @property + def exploited_by_malware(self): + return self.node.findtext("exploited_by_malware") + + @property + def exploited_by_nessus(self): + return self.node.findtext("exploited_by_nessus") + + @property + def hardware_inventory(self): + return self.node.findtext("hardware_inventory") + + @property + def iava(self): + return self.node.findtext("iava") + + @property + def iavb(self): + return self.node.findtext("iavb") + + @property + def iavt(self): + return self.node.findtext("iavt") + + @property + def in_the_news(self): + return self.node.findtext("in_the_news") + + @property + def metasploit_name(self): + return self.node.findtext("metasploit_name") + + @property + def os_identification(self): + return self.node.findtext("os_identification") + + @property + def owasp(self): + return self.node.findtext("owasp") + + @property + def patch_publication_date(self): + return self.node.findtext("patch_publication_date") + + + @property + def stig_severity(self): + return self.node.findtext("stig_severity") + + @property + def d2_elliot_name(self): + return self.node.findtext("d2_elliot_name") + + @property + def unsupported_by_vendor(self): + return self.node.findtext("unsupported_by_vendor") + + @property + def vuln_publication_date(self): + return self.node.findtext("vuln_publication_date") + + @property + def msft(self): + return self.node.findtext("msft") + + + @property + def cert(self) -> list: + return self.node.findall("cert") + + @property + def bid(self) -> list: + return self.node.findall("bid") + + @property + def cve(self) -> list: + return self.node.findall("cve") + + @property + def cwe(self) -> list: + return self.node.findall("cwe") + + @property + def edb_id(self) -> list: + return self.node.findall("edb-id") + + @property + def mskb(self) -> list: + return self.node.findall("mskb") + + @property + def xref(self) -> list: + return self.node.findall("xref") + + @property + def attachment(self) -> Attachment: + attachment = self.node.find("attachment") + return Attachment(attachment) if attachment else None + + # def getinfoitem(self): + # item_tags = {} + # for i in self.node: + # item_tags.setdefault(i.tag, i.text) + # return item_tags + + + +class Tag: + def __init__(self, node): + self.node = node + + @property + def name_attr(self) -> str: + return self.node.get("name") + + @property + def text(self) -> str: + return self.node.text + + +class HostProperties: + def __init__(self, node): + self.node = node + + @property + def tag(self) -> list: + return [Tag(i) for i in self.node.findall('tag')] + + @property + def host_end(self) -> str: + _dict = self.dict_tags + return _dict.get("HOST_END") + + @property + def mac_address(self) -> str: + _dict = self.dict_tags + return _dict.get("mac-address", None) + + @property + def operating_system(self) -> str: + _dict = self.dict_tags + return _dict.get("operating-system", None) + + @property + def host_ip(self) -> str: + _dict = self.dict_tags + return _dict.get("host-ip", None) + + @property + def host_fqdn(self) -> str: + _dict = self.dict_tags + return _dict.get("host-fqdn", None) + + @property + def dict_tags(self): + host_tags = {} + for t in self.node: + host_tags.setdefault(t.attrib.get('name'), t.text) + return host_tags + + + +class ReportHost: + def __init__(self, node): + self.node = node + + @property + def name(self) -> str: + return self.node.get("name") + + @property + def host_properties(self) -> HostProperties: + return HostProperties(self.node.find("HostProperties")) + + @property + def report_items(self) -> List[ReportItem]: + return [ReportItem(i) for i in self.node.findall("ReportItem")] + + +class Report: + + def __init__(self, node): + self.node = node + + @property + def name_attr(self) -> str: + return self.node.get("name") + + @property + def report_hosts(self) -> List[ReportHost]: + return [ReportHost(i) for i in self.node.findall('ReportHost')] + diff --git a/faraday_plugins/plugins/repo/nessus/nessusParser.py b/faraday_plugins/plugins/repo/nessus/nessusParser.py index df537d38..b876e9e3 100644 --- a/faraday_plugins/plugins/repo/nessus/nessusParser.py +++ b/faraday_plugins/plugins/repo/nessus/nessusParser.py @@ -1,8 +1,6 @@ import xml.etree.ElementTree as ET -from collections import namedtuple -ReportItem = namedtuple('ReportItem', ['port', 'svc_name', 'protocol', 'severity', 'plugin_id', - 'plugin_name', 'plugin_family', 'description', 'plugin_output', 'info']) +from faraday_plugins.plugins.repo.nessus.DTO import Report class NessusParser: @@ -18,91 +16,87 @@ class NessusParser: def __init__(self, output): self.tree = ET.fromstring(output) - self.report = None - + self.report = [] if self.tree: - self.report = self.getReport(self.tree) - - @staticmethod - def getReport(tree): - if tree.find('Report'): - return Report(tree.find('Report')) - else: - return None - - @staticmethod - def parse_compliance_data(data: dict): - compliance_data = {} - for key, value in data.items(): - if 'compliance-' in key: - compliance_name = key.split("}")[-1] - compliance_data[compliance_name] = value - return compliance_data - - -class Report: - def __init__(self, report_node): - self.node = report_node - self.report_name = self.node.attrib.get('name') - self.report_host = self.node.find('ReportHost') - self.report_desc = [] - self.report_ip = [] - self.report_serv = [] - self.report_json = {} - if self.report_host is not None: - for x in self.node: - report_host_ip = x.attrib.get('name') - host_properties = self.gethosttag(x.find('HostProperties')) - report_items = self.getreportitems(x.findall('ReportItem')) - self.report_ip.append(report_host_ip) - self.report_desc.append(host_properties) - self.report_serv.append(report_items) - self.report_json['ip'] = self.report_ip - self.report_json['desc'] = self.report_desc - self.report_json['serv'] = self.report_serv - self.report_json['host_end'] = host_properties.get('HOST_END') - - else: - self.report_host_ip = None - self.host_properties = None - self.report_items = None - self.report_json = None - - def getreportitems(self, items): - report_items = [] - - for item in items: - port = item.attrib.get('port') - svc_name = item.attrib.get('svc_name') - protocol = item.attrib.get('protocol') - severity = item.attrib.get('severity') - plugin_id = item.attrib.get('pluginID') - plugin_name = item.attrib.get('pluginName') - plugin_family = item.attrib.get('pluginFamily') - if item.find('plugin_output') is not None: - plugin_output = item.find('plugin_output').text - else: - plugin_output = "Not Description" - if item.find('description') is not None: - description = item.find('description').text - else: - description = "Not Description" - info = self.getinfoitem(item) - report_items.append(ReportItem(*[port, svc_name, protocol, severity, plugin_id, - plugin_name, plugin_family, description, plugin_output, info])) - return report_items - - @staticmethod - def getinfoitem(item): - item_tags = {} - for i in item: - item_tags.setdefault(i.tag, i.text) - return item_tags - - @staticmethod - def gethosttag(tags): - host_tags = {} - for t in tags: - host_tags.setdefault(t.attrib.get('name'), t.text) - return host_tags - + self.report = self.__get_report() + + def __get_report(self) -> Report: + report = self.tree.find('Report') + return Report(report) if report else None + + + + + + +# class + +# +# class Report: +# def __init__(self, report_node): +# self.node = report_node +# +# +# +# self.report_name = self.node.attrib.get('name') +# self.report_host = self.node.find('ReportHost') +# self.report_desc = [] +# self.report_ip = [] +# self.report_serv = [] self.node.find("HostProperties") +# self.report_json = {} +# if self.report_host is not None: +# for x in self.node: +# report_host_ip = x.attrib.get('name') +# host_properties = self.gethosttag(x.find('HostProperties')) +# report_items = self.getreportitems(x.findall('ReportItem')) +# self.report_ip.append(report_host_ip) +# self.report_desc.append(host_properties) +# self.report_serv.append(report_items) +# self.report_json['ip'] = self.report_ip +# self.report_json['desc'] = self.report_desc +# self.report_json['serv'] = self.report_serv +# self.report_json['host_end'] = host_properties.get('HOST_END') +# else: +# self.report_host_ip = None +# self.host_properties = None +# self.report_items = None +# self.report_json = None +# +# def getreportitems(self, items): +# report_items = [] +# +# for item in items: +# port = item.attrib.get('port') +# svc_name = item.attrib.get('svc_name') +# protocol = item.attrib.get('protocol') +# severity = item.attrib.get('severity') +# plugin_id = item.attrib.get('pluginID') +# plugin_name = item.attrib.get('pluginName') +# plugin_family = item.attrib.get('pluginFamily') +# if item.find('plugin_output') is not None: +# plugin_output = item.find('plugin_output').text +# else: +# plugin_output = "Not Description" +# if item.find('description') is not None: +# description = item.find('description').text +# else: +# description = "Not Description" +# info = self.getinfoitem(item) +# report_items.append(ReportItem(*[port, svc_name, protocol, severity, plugin_id, +# plugin_name, plugin_family, description, plugin_output, info])) +# return report_items +# +# @staticmethod +# def getinfoitem(item): +# item_tags = {} +# for i in item: +# item_tags.setdefault(i.tag, i.text) +# return item_tags +# +# @staticmethod +# def gethosttag(tags): +# host_tags = {} +# for t in tags: +# host_tags.setdefault(t.attrib.get('name'), t.text) +# return host_tags +# diff --git a/faraday_plugins/plugins/repo/nessus/plugin.py b/faraday_plugins/plugins/repo/nessus/plugin.py index 663f5b97..0ddad3bb 100644 --- a/faraday_plugins/plugins/repo/nessus/plugin.py +++ b/faraday_plugins/plugins/repo/nessus/plugin.py @@ -37,6 +37,15 @@ def __init__(self, *arg, **kwargs): self.framework_version = "1.0.1" self.options = None + @staticmethod + def parse_compliance_data(data: dict): + compliance_data = {} + for key, value in data.items(): + if 'compliance-' in key: + compliance_name = key.split("}")[-1] + compliance_data[compliance_name] = value + return compliance_data + def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it from @@ -45,16 +54,35 @@ def parseOutputString(self, output): NOTE: if 'debug' is true then it is being run from a test case and the output being sent is valid. """ + try: parser = NessusParser(output) except Exception as e: self.logger.error(str(e)) return None + report_hosts = parser.report.report_hosts - if parser.report.report_json is not None: - run_date = parser.report.report_json.get('host_end') + if report_hosts: + run_date = report_hosts[-1].host_properties.host_end if run_date: - run_date = dateutil.paparser.prser.parse(run_date) + run_date = dateutil.parser.parse(run_date) + + for host in report_hosts: + properties = host.host_properties + website = None + mac = properties.mac_address + os = properties.operating_system + ip_host = properties.host_ip + host_name = properties.host_fqdn + if host_name: + website = host_name + host_id = self.createAndAddHost(ip_host, os=os, hostnames=host_name, mac=mac) + + for items in host.report_items: + import ipdb; + ipdb.set_trace() + + for set_info, ip in enumerate(parser.report.report_json['ip'], start=1): website = None mac = parser.report.report_json['desc'][set_info - 1].get('mac-address', '') From bc46e7e990c465e77d5a2335cc78622af6ab9c81 Mon Sep 17 00:00:00 2001 From: Manuel Jose Sotomayor Torrealba Date: Fri, 23 Apr 2021 14:34:58 -0300 Subject: [PATCH 193/698] cve, cvss3_base_score, cvss3_vector, exploit_available when import nessus and change the structure of external_id to NESSUS-XXX, add new structure and DTO to make more easier read the code --- ...t_report_of_nessus_we_can_get_more_data.md | 1 + faraday_plugins/plugins/repo/nessus/DTO.py | 63 +++-- .../plugins/repo/nessus/nessusParser.py | 102 ------- faraday_plugins/plugins/repo/nessus/plugin.py | 254 +++++++++--------- 4 files changed, 166 insertions(+), 254 deletions(-) create mode 100644 CHANGELOG/current/when_import_report_of_nessus_we_can_get_more_data.md delete mode 100644 faraday_plugins/plugins/repo/nessus/nessusParser.py diff --git a/CHANGELOG/current/when_import_report_of_nessus_we_can_get_more_data.md b/CHANGELOG/current/when_import_report_of_nessus_we_can_get_more_data.md new file mode 100644 index 00000000..3fe6ad29 --- /dev/null +++ b/CHANGELOG/current/when_import_report_of_nessus_we_can_get_more_data.md @@ -0,0 +1 @@ +ADD cve, cvss3_base_score, cvss3_vector, exploit_available when import nessus and change the structure of external_id to NESSUS-XXX \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/nessus/DTO.py b/faraday_plugins/plugins/repo/nessus/DTO.py index 270d82df..6d638dbc 100644 --- a/faraday_plugins/plugins/repo/nessus/DTO.py +++ b/faraday_plugins/plugins/repo/nessus/DTO.py @@ -40,7 +40,10 @@ def severity_attr(self): @property def plugin_id_attr(self): - return self.node.get("pluginID") + plugin_id = self.node.get("pluginID") + if plugin_id: + plugin_id = f'NESSUS-{plugin_id}' + return plugin_id @property def plugin_name_attr(self): @@ -67,7 +70,11 @@ def plugin_modification_date(self): @property def plugin_name(self): - return self.node.findtext("plugin_name") + + plugin_name = self.node.findtext("plugin_name") + if not plugin_name: + plugin_name = self.plugin_name_attr + return plugin_name @property def plugin_publication_date(self): @@ -79,7 +86,10 @@ def plugin_type(self): @property def risk_factor(self): - return self.node.findtext("risk_factor") + risk_factor = self.node.findtext("risk_factor") + if risk_factor == 'None' or risk_factor is None: + risk_factor = self.severity_attr # I checked several external id and most of them were info + return risk_factor @property def script_version(self): @@ -91,7 +101,7 @@ def see_also(self): @property def solution(self): - return self.node.findtext("solution") + return self.node.findtext("solution", '') @property def synopsis(self): @@ -99,7 +109,7 @@ def synopsis(self): @property def plugin_output(self): - return self.node.findtext("plugin_output", "Not Description") + return self.node.findtext("plugin_output", "") @property def always_run(self): @@ -116,7 +126,10 @@ def canvas_package(self): @property def cvss3_base_score(self): - return self.node.findtext("cvss3_base_score") + cvss_base_score = self.node.findtext("cvss3_base_score") + if cvss_base_score: + cvss_base_score = f"CVSS3:{cvss_base_score}" + return cvss_base_score @property def cvss3_temporal_score(self): @@ -136,7 +149,10 @@ def cvss3_vector(self): @property def cvss_base_score(self): - return self.node.findtext("cvss_base_score") + cvss_base_score = self.node.findtext("cvss_base_score") + if cvss_base_score: + cvss_base_score = f"CVSS:{cvss_base_score}" + return cvss_base_score @property def cvss_score_rationale(self): @@ -156,11 +172,17 @@ def cvss_temporal_vector(self): @property def cvss_vector(self): - return self.node.findtext("cvss_vector") + cvss_vector = self.node.findtext("cvss_vector") + if cvss_vector: + cvss_vector = f"CVSSVECTOR:{cvss_vector}" + return cvss_vector @property def exploit_available(self): - return self.node.findtext("exploit_available") + exploit_avalible = self.node.findtext("exploit_available", "") + if exploit_avalible: + exploit_avalible = f"Exploit available: {exploit_avalible.capitalize()}\n" + return exploit_avalible @property def exploit_framework_canvas(self): @@ -258,11 +280,11 @@ def bid(self) -> list: @property def cve(self) -> list: - return self.node.findall("cve") + return [i.text for i in self.node.findall("cve")] @property def cwe(self) -> list: - return self.node.findall("cwe") + return [i.text for i in self.node.findall("cwe")] @property def edb_id(self) -> list: @@ -273,20 +295,19 @@ def mskb(self) -> list: return self.node.findall("mskb") @property - def xref(self) -> list: - return self.node.findall("xref") + def xref(self) -> str: + return self.node.findtext("xref") @property def attachment(self) -> Attachment: attachment = self.node.find("attachment") return Attachment(attachment) if attachment else None - # def getinfoitem(self): - # item_tags = {} - # for i in self.node: - # item_tags.setdefault(i.tag, i.text) - # return item_tags - + def get_data(self): + item_tags = {} + for i in self.node: + item_tags.setdefault(i.tag, i.text) + return item_tags class Tag: @@ -318,7 +339,7 @@ def host_end(self) -> str: @property def mac_address(self) -> str: _dict = self.dict_tags - return _dict.get("mac-address", None) + return _dict.get("mac-address", "") @property def operating_system(self) -> str: @@ -328,6 +349,7 @@ def operating_system(self) -> str: @property def host_ip(self) -> str: _dict = self.dict_tags + return _dict.get("host-ip", None) @property @@ -343,7 +365,6 @@ def dict_tags(self): return host_tags - class ReportHost: def __init__(self, node): self.node = node diff --git a/faraday_plugins/plugins/repo/nessus/nessusParser.py b/faraday_plugins/plugins/repo/nessus/nessusParser.py deleted file mode 100644 index b876e9e3..00000000 --- a/faraday_plugins/plugins/repo/nessus/nessusParser.py +++ /dev/null @@ -1,102 +0,0 @@ -import xml.etree.ElementTree as ET - -from faraday_plugins.plugins.repo.nessus.DTO import Report - - -class NessusParser: - """ - The objective of this class is to parse an xml file generated by the nessus tool. - - TODO: Handle errors. - TODO: Test nessus output version. Handle what happens if the parser doesn't support it. - TODO: Test cases. - - @param nessus_filepath A proper simple report generated by nessus - """ - - def __init__(self, output): - self.tree = ET.fromstring(output) - self.report = [] - if self.tree: - self.report = self.__get_report() - - def __get_report(self) -> Report: - report = self.tree.find('Report') - return Report(report) if report else None - - - - - - -# class - -# -# class Report: -# def __init__(self, report_node): -# self.node = report_node -# -# -# -# self.report_name = self.node.attrib.get('name') -# self.report_host = self.node.find('ReportHost') -# self.report_desc = [] -# self.report_ip = [] -# self.report_serv = [] self.node.find("HostProperties") -# self.report_json = {} -# if self.report_host is not None: -# for x in self.node: -# report_host_ip = x.attrib.get('name') -# host_properties = self.gethosttag(x.find('HostProperties')) -# report_items = self.getreportitems(x.findall('ReportItem')) -# self.report_ip.append(report_host_ip) -# self.report_desc.append(host_properties) -# self.report_serv.append(report_items) -# self.report_json['ip'] = self.report_ip -# self.report_json['desc'] = self.report_desc -# self.report_json['serv'] = self.report_serv -# self.report_json['host_end'] = host_properties.get('HOST_END') -# else: -# self.report_host_ip = None -# self.host_properties = None -# self.report_items = None -# self.report_json = None -# -# def getreportitems(self, items): -# report_items = [] -# -# for item in items: -# port = item.attrib.get('port') -# svc_name = item.attrib.get('svc_name') -# protocol = item.attrib.get('protocol') -# severity = item.attrib.get('severity') -# plugin_id = item.attrib.get('pluginID') -# plugin_name = item.attrib.get('pluginName') -# plugin_family = item.attrib.get('pluginFamily') -# if item.find('plugin_output') is not None: -# plugin_output = item.find('plugin_output').text -# else: -# plugin_output = "Not Description" -# if item.find('description') is not None: -# description = item.find('description').text -# else: -# description = "Not Description" -# info = self.getinfoitem(item) -# report_items.append(ReportItem(*[port, svc_name, protocol, severity, plugin_id, -# plugin_name, plugin_family, description, plugin_output, info])) -# return report_items -# -# @staticmethod -# def getinfoitem(item): -# item_tags = {} -# for i in item: -# item_tags.setdefault(i.tag, i.text) -# return item_tags -# -# @staticmethod -# def gethosttag(tags): -# host_tags = {} -# for t in tags: -# host_tags.setdefault(t.attrib.get('name'), t.text) -# return host_tags -# diff --git a/faraday_plugins/plugins/repo/nessus/plugin.py b/faraday_plugins/plugins/repo/nessus/plugin.py index 0ddad3bb..4ae331b4 100644 --- a/faraday_plugins/plugins/repo/nessus/plugin.py +++ b/faraday_plugins/plugins/repo/nessus/plugin.py @@ -5,8 +5,9 @@ """ -import dateutil +import xml.etree.ElementTree as ET +import dateutil from faraday_plugins.plugins.plugin import PluginXMLFormat __author__ = "Blas" @@ -18,7 +19,29 @@ __email__ = "bmoyano@infobytesec.com" __status__ = "Development" -from faraday_plugins.plugins.repo.nessus.nessusParser import NessusParser +from faraday_plugins.plugins.repo.nessus.DTO import ReportHost, Report, ReportItem + + +class NessusParser: + """ + The objective of this class is to parse an xml file generated by the nessus tool. + + TODO: Handle errors. + TODO: Test nessus output version. Handle what happens if the parser doesn't support it. + TODO: Test cases. + + @param nessus_filepath A proper simple report generated by nessus + """ + + def __init__(self, output): + self.tree = ET.fromstring(output) + self.report = [] + if self.tree: + self.report = self.__get_report() + + def __get_report(self) -> Report: + report = self.tree.find('Report') + return Report(report) if report else None class NessusPlugin(PluginXMLFormat): @@ -46,6 +69,62 @@ def parse_compliance_data(data: dict): compliance_data[compliance_name] = value return compliance_data + @staticmethod + def map_properties(host: ReportHost): + return { + "name": host.host_properties.host_ip if host.host_properties.host_ip else host.name, + "hostnames": host.host_properties.host_fqdn, + "mac": host.host_properties.mac_address, + "os": host.host_properties.operating_system + } + + @staticmethod + def map_item(host_id, run_date, plugin_name, item: ReportItem) -> dict: + cvss_base_score = item.cvss_base_score + data = item.plugin_output + data += f'{item.exploit_available}' + return { + "host_id": host_id, + "name": plugin_name, + "severity": item.risk_factor, + "data": data, + "external_id": item.plugin_id_attr, + "run_date": run_date, + "desc": item.description, + "resolution": item.solution, + "ref": [cvss_base_score] if cvss_base_score else [] + } + + def map_policy_general(self, kwargs, item: ReportItem): + kwargs.update({"policyviolations": []}) + if item.plugin_family_attr == 'Policy Compliance': + data = item.get_data() + bis_benchmark_data = kwargs["desc"].split('\n') + compliance_data = self.parse_compliance_data(data) + compliance_info = compliance_data.get('compliance-info', '') + if compliance_info and not kwargs["desc"]: + kwargs["desc"] = compliance_info + compliance_reference = compliance_data.get( + 'compliance-reference', '').replace('|', ':').split(',') + compliance_result = compliance_data.get('compliance-result', '') + for reference in compliance_reference: + kwargs["ref"].append(reference) + compliance_check_name = compliance_data.get('compliance-check-name', '') + compliance_solution = compliance_data.get('compliance-solution', '') + if compliance_solution and not kwargs["resolution"]: + kwargs["resolution"] = compliance_solution + policy_item = f'{compliance_check_name} - {compliance_result}' + for policy_check_data in bis_benchmark_data: + if 'ref.' in policy_check_data: + kwargs["ref"].append(policy_check_data) + if 'compliance-see-also' in compliance_data: + kwargs["ref"].append(compliance_data.get('compliance-see-also')) + # We used this info from tenable: https://community.tenable.com/s/article/Compliance-checks-in-SecurityCenter + kwargs["policyviolations"].append(policy_item) + kwargs["name"] = f'{kwargs["name"]}: {policy_item}' + + return kwargs + def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it from @@ -63,142 +142,55 @@ def parseOutputString(self, output): report_hosts = parser.report.report_hosts if report_hosts: - run_date = report_hosts[-1].host_properties.host_end - if run_date: - run_date = dateutil.parser.parse(run_date) - for host in report_hosts: - properties = host.host_properties - website = None - mac = properties.mac_address - os = properties.operating_system - ip_host = properties.host_ip - host_name = properties.host_fqdn - if host_name: - website = host_name - host_id = self.createAndAddHost(ip_host, os=os, hostnames=host_name, mac=mac) - - for items in host.report_items: - import ipdb; - ipdb.set_trace() - - - for set_info, ip in enumerate(parser.report.report_json['ip'], start=1): - website = None - mac = parser.report.report_json['desc'][set_info - 1].get('mac-address', '') - os = parser.report.report_json['desc'][set_info - 1].get('operating-system', None) - ip_host = parser.report.report_json['desc'][set_info - 1].get('host-ip', ip) - host_name = parser.report.report_json['desc'][set_info - 1].get('host-fqdn', None) - if host_name: - website = host_name - host_id = self.createAndAddHost(ip_host, os=os, hostnames=host_name, mac=mac) - - for report_item in parser.report.report_json['serv'][set_info - 1]: - vulnerability_name = report_item.plugin_name + run_date = host.host_properties.host_end + if run_date: + run_date = dateutil.parser.parse(run_date) + website = host.host_properties.host_fqdn + host_id = self.createAndAddHost(**self.map_properties(host)) + + for item in host.report_items: + vulnerability_name = item.plugin_name if not vulnerability_name: continue - item_name = report_item.svc_name - item_port = report_item.port - item_protocol = report_item.protocol - item_severity = report_item.severity - external_id = report_item.plugin_id - serv_description = report_item.description - # cve.append(report_item.plugin_output) - description = report_item.plugin_output - data = report_item.info - risk_factor = data.get('risk_factor', None) - cve = [] - ref = [] - if risk_factor == 'None' or risk_factor is None: - risk_factor = item_severity # I checked several external id and most of them were info + item_name = item.svc_name_attr + + _main_data = self.map_item( + host_id, run_date, vulnerability_name, item) + + _main_data = self.map_add_ref(_main_data, item) if item_name == 'general': - description = data.get('description', '') - resolution = data.get('solution', '') - data_pluin_ouput = data.get('plugin_output', '') - if 'cvss_base_score' in data: - cvss_base_score = f"CVSS:{data['cvss_base_score']}" - ref.append(cvss_base_score) - policyviolations = [] - if report_item.plugin_family == 'Policy Compliance': - # This condition was added to support CIS Benchmark in policy violation field. - bis_benchmark_data = report_item.description.split('\n') - compliance_data = parser.parse_compliance_data(data) - compliance_info = compliance_data.get('compliance-info', '') - if compliance_info and not description: - description = compliance_info - compliance_reference = compliance_data.get('compliance-reference', '').replace('|', - ':').split( - ',') - compliance_result = compliance_data.get('compliance-result', '') - for reference in compliance_reference: - ref.append(reference) - compliance_check_name = compliance_data.get('compliance-check-name', '') - compliance_solution = compliance_data.get('compliance-solution', '') - if compliance_solution and not resolution: - resolution = compliance_solution - policy_item = f'{compliance_check_name} - {compliance_result}' - for policy_check_data in bis_benchmark_data: - if 'ref.' in policy_check_data: - ref.append(policy_check_data) - if 'compliance-see-also' in compliance_data: - ref.append(compliance_data.get('compliance-see-also')) - # We used this info from tenable: https://community.tenable.com/s/article/Compliance-checks-in-SecurityCenter - policyviolations.append(policy_item) - vulnerability_name = f'{vulnerability_name}: {policy_item}' - self.createAndAddVulnToHost(host_id, - vulnerability_name, - desc=description, - severity=risk_factor, - resolution=resolution, - data=data_pluin_ouput, - ref=ref, - policyviolations=policyviolations, - external_id=external_id, - run_date=run_date) + _main_data = self.map_policy_general(_main_data, item) + self.createAndAddVulnToHost(**_main_data) else: - vulnerability_name = report_item.plugin_name - description = data.get('description', '') - resolution = data.get('solution', '') - data_pluin_ouput = data.get('plugin_output', '') - if 'cvss_base_score' in data: - cvss_base_score = f"CVSS:{data['cvss_base_score']}" - ref.append(cvss_base_score) - if 'cvss_vector' in data: - cvss_vector = f"CVSSVECTOR:{data['cvss_vector']}" - ref.append(cvss_vector) - if 'see_also' in data: - ref.append(data['see_also']) - if 'cpe' in data: - ref.append(data['cpe']) - if 'xref' in data: - ref.append(data['xref']) - - service_id = self.createAndAddServiceToHost(host_id, name=item_name, protocol=item_protocol, - ports=item_port) - + _main_data["service_id"] = self.createAndAddServiceToHost( + host_id, name=item_name, protocol=item.protocol_attr, + ports=item.port_attr) if item_name == 'www' or item_name == 'http': - self.createAndAddVulnWebToService(host_id, - service_id, - name=vulnerability_name, - desc=description, - data=data_pluin_ouput, - severity=risk_factor, - resolution=resolution, - ref=ref, - external_id=external_id, - website=website, - run_date=run_date) + _main_data.update({"website": website}) + self.createAndAddVulnWebToService(**_main_data) else: - self.createAndAddVulnToService(host_id, - service_id, - name=vulnerability_name, - severity=risk_factor, - desc=description, - ref=ref, - data=data_pluin_ouput, - external_id=external_id, - resolution=resolution, - run_date=run_date) + self.createAndAddVulnToService(**_main_data) + + @staticmethod + def map_add_ref(kwargs, item: ReportItem): + + if item.cvss_vector: + kwargs["ref"].append(item.cvss_vector) + if item.see_also: + kwargs["ref"].append(item.see_also) + if item.cpe: + kwargs["ref"].append(item.cpe) + if item.xref: + kwargs["ref"].append(item.xref) + if item.cve: + kwargs["ref"] = kwargs["ref"] + item.cve + if item.cvss3_base_score: + kwargs["ref"].append(item.cvss3_base_score) + if item.cvss3_vector: + kwargs["ref"].append(item.cvss3_vector) + + return kwargs def createPlugin(ignore_info=False): From 8123fec64ea9347886d153a61dc9cc2b11dccda2 Mon Sep 17 00:00:00 2001 From: Manuel Jose Sotomayor Torrealba Date: Fri, 23 Apr 2021 15:20:10 -0300 Subject: [PATCH 194/698] repair flake8 --- faraday_plugins/plugins/repo/nessus/DTO.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faraday_plugins/plugins/repo/nessus/DTO.py b/faraday_plugins/plugins/repo/nessus/DTO.py index 6d638dbc..599c99fe 100644 --- a/faraday_plugins/plugins/repo/nessus/DTO.py +++ b/faraday_plugins/plugins/repo/nessus/DTO.py @@ -52,6 +52,7 @@ def plugin_name_attr(self): @property def plugin_family_attr(self): return self.node.get("pluginFamily") + @property def agent(self): return self.node.findtext("agent") @@ -115,7 +116,6 @@ def plugin_output(self): def always_run(self): return self.node.findtext("always_run") - @property def asset_inventory(self): return self.node.findtext("asset_inventory") From 3ada4d9654ee28d2bff888a21ffc452f3d0fe330 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Mon, 26 Apr 2021 16:37:11 -0300 Subject: [PATCH 195/698] add support for nuclei 2.3.0 --- CHANGELOG/current/update_nuclei.md | 1 + faraday_plugins/plugins/repo/nuclei/plugin.py | 120 +++++++++--------- 2 files changed, 59 insertions(+), 62 deletions(-) create mode 100644 CHANGELOG/current/update_nuclei.md diff --git a/CHANGELOG/current/update_nuclei.md b/CHANGELOG/current/update_nuclei.md new file mode 100644 index 00000000..f0ff714a --- /dev/null +++ b/CHANGELOG/current/update_nuclei.md @@ -0,0 +1 @@ +Support for nuclei 2.3.0 diff --git a/faraday_plugins/plugins/repo/nuclei/plugin.py b/faraday_plugins/plugins/repo/nuclei/plugin.py index 01e32134..e11dbc2b 100644 --- a/faraday_plugins/plugins/repo/nuclei/plugin.py +++ b/faraday_plugins/plugins/repo/nuclei/plugin.py @@ -6,26 +6,22 @@ """ import socket import json +import dateutil +from collections import defaultdict from urllib.parse import urlparse from faraday_plugins.plugins.plugin import PluginMultiLineJsonFormat from faraday_plugins.plugins.plugins_utils import resolve_hostname -__author__ = "Blas Moyano" -__copyright__ = "Copyright (c) 2020, Infobyte LLC" -__credits__ = ["Blas Moyano"] +__author__ = "Nicolas Rebagliati" +__copyright__ = "Copyright (c) 2021, Infobyte LLC" +__credits__ = ["Nicolas Rebagliati"] __license__ = "" __version__ = "0.0.1" -__maintainer__ = "Blas Moyano" -__email__ = "bmoyano@infobytesec.com" +__maintainer__ = "Nicolas Rebagliati" +__email__ = "nrebagliati@infobytesec.com" __status__ = "Development" -class NucleiJsonParser: - - def __init__(self, json_output): - self.list_to_vulns = json_output.split("\n") - - class NucleiPlugin(PluginMultiLineJsonFormat): """ Handle the Nuclei tool. Detects the output of the tool and adds the information to Faraday. @@ -36,68 +32,68 @@ def __init__(self, *arg, **kwargs): self.id = "nuclei" self.name = "Nuclei" self.plugin_version = "0.1" - self.version = "0.0.1" - self.json_keys = {"matched", "template"} + self.version = "2.3.0" + self.json_keys = {"matched", "templateID", "host"} def parseOutputString(self, output, debug=False): - parser = NucleiJsonParser(output) - matched_list = [] - matched_json = {} - for vuln in parser.list_to_vulns: - if vuln != '': - json_vuln = json.loads(vuln) - matched = json_vuln.get('matched', None) - - if matched is not None: - url_parser = urlparse(matched) - url_scheme = f'{url_parser.scheme}://{url_parser.hostname}' - - if url_scheme in matched_list: - matched_json[url_scheme].append(json_vuln) - else: - matched_list.append(url_scheme) - matched_json[url_scheme] = [json_vuln] - - for url in matched_list: - url_data = urlparse(url) - url_name = url_data.hostname - url_protocol = url_data.scheme - ip = resolve_hostname(url_name) + for vuln_json in filter(lambda x: x != '', output.split("\n")): + vuln_dict = json.loads(vuln_json) + host = vuln_dict.get('host') + url_data = urlparse(host) + ip = vuln_dict.get("ip", resolve_hostname(url_data.hostname)) host_id = self.createAndAddHost( name=ip, - hostnames=[url_name]) - port = 80 - if url_parser.scheme == 'https': - port = 443 - + hostnames=[url_data.hostname]) + port = url_data.port + if not port: + if url_data.scheme == 'https': + port = 443 + else: + port = 80 service_id = self.createAndAddServiceToHost( host_id, - name=url_parser.scheme, + name=url_data.scheme, ports=port, protocol="tcp", status='open', version='', - description='') + description='web server') + matched = vuln_dict.get('matched') + matched_data = urlparse(matched) + references = [f"author: {vuln_dict['info'].get('author', '')}"] + request = vuln_dict.get('request', '') + if request: + method = request.split(" ")[0] + else: + method = "" + data = [f"Matched: {vuln_dict.get('matched')}", + f"Tags: {vuln_dict['info'].get('tags')}", + f"Template ID: {vuln_dict['templateID']}"] + + name = vuln_dict["info"].get("name") + run_date = vuln_dict.get('timestamp') + if run_date: + run_date = dateutil.parser.parse(run_date) + self.createAndAddVulnWebToService( + host_id, + service_id, + name=name, + desc=vuln_dict["info"].get("description", name), + ref=references, + severity=vuln_dict["info"].get('severity'), + website=host, + request=request, + response=vuln_dict.get('response', ''), + method=method, + query=matched_data.query, + params=matched_data.params, + path=matched_data.path, + data="\n".join(data), + external_id=f"NUCLEI-{vuln_dict.get('templateID', '')}", + run_date=run_date + ) + - for info_vuln in matched_json[url]: - desc = f'{info_vuln.get("template", None)} - {info_vuln.get("author", None)}' - if info_vuln.get("author", None): - ref = [f"author: {info_vuln.get('author', None)}"] - else: - ref = None - self.createAndAddVulnWebToService( - host_id, - service_id, - name=info_vuln.get('template', ""), - desc=info_vuln.get('description', info_vuln.get('name', None)), - ref=ref, - severity=info_vuln.get('severity', ""), - website=url, - request=info_vuln.get('request', None), - response=info_vuln.get('response', None), - method=info_vuln.get('type', None), - data=info_vuln.get('matcher_name', info_vuln.get('name', None)), - external_id=info_vuln.get('template', "")) def createPlugin(ignore_info=False): From cab9fe23c594e2777326c57af649d172e52f40e1 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Mon, 26 Apr 2021 16:41:33 -0300 Subject: [PATCH 196/698] add licencese --- COPYING | 674 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ setup.py | 2 +- 2 files changed, 675 insertions(+), 1 deletion(-) create mode 100644 COPYING diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..f288702d --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 3 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/setup.py b/setup.py index d3654f8a..72afa27c 100644 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ version=version, packages=find_packages(include=['faraday_plugins', 'faraday_plugins.*']), url='', - license='', + license="GNU General Public License v3", author='Faradaysec', author_email='devel@faradaysec.com', description='Faraday plugins package', From 87e9d0a5ccb0c2e15e311fb119ff3616efeb63f4 Mon Sep 17 00:00:00 2001 From: Manuel Jose Sotomayor Torrealba Date: Mon, 26 Apr 2021 18:16:53 -0300 Subject: [PATCH 197/698] removing the text in the changelog --- ...of_owasp_and_zap_we_might_get_more_data.md | 26 +------------------ 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/CHANGELOG/current/when_import_reports_of_owasp_and_zap_we_might_get_more_data.md b/CHANGELOG/current/when_import_reports_of_owasp_and_zap_we_might_get_more_data.md index 24c06bea..d9d98473 100644 --- a/CHANGELOG/current/when_import_reports_of_owasp_and_zap_we_might_get_more_data.md +++ b/CHANGELOG/current/when_import_reports_of_owasp_and_zap_we_might_get_more_data.md @@ -1,25 +1 @@ -FIX a validation to get the info "method" from the .xml changing the function from find to findtext - -ADD the info of "attack" and "param" into data to show more info - -CHANGE the structure of the reference CWE from CWE-12 to CWE:12 - -REPAIR some pylint with static_method, removing the try and except - -CHANGE the function to extract params from url with a regex - -FIX service name was hardcoded, now is set by report information - -FIX references are now added in the proper - -FIX readability of the descriptions, remediation & reference by stripping html tags - -ADD now data includes the affected URL, Evidence & Affected Parameter when possible - -ADD new function to strip html tags - -ADD included information in reference for WASC - -ADD ZAP pluginid into external_id - -CHANGE external_id to the correct Structure ZAP-XXXX +ADD more data like attack, params, uri, method, WASC, CWE and format externail_id \ No newline at end of file From b4e6fa460442d49161d8ae3d46da436c4f849a21 Mon Sep 17 00:00:00 2001 From: Manuel Jose Sotomayor Torrealba Date: Mon, 26 Apr 2021 21:19:37 -0300 Subject: [PATCH 198/698] removing import xml.etree.ElementTree as ET, some unused variables and unused import, some code smell and unnecesary listcompression --- faraday_plugins/commands.py | 9 +- faraday_plugins/plugins/manager.py | 22 +- faraday_plugins/plugins/plugin.py | 44 +- faraday_plugins/plugins/plugins_utils.py | 22 +- .../plugins/repo/acunetix/plugin.py | 26 +- faraday_plugins/plugins/repo/amap/plugin.py | 20 +- .../plugins/repo/appscan/plugin.py | 34 +- .../plugins/repo/appspider/plugin.py | 45 +- .../plugins/repo/arachni/plugin.py | 23 +- faraday_plugins/plugins/repo/beef/plugin.py | 3 - faraday_plugins/plugins/repo/burp/plugin.py | 13 +- .../plugins/repo/checkmarx/plugin.py | 13 +- .../plugins/repo/dnsenum/plugin.py | 13 +- .../plugins/repo/dnsrecon/plugin.py | 15 +- faraday_plugins/plugins/repo/hydra/plugin.py | 3 +- faraday_plugins/plugins/repo/impact/plugin.py | 14 +- faraday_plugins/plugins/repo/junit/plugin.py | 10 +- .../plugins/repo/maltego/plugin.py | 20 +- faraday_plugins/plugins/repo/medusa/plugin.py | 3 +- .../plugins/repo/metasploit/plugin.py | 14 +- faraday_plugins/plugins/repo/ncrack/plugin.py | 7 +- faraday_plugins/plugins/repo/ndiff/plugin.py | 6 +- .../plugins/repo/netsparker/plugin.py | 10 +- .../plugins/repo/netsparkercloud/plugin.py | 15 +- .../plugins/repo/nexpose_full/plugin.py | 27 +- faraday_plugins/plugins/repo/nikto/plugin.py | 17 +- faraday_plugins/plugins/repo/nmap/plugin.py | 10 +- .../plugins/repo/openscap/plugin.py | 9 +- .../plugins/repo/openvas/plugin.py | 13 +- .../plugins/repo/qualysguard/plugin.py | 4 - .../plugins/repo/qualyswebapp/plugin.py | 8 +- faraday_plugins/plugins/repo/retina/plugin.py | 16 +- .../plugins/repo/skipfish/plugin.py | 16 +- faraday_plugins/plugins/repo/w3af/plugin.py | 10 +- faraday_plugins/plugins/repo/wapiti/plugin.py | 13 +- faraday_plugins/plugins/repo/wcscan/plugin.py | 10 +- .../plugins/repo/webinspect/plugin.py | 5 +- faraday_plugins/plugins/repo/x1/plugin.py | 24 +- .../plugins/repo/zap/java/Configuration.java | 163 ----- .../repo/zap/java/ConfigurationDialog.java | 589 ------------------ .../plugins/repo/zap/java/FaradayClient.java | 525 ---------------- .../repo/zap/java/FaradayExtension.java | 167 ----- .../plugins/repo/zap/java/Messages.properties | 56 -- .../repo/zap/java/PopupMenuItemSendAlert.java | 149 ----- .../zap/java/PopupMenuItemSendRequest.java | 137 ---- .../plugins/repo/zap/java/ZapAddOn.xml | 14 - faraday_plugins/plugins/repo/zap/plugin.py | 22 +- faraday_plugins/plugins/repo/zap/report.xml | 166 ----- .../plugins/repo/zap/zap-plugin.zap | Bin 39106 -> 0 bytes 49 files changed, 181 insertions(+), 2393 deletions(-) delete mode 100755 faraday_plugins/plugins/repo/zap/java/Configuration.java delete mode 100755 faraday_plugins/plugins/repo/zap/java/ConfigurationDialog.java delete mode 100755 faraday_plugins/plugins/repo/zap/java/FaradayClient.java delete mode 100755 faraday_plugins/plugins/repo/zap/java/FaradayExtension.java delete mode 100755 faraday_plugins/plugins/repo/zap/java/Messages.properties delete mode 100755 faraday_plugins/plugins/repo/zap/java/PopupMenuItemSendAlert.java delete mode 100755 faraday_plugins/plugins/repo/zap/java/PopupMenuItemSendRequest.java delete mode 100755 faraday_plugins/plugins/repo/zap/java/ZapAddOn.xml delete mode 100644 faraday_plugins/plugins/repo/zap/report.xml delete mode 100644 faraday_plugins/plugins/repo/zap/zap-plugin.zap diff --git a/faraday_plugins/commands.py b/faraday_plugins/commands.py index a498fa31..b120a970 100644 --- a/faraday_plugins/commands.py +++ b/faraday_plugins/commands.py @@ -1,12 +1,13 @@ +import getpass import io +import json import logging import os +import shlex +import subprocess import sys -import json + import click -import subprocess -import shlex -import getpass from faraday_plugins.plugins.manager import PluginsManager, ReportAnalyzer, CommandAnalyzer from faraday_plugins.plugins.plugin import PluginByExtension diff --git a/faraday_plugins/plugins/manager.py b/faraday_plugins/plugins/manager.py index 66069896..403e0cee 100644 --- a/faraday_plugins/plugins/manager.py +++ b/faraday_plugins/plugins/manager.py @@ -1,26 +1,21 @@ +import csv +import json import logging -import traceback -import re import os -import sys -import json import pkgutil +import re +import sys +import traceback +import xml.etree.ElementTree as ET import zipfile from importlib import import_module from importlib.machinery import SourceFileLoader -import csv from io import StringIO from . import repo logger = logging.getLogger("faraday").getChild(__name__) -try: - import xml.etree.cElementTree as ET -except ImportError: - logger.warning("cElementTree could not be imported. Using ElementTree instead") - import xml.etree.ElementTree as ET - class ReportAnalyzer: @@ -35,7 +30,7 @@ def get_plugin(self, report_path): else: file_name = os.path.basename(report_path) plugin = self._get_plugin_by_name(file_name) - if not plugin: # Was unable to detect plugin from report file name + if not plugin: # Was unable to detect plugin from report file name logger.debug("Plugin by name not found") plugin = self._get_plugin_by_file_type(report_path) if not plugin: @@ -68,7 +63,6 @@ def _get_plugin_by_file_type(self, report_path): file_name_base, file_extension = os.path.splitext(file_name) file_extension = file_extension.lower() main_tag = None - file_json_keys = {} file_csv_headers = set() file_json_keys = set() files_in_zip = set() @@ -151,7 +145,7 @@ def get_plugin(self, command_string): class PluginsManager: - def __init__(self, custom_plugins_folder=None, ignore_info = False): + def __init__(self, custom_plugins_folder=None, ignore_info=False): self.ignore_info = ignore_info self.plugins = {} self.plugin_modules = {} diff --git a/faraday_plugins/plugins/plugin.py b/faraday_plugins/plugins/plugin.py index 90cd541f..ec6d468c 100644 --- a/faraday_plugins/plugins/plugin.py +++ b/faraday_plugins/plugins/plugin.py @@ -4,27 +4,26 @@ See the file 'doc/LICENSE' for the license information """ +import hashlib +import logging import os +import re import shutil import tempfile - -from collections import defaultdict - -import pytz -import re import uuid -import logging -import simplejson as json import zipfile +from collections import defaultdict from datetime import datetime -import hashlib +import pytz +import simplejson as json logger = logging.getLogger("faraday").getChild(__name__) VALID_SERVICE_STATUS = ("open", "closed", "filtered") VULN_SKIP_FIELDS_TO_HASH = ['run_date'] + class PluginBase: # TODO: Add class generic identifier class_signature = "PluginBase" @@ -102,6 +101,7 @@ def align_string_based_vulns(severity): if severity[0:3] in sev: return sev return severity + severity = align_string_based_vulns(severity) # Transform numeric severity into desc severity numeric_severities = {"0": "info", @@ -170,7 +170,6 @@ def save_host_vuln_cache(self, host_id, vuln): def _get_dict_hash(d, keys): return hash(frozenset(map(lambda x: (x, d.get(x, None)), keys))) - @classmethod def get_host_cache_id(cls, host): cache_id = cls._get_dict_hash(host, ['ip']) @@ -187,14 +186,17 @@ def get_host_service_cache_id(cls, host_id, service): def get_service_vuln_cache_id(cls, host_id, service_id, vuln): vuln_copy = vuln.copy() vuln_copy.update({"host_cache_id": host_id, "service_cache_id": service_id}) - cache_id = cls._get_dict_hash(vuln_copy, ['host_cache_id', 'service_cache_id', 'name', 'desc', 'website', 'path', 'pname', 'method']) + cache_id = cls._get_dict_hash(vuln_copy, + ['host_cache_id', 'service_cache_id', 'name', 'desc', 'website', 'path', 'pname', + 'method']) return cache_id @classmethod def get_host_vuln_cache_id(cls, host_id, vuln): vuln_copy = vuln.copy() vuln_copy.update({"host_cache_id": host_id}) - cache_id = cls._get_dict_hash(vuln_copy, ['host_cache_id', 'name', 'desc', 'website', 'path', 'pname', 'method']) + cache_id = cls._get_dict_hash(vuln_copy, + ['host_cache_id', 'name', 'desc', 'website', 'path', 'pname', 'method']) return cache_id def save_cache(self, obj): @@ -228,7 +230,7 @@ def getSettings(self): for param, (param_type, value) in self._settings.items(): yield param, value - def get_ws(self): # TODO Borrar + def get_ws(self): # TODO Borrar return "" def getSetting(self, name): @@ -334,15 +336,15 @@ def createAndAddHost(self, name, os="unknown", hostnames=None, mac=None, descrip tags = [] if isinstance(tags, str): tags = [tags] - host = {"ip": name, "os": os, "hostnames": hostnames, "description": description, "mac": mac, + host = {"ip": name, "os": os, "hostnames": hostnames, "description": description, "mac": mac, "credentials": [], "services": [], "vulnerabilities": [], "tags": tags} host_id = self.save_host_cache(host) return host_id def createAndAddServiceToHost(self, host_id, name, - protocol="tcp", ports=None, - status="open", version="unknown", - description="", tags=None): + protocol="tcp", ports=None, + status="open", version="unknown", + description="", tags=None): if ports: if isinstance(ports, list): ports = int(ports[0]) @@ -412,7 +414,8 @@ def createAndAddVulnToService(self, host_id, service_id, name, desc="", tags = [tags] vulnerability = {"name": name, "desc": desc, "severity": self.normalize_severity(severity), "refs": ref, "external_id": external_id, "type": "Vulnerability", "resolution": resolution, "data": data, - "custom_fields": custom_fields, "status": status, "impact": impact, "policyviolations": policyviolations, + "custom_fields": custom_fields, "status": status, "impact": impact, + "policyviolations": policyviolations, "easeofresolution": easeofresolution, "confirmed": confirmed, "tags": tags } if run_date: @@ -426,7 +429,8 @@ def createAndAddVulnWebToService(self, host_id, service_id, name, desc="", response="", method="", pname="", params="", query="", category="", data="", external_id=None, confirmed=False, status="", easeofresolution=None, impact=None, - policyviolations=None, status_code=None, custom_fields=None, run_date=None, tags=None): + policyviolations=None, status_code=None, custom_fields=None, run_date=None, + tags=None): if params is None: params = "" if response is None: @@ -476,7 +480,6 @@ def createAndAddVulnWebToService(self, host_id, service_id, name, desc="", def createAndAddNoteToHost(self, host_id, name, text): return None - def createAndAddNoteToService(self, host_id, service_id, name, text): return None @@ -529,6 +532,7 @@ def get_summary(self): summary['vuln_hashes'].append(dict_hash) return summary + # TODO Borrar class PluginTerminalOutput(PluginBase): def __init__(self): @@ -667,5 +671,3 @@ def report_belongs_to(self, files_in_zip=None, **kwargs): match = bool(self.files_list & files_in_zip) self.logger.debug("Files List Match: [%s =/in %s] -> %s", files_in_zip, self.files_list, match) return match - - diff --git a/faraday_plugins/plugins/plugins_utils.py b/faraday_plugins/plugins/plugins_utils.py index 81f21c41..a89525d7 100644 --- a/faraday_plugins/plugins/plugins_utils.py +++ b/faraday_plugins/plugins/plugins_utils.py @@ -4,14 +4,11 @@ See the file 'doc/LICENSE' for the license information """ -import os import logging +import os import socket -from collections import defaultdict - from urllib.parse import urlsplit - SERVICE_MAPPER = None logger = logging.getLogger(__name__) @@ -24,7 +21,8 @@ def get_vulnweb_url_fields(url): "website": "{}://{}".format(parse.scheme, parse.netloc), "path": parse.path, "query": parse.query - } + } + def filter_services(): global SERVICE_MAPPER @@ -111,19 +109,19 @@ def resolve_hostname(hostname): else: return ip_address + def get_severity_from_cvss(cvss): try: if type(cvss) != float: cvss = float(cvss) - - cvss_ranges = [(0.0, 0.1, 'info'), - (0.1, 4.0, 'low'), - (4.0, 7.0, 'med'), - (7.0, 9.0, 'high'), - (9.0, 10.1, 'critical')] + + cvss_ranges = [(0.0, 0.1, 'info'), + (0.1, 4.0, 'low'), + (4.0, 7.0, 'med'), + (7.0, 9.0, 'high'), + (9.0, 10.1, 'critical')] for (lower, upper, severity) in cvss_ranges: if lower <= cvss < upper: return severity except ValueError: return 'unclassified' - diff --git a/faraday_plugins/plugins/repo/acunetix/plugin.py b/faraday_plugins/plugins/repo/acunetix/plugin.py index 6c8004df..939b4e2d 100644 --- a/faraday_plugins/plugins/repo/acunetix/plugin.py +++ b/faraday_plugins/plugins/repo/acunetix/plugin.py @@ -4,25 +4,18 @@ See the file 'doc/LICENSE' for the license information """ -from urllib.parse import urlsplit import re -import os +import xml.etree.ElementTree as ET +from urllib.parse import urlsplit from lxml import etree -try: - import xml.etree.cElementTree as ET - import xml.etree.ElementTree as ET_ORIG - ETREE_VERSION = ET_ORIG.VERSION -except ImportError: - import xml.etree.ElementTree as ET - ETREE_VERSION = ET.VERSION - from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import resolve_hostname -ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] +ETREE_VERSION = ET.VERSION +ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] __author__ = "Francisco Amato" __copyright__ = "Copyright (c) 2013, Infobyte LLC" @@ -53,7 +46,8 @@ def __init__(self, xml_output): else: self.sites = [] - def parse_xml(self, xml_output): + @staticmethod + def parse_xml(xml_output): """ Open and parse an xml file. @@ -71,7 +65,8 @@ def parse_xml(self, xml_output): return tree - def get_items(self, tree): + @staticmethod + def get_items(tree): """ @return items A list of Host instances """ @@ -287,9 +282,6 @@ def parseOutputString(self, output): ref=item.ref) del parser - def setHost(self): - pass - def createPlugin(ignore_info=False): - return AcunetixPlugin(ignore_info=ignore_info) \ No newline at end of file + return AcunetixPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/amap/plugin.py b/faraday_plugins/plugins/repo/amap/plugin.py index 54714eaa..1d680477 100644 --- a/faraday_plugins/plugins/repo/amap/plugin.py +++ b/faraday_plugins/plugins/repo/amap/plugin.py @@ -4,17 +4,11 @@ See the file 'doc/LICENSE' for the license information """ import argparse -import random +import re import shlex -import tempfile - -from faraday_plugins.plugins.plugin import PluginBase import socket -import re -import os - -from faraday_plugins.plugins.plugins_utils import resolve_hostname +from faraday_plugins.plugins.plugin import PluginBase class AmapPlugin(PluginBase): @@ -31,6 +25,7 @@ def __init__(self, *arg, **kwargs): self._command_regex = re.compile(r'^(amap|sudo amap)\s+.*?') self._use_temp_file = True self._hosts = [] + self.args = None def parseOutputString(self, output): services = {} @@ -107,9 +102,6 @@ def get_ip_6(self, host, port=0): return ip6[0][4][0] - def setHost(self): - pass - def processCommandString(self, username, current_path, command_string): """ Adds the -m parameter to get machine readable output. @@ -136,18 +128,14 @@ def processCommandString(self, username, current_path, command_string): cmd.remove("-6") cmd.insert(1, "-6") - args = None if len(cmd) > 4: try: - args, unknown = parser.parse_known_args(cmd) + self.args, unknown = parser.parse_known_args(cmd) except SystemExit: pass - self.args = args return final def createPlugin(ignore_info=False): return AmapPlugin(ignore_info=ignore_info) - - diff --git a/faraday_plugins/plugins/repo/appscan/plugin.py b/faraday_plugins/plugins/repo/appscan/plugin.py index 6edc7d0e..ed755f19 100644 --- a/faraday_plugins/plugins/repo/appscan/plugin.py +++ b/faraday_plugins/plugins/repo/appscan/plugin.py @@ -1,12 +1,9 @@ +from urllib.parse import urlparse + from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import resolve_hostname -import dateutil.parser -from urllib.parse import urlparse -try: - import xml.etree.cElementTree as ET -except ImportError: - import xml.etree.ElementTree as ET +import xml.etree.ElementTree as ET __author__ = "Nicolas Rebagliati" __copyright__ = "Copyright (c) 2021, Infobyte LLC" @@ -33,9 +30,8 @@ def __init__(self, xml_output): self.entities = self.get_entity_groups(tree.find('entity-group')) self.issues = self.get_dast_issues(tree.find("issue-group")) - - - def parse_xml(self, xml_output): + @staticmethod + def parse_xml(xml_output): try: tree = ET.fromstring(xml_output) except SyntaxError as err: @@ -43,7 +39,8 @@ def parse_xml(self, xml_output): return None return tree - def get_fixes(self, tree): + @staticmethod + def get_fixes(tree): fixes = {} for item in tree: fix_id = item.attrib['id'] @@ -52,7 +49,8 @@ def get_fixes(self, tree): fixes[fix_id] = {"library": library, "location": location} return fixes - def get_issue_types(self, tree): + @staticmethod + def get_issue_types(tree): issue_types = {} for item in tree: type_id = item.attrib['id'] @@ -60,7 +58,8 @@ def get_issue_types(self, tree): issue_types[type_id] = name return issue_types - def get_remediations(self, tree): + @staticmethod + def get_remediations(tree): remediations = {} for item in tree: remediation_id = item.attrib['id'] @@ -68,7 +67,8 @@ def get_remediations(self, tree): remediations[remediation_id] = name return remediations - def get_hosts(self, tree): + @staticmethod + def get_hosts(tree): hosts = {} for item in tree: host = item.find("host").text @@ -84,7 +84,8 @@ def get_hosts(self, tree): "service_name": service_name} return hosts - def get_entity_groups(self, tree): + @staticmethod + def get_entity_groups(tree): entity_groups = {} for item in tree: entity_id = item.attrib['id'] @@ -238,7 +239,6 @@ def get_sast_issues(self, tree): return sast_issues - class AppScanPlugin(PluginXMLFormat): def __init__(self, *arg, **kwargs): @@ -250,17 +250,15 @@ def __init__(self, *arg, **kwargs): self.version = '1.0.0' self.framework_version = '1.0.0' - def parseOutputString(self, output): parser = AppScanParser(output) scan_type = parser.scan_type - if scan_type == 'DAST': for issue in parser.issues: host = issue.pop("host") port = issue.pop("port") - host_os = issue.pop("os") + issue.pop("os") service_name = issue.pop("service_name") ip = resolve_hostname(host) host_id = self.createAndAddHost(ip, hostnames=host) diff --git a/faraday_plugins/plugins/repo/appspider/plugin.py b/faraday_plugins/plugins/repo/appspider/plugin.py index e1f98c8a..89dae76e 100644 --- a/faraday_plugins/plugins/repo/appspider/plugin.py +++ b/faraday_plugins/plugins/repo/appspider/plugin.py @@ -5,12 +5,10 @@ Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/) See the file 'doc/LICENSE' for the license information """ -from faraday_plugins.plugins.plugin import PluginXMLFormat +import xml.etree.ElementTree as ET from datetime import datetime -try: - import xml.etree.cElementTree as ET -except ImportError: - import xml.etree.ElementTree as ET + +from faraday_plugins.plugins.plugin import PluginXMLFormat __author__ = 'Blas Moyano' __copyright__ = 'Copyright 2020, Faraday Project' @@ -25,11 +23,12 @@ def __init__(self, xml_output): self.tree = self.parse_xml(xml_output) if self.tree: self.vuln_list = self.tree.find('VulnList') - self.name_scan = self.tree.find('ScanName').text + self.name_scan = self.tree.findtext('ScanName') else: self.tree = None - def parse_xml(self, xml_output): + @staticmethod + def parse_xml(xml_output): try: tree = ET.fromstring(xml_output) except SyntaxError as err: @@ -72,22 +71,22 @@ def parseOutputString(self, output): data_info = [] for vulns in parser.vuln_list: - vuln_name = vulns.find('VulnType').text - vuln_desc = vulns.find('Description').text - vuln_ref = vulns.find('VulnUrl').text - severity = vulns.find('AttackScore').text - vuln_resolution = vulns.find('Recommendation').text - vuln_external_id = vulns.find('DbId').text - vuln_run_date = vulns.find('ScanDate').text - data_info.append(vulns.find('AttackClass').text) - data_info.append(vulns.find('CweId').text) - data_info.append(vulns.find('CAPEC').text) - data_info.append(vulns.find('DISSA_ASC').text) - data_info.append(vulns.find('OWASP2007').text) - data_info.append(vulns.find('OWASP2010').text) - data_info.append(vulns.find('OWASP2013').text) - data_info.append(vulns.find('OVAL').text) - data_info.append(vulns.find('WASC').text) + vuln_name = vulns.findtext('VulnType') + vuln_desc = vulns.findtext('Description') + vuln_ref = vulns.findtext('VulnUrl') + severity = vulns.findtext('AttackScore') + vuln_resolution = vulns.findtext('Recommendation') + vuln_external_id = vulns.findtext('DbId') + vuln_run_date = vulns.findtext('ScanDate') + data_info.append(vulns.findtext('AttackClass')) + data_info.append(vulns.findtext('CweId')) + data_info.append(vulns.findtext('CAPEC')) + data_info.append(vulns.findtext('DISSA_ASC')) + data_info.append(vulns.findtext('OWASP2007')) + data_info.append(vulns.findtext('OWASP2010')) + data_info.append(vulns.findtext('OWASP2013')) + data_info.append(vulns.findtext('OVAL')) + data_info.append(vulns.findtext('WASC')) if severity == '1-Informational': severity = 0 diff --git a/faraday_plugins/plugins/repo/arachni/plugin.py b/faraday_plugins/plugins/repo/arachni/plugin.py index 4db7d7b8..8bba46d0 100755 --- a/faraday_plugins/plugins/repo/arachni/plugin.py +++ b/faraday_plugins/plugins/repo/arachni/plugin.py @@ -3,17 +3,14 @@ Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/) See the file 'doc/LICENSE' for the license information """ +import os import re +import xml.etree.ElementTree as ET from urllib.parse import urlparse -import os + from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import resolve_hostname -try: - import xml.etree.cElementTree as ET -except ImportError: - import xml.etree.ElementTree as ET - __author__ = 'Ezequiel Tavella' __copyright__ = 'Copyright 2016, Faraday Project' __credits__ = ['Ezequiel Tavella', 'MatĂ­as Ariel RĂ© Medina', 'Conrad Stein K'] @@ -200,7 +197,6 @@ def getOptions(self): else: options_string = None - try: self.user_agent = self.node.find('user_agent').text except: @@ -231,17 +227,16 @@ def getDesc(self, tag): def getNote(self): result = ('Scan url:\n {} \nUser Agent:\n {} \nVersion Arachni:\n {} \nStart time:\n {} \nFinish time:\n {}' - '\nAudited Elements:\n {} \nModules:\n {} \nCookies:\n {}').format(self.url, self.user_agent, - self.version, self.start_time, - self.finish_time, - self.audited_elements, - self.modules, self.cookies) + '\nAudited Elements:\n {} \nModules:\n {} \nCookies:\n {}').format(self.url, self.user_agent, + self.version, self.start_time, + self.finish_time, + self.audited_elements, + self.modules, self.cookies) return result class Plugins(): - """ Support: WAF (Web Application Firewall) Detector (waf_detector) @@ -493,5 +488,3 @@ def getHostname(self, url): def createPlugin(ignore_info=False): return ArachniPlugin(ignore_info=ignore_info) - - diff --git a/faraday_plugins/plugins/repo/beef/plugin.py b/faraday_plugins/plugins/repo/beef/plugin.py index f84fbcb8..debb4a63 100644 --- a/faraday_plugins/plugins/repo/beef/plugin.py +++ b/faraday_plugins/plugins/repo/beef/plugin.py @@ -95,9 +95,6 @@ def parseOutputString(self, output): severity=3) - def setHost(self): - pass - def createPlugin(ignore_info=False): return BeefPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/burp/plugin.py b/faraday_plugins/plugins/repo/burp/plugin.py index 52927343..72c24fae 100644 --- a/faraday_plugins/plugins/repo/burp/plugin.py +++ b/faraday_plugins/plugins/repo/burp/plugin.py @@ -12,14 +12,8 @@ from urllib.parse import urlsplit import distutils.util #pylint: disable=import-error - -try: - import xml.etree.cElementTree as ET - import xml.etree.ElementTree as ET_ORIG - ETREE_VERSION = ET_ORIG.VERSION -except ImportError: - import xml.etree.ElementTree as ET - ETREE_VERSION = ET.VERSION +import xml.etree.ElementTree as ET +ETREE_VERSION = ET.VERSION ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] @@ -292,9 +286,6 @@ def removeHtml(self, markup): return str(soup) - def setHost(self): - pass - def createPlugin(ignore_info=False): return BurpPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/checkmarx/plugin.py b/faraday_plugins/plugins/repo/checkmarx/plugin.py index ef7c0b76..06ed2080 100755 --- a/faraday_plugins/plugins/repo/checkmarx/plugin.py +++ b/faraday_plugins/plugins/repo/checkmarx/plugin.py @@ -3,17 +3,11 @@ Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/) See the file 'doc/LICENSE' for the license information """ -import re +import xml.etree.ElementTree as ET from urllib.parse import urlparse from faraday_plugins.plugins.plugin import PluginXMLFormat - -try: - import xml.etree.cElementTree as ET -except ImportError: - import xml.etree.ElementTree as ET - __author__ = 'Blas Moyano' __copyright__ = 'Copyright 2020, Faraday Project' __credits__ = ['Blas Moyano'] @@ -70,7 +64,8 @@ def get_path_node_info(self, path_node): for info_pn in pn: if info_pn.tag == 'Snippet': valor = ( - 'Number', info_pn.find('Line').find('Number').text, 'Code', info_pn.find('Line').find('Code').text) + 'Number', info_pn.find('Line').find('Number').text, 'Code', + info_pn.find('Line').find('Code').text) else: valor = (info_pn.tag, info_pn.text) lista_v.append(valor) @@ -90,7 +85,6 @@ def __init__(self, *arg, **kwargs): self.framework_version = '1.0.0' self.options = None - def parseOutputString(self, output): parser = CheckmarxXmlParser(output) if not parser.query: @@ -140,4 +134,3 @@ def parseOutputString(self, output): def createPlugin(ignore_info=False): return CheckmarxPlugin(ignore_info=ignore_info) - diff --git a/faraday_plugins/plugins/repo/dnsenum/plugin.py b/faraday_plugins/plugins/repo/dnsenum/plugin.py index bff14665..bd8416ef 100644 --- a/faraday_plugins/plugins/repo/dnsenum/plugin.py +++ b/faraday_plugins/plugins/repo/dnsenum/plugin.py @@ -7,14 +7,8 @@ from faraday_plugins.plugins.plugin import PluginBase import re import os - -try: - import xml.etree.cElementTree as ET - import xml.etree.ElementTree as ET_ORIG - ETREE_VERSION = ET_ORIG.VERSION -except ImportError: - import xml.etree.ElementTree as ET - ETREE_VERSION = ET.VERSION +import xml.etree.ElementTree as ET +ETREE_VERSION = ET.VERSION ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] @@ -193,9 +187,6 @@ def processCommandString(self, username, current_path, command_string): else: return re.sub(arg_match.group(1), r"-o %s" % self._output_file_path, command_string) - def setHost(self): - pass - def createPlugin(ignore_info=False): return DnsenumPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/dnsrecon/plugin.py b/faraday_plugins/plugins/repo/dnsrecon/plugin.py index 08a63463..2b2ac0c8 100644 --- a/faraday_plugins/plugins/repo/dnsrecon/plugin.py +++ b/faraday_plugins/plugins/repo/dnsrecon/plugin.py @@ -5,14 +5,8 @@ """ from faraday_plugins.plugins.plugin import PluginBase import re - -try: - import xml.etree.cElementTree as ET - import xml.etree.ElementTree as ET_ORIG - ETREE_VERSION = ET_ORIG.VERSION -except ImportError: - import xml.etree.ElementTree as ET - ETREE_VERSION = ET.VERSION +import xml.etree.ElementTree as ET +ETREE_VERSION = ET.VERSION ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] @@ -205,7 +199,7 @@ def parseOutputString(self, output): status="open") if host.zonetransfer == "success": - v_id = self.createAndAddVulnToService( + self.createAndAddVulnToService( h_id, s_id, name="Zone transfer", @@ -239,9 +233,6 @@ def processCommandString(self, username, current_path, command_string): r"--xml %s" % self._output_file_path, command_string) - def setHost(self): - pass - def createPlugin(ignore_info=False): return DnsreconPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/hydra/plugin.py b/faraday_plugins/plugins/repo/hydra/plugin.py index 841077d5..fab9a443 100644 --- a/faraday_plugins/plugins/repo/hydra/plugin.py +++ b/faraday_plugins/plugins/repo/hydra/plugin.py @@ -127,8 +127,7 @@ def _isIPV4(self, ip): else: return False - def setHost(self): - pass + def createPlugin(ignore_info=False): diff --git a/faraday_plugins/plugins/repo/impact/plugin.py b/faraday_plugins/plugins/repo/impact/plugin.py index 663b4859..440a2fd1 100644 --- a/faraday_plugins/plugins/repo/impact/plugin.py +++ b/faraday_plugins/plugins/repo/impact/plugin.py @@ -7,13 +7,8 @@ import re from faraday_plugins.plugins.plugin import PluginXMLFormat -try: - import xml.etree.cElementTree as ET - import xml.etree.ElementTree as ET_ORIG - ETREE_VERSION = ET_ORIG.VERSION -except ImportError: - import xml.etree.ElementTree as ET - ETREE_VERSION = ET.VERSION +import xml.etree.ElementTree as ET +ETREE_VERSION = ET.VERSION ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] @@ -42,7 +37,7 @@ class ImpactXmlParser: def __init__(self, xml_output): tree = self.parse_xml(xml_output) if tree: - self.items = [data for data in self.get_items(tree)] + self.items = self.get_items(tree) else: self.items = [] @@ -282,8 +277,7 @@ def parseOutputString(self, output): del parser - def setHost(self): - pass + def createPlugin(ignore_info=False): diff --git a/faraday_plugins/plugins/repo/junit/plugin.py b/faraday_plugins/plugins/repo/junit/plugin.py index fe9b2721..df1a551e 100644 --- a/faraday_plugins/plugins/repo/junit/plugin.py +++ b/faraday_plugins/plugins/repo/junit/plugin.py @@ -8,14 +8,8 @@ from lxml import etree from faraday_plugins.plugins.plugin import PluginXMLFormat - -try: - import xml.etree.cElementTree as ET - import xml.etree.ElementTree as ET_ORIG - ETREE_VERSION = ET_ORIG.VERSION -except ImportError: - import xml.etree.ElementTree as ET - ETREE_VERSION = ET.VERSION +import xml.etree.ElementTree as ET +ETREE_VERSION = ET.VERSION ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] diff --git a/faraday_plugins/plugins/repo/maltego/plugin.py b/faraday_plugins/plugins/repo/maltego/plugin.py index 5c55d140..4b185db4 100755 --- a/faraday_plugins/plugins/repo/maltego/plugin.py +++ b/faraday_plugins/plugins/repo/maltego/plugin.py @@ -3,24 +3,16 @@ Copyright (C) 2015 Infobyte LLC (http://www.infobytesec.com/) See the file 'doc/LICENSE' for the license information """ -from faraday_plugins.plugins.plugin import PluginZipFormat -import re -import os +import xml.etree.ElementTree as ET import zipfile +from faraday_plugins.plugins.plugin import PluginZipFormat from faraday_plugins.plugins.plugins_utils import resolve_hostname -try: - import xml.etree.cElementTree as ET - import xml.etree.ElementTree as ET_ORIG - ETREE_VERSION = ET_ORIG.VERSION -except ImportError: - import xml.etree.ElementTree as ET - ETREE_VERSION = ET.VERSION +ETREE_VERSION = ET.VERSION ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] - __author__ = "Ezequiel Tavella" __copyright__ = "Copyright (c) 2015, Infobyte LLC" __credits__ = ["Ezequiel Tavella"] @@ -171,7 +163,6 @@ def getIpAndId(self, node): "{http://graphml.graphdrawing.org/xmlns}data/" "{http://maltego.paterva.com/xml/mtgx}MaltegoEntity") - # Check if is IPv4Address if entity.get("type") not in ("maltego.IPv4Address", "maltego.Domain", "maltego.Website"): return None @@ -419,7 +410,7 @@ def parseOutputString(self, output): try: text = f'Location:\n {host.location["name"]} \nArea:\n {host.location["area"]} ' \ f'\nArea 2:\n {host.location["area_2"]} ' \ - f'\nCountry_code:\n { host.location["country_code"]} ' \ + f'\nCountry_code:\n {host.location["country_code"]} ' \ f'\nLatitude:\n {host.location["latitude"]} \nLongitude:\n {host.location["longitude"]}' except TypeError: text = "unknown" @@ -467,7 +458,6 @@ def parseOutputString(self, output): host_ip = '0.0.0.0' host_id = self.createAndAddHost(name=host_ip, hostnames=hostnames) - if maltego_parser.xml.get('location'): location_name = maltego_parser.getInfoMtgl(maltego_parser.xml['location'], 'location.name') location_area = maltego_parser.getInfoMtgl(maltego_parser.xml['location'], 'location.area') @@ -510,7 +500,5 @@ def parseOutputString(self, output): description="DNS Server") - - def createPlugin(ignore_info=False): return MaltegoPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/medusa/plugin.py b/faraday_plugins/plugins/repo/medusa/plugin.py index dae0e390..f56433cd 100644 --- a/faraday_plugins/plugins/repo/medusa/plugin.py +++ b/faraday_plugins/plugins/repo/medusa/plugin.py @@ -130,8 +130,7 @@ def _isIPV4(self, ip): else: return False - def setHost(self): - pass + def createPlugin(ignore_info=False): diff --git a/faraday_plugins/plugins/repo/metasploit/plugin.py b/faraday_plugins/plugins/repo/metasploit/plugin.py index 8d6d0372..299b3c68 100644 --- a/faraday_plugins/plugins/repo/metasploit/plugin.py +++ b/faraday_plugins/plugins/repo/metasploit/plugin.py @@ -6,14 +6,8 @@ from faraday_plugins.plugins.plugin import PluginXMLFormat import re - -try: - import xml.etree.cElementTree as ET - import xml.etree.ElementTree as ET_ORIG - ETREE_VERSION = ET_ORIG.VERSION -except ImportError: - import xml.etree.ElementTree as ET - ETREE_VERSION = ET.VERSION +import xml.etree.ElementTree as ET +ETREE_VERSION = ET.VERSION ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] @@ -399,10 +393,6 @@ def _isIPV4(self, ip): return False - def setHost(self): - pass - - def createPlugin(ignore_info=False): return MetasploitPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/ncrack/plugin.py b/faraday_plugins/plugins/repo/ncrack/plugin.py index 3b194e16..7c3611c6 100644 --- a/faraday_plugins/plugins/repo/ncrack/plugin.py +++ b/faraday_plugins/plugins/repo/ncrack/plugin.py @@ -5,12 +5,9 @@ """ -from faraday_plugins.plugins.plugin import PluginXMLFormat -try: - import xml.etree.cElementTree as ET -except ImportError: - import xml.etree.ElementTree as ET +import xml.etree.ElementTree as ET +from faraday_plugins.plugins.plugin import PluginXMLFormat __author__ = "Blas Moyano" __copyright__ = "Copyright (c) 2020, Infobyte LLC" diff --git a/faraday_plugins/plugins/repo/ndiff/plugin.py b/faraday_plugins/plugins/repo/ndiff/plugin.py index 6419dc34..75f86fd0 100644 --- a/faraday_plugins/plugins/repo/ndiff/plugin.py +++ b/faraday_plugins/plugins/repo/ndiff/plugin.py @@ -7,11 +7,7 @@ from faraday_plugins.plugins.plugin import PluginBase import re -try: - import xml.etree.cElementTree as ET - import xml.etree.ElementTree as ET_ORIG -except ImportError: - import xml.etree.ElementTree as ET +import xml.etree.ElementTree as ET __author__ = 'Ezequiel Tavella' __copyright__ = 'Copyright (c) 2016, Infobyte LLC' diff --git a/faraday_plugins/plugins/repo/netsparker/plugin.py b/faraday_plugins/plugins/repo/netsparker/plugin.py index e4fb5947..01c5e7a6 100644 --- a/faraday_plugins/plugins/repo/netsparker/plugin.py +++ b/faraday_plugins/plugins/repo/netsparker/plugin.py @@ -8,14 +8,8 @@ from bs4 import BeautifulSoup from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import resolve_hostname - -try: - import xml.etree.cElementTree as ET - import xml.etree.ElementTree as ET_ORIG - ETREE_VERSION = ET_ORIG.VERSION -except ImportError: - import xml.etree.ElementTree as ET - ETREE_VERSION = ET.VERSION +import xml.etree.ElementTree as ET +ETREE_VERSION = ET.VERSION ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] diff --git a/faraday_plugins/plugins/repo/netsparkercloud/plugin.py b/faraday_plugins/plugins/repo/netsparkercloud/plugin.py index 4ce6e33f..0416d750 100644 --- a/faraday_plugins/plugins/repo/netsparkercloud/plugin.py +++ b/faraday_plugins/plugins/repo/netsparkercloud/plugin.py @@ -8,14 +8,8 @@ from urllib.parse import urlparse from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import resolve_hostname - -try: - import xml.etree.cElementTree as ET - import xml.etree.ElementTree as ET_ORIG - ETREE_VERSION = ET_ORIG.VERSION -except ImportError: - import xml.etree.ElementTree as ET - ETREE_VERSION = ET.VERSION +import xml.etree.ElementTree as ET +ETREE_VERSION = ET.VERSION ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] @@ -55,7 +49,7 @@ def __init__(self, xml_output): self.filepath = xml_output tree = self.parse_xml(xml_output) if tree: - self.items = [data for data in self.get_items(tree)] + self.items = self.get_items(tree) else: self.items = [] @@ -206,8 +200,7 @@ def parseOutputString(self, output): del parser - def setHost(self): - pass + def createPlugin(ignore_info=False): diff --git a/faraday_plugins/plugins/repo/nexpose_full/plugin.py b/faraday_plugins/plugins/repo/nexpose_full/plugin.py index 3cfad5da..3c528203 100644 --- a/faraday_plugins/plugins/repo/nexpose_full/plugin.py +++ b/faraday_plugins/plugins/repo/nexpose_full/plugin.py @@ -4,22 +4,15 @@ See the file 'doc/LICENSE' for the license information """ -from faraday_plugins.plugins.plugin import PluginXMLFormat import re +import xml.etree.ElementTree as ET -try: - import xml.etree.cElementTree as ET - import xml.etree.ElementTree as ET_ORIG - - ETREE_VERSION = ET_ORIG.VERSION -except ImportError: - import xml.etree.ElementTree as ET +from faraday_plugins.plugins.plugin import PluginXMLFormat - ETREE_VERSION = ET.VERSION +ETREE_VERSION = ET.VERSION ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] - __author__ = "Micaela Ranea Sanchez" __copyright__ = "Copyright (c) 2013, Infobyte LLC" __credits__ = ["Francisco Amato", "Federico Kirschbaum", @@ -51,7 +44,8 @@ def __init__(self, xml_output): else: self.items = [] - def parse_xml(self, xml_output): + @staticmethod + def parse_xml(xml_output): """ Open and parse an xml file. @@ -275,7 +269,7 @@ def parseOutputString(self, output): h_id = self.createAndAddHost(item['name'], item['os'], hostnames=item['hostnames'], mac=mac) for v in item['vulns']: v['data'] = {"vulnerable_since": v['vulnerable_since'], "scan_id": v['scan_id'], "PCI": v['pci']} - v_id = self.createAndAddVulnToHost( + self.createAndAddVulnToHost( h_id, v['name'], v['desc'], @@ -285,7 +279,6 @@ def parseOutputString(self, output): ) for s in item['services']: - web = False version = s.get("version", "") s_id = self.createAndAddServiceToHost( h_id, @@ -298,7 +291,7 @@ def parseOutputString(self, output): for v in s['vulns']: if v['is_web']: - v_id = self.createAndAddVulnWebToService( + self.createAndAddVulnWebToService( h_id, s_id, v['name'], @@ -308,7 +301,7 @@ def parseOutputString(self, output): v['resolution'], path=v.get('path', '')) else: - v_id = self.createAndAddVulnToService( + self.createAndAddVulnToService( h_id, s_id, v['name'], @@ -321,11 +314,7 @@ def parseOutputString(self, output): del parser - def setHost(self): - pass def createPlugin(ignore_info=False): return NexposeFullPlugin(ignore_info=ignore_info) - - diff --git a/faraday_plugins/plugins/repo/nikto/plugin.py b/faraday_plugins/plugins/repo/nikto/plugin.py index 9a3d2949..89c36185 100644 --- a/faraday_plugins/plugins/repo/nikto/plugin.py +++ b/faraday_plugins/plugins/repo/nikto/plugin.py @@ -8,14 +8,8 @@ from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins import plugins_utils - -try: - import xml.etree.cElementTree as ET - import xml.etree.ElementTree as ET_ORIG - ETREE_VERSION = ET_ORIG.VERSION -except ImportError: - import xml.etree.ElementTree as ET - ETREE_VERSION = ET.VERSION +import xml.etree.ElementTree as ET +ETREE_VERSION = ET.VERSION ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] @@ -46,7 +40,7 @@ def __init__(self, xml_output): tree = self.parse_xml(xml_output) if tree: - self.hosts = [host for host in self.get_hosts(tree)] + self.hosts = self.get_hosts(tree) else: self.hosts = [] @@ -222,7 +216,7 @@ def __init__(self, host_node): self.starttime = self.node.get('starttime') self.sitename = self.node.get('sitename') self.siteip = self.node.get('hostheader') - self.items = [item for item in self.get_items()] + self.items = self.get_items() def get_items(self): """ @@ -360,9 +354,6 @@ def processCommandString(self, username, current_path, command_string): data = re.sub(" \-Format XML", "", command_string) return re.sub(arg_match.group(1), r"-output %s -Format XML" % self._output_file_path, data) - def setHost(self): - pass - def createPlugin(ignore_info=False): return NiktoPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/nmap/plugin.py b/faraday_plugins/plugins/repo/nmap/plugin.py index 61e4e33f..ec4a92b0 100644 --- a/faraday_plugins/plugins/repo/nmap/plugin.py +++ b/faraday_plugins/plugins/repo/nmap/plugin.py @@ -8,14 +8,8 @@ import re import os from io import BytesIO - -try: - import xml.etree.cElementTree as ET - import xml.etree.ElementTree as ET_ORIG - ETREE_VERSION = ET_ORIG.VERSION -except ImportError: - import xml.etree.ElementTree as ET - ETREE_VERSION = ET.VERSION +import xml.etree.ElementTree as ET +ETREE_VERSION = ET.VERSION from lxml import etree from lxml.etree import XMLParser from faraday_plugins.plugins.plugin import PluginXMLFormat diff --git a/faraday_plugins/plugins/repo/openscap/plugin.py b/faraday_plugins/plugins/repo/openscap/plugin.py index 437ba2ad..6bdc4583 100644 --- a/faraday_plugins/plugins/repo/openscap/plugin.py +++ b/faraday_plugins/plugins/repo/openscap/plugin.py @@ -5,15 +5,12 @@ Copyright (C) 2020 Infobyte LLC (http://www.infobytesec.com/) See the file 'doc/LICENSE' for the license information """ -from faraday_plugins.plugins.plugin import PluginXMLFormat +import ipaddress from datetime import datetime + from lxml import etree -import ipaddress -try: - import xml.etree.cElementTree as ET -except ImportError: - import xml.etree.ElementTree as ET +from faraday_plugins.plugins.plugin import PluginXMLFormat __author__ = 'Blas Moyano' __copyright__ = 'Copyright 2020, Faraday Project' diff --git a/faraday_plugins/plugins/repo/openvas/plugin.py b/faraday_plugins/plugins/repo/openvas/plugin.py index fa66b163..4f3f2033 100644 --- a/faraday_plugins/plugins/repo/openvas/plugin.py +++ b/faraday_plugins/plugins/repo/openvas/plugin.py @@ -7,14 +7,8 @@ import re from collections import defaultdict from copy import copy - -try: - import xml.etree.cElementTree as ET - import xml.etree.ElementTree as ET_ORIG - ETREE_VERSION = ET_ORIG.VERSION -except ImportError: - import xml.etree.ElementTree as ET - ETREE_VERSION = ET.VERSION +import xml.etree.ElementTree as ET +ETREE_VERSION = ET.VERSION from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import filter_services @@ -443,9 +437,6 @@ def _isIPV4(self, ip): else: return False - def setHost(self): - pass - def createPlugin(ignore_info=False): return OpenvasPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/qualysguard/plugin.py b/faraday_plugins/plugins/repo/qualysguard/plugin.py index f84bce52..736d78ef 100644 --- a/faraday_plugins/plugins/repo/qualysguard/plugin.py +++ b/faraday_plugins/plugins/repo/qualysguard/plugin.py @@ -415,10 +415,6 @@ def parseOutputString(self, output): del parser - def setHost(self): - pass - - def createPlugin(ignore_info=False): return QualysguardPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/qualyswebapp/plugin.py b/faraday_plugins/plugins/repo/qualyswebapp/plugin.py index 298ed048..5e769251 100644 --- a/faraday_plugins/plugins/repo/qualyswebapp/plugin.py +++ b/faraday_plugins/plugins/repo/qualyswebapp/plugin.py @@ -5,18 +5,13 @@ Copyright (C) 2016 Infobyte LLC (http://www.infobytesec.com/) See the file 'doc/LICENSE' for the license information """ -import re +import xml.etree.ElementTree as ET from urllib.parse import urlparse from dateutil.parser import parse from faraday_plugins.plugins.plugin import PluginXMLFormat -try: - import xml.etree.cElementTree as ET -except ImportError: - import xml.etree.ElementTree as ET - __author__ = 'Blas Moyano' __copyright__ = 'Copyright 2020, Faraday Project' __credits__ = ['Blas Moyano'] @@ -81,7 +76,6 @@ class Glossary(): def __init__(self, glossary_tags): self.lista_qid = self.get_qid_list(glossary_tags) - def get_qid_list(self, qid_list_tags): self.dict_result_qid = {} for qid in qid_list_tags: diff --git a/faraday_plugins/plugins/repo/retina/plugin.py b/faraday_plugins/plugins/repo/retina/plugin.py index 83aec976..4e86ca29 100644 --- a/faraday_plugins/plugins/repo/retina/plugin.py +++ b/faraday_plugins/plugins/repo/retina/plugin.py @@ -7,14 +7,8 @@ import re from faraday_plugins.plugins.plugin import PluginXMLFormat - -try: - import xml.etree.cElementTree as ET - import xml.etree.ElementTree as ET_ORIG - ETREE_VERSION = ET_ORIG.VERSION -except ImportError: - import xml.etree.ElementTree as ET - ETREE_VERSION = ET.VERSION +import xml.etree.ElementTree as ET +ETREE_VERSION = ET.VERSION ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] @@ -43,7 +37,7 @@ class RetinaXmlParser: def __init__(self, xml_output): tree = self.parse_xml(xml_output) if tree: - self.items = [data for data in self.get_items(tree)] + self.items = self.get_items(tree) else: self.items = [] @@ -223,10 +217,6 @@ def parseOutputString(self, output): del parser - def setHost(self): - pass - - def createPlugin(ignore_info=False): return RetinaPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/skipfish/plugin.py b/faraday_plugins/plugins/repo/skipfish/plugin.py index 871da865..f0149138 100644 --- a/faraday_plugins/plugins/repo/skipfish/plugin.py +++ b/faraday_plugins/plugins/repo/skipfish/plugin.py @@ -148,10 +148,7 @@ def parseOutputString(self, output): p = SkipfishParser(self._output_file_path) hostc = {} - port = 80 for issue in p.issues: - req = "" - res = "" for sample in issue["samples"]: if not sample["url"] in hostc: reg = re.search( @@ -177,16 +174,6 @@ def parseOutputString(self, output): 'protocol': protocol, 's_id': s_id} - try: - req = open("%s/request.dat" % sample["dir"], "r").read() - except: - pass - - try: - res = open("%s/request.dat" % sample["dir"], "r").read() - except Exception: - pass - d = hostc[sample["url"]] self.createAndAddVulnWebToService( d['h_id'], @@ -214,8 +201,7 @@ def processCommandString(self, username, current_path, command_string): else: return re.sub(arg_match.group(1), r"-o %s" % self._output_file_path, command_string, 1) - def setHost(self): - pass + def createPlugin(ignore_info=False): diff --git a/faraday_plugins/plugins/repo/w3af/plugin.py b/faraday_plugins/plugins/repo/w3af/plugin.py index bd75216b..a18f205c 100644 --- a/faraday_plugins/plugins/repo/w3af/plugin.py +++ b/faraday_plugins/plugins/repo/w3af/plugin.py @@ -8,14 +8,8 @@ from urllib.parse import urlparse from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import resolve_hostname - -try: - import xml.etree.cElementTree as ET - import xml.etree.ElementTree as ET_ORIG - ETREE_VERSION = ET_ORIG.VERSION -except ImportError: - import xml.etree.ElementTree as ET - ETREE_VERSION = ET.VERSION +import xml.etree.ElementTree as ET +ETREE_VERSION = ET.VERSION ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] diff --git a/faraday_plugins/plugins/repo/wapiti/plugin.py b/faraday_plugins/plugins/repo/wapiti/plugin.py index b9602a3f..50472f9c 100644 --- a/faraday_plugins/plugins/repo/wapiti/plugin.py +++ b/faraday_plugins/plugins/repo/wapiti/plugin.py @@ -8,14 +8,8 @@ from urllib.parse import urlparse from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import resolve_hostname - -try: - import xml.etree.cElementTree as ET - import xml.etree.ElementTree as ET_ORIG - ETREE_VERSION = ET_ORIG.VERSION -except ImportError: - import xml.etree.ElementTree as ET - ETREE_VERSION = ET.VERSION +import xml.etree.ElementTree as ET +ETREE_VERSION = ET.VERSION ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] @@ -342,9 +336,6 @@ def processCommandString(self, username, current_path, command_string): self.logger.debug("host = %s, port = %s",self.host, self.port) return "%s -o %s -f xml \n" % (command_string, self._output_file_path) - def setHost(self): - pass - def createPlugin(ignore_info=False): return WapitiPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/wcscan/plugin.py b/faraday_plugins/plugins/repo/wcscan/plugin.py index ef26f659..5a228411 100644 --- a/faraday_plugins/plugins/repo/wcscan/plugin.py +++ b/faraday_plugins/plugins/repo/wcscan/plugin.py @@ -8,14 +8,8 @@ import os import sys import random - -try: - import xml.etree.cElementTree as ET - import xml.etree.ElementTree as ET_ORIG - ETREE_VERSION = ET_ORIG.VERSION -except ImportError: - import xml.etree.ElementTree as ET - ETREE_VERSION = ET.VERSION +import xml.etree.ElementTree as ET +ETREE_VERSION = ET.VERSION ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] diff --git a/faraday_plugins/plugins/repo/webinspect/plugin.py b/faraday_plugins/plugins/repo/webinspect/plugin.py index 2ab7d1f1..c4fd8e19 100644 --- a/faraday_plugins/plugins/repo/webinspect/plugin.py +++ b/faraday_plugins/plugins/repo/webinspect/plugin.py @@ -8,10 +8,7 @@ from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import get_vulnweb_url_fields -try: - import xml.etree.cElementTree as ET -except ImportError: - import xml.etree.ElementTree as ET +import xml.etree.ElementTree as ET def cleanhtml(raw_html): diff --git a/faraday_plugins/plugins/repo/x1/plugin.py b/faraday_plugins/plugins/repo/x1/plugin.py index 044e51b0..acaf9146 100644 --- a/faraday_plugins/plugins/repo/x1/plugin.py +++ b/faraday_plugins/plugins/repo/x1/plugin.py @@ -4,18 +4,13 @@ See the file 'doc/LICENSE' for the license information """ -from faraday_plugins.plugins.plugin import PluginXMLFormat -import re import os -import sys +import re +import xml.etree.ElementTree as ET -try: - import xml.etree.cElementTree as ET - import xml.etree.ElementTree as ET_ORIG - ETREE_VERSION = ET_ORIG.VERSION -except ImportError: - import xml.etree.ElementTree as ET - ETREE_VERSION = ET.VERSION +from faraday_plugins.plugins.plugin import PluginXMLFormat + +ETREE_VERSION = ET.VERSION ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] @@ -134,7 +129,6 @@ def __init__(self, issue_node): self.resolution = self.get_text_from_subnode('solution') self.ref = [] for r in issue_node.findall('refs/reference'): - self.ref.append(r.get('type') + "-" + r.get('text')) def get_text_from_subnode(self, subnode_xpath_expr): @@ -167,8 +161,6 @@ def __init__(self, *arg, **kwargs): self._current_output = None self._command_regex = re.compile(r'^(sudo x1|\.\/x1)\s+.*?') - - def parseOutputString(self, output): parser = X1XmlParser(output) @@ -189,11 +181,5 @@ def parseOutputString(self, output): del parser - def setHost(self): - pass - - def createPlugin(ignore_info=False): return X1Plugin(ignore_info=ignore_info) - - diff --git a/faraday_plugins/plugins/repo/zap/java/Configuration.java b/faraday_plugins/plugins/repo/zap/java/Configuration.java deleted file mode 100755 index 5071ccac..00000000 --- a/faraday_plugins/plugins/repo/zap/java/Configuration.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Zed Attack Proxy (ZAP) and its related class files. - * - * ZAP is an HTTP/HTTPS proxy for assessing web application security. - * - * Copyright 2018 The ZAP Development Team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.zaproxy.zap.extension.faraday; - -import org.parosproxy.paros.Constant; - -import javax.swing.*; -import java.io.*; -import java.util.Properties; - -public class Configuration { - private String server; - private String user; - private String password; - private String session; - private String workspace; - private boolean autoImport; - private static Configuration _instance; - - private Configuration() { - this.user = ""; - this.password = ""; - this.server = "http://127.0.0.1:5985/"; - this.autoImport = false; - } - - public static Configuration getSingleton() { - if (_instance == null) - _instance = new Configuration(); - return _instance; - } - - public boolean save() throws IOException { - - Properties prop = new Properties(); - OutputStream output = null; - - String userHome = System.getProperty("user.home"); - String outputFolder = Constant.getZapHome() + "faraday"; - File folder = new File(outputFolder); - if (!folder.exists()) { - folder.mkdir(); - } - - - String filePath = outputFolder + File.separator + this.getUser() + ".properties"; - output = new FileOutputStream(filePath); - - // set the properties value - prop.setProperty("fuser", this.getUser()); - prop.setProperty("fpassword", this.getPassword()); - prop.setProperty("fserver", this.getServer()); - prop.setProperty("fworkspace", this.getWorkspace()); - prop.setProperty("fsession", this.getSession()); - - // save properties to project root folder - prop.store(output, null); - - if (output != null) { - try { - output.close(); - } catch (IOException e) { - e.printStackTrace(); - return false; - } - } - - return true; - } - - - public void restore(String fUser) throws IOException { - Properties prop = new Properties(); - InputStream input = null; - - String outputFolder = Constant.getZapHome() + "faraday"; - String filePath = outputFolder + File.separator + fUser + ".properties"; - input = new FileInputStream(filePath); - - // load a properties file - prop.load(input); - - this.setUser(prop.getProperty("fuser")); - this.setPassword(prop.getProperty("fpassword")); - this.setServer(prop.getProperty("fserver")); - this.setWorkspace(prop.getProperty("fworkspace")); - - if (input != null) { - try { - input.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - } - - public String getUser() { - return user; - } - - public void setUser(String user) { - this.user = user; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public String getServer() { - return server; - } - - public void setServer(String server) { - this.server = server; - } - - public boolean isAutoImport() { - return autoImport; - } - - public void setAutoImport(boolean autoImport) { - this.autoImport = autoImport; - } - - public String getSession() { - return session; - } - - public void setSession(String session) { - this.session = session; - } - - public String getWorkspace() { - return workspace; - } - - public void setWorkspace(String workspace) { - this.workspace = workspace; - } -} diff --git a/faraday_plugins/plugins/repo/zap/java/ConfigurationDialog.java b/faraday_plugins/plugins/repo/zap/java/ConfigurationDialog.java deleted file mode 100755 index 9d51e886..00000000 --- a/faraday_plugins/plugins/repo/zap/java/ConfigurationDialog.java +++ /dev/null @@ -1,589 +0,0 @@ -package org.zaproxy.zap.extension.faraday; - - -import org.apache.log4j.Logger; -import org.parosproxy.paros.Constant; - -import javax.swing.*; -import javax.swing.border.Border; -import java.awt.*; -import java.awt.event.*; -import java.io.*; -import java.util.ArrayList; -import java.util.Properties; -import java.util.ResourceBundle; - -public class ConfigurationDialog extends JFrame { - private static final Logger logger = Logger.getLogger(ConfigurationDialog.class); - private ResourceBundle messages = null; - private FaradayClient faradayClient; - - private static String LOGIN_BUTTON = "Login"; - private static String LOGOUT_BUTTON = "Logout"; - private static String WORKSPACES_FIELD = "Select faraday workspace"; - private static String IMPORT_NEW_VULNS_FIELD = "Import new vulnerabilities"; - private static String SET_CONFIG_AS_DEFAULT = "Set this configuration as default"; - private static String IMPORT_BUTTON = "Import vulnerabilities"; - private static String REFRESH_BUTTON = "Refresh"; - private static String RESTORE_BUTTON = "Restore"; - private static String SAVE_BUTTON = "Save"; - - private JTabbedPane tabbedPane; - private JPanel authPanel; - private JPanel configPanel; - - private JTextField fldUser; - private JTextField fldPass; - private JTextField fldServer; - - private JComboBox cmbWorkspaces; - private JCheckBox cboxSetConfigDefault; - - - private JButton loginButton; - private JButton logoutButton; - private JButton refreshButton; - private JButton restoreButton; - private JButton importButton; - private JButton saveButton; - private JButton closeButton; - - - public ConfigurationDialog(String s) throws HeadlessException { - super(s); - } - - - public void init() { - logger.debug("Init Faraday configuration dialog"); - messages = ResourceBundle.getBundle( - this.getClass().getPackage().getName() + - ".Messages", Constant.getLocale()); - // Setup the content-pane of JFrame in BorderLayout - Container cp = this.getContentPane(); - cp.setLayout(new BorderLayout(5, 5)); - Border padding = BorderFactory.createEmptyBorder(10, 10, 10, 10); - - - String USERNAME_FIELD = messages.getString("faraday.config.dialog.auth.user"); - String PASS_FIELD = messages.getString("faraday.config.dialog.auth.pass"); - String SERVER_FIELD = messages.getString("faraday.config.dialog.server"); - LOGIN_BUTTON = messages.getString("faraday.config.dialog.auth.login"); - LOGOUT_BUTTON = messages.getString("faraday.config.dialog.auth.logout"); - WORKSPACES_FIELD = messages.getString("faraday.config.dialog.workspace"); - IMPORT_NEW_VULNS_FIELD = messages.getString("faraday.config.dialog.import.new"); - SET_CONFIG_AS_DEFAULT = messages.getString("faraday.config.dialog.default"); - IMPORT_BUTTON = messages.getString("faraday.config.dialog.import.new"); - REFRESH_BUTTON = messages.getString("faraday.config.dialog.refresh"); - RESTORE_BUTTON = messages.getString("faraday.config.dialog.restore"); - SAVE_BUTTON = messages.getString("faraday.config.dialog.save"); - tabbedPane = new JTabbedPane(); - - JPanel buttonLoginPanel = new JPanel(); - buttonLoginPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); - - JPanel buttonConfigPanel = new JPanel(); - buttonConfigPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); - - authPanel = new JPanel(new GridLayout(4, 2, 10, 2)); - authPanel.setBorder(padding); - configPanel = new JPanel(new GridLayout(3, 2, 10, 2)); - configPanel.setBorder(padding); - - - Configuration configuration = Configuration.getSingleton(); - faradayClient = new FaradayClient(configuration.getServer()); - - authPanel.add(new JLabel(USERNAME_FIELD)); - fldUser = new JTextField(10); - authPanel.add(fldUser); - - authPanel.add(new JLabel(PASS_FIELD)); - fldPass = new JPasswordField(10); - authPanel.add(fldPass); - - authPanel.add(new JLabel(SERVER_FIELD)); - fldServer = new JTextField(10); - fldServer.setText(configuration.getServer()); - authPanel.add(fldServer); - - configPanel.add(getCBoxSetDefaultConfig()); - - buttonConfigPanel.add(getCloseButton()); - buttonConfigPanel.add(getCloseButton()); - buttonConfigPanel.add(getRefreshButton()); - buttonConfigPanel.add(getRestoreButton()); - buttonConfigPanel.add(getSaveButton()); -// buttonConfigPanel.add(getImportButton()); - buttonConfigPanel.add(getLoginButton()); - buttonConfigPanel.add(getLogoutButton()); - - - authPanel.addComponentListener(new ComponentListener() { - @Override - public void componentResized(ComponentEvent componentEvent) { - - } - - @Override - public void componentMoved(ComponentEvent componentEvent) { - - } - - @Override - public void componentShown(ComponentEvent componentEvent) { - - refreshButton.setVisible(false); - restoreButton.setVisible(false); -// importButton.setVisible(false); - saveButton.setVisible(false); - } - - @Override - public void componentHidden(ComponentEvent componentEvent) { - refreshButton.setVisible(true); - restoreButton.setVisible(true); -// importButton.setVisible(true); - saveButton.setVisible(true); - } - }); - - configPanel.addComponentListener(new ComponentListener() { - @Override - public void componentResized(ComponentEvent componentEvent) { - - } - - @Override - public void componentMoved(ComponentEvent componentEvent) { - - } - - @Override - public void componentShown(ComponentEvent componentEvent) { - loginButton.setVisible(false); - logoutButton.setVisible(false); - } - - @Override - public void componentHidden(ComponentEvent componentEvent) { - if (configuration.getSession().equals("")) { - loginButton.setVisible(true); - } else { - logoutButton.setVisible(true); - } - } - }); - - tabbedPane.addTab(messages.getString("faraday.config.dialog.tab.auth"), null, authPanel, null); - tabbedPane.setMnemonicAt(0, KeyEvent.VK_1); - - - tabbedPane.addTab(messages.getString("faraday.config.dialog.tabs.conf"), null, configPanel, null); - tabbedPane.setMnemonicAt(1, KeyEvent.VK_2); - - tabbedPane.setEnabledAt(1, false); - - cp.add(tabbedPane, BorderLayout.NORTH); - cp.add(buttonConfigPanel, BorderLayout.SOUTH); - - if (configuration.getSession() != null && !configuration.getSession().equals("")) { - logoutButton.setVisible(true); - loginButton.setVisible(false); - } else { - loginButton.setVisible(true); - logoutButton.setVisible(false); - } - - - if (!configuration.getUser().equals("") && !configuration.getPassword().equals("")) { - if (faradayClient.Login(configuration.getUser(), configuration.getPassword(), configuration.getServer())) { - fldUser.setText(configuration.getUser()); - fldPass.setText(configuration.getPassword()); - fldServer.setText(configuration.getServer()); - - tabbedPane.setEnabledAt(1, true); - tabbedPane.setSelectedIndex(1); - - cboxSetConfigDefault.setSelected(true); - - if (cmbWorkspaces == null) { - configPanel.add(new JLabel(WORKSPACES_FIELD)); - configPanel.add(getWSComboBox()); - } - } - } - - this.setSize(550, 300); - this.setResizable(false); - this.setLocationRelativeTo(null); - this.setVisible(true); - } - - - private JButton getLoginButton() { - if (this.loginButton == null) { - this.loginButton = new JButton(); - this.loginButton.setText(LOGIN_BUTTON); - this.loginButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - if (fldUser.getText().equals("") || fldPass.getText().equals("") || fldServer.getText().equals("")) { - showMessage(messages.getString("faraday.message.invalid.check.credentials"), messages.getString("faraday.dialog.login.title"), JOptionPane.ERROR_MESSAGE); - } else { - if (faradayClient.Login(fldUser.getText(), fldPass.getText(), fldServer.getText())) { - logoutButton.setVisible(true); - loginButton.setVisible(false); - if (!tabbedPane.isEnabledAt(1)) { - tabbedPane.setEnabledAt(1, true); - } - tabbedPane.setSelectedIndex(1); - if (cmbWorkspaces == null) { - configPanel.add(new JLabel(WORKSPACES_FIELD)); - configPanel.add(getWSComboBox()); - } else { - configPanel.remove(cmbWorkspaces); - configPanel.add(getWSComboBox()); - } - } else { - showMessage(messages.getString("faraday.message.invalid.credentials"), messages.getString("faraday.dialog.login.title"), JOptionPane.ERROR_MESSAGE); - } - } - - - } - }); - - - } - - return this.loginButton; - } - - - private JButton getLogoutButton() { - if (this.logoutButton == null) { - this.logoutButton = new JButton(); - this.logoutButton.setText(LOGOUT_BUTTON); - this.logoutButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - Configuration configuration = Configuration.getSingleton(); - String userTemp = configuration.getUser(); - if (faradayClient.Logout()) { - logoutButton.setVisible(false); - loginButton.setVisible(true); - - if (tabbedPane.isEnabledAt(1)) { - tabbedPane.setEnabledAt(1, false); - } - tabbedPane.setSelectedIndex(0); - - Properties prop = new Properties(); - InputStream input = null; - try { - String filePath = Constant.getZapHome() + "faraday" + File.separator + "default.properties"; - input = new FileInputStream(filePath); - // load a properties file - prop.load(input); - // set the properties value - String fUser = prop.getProperty("default"); - if (fUser.equals(userTemp)) { - removeDefaultConfig(); - } - - } catch (IOException io) { - System.out.println("We can't found default.properties file"); - } finally { - if (input != null) { - try { - input.close(); - } catch (IOException er) { - er.printStackTrace(); - } - } - } - - - showMessage(messages.getString("faraday.dialog.logout.success"), messages.getString("faraday.dialog.logout.title"), JOptionPane.INFORMATION_MESSAGE); - } else { - showMessage(messages.getString("faraday.dialog.logout.error"), messages.getString("faraday.dialog.logout.title"), JOptionPane.ERROR_MESSAGE); - } - } - }); - } - - return this.logoutButton; - } - - - private JButton getRefreshButton() { - if (this.refreshButton == null) { - this.refreshButton = new JButton(); - this.refreshButton.setText(REFRESH_BUTTON); - this.refreshButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - refreshWorkspaces(true); - } - }); - } - - return this.refreshButton; - } - - - private JButton getCloseButton() { - if (this.closeButton == null) { - this.closeButton = new JButton(); - this.closeButton.setText(messages.getString("faraday.dialog.button.close")); - this.closeButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - setVisible(false); - dispose(); - } - }); - } - - return this.closeButton; - } - - - private JButton getRestoreButton() { - if (this.restoreButton == null) { - this.restoreButton = new JButton(); - this.restoreButton.setText(RESTORE_BUTTON); - this.restoreButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - String fUser = JOptionPane.showInputDialog(messages.getString("faraday.config.dialog.restore"), messages.getString("faraday.dialog.enter.user")); - if (fUser != null) { - restoreConfiguration(fUser); - } - } - }); - } - - return this.restoreButton; - } - - - private JButton getImportButton() { - if (this.importButton == null) { - this.importButton = new JButton(); - this.importButton.setText(IMPORT_BUTTON); - this.importButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - - } - }); - } - - return this.importButton; - } - - - private JButton getSaveButton() { - if (this.saveButton == null) { - this.saveButton = new JButton(); - this.saveButton.setText(SAVE_BUTTON); - this.saveButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - saveConfiguration(); - } - }); - } - - return this.saveButton; - } - - - private JComboBox getWSComboBox() { - Configuration configuration = Configuration.getSingleton(); - - ArrayList wsList = faradayClient.GetWorkspaces(); - String[] workspaces = new String[wsList.size()]; - for (int i = 0; i < wsList.size(); i++) { - workspaces[i] = wsList.get(i); - } - cmbWorkspaces = new JComboBox(workspaces); - if (workspaces.length > 0) { - if (configuration.getWorkspace() != null) { - cmbWorkspaces.setSelectedItem(configuration.getWorkspace()); - } else { - configuration.setWorkspace(workspaces[0]); - } - } - cmbWorkspaces.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent actionEvent) { - Configuration.getSingleton().setWorkspace(cmbWorkspaces.getSelectedItem().toString()); - } - }); - - - return cmbWorkspaces; - } - - - private JCheckBox getCBoxSetDefaultConfig() { - if (this.cboxSetConfigDefault == null) { - cboxSetConfigDefault = new JCheckBox(SET_CONFIG_AS_DEFAULT, false); - - cboxSetConfigDefault.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent actionEvent) { - if (cboxSetConfigDefault.isSelected()) { - setConfigAsDefault(); - } else { - removeDefaultConfig(); - } - } - }); - } - - return cboxSetConfigDefault; - } - - - private void showMessage(String message, String title, int icon) { - JOptionPane.showMessageDialog( - this, - message, - title, - icon); - } - - - private void saveConfiguration() { - try { - if (Configuration.getSingleton().save()) { - JOptionPane.showMessageDialog( - this, - messages.getString("faraday.save.config.success"), - messages.getString("faraday.config.dialog.title"), - JOptionPane.INFORMATION_MESSAGE); - } else { - JOptionPane.showMessageDialog( - this, - messages.getString("faraday.save.config.error"), - messages.getString("faraday.config.dialog.title"), - JOptionPane.ERROR_MESSAGE); - - } - } catch (IOException io) { - JOptionPane.showMessageDialog( - this, - messages.getString("faraday.save.config.error"), - messages.getString("faraday.config.dialog.title"), - JOptionPane.ERROR_MESSAGE); - io.printStackTrace(); - - } - } - - - private void restoreConfiguration(String fUser) { - try { - Configuration configuration = Configuration.getSingleton(); - configuration.restore(fUser); - if (faradayClient.Login(configuration.getUser(), configuration.getPassword(), configuration.getServer())) { - fldUser.setText(configuration.getUser()); - fldPass.setText(configuration.getPassword()); - fldServer.setText(configuration.getServer()); - - tabbedPane.setEnabledAt(1, true); - tabbedPane.setSelectedIndex(0); - - cboxSetConfigDefault.setSelected(false); - refreshWorkspaces(false); - } else { - JOptionPane.showMessageDialog( - this, - messages.getString("faraday.restore.config.error.login"), - messages.getString("faraday.config.dialog.title"), - JOptionPane.ERROR_MESSAGE); - } - } catch (IOException ex) { - JOptionPane.showMessageDialog( - this, - messages.getString("faraday.restore.config.error"), - messages.getString("faraday.config.dialog.title"), - JOptionPane.ERROR_MESSAGE); - } - - } - - - private void setConfigAsDefault() { - Configuration configuration = Configuration.getSingleton(); - - Properties prop = new Properties(); - OutputStream output = null; - - try { - String outputFolder = Constant.getZapHome() + "faraday"; - File folder = new File(outputFolder); - if (!folder.exists()) { - folder.mkdir(); - } - - String filePath = outputFolder + File.separator + "default.properties"; - output = new FileOutputStream(filePath); - - // set the properties value - prop.setProperty("default", configuration.getUser()); - - // save properties to project root folder - prop.store(output, null); - - } catch (IOException io) { - JOptionPane.showMessageDialog( - this, - messages.getString("faraday.set.default.config.error"), - messages.getString("faraday.config.dialog.title"), - JOptionPane.ERROR_MESSAGE); - io.printStackTrace(); - } finally { - if (output != null) { - try { - output.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - } - } - - - private void removeDefaultConfig() { - try { - - String filePath = Constant.getZapHome() + "faraday" + File.separator + "default.properties"; - File file = new File(filePath); - if (file.delete()) { - System.out.println(file.getName() + " is deleted!"); - } else { - System.out.println("Delete operation is failed."); - } - - } catch (Exception e) { - - e.printStackTrace(); - - } - } - - - private void refreshWorkspaces(boolean canShowAlert) { - if (cmbWorkspaces != null) { - configPanel.remove(cmbWorkspaces); - configPanel.add(getWSComboBox()); - if (canShowAlert) { - JOptionPane.showMessageDialog( - this, - messages.getString("faraday.refresh.workspace.done"), - messages.getString("faraday.config.dialog.title"), - JOptionPane.INFORMATION_MESSAGE); - } - } - } - -} diff --git a/faraday_plugins/plugins/repo/zap/java/FaradayClient.java b/faraday_plugins/plugins/repo/zap/java/FaradayClient.java deleted file mode 100755 index 51dffe4f..00000000 --- a/faraday_plugins/plugins/repo/zap/java/FaradayClient.java +++ /dev/null @@ -1,525 +0,0 @@ -package org.zaproxy.zap.extension.faraday; - -import net.sf.json.JSONArray; -import net.sf.json.JSONObject; -import org.apache.commons.httpclient.URIException; -import org.apache.commons.httpclient.methods.PostMethod; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; - -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.HttpClient; -import org.apache.http.entity.StringEntity; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.NameValuePair; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.util.EntityUtils; -import org.parosproxy.paros.Constant; -import org.parosproxy.paros.core.scanner.Alert; -import org.parosproxy.paros.model.HistoryReference; - -import java.io.*; -import java.net.*; -import java.nio.charset.StandardCharsets; -import java.sql.Time; -import java.time.Instant; -import java.util.*; - - -public class FaradayClient { - - private String baseUrl; - private ResourceBundle messages = null; - - public FaradayClient(String baseUrl) { - this.baseUrl = baseUrl; - messages = ResourceBundle.getBundle( - this.getClass().getPackage().getName() + - ".Messages", Constant.getLocale()); - - } - - public boolean Login(String username, String password, String server) { - Logout(); - HttpClient httpClient = HttpClients.createDefault(); - String LOGIN_URL = "_api/login"; - HttpPost httpPost = new HttpPost(server + LOGIN_URL); - - // Request parameters and other properties. - List params = new ArrayList<>(2); - params.add(new BasicNameValuePair("email", username)); - params.add(new BasicNameValuePair("password", password)); - - try { - httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8")); - HttpResponse response = httpClient.execute(httpPost); - if (response.getFirstHeader("Set-Cookie") != null) { - Configuration configuration = Configuration.getSingleton(); - configuration.setSession(response.getFirstHeader("Set-Cookie").getValue()); - configuration.setUser(username); - configuration.setPassword(password); - configuration.setServer(server); - setBaseUrl(server); - return true; - } else if (response.getStatusLine().getStatusCode() == 302) { - return true; - } - return false; - } catch (UnsupportedEncodingException e) { - // writing error to Log - e.printStackTrace(); - return false; - } catch (ClientProtocolException e) { - e.printStackTrace(); - return false; - } catch (IOException e) { - e.printStackTrace(); - return false; - } - - } - - public boolean Logout() { - String LOGOUT_URL = "_api/logout"; - HttpGet httpGet = new HttpGet(this.baseUrl + LOGOUT_URL); - Configuration configuration = Configuration.getSingleton(); - - if (!Objects.equals(configuration.getSession(), "")) { - httpGet.setHeader("Cookie", configuration.getSession()); - - //Execute and get the response. - HttpResponse response = null; - - try { - HttpClient httpClient = HttpClients.createDefault(); - response = httpClient.execute(httpGet); - HttpEntity entity = response.getEntity(); - if (response.getStatusLine().getStatusCode() == 200) { - configuration.setSession(""); - configuration.setUser(""); - configuration.setPassword(""); - return true; - } - return false; - } catch (IOException e) { - e.printStackTrace(); - return false; - } - } - return true; - } - - public ArrayList GetWorkspaces() { - ArrayList workspaces = new ArrayList<>(); - String WORKSPACES_URL = "_api/v2/ws/"; - HttpGet httpGet = new HttpGet(this.baseUrl + WORKSPACES_URL); - Configuration configuration = Configuration.getSingleton(); - - if (configuration.getSession() != "") { - httpGet.setHeader("Cookie", configuration.getSession()); - - //Execute and get the response. - HttpResponse response = null; - InputStream instream = null; - try { - HttpClient httpClient = HttpClients.createDefault(); - response = httpClient.execute(httpGet); - HttpEntity entity = response.getEntity(); - - if (entity != null && response.getStatusLine().getStatusCode() == 200) { - instream = entity.getContent(); - - BufferedReader br = new BufferedReader(new InputStreamReader(instream)); - String output; - JSONArray jsonArray = new JSONArray(); - while ((output = br.readLine()) != null) { - System.out.println(output); - jsonArray = JSONArray.fromObject(output); - } - - for (int i = 0; i < jsonArray.size(); i++) { - JSONObject jsonObject = jsonArray.getJSONObject(i); - workspaces.add(jsonObject.get("name").toString()); - } - } - } catch (IOException e) { - e.printStackTrace(); - } finally { - try { - instream.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - return workspaces; - } - - - private int AddCommand(String commandName, String workspace, String session) { - String COMMAND_URL = "_api/v2/ws/" + workspace + "/commands/"; - HttpClient httpClient = HttpClients.createDefault(); - HttpPost httpPost = new HttpPost(this.baseUrl + COMMAND_URL); - - try { - StringEntity stringEntity = new StringEntity(ConvertCommandToParams(commandName).toString()); - httpPost.setHeader("Cookie", session); - httpPost.setHeader("Content-Type", "application/json"); - httpPost.setEntity(stringEntity); - HttpResponse response = httpClient.execute(httpPost); - HttpEntity entity = response.getEntity(); - - if (response.getStatusLine().getStatusCode() == 200 || response.getStatusLine().getStatusCode() == 201 || response.getStatusLine().getStatusCode() == 409) { - BufferedReader br = new BufferedReader(new InputStreamReader(entity.getContent())); - String output; - JSONObject json; - String commandStr = "-1"; - while ((output = br.readLine()) != null) { - json = JSONObject.fromObject(output); - if (response.getStatusLine().getStatusCode() == 409) { - JSONObject jsonObject = JSONObject.fromObject(json.get("object")); - commandStr = jsonObject.get("_id").toString(); - } else { - commandStr = json.get("_id").toString(); - } - } - return Integer.parseInt(commandStr); - } - return -1; - } catch (UnsupportedEncodingException e) { - // writing error to Log - e.printStackTrace(); - return -1; - } catch (ClientProtocolException e) { - e.printStackTrace(); - return -1; - } catch (IOException e) { - e.printStackTrace(); - return -1; - } - } - - private int AddHost(Alert alert, String workspace, String session) { - String VULN_URL = "_api/v2/ws/" + workspace + "/hosts/"; - HttpClient httpClient = HttpClients.createDefault(); - HttpPost httpPost = new HttpPost(this.baseUrl + VULN_URL); - - try { - StringEntity stringEntity = new StringEntity(ConvertHostToParams(alert).toString()); - httpPost.setHeader("Cookie", session); - httpPost.setHeader("Content-Type", "application/json"); - httpPost.setEntity(stringEntity); - HttpResponse response = httpClient.execute(httpPost); - HttpEntity entity = response.getEntity(); - - if (response.getStatusLine().getStatusCode() == 200 || response.getStatusLine().getStatusCode() == 201 || response.getStatusLine().getStatusCode() == 409) { - BufferedReader br = new BufferedReader(new InputStreamReader(entity.getContent())); - String output; - JSONObject json; - String hostStr = "-1"; - while ((output = br.readLine()) != null) { - json = JSONObject.fromObject(output); - if (response.getStatusLine().getStatusCode() == 409) { - JSONObject jsonObject = JSONObject.fromObject(json.get("object")); - hostStr = jsonObject.get("id").toString(); - } else { - hostStr = json.get("id").toString(); - } - } - return Integer.parseInt(hostStr); - } - return -1; - } catch (UnsupportedEncodingException e) { - // writing error to Log - e.printStackTrace(); - return -1; - } catch (ClientProtocolException e) { - e.printStackTrace(); - return -1; - } catch (IOException e) { - e.printStackTrace(); - return -1; - } - } - - private int AddService(Alert alert, String workspace, String session, int hostId) { - String VULN_URL = "_api/v2/ws/" + workspace + "/services/"; - HttpClient httpClient = HttpClients.createDefault(); - HttpPost httpPost = new HttpPost(this.baseUrl + VULN_URL); - - try { - StringEntity stringEntity = new StringEntity(ConvertServiceToParams(alert, hostId).toString()); - httpPost.setHeader("Cookie", session); - httpPost.setHeader("Content-Type", "application/json"); - httpPost.setEntity(stringEntity); - HttpResponse response = httpClient.execute(httpPost); - HttpEntity entity = response.getEntity(); - - BufferedReader br = new BufferedReader(new InputStreamReader(entity.getContent())); - String output; - if (response.getStatusLine().getStatusCode() == 200 || response.getStatusLine().getStatusCode() == 201 || response.getStatusLine().getStatusCode() == 409) { - JSONObject json; - String serviceStr = "-1"; - while ((output = br.readLine()) != null) { - json = JSONObject.fromObject(output); - if (response.getStatusLine().getStatusCode() == 409) { - JSONObject jsonObject = JSONObject.fromObject(json.get("object")); - serviceStr = jsonObject.get("id").toString(); - } else { - serviceStr = json.get("id").toString(); - } - } - return Integer.parseInt(serviceStr); - } else { - while ((output = br.readLine()) != null) { - System.out.println(output); - } - - return -1; - } - - } catch (UnsupportedEncodingException e) { - // writing error to Log - e.printStackTrace(); - return -1; - } catch (ClientProtocolException e) { - e.printStackTrace(); - return -1; - } catch (IOException e) { - e.printStackTrace(); - return -1; - } - } - - public int AddVulnerability(Alert alert, String workspace, String session) { - int hostId = AddHost(alert, workspace, session); - if (hostId == -1) { - return 500; - } - - String parentType = "Service"; - int serviceId = AddService(alert, workspace, session, hostId); - if (serviceId == -1) { - return 500; - } - - - String commandName = messages.getString("faraday.tool.command.name"); - int commandId = AddCommand(commandName, workspace, session); - if (commandId == -1) { - return 500; - } - - - String VULN_URL = "_api/v2/ws/" + workspace + "/vulns/?command_id=" + commandId; - HttpClient httpClient = HttpClients.createDefault(); - HttpPost httpPost = new HttpPost(this.baseUrl + VULN_URL); - try { - - StringEntity stringEntity = new StringEntity(ConvertAlertToParams(alert, workspace, parentType, serviceId).toString()); - httpPost.setHeader("Cookie", session); - httpPost.setHeader("Content-Type", "application/json"); - httpPost.setEntity(stringEntity); - HttpResponse response = httpClient.execute(httpPost); - return response.getStatusLine().getStatusCode(); - - } catch (UnsupportedEncodingException e) { - // writing error to Log - e.printStackTrace(); - return 402; - } catch (ClientProtocolException e) { - e.printStackTrace(); - return 402; - } catch (IOException e) { - e.printStackTrace(); - return 402; - } - } - - private JSONObject ConvertAlertToParams(Alert alert, String workspace, String parentType, int parentId) { - // Request parameters and other properties. - JSONObject params = new JSONObject(); - - params.put("name", alert.getName()); - params.put("ws", workspace); - params.put("request", alert.getMessage().getRequestHeader().toString()); - params.put("response", alert.getMessage().getResponseHeader().toString()); - String desc = !alert.getParam().equals("") ? alert.getDescription() + "\nWith parameter: '" + alert.getParam() + "'" : - alert.getDescription(); - params.put("desc", desc); - params.put("resolution", alert.getSolution()); - params.put("type", "VulnerabilityWeb"); - params.put("data", alert.getPostData()); - params.put("policyviolations", "[]"); - params.put("parent_type", parentType); - params.put("parent", parentId); - params.put("params", alert.getParam()); - - JSONObject metadata = new JSONObject(); - metadata.put("creator", "OWASP"); - params.put("metadata", metadata); - - String hostname = alert.getMessage().getRequestHeader().getHostName(); - String IpAddres = GetIPFromHostname(hostname); - JSONArray hostNamesArray = new JSONArray(); - hostNamesArray.add(hostname); - hostNamesArray.add(IpAddres); - params.put("hostnames", hostNamesArray); - params.put("target", IpAddres); - params.put("website", hostname); - - JSONArray refsJsonArray = new JSONArray(); - String[] resfArray = alert.getReference().split("\n"); - Collections.addAll(refsJsonArray, resfArray); - params.put("refs", refsJsonArray); - - try { - params.put("path", alert.getMsgUri().getPath()); - } catch (URIException e) { - e.printStackTrace(); - } - - if (alert.getConfidence() == 4) { - params.put("confirmed", true); - } - - switch (alert.getRisk()) { - case 0: - params.put("severity", "informational"); - break; - case 1: - params.put("severity", "low"); - break; - case 2: - params.put("severity", "medium"); - break; - case 3: - params.put("severity", "high"); - break; - } - return params; - - } - - private JSONObject ConvertHostToParams(Alert alert) { - // Request parameters and other properties. - JSONObject params = new JSONObject(); - - try { - String ipAddress = GetIPFromHostname(alert.getMsgUri().getHost()); - params.put("ip", ipAddress); - params.put("name", alert.getMsgUri().getName()); - params.put("os", "Unknown"); - params.put("description", ""); - JSONObject metadata = new JSONObject(); - metadata.put("creator", "Zap"); - params.put("metadata", metadata); - - String hostname = alert.getMessage().getRequestHeader().getHostName(); - JSONArray hostNamesArray = new JSONArray(); - hostNamesArray.add(hostname); - params.put("hostnames", hostNamesArray); - - } catch (URIException e) { - e.printStackTrace(); - } - return params; - } - - private JSONObject ConvertServiceToParams(Alert alert, int parentId) { - // Request parameters and other properties. - JSONObject params = new JSONObject(); - JSONArray portsJson = new JSONArray(); - portsJson.add(alert.getMessage().getRequestHeader().getHostPort()); - params.put("ports", portsJson); - params.put("parent", parentId); - params.put("status", "open"); - params.put("type", "Service"); - params.put("description", ""); - JSONObject metadata = new JSONObject(); - metadata.put("creator", "OWASP"); - params.put("metadata", metadata); - - switch (alert.getMessage().getRequestHeader().getHostPort()) { - case 21: - params.put("name", "FTP"); - params.put("protocol", "tcp"); - break; - case 22: - params.put("name", "SSH"); - params.put("protocol", "tcp"); - break; - case 23: - params.put("name", "TELNET"); - params.put("protocol", "tcp"); - break; - case 25: - params.put("name", "SMTP"); - params.put("protocol", "tcp"); - break; - case 80: - params.put("name", "HTTP"); - params.put("protocol", "tcp"); - break; - case 110: - params.put("name", "POP"); - params.put("protocol", "tcp"); - break; - case 443: - params.put("name", "SSL"); - params.put("protocol", "tcp"); - break; - default: - params.put("name", "unknown"); - params.put("protocol", "unknown"); - break; - } - - return params; - } - - private JSONObject ConvertCommandToParams(String commandName) { - // Request parameters and other properties. - JSONObject params = new JSONObject(); - params.put("itime", Instant.EPOCH.getEpochSecond()); - params.put("import_source", "shell"); - params.put("duration", ""); - params.put("command", "Zap"); - params.put("tool", commandName); - return params; - } - - private String GetIPFromHostname(String hostname) { - try { - InetAddress inetAddr = InetAddress.getByName(hostname); - byte[] addr = inetAddr.getAddress(); - - // Convert to dot representation - String ipAddr = ""; - for (int i = 0; i < addr.length; i++) { - if (i > 0) { - ipAddr += "."; - } - - ipAddr += addr[i] & 0xFF; - } - - System.out.println("IP Address: " + ipAddr); - return ipAddr; - } catch (UnknownHostException e) { - System.out.println("Host not found: " + e.getMessage()); - return ""; - } - } - - public void setBaseUrl(String baseUrl) { - this.baseUrl = baseUrl; - } -} - - - diff --git a/faraday_plugins/plugins/repo/zap/java/FaradayExtension.java b/faraday_plugins/plugins/repo/zap/java/FaradayExtension.java deleted file mode 100755 index 4d735513..00000000 --- a/faraday_plugins/plugins/repo/zap/java/FaradayExtension.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Zed Attack Proxy (ZAP) and its related class files. - * - * ZAP is an HTTP/HTTPS proxy for assessing web application security. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.zaproxy.zap.extension.faraday; - -import org.apache.log4j.Logger; -import org.parosproxy.paros.Constant; -import org.parosproxy.paros.control.Control; -import org.parosproxy.paros.extension.ExtensionAdaptor; -import org.parosproxy.paros.extension.ExtensionHook; -import org.parosproxy.paros.extension.ExtensionPopupMenuItem; -import org.zaproxy.zap.view.ZapMenuItem; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.KeyEvent; -import java.io.*; -import java.util.Properties; -import java.util.ResourceBundle; - -public class FaradayExtension extends ExtensionAdaptor { - private static final Logger logger = Logger.getLogger(FaradayExtension.class); - private ZapMenuItem menuItemFaradayConfig; - private ConfigurationDialog configurationDialog; - private PopupMenuItemSendAlert popupMenuItemSendAlert; - private PopupMenuItemSendRequest popupMenuItemSendRequest; - private ResourceBundle messages = null; - - - - public FaradayExtension(String name) { - super(name); - } - - - public FaradayExtension() { - super(); - initialize(); - } - - - private void initialize() { - messages = ResourceBundle.getBundle( - this.getClass().getPackage().getName() + - ".Messages", Constant.getLocale()); - this.setName(messages.getString("faraday.extension.name")); - this.initConfiguration(); - } - - @Override - public String getAuthor() { - return messages.getString("faraday.extension.author"); - } - - @Override - public void hook(ExtensionHook extensionHook) { - super.hook(extensionHook); - - if (getView() != null) { - extensionHook.getHookMenu().addToolsMenuItem(getMenuItemFaradayConfig()); - extensionHook.getHookMenu().addPopupMenuItem(this.getPopupMenuItem()); - extensionHook.getHookMenu().addPopupMenuItem(this.getPopupMenuItemRequest()); - } - } - - @Override - public boolean canUnload() { - return true; - } - - private ZapMenuItem getMenuItemFaradayConfig() { - if (menuItemFaradayConfig == null) { - menuItemFaradayConfig = new ZapMenuItem( - "faraday.menu.tools.label", - KeyStroke.getKeyStroke( - KeyEvent.VK_F, - Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() | KeyEvent.ALT_DOWN_MASK, - false)); - menuItemFaradayConfig.setEnabled(Control.getSingleton().getMode() != Control.Mode.safe); - - menuItemFaradayConfig.addActionListener(new java.awt.event.ActionListener() { - - @Override - public void actionPerformed(java.awt.event.ActionEvent e) { - showConfigurationDialog(); - } - }); - } - return menuItemFaradayConfig; - } - - - private void showConfigurationDialog() { - if (configurationDialog == null) { - configurationDialog = new ConfigurationDialog(messages.getString("faraday.config.dialog.title")); - configurationDialog.init(); - } - configurationDialog.setVisible(true); - } - - - private ExtensionPopupMenuItem getPopupMenuItem() { - if (popupMenuItemSendAlert == null) { - popupMenuItemSendAlert = new PopupMenuItemSendAlert(messages.getString("faraday.button.send.alert")); - } - - return popupMenuItemSendAlert; - - } - - - private ExtensionPopupMenuItem getPopupMenuItemRequest() { - if (popupMenuItemSendRequest == null) { - popupMenuItemSendRequest = new PopupMenuItemSendRequest(messages.getString("faraday.button.send.request")); - } - - return popupMenuItemSendRequest; - - } - - - private void initConfiguration() { - Configuration configuration = Configuration.getSingleton(); - - Properties prop = new Properties(); - InputStream input = null; - - try { - String filePath = Constant.getZapHome() + "faraday" + File.separator + "default.properties"; - input = new FileInputStream(filePath); - - // load a properties file - prop.load(input); - - // set the properties value - String fUser = prop.getProperty("default"); - configuration.restore(fUser); - - } catch (IOException io) { - System.out.println("We can't found default.properties file"); - } finally { - if (input != null) { - try { - input.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - } - } - -} diff --git a/faraday_plugins/plugins/repo/zap/java/Messages.properties b/faraday_plugins/plugins/repo/zap/java/Messages.properties deleted file mode 100755 index 5d7d22b3..00000000 --- a/faraday_plugins/plugins/repo/zap/java/Messages.properties +++ /dev/null @@ -1,56 +0,0 @@ -# An example ZAP extension which adds a top level menu item. -# -# This file defines the default (English) variants of all of the - -faraday.extension.name = Faraday Extension -faraday.extension.author = Jorge Luis GonzĂ lez Iznaga - -faraday.menu.tools.label = Faraday configuration options -faraday.config.dialog.title = Faraday configuration -faraday.config.dialog.tabs.auth = Authorization -faraday.config.dialog.tabs.conf = Configuration -faraday.config.dialog.auth.user = Faraday user -faraday.config.dialog.auth.pass = Faraday password -faraday.config.dialog.server = Faraday server -faraday.config.dialog.auth.login = Login -faraday.config.dialog.auth.logout = Logout -faraday.config.dialog.import.current = Import current vulnerabilities -faraday.config.dialog.import.new = Import new vulnerabilities -faraday.config.dialog.restore = Restore configuration -faraday.config.dialog.refresh = Refresh -faraday.config.dialog.save = Save configuration -faraday.config.dialog.workspace = Select faraday workspace -faraday.config.dialog.default = Set this configuration as default - -faraday.config.dialog.tab.auth = Authorization -faraday.config.dialog.tab.conf = Configuration - -faraday.dialog.enter.user = Please enter your user - - -faraday.button.send.alert = Send alert to Faraday -faraday.button.send.request = Send request to Faraday - -faraday.message.invalid.check.credentials = Please, check your credentials -faraday.message.invalid.credentials = Invalid credentials -faraday.dialog.login.title = Faraday login -faraday.dialog.logout.title = Faraday logout -faraday.dialog.logout.success = You're logout successfully ! -faraday.dialog.logout.error = We can't complete logout operation - -faraday.dialog.button.close = Close - -faraday.save.config.success = Configuration saved successfully -faraday.save.config.error = We can't save your configuration, please check home ZAP directory -faraday.restore.config.error = You haven't a configuration saved with this user -faraday.refresh.workspace.done = Your workspaces are up to date -faraday.restore.config.error.login = Unable to restore this configuration -faraday.set.default.config.error = We can't set your configuration - -faraday.send.alert.permissions.error = You should check your current workspace and your permissions -faraday.send.alert.conflict = This alert already exists in Faraday -faraday.send.request.conflict = This request already exists in Faraday -faraday.send.alert.success = Alert added successfully -faraday.send.request.success = Request added successfully - -faraday.tool.command.name = OWASP \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/zap/java/PopupMenuItemSendAlert.java b/faraday_plugins/plugins/repo/zap/java/PopupMenuItemSendAlert.java deleted file mode 100755 index 8b202836..00000000 --- a/faraday_plugins/plugins/repo/zap/java/PopupMenuItemSendAlert.java +++ /dev/null @@ -1,149 +0,0 @@ -package org.zaproxy.zap.extension.faraday; - -import org.apache.log4j.Logger; -import org.parosproxy.paros.Constant; -import org.parosproxy.paros.core.scanner.Alert; -import org.parosproxy.paros.view.View; -import org.zaproxy.zap.extension.alert.AlertNode; -import org.zaproxy.zap.extension.alert.PopupMenuItemAlert; - -import javax.swing.*; -import java.awt.*; -import java.util.ResourceBundle; - -public class PopupMenuItemSendAlert extends PopupMenuItemAlert { - private static final Logger logger = Logger.getLogger(PopupMenuItemSendAlert.class); - private FaradayClient faradayClient; - private ResourceBundle messages = null; - private int selectionCount = 0; - private int totalSelectionCount = 0; - private boolean treeAlertParentSelected = false; - - public PopupMenuItemSendAlert(String label) { - super(label, true); - Configuration configuration = Configuration.getSingleton(); - faradayClient = new FaradayClient(configuration.getServer()); - messages = ResourceBundle.getBundle( - this.getClass().getPackage().getName() + - ".Messages", Constant.getLocale()); - } - - @Override - protected void performAction(Alert alert) { - Configuration configuration = Configuration.getSingleton(); - String workspace = configuration.getWorkspace(); - String session = configuration.getSession(); - if (workspace != null && session != null && !workspace.equals("") && !session.equals("")) { - int responseCode = faradayClient.AddVulnerability(alert, configuration.getWorkspace(), session); - String message; - int iconMessage = 1; - switch (responseCode) { - case 200: - case 201: - case 409: - message = messages.getString("faraday.send.alert.success"); - break; - case 403: - message = messages.getString("faraday.send.alert.permissions.error"); - iconMessage = JOptionPane.WARNING_MESSAGE; - break; -// case 409: -// message = messages.getString("faraday.send.alert.conflict"); -// iconMessage = JOptionPane.WARNING_MESSAGE; -// break; - case 400: - case 500: - message = "Unable to send " + alert.getName() + " to Faraday"; - iconMessage = JOptionPane.ERROR_MESSAGE; - break; - - default: - message = "Unable to send " + alert.getName() + " to Faraday"; - iconMessage = JOptionPane.ERROR_MESSAGE; - break; - } - - if (canShowMessageDialog()/*this.selectionCount == 1 && !treeAlertParentSelected*/) { - JOptionPane.showMessageDialog( - this, - message, - messages.getString("faraday.button.send.alert"), - iconMessage); - } - - - logger.error(message); - if (View.isInitialised()) { - // Report info to the Output tab - View.getSingleton().getOutputPanel().append(message + "\n"); - } - - - } else { - if (canShowMessageDialog()) { - JOptionPane.showMessageDialog( - this, - messages.getString("faraday.send.alert.permissions.error"), - messages.getString("faraday.button.send.alert"), - JOptionPane.ERROR_MESSAGE); - logger.error(messages.getString("faraday.send.alert.permissions.error")); - } - - - if (View.isInitialised()) { - // Report info to the Output tab - View.getSingleton().getOutputPanel().append(messages.getString("faraday.send.alert.permissions.error") + "\n"); - } - } - - } - - @Override - public boolean isEnableForComponent(Component invoker) { - logger.info(invoker.getName()); - this.totalSelectionCount = 0; - try { - if (Configuration.getSingleton().getSession() == null || Configuration.getSingleton().getSession().equals("")) { - return false; - } - treeAlertParentSelected = ((JTree) invoker).isRowSelected(0); - if (super.isEnableForComponent(invoker) || treeAlertParentSelected) { - this.selectionCount = ((JTree) invoker).getSelectionCount(); - for (int i = 0; i < ((JTree) invoker).getSelectionPaths().length; i++) { - AlertNode nodeTemp = (AlertNode) ((JTree) invoker).getSelectionPaths()[i].getLastPathComponent(); - this.totalSelectionCount += getTotalAlertsToProcess(nodeTemp); - } - - setEnabled(true); - return true; - } - return false; - } catch (Exception e) { - return false; - } - } - - - private int getTotalAlertsToProcess(AlertNode node) { - if (node.getChildCount() > 0) { - int total = 0; - for (int i = 0; i < node.getChildCount(); i++) { - total += getTotalAlertsToProcess(node.getChildAt(i)); - } - return total; - } else { - return 1; - } - - } - - private boolean canShowMessageDialog() { - this.totalSelectionCount--; - if (this.treeAlertParentSelected) { - this.totalSelectionCount = 1; - this.treeAlertParentSelected = false; - } - - return this.totalSelectionCount == 0; - } -} diff --git a/faraday_plugins/plugins/repo/zap/java/PopupMenuItemSendRequest.java b/faraday_plugins/plugins/repo/zap/java/PopupMenuItemSendRequest.java deleted file mode 100755 index 3aba6cbf..00000000 --- a/faraday_plugins/plugins/repo/zap/java/PopupMenuItemSendRequest.java +++ /dev/null @@ -1,137 +0,0 @@ -package org.zaproxy.zap.extension.faraday; - -import org.apache.log4j.Logger; -import org.parosproxy.paros.Constant; -import org.parosproxy.paros.core.scanner.Alert; -import org.parosproxy.paros.db.DatabaseException; -import org.parosproxy.paros.db.RecordAlert; -import org.parosproxy.paros.model.HistoryReference; -import org.parosproxy.paros.network.HttpMalformedHeaderException; -import org.parosproxy.paros.view.View; -import org.zaproxy.zap.extension.alert.PopupMenuAlert; -import org.zaproxy.zap.view.messagecontainer.http.HttpMessageContainer; -import org.zaproxy.zap.view.popup.PopupMenuItemHistoryReferenceContainer; - -import javax.swing.*; -import java.awt.*; -import java.util.Iterator; -import java.util.List; -import java.util.ResourceBundle; - - -public class PopupMenuItemSendRequest extends PopupMenuItemHistoryReferenceContainer { - private FaradayClient faradayClient; - private ResourceBundle messages = null; - private int selectionCount = 0; - private static final Logger logger = Logger.getLogger(PopupMenuItemSendRequest.class); - - - public PopupMenuItemSendRequest(String label) { - super(label, true); - Configuration configuration = Configuration.getSingleton(); - faradayClient = new FaradayClient(configuration.getServer()); - messages = ResourceBundle.getBundle( - this.getClass().getPackage().getName() + - ".Messages", Constant.getLocale()); - } - - @Override - public void performAction(HistoryReference href) { - try { - Alert alert = new Alert(new RecordAlert(), href); - alert.setName(href.getSiteNode().getName()); - alert.setUri(href.getURI().toString()); - alert.setMessage(href.getHttpMessage()); - alert.setDescription(""); - alert.setRiskConfidence(0, 0); - - Configuration configuration = Configuration.getSingleton(); - String workspace = configuration.getWorkspace(); - String session = configuration.getSession(); - if (workspace != null && session != null && !workspace.equals("") && !session.equals("")) { - int responseCode = faradayClient.AddVulnerability(alert, configuration.getWorkspace(), session); - String message = ""; - int iconMessage = 1; - switch (responseCode) { - case 403: - message = messages.getString("faraday.send.alert.permissions.error"); - iconMessage = JOptionPane.WARNING_MESSAGE; - break; - case 409: - message = messages.getString("faraday.send.request.conflict"); - iconMessage = JOptionPane.WARNING_MESSAGE; - break; - case 500: - message = "Unable to send " + alert.getName() + " to Faraday"; - iconMessage = JOptionPane.ERROR_MESSAGE; - break; - case 201: - message = messages.getString("faraday.send.request.success"); - break; - } - - if (this.selectionCount == 1) { - JOptionPane.showMessageDialog( - this, - message, - messages.getString("faraday.button.send.alert"), - iconMessage); - } - - logger.error(message); - if (View.isInitialised()) { - // Report info to the Output tab - View.getSingleton().getOutputPanel().append(message + "\n"); - } - - - } else { - JOptionPane.showMessageDialog( - this, - messages.getString("faraday.send.alert.permissions.error"), - messages.getString("faraday.button.send.request"), - JOptionPane.ERROR_MESSAGE); - - logger.error(messages.getString("faraday.send.alert.permissions.error")); - if (View.isInitialised()) { - // Report info to the Output tab - View.getSingleton().getOutputPanel().append(messages.getString("faraday.send.alert.permissions.error") + "\n"); - } - } - - - } catch (HttpMalformedHeaderException e) { - e.printStackTrace(); - } catch (DatabaseException e) { - e.printStackTrace(); - } - } - - - @Override - public void performHistoryReferenceActions(List hrefs) { - this.selectionCount = hrefs.size(); - - for (HistoryReference href : hrefs) { - this.performAction(href); - } - } - - @Override - public boolean isEnableForInvoker(Invoker invoker, HttpMessageContainer httpMessageContainer) { - if (Configuration.getSingleton().getSession() == null || Configuration.getSingleton().getSession().equals("") || - invoker.name().equals("ALERTS_PANEL")) { - return false; - } - return super.isEnableForInvoker(invoker, httpMessageContainer); - } - - @Override - public boolean isButtonEnabledForHistoryReference(HistoryReference href) { - if (Configuration.getSingleton().getSession() == null || Configuration.getSingleton().getSession().equals("")) { - return false; - } - - return href.getSiteNode() != null && super.isButtonEnabledForHistoryReference(href); - } -} \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/zap/java/ZapAddOn.xml b/faraday_plugins/plugins/repo/zap/java/ZapAddOn.xml deleted file mode 100755 index 7cbc939a..00000000 --- a/faraday_plugins/plugins/repo/zap/java/ZapAddOn.xml +++ /dev/null @@ -1,14 +0,0 @@ - - Faraday - 1 - release - This extension integrates ZAP with the Faraday Integrated Penetration-Test Environment - Jorge Luis GonzĂĄlez Iznaga - - org.zaproxy.zap.extension.faraday.FaradayExtension - - - - 2.7.0 - - diff --git a/faraday_plugins/plugins/repo/zap/plugin.py b/faraday_plugins/plugins/repo/zap/plugin.py index 56170720..6b65a097 100644 --- a/faraday_plugins/plugins/repo/zap/plugin.py +++ b/faraday_plugins/plugins/repo/zap/plugin.py @@ -5,15 +5,12 @@ """ import re from urllib.parse import urlparse + from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import resolve_hostname -try: - import xml.etree.cElementTree as ET - ETREE_VERSION = ET.VERSION -except ImportError: - import xml.etree.ElementTree as ET - ETREE_VERSION = ET.VERSION +import xml.etree.ElementTree as ET +ETREE_VERSION = ET.VERSION ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] @@ -28,7 +25,6 @@ __status__ = "Development" - class ZapXmlParser: """ The objective of this class is to parse an xml @@ -52,7 +48,8 @@ def __init__(self, xml_output): else: self.sites = [] - def parse_xml(self, xml_output): + @staticmethod + def parse_xml(xml_output): """ Open and parse an xml file. @@ -72,7 +69,8 @@ def parse_xml(self, xml_output): return tree - def get_items(self, tree): + @staticmethod + def get_items(tree): """ @return items A list of Host instances """ @@ -144,7 +142,6 @@ def get_text_from_subnode(self, subnode_xpath_expr): return None - class Item: """ An abstract representation of a Item @@ -244,7 +241,6 @@ def __init__(self, *arg, **kwargs): self.framework_version = "1.0.0" self.options = None - def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it @@ -283,9 +279,5 @@ def parseOutputString(self, output): del parser - def setHost(self): - pass - - def createPlugin(ignore_info=False): return ZapPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/zap/report.xml b/faraday_plugins/plugins/repo/zap/report.xml deleted file mode 100644 index 7bdb0299..00000000 --- a/faraday_plugins/plugins/repo/zap/report.xml +++ /dev/null @@ -1,166 +0,0 @@ - -Report generated at Tue, 12 Jul 2011 08:32:22. - - 40000 - Cookie set without HttpOnly flag - 1 - 2 - Low (Warning) - A cookie has been set without the HttpOnly flag, which means that the cookie can be accessed by JavaScript. If a malicious script can be run on this page then the cookie will be accessible and can be transmitted to another site. If this is a session cookie then session hijacking may be possible. - - http://192.168.1.100/ - ASPSESSIONIDQSDRBCRQ=EEFHJOACLHOKLJHFNAFBBECK; path=/ - - http://www.web3.com.ar/ServFotoPorNoticia.asp - ASPSESSIONIDCQATADBB=LMFPHGLBHIIEDFILGFJEJNGE; path=/ - - http://www.web1.com.ar/acceso/include/valida.asp - ASPSESSIONIDSCBABSTB=MNPOKADDPAIDCDNBPGFDHGBF; path=/ - - http://www.web3.com.ar/files/ - ASPSESSIONIDCSCTCABB=HFCNOPJBMNJEAHDHMCKAHOBN; path=/ - - http://www.web2.com.ar/acceso/include/valida.asp - ASPSESSIONIDQAASDACB=HADJFCIBOIANGBGNAOIDBGIL; path=/ - - http://www.web3.com.ar/ - ASPSESSIONIDSABQACDB=PAJBMJHBLOFELCIKBNLAAKKJ; path=/ - - Ensure that the HttpOnly flag is set for all cookies. - - www.owasp.org/index.php/HttpOnly - - - - 40001 - Password Autocomplete in browser - 1 - 2 - Low (Warning) - AUTOCOMPLETE attribute is not disabled in HTML FORM/INPUT element containing password type input. Passwords may be stored in browsers and retrieved. - - http://192.168.1.100/ - input - - http://www.web3.com.ar/ - input - - http://www.web3.com.ar/default.asp?errsession=1 - input - - http://www.web3.com.ar/ - input - - http://www.web3.com.ar/ - input - - http://www.web2.com.ar/dealers.htm - input - - http://www.web3.com.ar/ - input - - Turn off AUTOCOMPLETE attribute in form or individual input elements containing password by using AUTOCOMPLETE='OFF' - - http://msdn.microsoft.com/library/default.asp?url=/workshop/author/forms/autocomplete_ovr.asp - - - - 40003 - Cross site scripting - 3 - 2 - High (Warning) - Cross-site scripting or HTML injection is possible. Malicious script may be injected into the browser which appeared to be genuine content from the original site. These scripts can be used to execute arbitrary code or steal customer sensitive information such as user password or cookies. - Very often this is in the form of a hyperlink with the injected script embeded in the query strings. However, XSS is possible via FORM POST data, cookies, user data sent from another user or shared data retrieved from database. - Currently this check does not verify XSS from cookie or database. They should be checked manually if the application retrieve database records from another user's input. - - http://www.web3.com.ar/Mes.asp?hhFrm=frm&hhDia=DiaF&hhMes=MesF&hhAnno=%3CSCRIPT%3Ealert(%22OWASP%20ZAP%22);%3C/SCRIPT%3E - hhAnno=<SCRIPT>alert("OWASP ZAP");</SCRIPT> - - http://www.web3.com.ar/Mes.asp?hhFrm=frm&hhDia=DiaF&hhMes=%3CSCRIPT%3Ealert(%22OWASP%20ZAP%22);%3C/SCRIPT%3E&hhAnno=AnnoF - hhMes=<SCRIPT>alert("OWASP ZAP");</SCRIPT> - - http://www.web3.com.ar/Mes.asp?hhFrm=frm&hhDia=%3CSCRIPT%3Ealert(%22OWASP%20ZAP%22);%3C/SCRIPT%3E&hhMes=MesF&hhAnno=AnnoF - hhDia=<SCRIPT>alert("OWASP ZAP");</SCRIPT> - - http://www.web3.com.ar/Mes.asp?hhFrm=%3CSCRIPT%3Ealert(%22OWASP%20ZAP%22);%3C/SCRIPT%3E&hhDia=DiaF&hhMes=MesF&hhAnno=AnnoF - hhFrm=<SCRIPT>alert("OWASP ZAP");</SCRIPT> - - Do not trust client side input even if there is client side validation. Sanitize potentially danger characters in the server side. Very often filtering the <, >, " characters prevented injected script to be executed in most cases. However, sometimes other danger meta-characters such as ' , (, ), /, &, ; etc are also needed. - In addition (or if these characters are needed), HTML encode meta-characters in the response. For example, encode < as &lt; - - - The OWASP guide at http://www.owasp.org/documentation/guide - http://www.technicalinfo.net/papers/CSS.html - http://www.cgisecurity.org/articles/xss-faq.shtml - http://www.cert.org/tech_tips/malicious_code_FAQ.html - http://sandsprite.com/Sleuth/papers/RealWorld_XSS_1.html - - - - - 40004 - Cross site scripting without brackets - 3 - 1 - High (Suspicious) - Cross-site scripting or HTML injection is possible without '<' and '>'. Malicious script may be injected into the browser which appeared to be genuine content from the original site. These scripts can be used to execute arbitrary code or steal customer sensitive information such as user password or cookies. - Very often this is in the form of a hyperlink with the injected script embeded in the query strings. However, XSS is possible via FORM POST data, cookies, user data sent from another user or shared data retrieved from database. - Currently this check does not verify XSS from cookie or database. They should be checked manually if the application retrieve database records from another user's input. - - http://www.web3.com.ar/Mes.asp?hhFrm=frm&hhDia=DiaF&hhMes=MesF&hhAnno=paros%22%20style=%22background:url(javascript:alert('OWASP%20ZAP')) - hhAnno=paros" style="background:url(javascript:alert('OWASP ZAP')) - - http://www.web3.com.ar/Mes.asp?hhFrm=frm&hhDia=DiaF&hhMes=paros%22%20style=%22background:url(javascript:alert('OWASP%20ZAP'))&hhAnno=%3CSCRIPT%3Ealert(%22OWASP%20ZAP%22);%3C/SCRIPT%3E - hhMes=paros" style="background:url(javascript:alert('OWASP ZAP')) - - http://www.web3.com.ar/Mes.asp?hhFrm=frm&hhDia=paros%22%20style=%22background:url(javascript:alert('OWASP%20ZAP'))&hhMes=MesF&hhAnno=%3CSCRIPT%3Ealert(%22OWASP%20ZAP%22);%3C/SCRIPT%3E - hhDia=paros" style="background:url(javascript:alert('OWASP ZAP')) - - http://www.web3.com.ar/Mes.asp?hhFrm=paros%22%20style=%22background:url(javascript:alert('OWASP%20ZAP'))&hhDia=DiaF&hhMes=MesF&hhAnno=%3CSCRIPT%3Ealert(%22OWASP%20ZAP%22);%3C/SCRIPT%3E - hhFrm=paros" style="background:url(javascript:alert('OWASP ZAP')) - - Do not trust client side input even if there is client side validation. Sanitize potentially danger characters in the server side. Very often filtering the <, >, " characters prevented injected script to be executed in most cases. However, sometimes other danger meta-characters such as ' , (, ), /, &, ; etc are also needed. - In addition (or if these characters are needed), HTML encode meta-characters in the response. For example, encode < as &lt; - - - The OWASP guide at http://www.owasp.org/documentation/guide - http://www.technicalinfo.net/papers/CSS.html - http://www.cgisecurity.org/articles/xss-faq.shtml - http://www.cert.org/tech_tips/malicious_code_FAQ.html - http://sandsprite.com/Sleuth/papers/RealWorld_XSS_1.html - - - - - 40030 - SQL Injection - 3 - 2 - High (Warning) - SQL injection is possible. User parameters submitted will be formulated into a SQL query for database processing. If the query is built by simple 'string concatenation', it is possible to modify the meaning of the query by carefully crafting the parameters. Depending on the access right and type of database used, tampered query can be used to retrieve sensitive information from the database or execute arbitrary code. MS SQL and PostGreSQL, which supports multiple statements, may be exploited if the database access right is more powerful. - This can occur in URL query strings, POST paramters or even cookies. Currently check on cookie is not supported by Paros. You should check SQL injection manually as well as some blind SQL injection areas cannot be discovered by this check. - - http://www.web3.com.ar/buscador.asp - hId=&hAreturn=&hAccion=OK&txtBuscar=test&x=0&y=0%27+AND+%271%27%3D%271 - - http://www.web3.com.ar/buscador.asp - hId=&hAreturn=&hAccion=OK%22+OR+%221%22%3D%221&txtBuscar=test&x=0&y=0 - - Do not trust client side input even if there is client side validation. In general, If the input string is numeric, type check it. - If the application used JDBC, use PreparedStatement or CallableStatement with parameters passed by '?' - If the application used ASP, use ADO Command Objects with strong type checking and parameterized query. - If stored procedure or bind variables can be used, use it for parameter passing into query. Do not just concatenate string into query in the stored procedure! - Do not create dynamic SQL query by simple string concatentation. - Use minimum database user privilege for the application. This does not eliminate SQL injection but minimize its damage. Eg if the application require reading one table only, grant such access to the application. Avoid using 'sa' or 'db-owner'. - - - The OWASP guide at http://www.owasp.org/documentation/guide - http://www.sqlsecurity.com/DesktopDefault.aspx?tabid=23 - http://www.spidynamics.com/whitepapers/WhitepaperSQLInjection.pdf - For Oracle database, refer to http://www.integrigy.com/info/IntegrigyIntrotoSQLInjectionAttacks.pdf - - - - \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/zap/zap-plugin.zap b/faraday_plugins/plugins/repo/zap/zap-plugin.zap deleted file mode 100644 index 208665f5e13cd2a048b9fc3f66619fa63cddc1de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39106 zcmbrlV{|6r)~*}9aniAE+qP}nHagZD+qP}nwmP=eVRzEW>AkT_*E)Vj*9WWpeAoAjB!t~M#5{#cyARtQr2!#e= z`WuSHdxqxzHyrr)Li>CDuTXhm1!)O!RW$~AiAVXFX*pSXhD8KfdYZYJ`DPWS71sR| zml;tMXF4glIVp9JC{S|xXF0FVoM;tPSrt{cTpHm^`X~591bTRPdKqD}q{7BJV`~*_ z1L?}3yu!@9phyBOCE?+IDrRm<^+E3b3Zj0hMzZ8|Sz48KX!?J%@e3u6~!GvohzmCzvnBfr(nMMwn-1jOL>LHw4VEXer^;B-0h)1Snl(4) zW|qRJ(2A=Si0jtEw%ORC*J=f&A#g-}s^yQLJs6_wv9gk7n;#Za9BjMZ@xN}r_MC0A zejFL*?||NueO8(BPEqH`k;ZC@$(1tEA5kOkAvx;|SM!WF0Ua-`kRI3FeBmtFdg@HE zr+DTLw~BIQ4|rMpHHTl_YKFX#F~#)cRC|aGcI6I|fOl6~;g8fGLU?_tLt9PH!)X3w zN4(S@T4VVo_o~>8(TnK#g2UZ7yUU5A^XwlYlG%C-fre3Bq`1Gn zgwvr=O_p$aK$rGQZb&lu_%k|{=(g`9!}mVzlv(=TINmH?^E5q68=bKn_7h$4hotH3 zI&Kq%vlpJx9)2AU`TXi0tsP@b`+)S|-=}HCBaQ3Wh2`eG9*aC`d3?s5k~63PStZ_K zi-U@bA1v`0sGk`()Jzie0fEkFbcXi=i`zc~K(tx*vxiarEH3gK=lQGw4Opcj_UaSa zH^+zsyPWKHsYM|$yDBORSPtoa-3eD`Q76CKPNYK>HW^d@aKrI%;ngJgPUn<}%S;IF z%l$+lW!t?&lOQ9s5l~5+%iVFrq~lIL+i?7CN~f|`4&1YTi#QnX<=b;6 z4?cZYWh|k5oQK*}{4ok*rCu`XorB}AXj#I;W+0tr3L9yTip{pr5>S_e({rh(O5Chw^#OgxCAh*Sep{$8#!4`lRk{-V z^`HTOX(5&Yod4WpY0S5OC3o6>v#ZySHK5(i)6L!E7~U;vlEHU!Ky{;*=v7by4<@D> zbBTC#L14^g!D)7Y@V+s4wN>nndP@Zp=hJGR=O?7YK1FA|1Is87M9 zN&3-1(u}Xrd95}`i?Anj=J@G>d~;iO_M)mNwtLKNW+ocvO%e*R4z4*F_6E_zEoy2# zf%)A7)T6bAfcW>U^o{|R<4zn+XXIh)`F4t8mv7!V8V$s^m7~4s;Ux|-WmjIt7Z6n` zQEcjhHP6J&XdY0jbg4BYd-G*qQ+{gXOZ2{H20~Tr<~{N<*~I&b+RU24F6&WDUPQEsUf4JJ^|DCiQd6`cyKv4?qN(V$W;@oQd4G^ZpAk< zl5FYS;H=tyz>UPdIpIl&5;Z4LQ0&vXoFTo{@#}YbokqeXWiZ1x7bjI5C?}>aOG^HU z`KfHFKlrj1i3B-8pD-#phWU^EXwNA(J>-&m*$?P*mxXlY$(9SUq+KeXlci{!pB&MU zJj~xy`(~21w7y$mOmi9f<9<_1n5-$NFf#Wv!KjAJMq#zOR^T9~)$#*aW3S^yUuUDV z^h8oj*#W*yZMH6IyJK8IX0KrLt*mExb8Y(_YuTPES6zudGglcxuZ~yxGplhb?O;{d z%K&EW^G(Hd0rZ;2Znp9|fZFGEly$7t@s3H3RCBTSU^6xq52h~rlJ;aYx5RS?J9C@v z%(e12UO5}e$ze3b9P*2FsTXsUKg8I-q5Yn`G6bN`Tk{dFwcFCpoS-B_p7x=;6gL|R$aeGW`sEsQMc9%4AuLQIij(!q>q`=QAc=F9M^IS_`Q05_ zX7g4B6h;umF@XN;gWL}LcJqlKLxp1?cW~vFu)nJP=>s!fO!n=;B*=?d#wEYW>$`39 zhEDF#G2IWy>?GC=w+eezz|Cgc%rN>f&4%2~qR^JeO{373%*}(4kIC|xSKy1HLD+6B zN2S~*0vO-y7iNC$^g2Nk1Z0v)0S~zLJctKtsO5yBpdgRvglTAO_XOiOnjmJm^1gRC z0flp1HRi@BIU^L-C3h2zcOsMr^Hj7Ig|>z15%#1K{vCG+>XYI8)>v`RwFL$l?j#Xz ze8DZl?66%A(!Bu6PXeYo2BRFqvGcG~uBj_|3qkQeAIWMVqb{qD3KHjNzsSVHJr{Kd zIuEtqSwfTy#CZxL-RK}BaGD0mHTBp8)#xuwixN3L%xp!2 zB;En_u18pwl&2?n8--*ZV%%21I%illF+iJ0O^#2rh_-BkdNAQeVxgL9F(%&m9tTN; zJS2pA_G7*r|7kk@OQa_r1VAmpKtKWjARzqz|3zBN+Sty~l8pHuVy&jDh$@Ws31pzJ zp;fyN)|9E$iSmFGiAldFGFd^B8+jURzwodMPr+{LrcZ}5^j$m;k@$*;Y=7JTb}xxN zPuE&oCbhJ4ea&rn=DU|O{c=`+CkQfQ>W>9eVh3+LH3lfL*ApAlN}qAz4x)uIL(Q;= z2xrGOgN5ge`cdEI<2$|1+kJWym8(=CWOGvIny>j**IlyORm0&+fbw1OXII@WMHH{f zq*LO7Mw?>X1xiS332m@(3stI?y`}YWG+y?gcSXv5`XwJU zL?`F_^8AbnhP0xigEhI@n;3+Pq8irH<{_k`OS)rtoz)T}+V+oTyY2IB(p^KW;bUUq z9b(!p>rkEn9eGFEDiK^SB3g9eh~6^XKFV9!*_H`Y-1&+;omunhvT4p#f1m@YTtaP3qNwk17rjVsXIZF->OvVx#xSrXop zGyK;4;|cy?jGxOYzGoWa0!>E!kY@?QzAH+P%Y`%5szUxEex`vf!n z6X6?$zX zLMRaU&Ag|%0I8OOEqkZe^>o`+@YJI3>+LtffL{t^!jL*Dcm|6z!n(ZNJ}@$S!umRG z%mKHM&Mw?5T0;bq$!Dgxx+ zBS(F9^vNTnjQ2(8z@(jGiN3J}x@n*hR+U$fSL1RW+;h~rp9qk4>BK*lRJ7#|PJDaT?QzZk!)TRn+RbY*=O2Qy6Vfo_1vF zA&zxwaTc{w7@If#k-r-2u~VSDunCv1Ak4N#x@a*$@Ou6PlPE-!v?`VOnjb@&f~6rf zn|3MRF{_`|ul(+)(kGEF8sz|!rQRSXF^{`L?e|pXoVP&Sq+wNy+|2X`yXGF?M`)@5 z?E5nU>JtuUX2@q^jHOM~)`C-Pner0XLNl(jDM|*LKY*CXH_!?GL^!~u%+4O(I}ZKs zB*Xo#%N;F?MLG&GW|}|UA@W7G8fu%QGszExv)B^ zyYDeVg)c2HMguEtn)I~7j-}+%Uzf=YcL|lzhnF6?=afD@VG`)*>X{6s@(Y}))QlBt z{%;|3PY*97^7Ll=RH>CPH|wk|KtOi;Fp_M+jyf5`*gK-wiw{ zf|sO9@cCUHxi$*%u5-~DYgn!m<+a5T_^#Ift7sSfg(FObH~C}`W`hJ?RyIvsw1@d8 zM4k*Q`x78H4?cUSw68*%nBGyrs*;*Mpy!9*^bp^lcvB-RsOgiH&PB(pf^i|>LbF+I zLOoJ%mlK4>pQsUIyyQ}Ld1fQR1k(3IXSBHkJ|tZl+~RkzGRRJ{8=5MuKkzRIlZ;Zm zqNf|&k9kxkw6)Ml%!6bqV)uy>r%2u}Fs|3<5ZVun+KCB#!x5JQhG1HjHg8#`VOWvk~3^A6-vfF76t83rg45#JG z{GMSyXpC_iHmt+ML0Pb?6pa*7DN(GyH3C&f*dT=!ERYFrObV;mIEHzo&5OEF_cThG zZfl#JF4>sNa#P$s-touUTwM-(;}Ps~p}2k6R?mQEtDU_Juy9eIJ!b@Ictktd62YJ; z3dLlK3BfbVm|vT6Eb~f%o+Y$NLzqd-6-bRSg*!duKbS6y7I{XOn~u?GFSYj#c+8Ex zLRm(AZ5PQKN95Vm7mP~kcCE4VW1~gRxNAPl^g0qu)R3ipti5BbU0>dA5tjVj=d|Q% z6@M{)1nawkbd`K&dmGuJF;Tyb{qm}0b(o#-kI^8%^^y83zE39!$bw?}=x^hdEm9Ut&T$d*k_Lx38wp?WgWv(^)>q8)@ zF`pW92%Won?(d|YJSuVrj8@BOTM^2_?_cGrb579e8}LW&56V6h7#7eJCkWJf>tRP^ z65;3ibSqmc)OR|bY?j$AD|vG%`s+T<_LQNK%gDDy2Uw{V@(inM%oJA(b6S8>%&_co z-+60Ajmt`^EKhrrc|7G#l;SfwgEa3*0!c|0&ksbFO7bTW|MGKc;)NeH@1O;lSs?J4LL z(E|G&=`amPNRBo{TIj(CC=5PGJLRH1{D4ClbP`3MjRM!_a8F7P3HaAS@2P6|`2M%Z zoBnO;{r4?4>wmpOwHg<$XzEB`{3tBOUP)Nc5D+0qLlhGZ9n!(dC@A{dPJoaRa7#}E z4pa(OV+#%lG{v4f-8ZQFYIQ8C+NJokPh|harJpo+G}UzU-Ih()kQnjox~=>>{oeKO z>pOQDil4rB;2_x#r+nLiH#{1J`r{gI=jS7FHrpk|aGb0zaM8JRUDb=lrkLNW7t0Sc zfDWdKD~-7A&1p-E@%%M6=8cNu{&+^r1BXPWo()(lP7(Q@ms-GK9-tFuwr8`4BKz&C zli08y4t!9R(a6v29}sP&dW_jz)-gV}$1wgBD`o|FdoH;n4F}j|&LoRRJi{6sXV{>H z-E_kq&AG=W;U`+c=|Ykj#Ul}*jCHp_dA*Kt+LgiPt!ZRD_Ej=U0-P^Vx}c!!C5 zYr=B?%-WxxArN)g&@nTM{-(ZJ9RmBOJu#Qf8&*`p6mz!`3iZj2`g<--e`v7&?tZN! z;pHMJY7(u0NmvpZ!x5oj%Ai(UG{&ZKL&6$E=FD-XVD!tCcjn@D!!^BFoA0##mA254j`H9>Carf$u4a z8f_!dSSK}xOZQD9v|j3m?0NS*yGUAos}OLNi(rhd_RuRp{5FK5W={Sp7PWkI^6b1O zUzbY0AbN8Es#b!!aFp#%E*#i;q0YFD3hO0uZ$YX$@)3CjZYI3>PD^R*%l&5)=l%>9 zl(j~Fsa^6A9m5|9A<`;4Sh}oJtW+zadn>E6m?m*7eDq5#20IBqI(KhnUR@yUh24qU z&#^WWQ(j!~FUCbNhKB1A(35bVM&7fGHj*I(O&?08_@r6NMZ9j7tt7yNs)OZ}{*x-HYz zK1=_!HbBTR`=P_@^r7#FG!`E6cSL&YT@FFEA{`E`OOMH;NfBhhO zY#W=Ymn>Zx<%Gn|feyQ=j@(OVv*j@*(@l;YTb{~53YR;~uQ^2|o;S^-duMX42*mj8 zwRAoZTBI#el#sKdcL4)KK4_EdwlI5 z<3t)uulqC$r2u8!>2z*Cin+o7)-@Cy(%NV{iKjL9JCPQHfgH~vW_q$}EBJeE9chL* z31j><@WQd(^J)lZG7>`**i=3lx0bx{jtJPMt5b!-OS(0Q2o0f2(h{Ed9AQ>cWS)A3 z{GpE?2I=~a2*BCBHpD902j&OHhkW4+{BG2>?POK-N*H?jig@T+{_MN9n)K=6P&Rqu zk9*`b$sbFvjo0_$dY+)u3g>`~bA?6g)rq zNox^sD>QM3Kh^E^pLu~@Yiueb^2YO=rf~eU)TbQVSaHZL{zH3)|5{b`TzrB>|4tW_ z|4tYF`&E_gA5~S;+6iwJ`7^KO$0mL(J@IA}hG7%4MWT7FIUH_%Oe8%SlD75`3Wv3S3;`DqJ^Wsh! zXQVU|%wxXsRc|PLHT$$Qm-nkww`2Us+tr5xzOn871cRJvzNmXq`&+Pm!xitOZ*{?U z)Ng&kgwUbA#=|=e;zp8F9zYby=Ni-axQCpC;=C5U;Wm_zu42olMzLyp1RPOr$yaEf zkizU2CAh{7b1h)IE)ljNS$y?7gh;K21gu&KyzK3CEWA{?CLt4yYHHJR*Je2{WIfyj zQZ;>nyH=W;j{J^0IlU)?!Y9z8OFS&kLayBn(%w?c0%C1UHT-G#yNKW+`LVIJcO<`n zH12TUT%z!B%1#&OjLz?tG6w|m?|kD88!YA_?OjXAR0qc1LdF}BadmBrEi){PBs9!+ zUEeBm&?{i9T=I-5x?o80=MxxQS!(R&vWG*F$)qnyTNo!Osz0;4z+{)29T^tfD#u6& z67hD*HRBShWWV$A`&pLfJ@Xgshr{}dDcA0UMo9n!Uretl!EEAlU6-16jM`T*8vRLa z0-V|bXW za32{V{*W0V{wNff{FWQMXX^!~XyXMNuy8NQN8eDB5d_efdEMR3F}5Hx-^*vqF>x+` zummkN!U9;b@rCFgzsBILxR$MF>*uFS))!r{2J82b6aWp3@<;f1{YyhvwgUpKh*vmVWXmbI)zQF!DW^zsN~1%Ruvugju~9q6oY!-< zHOgyzk84ul#IBE_UsO)BMRf|^EM&bYjw8L?^QQEgBlQZi&LR!M7dkj+G^LA?1V5Nc z75ic*82KO3O;FI9%>mAjHu{~n;j_Rpdfjt&?w0fNeUiCWDA#Ihh}0VrJl->Ce(fND zAKbHQEY11uOx2xk&*f;Zl0Jkyi~hwkb{#UG<%9prN(;f3Ry=kH$Ait+mo#nF8aT@^ z%nuep&w0m0r(yeMt|(R?K8^a2*^5UfLI04q9jkcG&I_s_l$@l_FUuTbS`fG(QPTc2g;J`d`zi~Lf+=?hJKJ$133i^?O^}usUZa^d9UAFH`nZTX?W0zz zn#t5Dp9W#^)$f`0ktqXl%;XyWNZjNDEv|TXN@sl*U!1Gzx(QQoR5lD~jya?n840iA zs)j;};zla_5fVnGy};L0b==1e8=N>)yey$V(t6C!#682MV{^a4>;BHHu< zgN;*kg?N9&L4j6e_bAOa#pMo;Q`$bYGda5v zZsl_1k^PT=aHqSaPoI`A&)|9FPrso6q5JUAuZVlXXoyepwy0E-Y%S8PQHREzZ&k$$ z=kNBYIt|gmH(Y)n`jQF3mdX-A-uwp!5)k_yiyX>4iv!(DFMMAfPD3Y-w@V-T-cXVG&lE!e#VUM zFZuj@Wk5UC2B8w984-UsaRk)|v&?7Yvu&hxd_He)N9rk(-}hZ0zJDF`l<3zh;lHZ$ zkDp?2r=TDpGvNP;Ib@AM*#QEN29bM%_tE2Yc58DpzrXJbAUaYnpRA$QrHR&fz$B&2bqH{d&1^~ zlk9olapzoH{@qC^9U0GwcRKFH2h2J5 zCj266X{hyC4;4gbd|9>OUWuxj_hrKR5PSQJ*6JW&U@%GyfVL?mO3#ZgWpQOaVx7ZHR!>f~rvs{tSBHqNL%=$8DpNr0ho=DH8)3>m)^)wsIBJ^dW%4a_ny)(S@bT1 zws`KfU*QaIqL}+A45;z|&8Zx5y2Z;y)ZQqYOvPjai9^nR1*k|J_UiU8K#l(qKpg)B zNY`${H$E&(G|7L=b?tL){PVc}N(gdW%pStpaatS&Ak=I)PrG8LTW!!Ah811C zohb5-KTs}`#|SulmxzzsCWuZ%uS(Dv1$Xe8ia(6g0MA4~Xbge6~ z?jlEQ3`KjQM1V5v@V!xy8T_-{2I4cB0etOhlre)%>M+jeC^0*ZV-A*;jKT5P1?G^4 zIkBPw*YEQN9hzvr!vU6^BN}KBI8jctu3goqcP?2gp(UIP@}<5<^qM~is`;|{t}R_s z4e~3}eSC4Y`+Q0=aj^=h%^ggqGGlti?{FEO@bfq06(8m`!=z*Ma?SQ^8{q*N!-6x! z42LMp-_4wzT{FsiMHKI8HuWqd^i%i#t%XSpPZ`qow}rX?9}PG;{{fQPmddgcntnKj zib$XiV;}}-Z3c#&kZ|24^dY^MIg$vZgGa>_J%Eowho`J*;5knqU3pN>QM!2qE|Ovn{PyGz3lE2b*<-DD!Cv zKK|mvH9=c{XJ117L7+3(8RPoEMT-M*-cuS49J(OrQo@AO;2?22=9reBSukdX5Tg+@ zwpttw!Rp|zLaGMm4dd_^hV&b|JD6=`p7zUfg_9|~ySHQKq!%3+*b!&l7~bfb2@CiA zb6DReovP2JAFn@;w`x}w2%qiNk8)4*zBdi=e_1V8OE#@0j_yh0qH1$Tx1?U!dRTBc z$X70}wNTqY9X&xV3*#7FwCGrVZ**Vu1PKW(qwZ3CgMT`eyD1tyKJ~n-f*E>lA=bE zHbo?@!qHR{>`Y;wH9bR?8OV7y37JF-Z{Au(;O=jq#ZChN<8O`Q0* z4TS*hmlcN|p}fdzq;^O)pIVq(-Jz0^?wN0Nin+Nt;q^+W^>T%^$lw=dhI!F(?BKbv zIZrWtODyf1tZ80#u`f`e<+a%CKlDXfP2Zyyq*|2kB!=@`^3516&8QnIXS$az5)=n* z8ssD5W0dQXr;C(w1Tt$sUrcX{h?fI>l^l$Al%8R-Ymdd^N)s#%DjHb~dZ?(wi5d7& zd9}X?BbC0aBpKA}-JNl%`V?#<5_iXyI~&ynnC z1c4lx>YY)Hcyshn+5!t!x9Me`@jE^YtXfyM0dJv8-fw-u9(~5QvXh-twz1p=V9ev3 zj9MK)NF@p3*m@XwI)&Dk^2?|CkvB$|-=u>_;pPUkTGYQdGeFzAquBKrWkY*^{zCXy zxfMnSylwx5BI-Yag8QFx`(J)-xrEDE9|gAMFBC*l)(K7tLR5h?L})N*0wqPeoO5G4 zQ#;~U@>woo_aO;FM2H_C{%9s^wSl6e#85t#d6v69nfPD-a}c@JVIYo;DLQkg5@B8g zp@rbYJ%DqNvZd}_EZ?!k$`QL4*}f)+_y>DBGMPtHVqDaCR0wZOzc`!*U;6;duSm>d z>0RzY$ohl><~2*z#qJtuN}n|$R7cVJmrKiD`b+G&WenYu97z+taq4UQU{kt$M4mOh zJtwL+!{&{gX8+;=gAK{UgspY>*zGi^aqZ?7swr|bIOcTY3WL8|sGWEBf?SQ+Nq}&u z(^iZfNj^>e_g|rhoPIp%drQ(5E~U$uOE+1gIajUiH*8@ArbOUiJCy9$@=dL1X8d+9vzOht}d63f0zU{8Aec`#7Zw z+%?U+87-#Dk-(>-n;&}xvTAXiexE3hulj4#`U;=Ysh_y~goFscjH^G4tM}>VoIPO9 zqW`+I2kleBYcLyefjevD$i08XhHQS~WDOex1o7_xoANqAWst=)F-?wS!jO3p??$~wzIJt;*WJ=2!el*f ztfJ4m^RL^k?mVwOYwftNy8o*F-J98yDfedL4|7pfS9e+WKaSh<^3T@+Q4l8C?W#f3 z4*tj}{1|tq#mP|x28Gi@Gzb3F=;aQs+-QBhoWa^|Y~JMP<_@mxXx9#|^ytS9uKZ}Y zjt-@eGpBE+n3Z0Q!1Vo6Sc5WQ3WK@>bgxpN=D{kCLC89beSOqAbC1C=?!5$p<50Hu zh%VYkCZy`U20}nwyR{eZr^u+^wr_ZpXVsf5dcdgYcIn{`d_e7?qgqe+qL2Fad_#2f zyBgmBQ;7-Za0t!r{5>eZhfOOco%T%^A&tpbDWvobNz*~~-WWmV0lDrYZZlwhqZmg3 z7@&0T3=C(}iu6JA6$zo)9-dXCc}sz;z9$CcuNA~~>x9kUo8_Gx#_REokLGuH8`_c_@mHW*J`zaannE6%!6u8|`3a-v*;228aezQX!=lS~U19w;gS0|;#u`JQu98v@lSLk8?@0c01<5ReZXG4HzVBd=);%i4AVIF2SQxb!HL+3v_gY~B zFCEdS7qdL#l~@`DGsDd+Er%l6_|#gJQ4>jhXr*pOOClK}X(gvc;-a2d9#MI`VUk7j zQ(d_rN<>{wa}-{EMs1W%eMVyxPkcsvVOm!gAs})c9~uiZRII+fbMv0mOzrJs7I4eq zd4y3M7}4B@p*B$lfVPQ7hVIDD3~(FOc=hlU_E|WhuV4r3^9U$zZ0T*Cv_;xWn04sy zp4`zse8#F34!vla&%Nd7uP;tE4q8NJ(*Y+iv<({7QL?}+6nKidJULOvO|R4L?dpOZ zG>p!V=AqwuG81nRMk__X>Y9QX)(bT`R;8l?|yR`t6qA= zQKzq}jBYJeO{?GASkhHhJA^S2JC zPZm9ed2_q9eBip3nq0ftEKB@>y^ayf>Oz*vSLiDC=M5cGNn@#T?tDMJ(DYO_Creid zilJh6$SkD>%L4b1ljA*h07I7_>FHOjlm2T<%dZb)5BmLG0&7`^r{7?SI)@^P)s!6>5_7j# z#N4*XIplp5I+4ccc^bu4y`_Wq%QRjHFI0xbTit6nuTDE8JR!P#X8E1qPFl+%H~yXp z71MkUS;X>a(mJ#^R%|~q@RUaQE>qOSoXna9iW=#Ab^*8e!nYLX6gyr4)b_V!6e@Vc ztW$9a0s+Yfj9N6H4+#3InmW4bdfGT17PVy^42PRM>~-|D2%4%mC6zQ@nRJRW?9${O zcQ{K{`SSxWb}2Akf@^@C*e#kJ`=ud+G|8s7T$8gbZm>J zA3YRdRIQ6~!+%mY{tO;Rx=`F!@J;0dkxJ)IRrCxsF?Rti_NJ*#_DD|)j@;b4aYA8~ zNbub~*f7z5{5>g?BbB#|x15GKN1_cc78y1+F+7HIy!;rhw?+>EQCb!IWKE>FCY9S= zYh~=1l)Gkj*_;id?Zr#*m(ZKeZAykR+&+yS!(--BJwyl^&CDtpvri}ahoq4hH)H?Q3v!a9K@=-WQkYv@BcOZq&d#88ZVrQwjZr^M zgi7klG>YZz2wRJDCogv}eSFpF1X2M7&zZqS@~mEP4+`R{$iw7}I&`J34x+TgBs)o{ ze!{=v()Zm+#BApBnVJ1q3Vg9XOQ@_NvideNcl~T<(7U*!BPpwTO`a=t_I#{xD{%;o zr>>qHeK4%X*Wl{W4`&SMxh^rHRn$0Q7W2GTXL(=16Ae z%kkVFCG#HX(K{kG1m9$!TgFZ9%mfmX)!Or=4ho^){hsyXVN=u0>H@A+aJB2lWBvrv z(y)zx5wTq&4@={CwXSiR7p#`I~F(Gtg6`&Do^^=*}?=X%Qwo zSEls6Ejz5v5&J$kS-bRnaVsddReH%5gx3ICRUaEhD$)M+)-`m6ld!k=j!a) zmApSM{%+R>QJf%)Zgx*&OyoRr0|T?R*cteF&{aL!HLPZtOUTJ(j3T2hutHtF#8Olvp6wW1H%aL)`=Gr__1 zrpms>sGk`VMd{vtyx-G5Abgfx`pYZZFT@zuF77>lpqLbIh;jEZY!`tR?n~xzcUg@H zM5%Y+!q+ooL9~{P&m&DBGP}Y+Sb=7n6*F)=e$I~J;Y%84#gTSS?2{x%BkPrz;^@CY zqDRDK&FMN+Gh~gX3BNLj*h{5HIX|qko;xJeRY%vF=z85f%3y6x+5u=|=az1k{0$n* z4AaXLz>-R$F@!7KMbLlUVYJbipTeNwbS{m-fpl?6FQg$T&7cY+;@;>TN8fa95GyQ* zLvgxAv3G4uZcHAcP4k;1O$l$AmN6)xmm}!-t`(45Ufnak<=pNXcxoNzR zJCEIRtcTxc(h5l};JA>4cBY8geI8sH%{t=Hr87>z+r_1tV~&sEhr;x7+3fC&=riA0 zq=k7l$O-)j**OpU4sV+Ki*M#v$em{w0|OG~rAd6pMB6={=rAwU0s||ouI98U#5~vRmwh4uRdiGI#@+aemGCb883icDkzr zW6`5*DOSK&M53}Ly7!PoT(3O(Y80VFJB>17)yyllV3AE2ne+0HfGmfVGd5jh^c?nS;*BLlx_hAhkbZ>F#$kL@zVFB8y5;w1vUS*VD z&MZJNOn8(^XHJLYcoS=75sb_cm3JiTFsTNaI+3F8+F7g86bqf6_GL7nqh6qd+!$dnjs`b}mmD)n~9z3d$_gI&rOO zl^SI2$rNF6O6lzf=Ngt33XrX0Nc*}UpN4^XECuX31B%~IqboQ2*~9NEj+)|`3VdOX zi7O*b@Eub!H^IGUBmL6Tzw5SBg?C5t(Q$4$SVoc5e%vOb#!FQt59K%|k0&^lgmG39 zhYXtOI$G%b2$xo{*eck=@W0OSZV^*SW8nX(PT5xuoHbA&_7Lvr91mE=5_zexW7qMm z%^NfE2bO)erVTHos7tD!@=VR?;D{p(Ve1qL3XB0pj!EA*I2Pnbj5-do?dvEGkb)DA ze|wDO(*_bfeugjw2-W{`wvYlZfzZMiXpbrTxklk1q1cuvmtOIB%{DW+Joa+UHteJ` z5X0C5+xmBF;bGbu-~Tw`&Xx6@hF;Z~^zoHvWkdiGeb$&^*o749S(%mh))I9$7__pA zl(#%brU@mxjjz1knH$VLqFXN4)VpQ*!|Ddusw}GHAE|qjUPblkggD^Pw!70dL>Z4;95N#cl(pJiJARlR5E~EU zozNy_Y)@rS8OY%zGK{iafUrI9xqjPIIdp7k!QY>)lJWnem=B zu&->5oiWtvJUx-O@Nb35kFcm>S`|=yteL-fy(2aPMxeF>Kzy!tfmqcGS6N#PFRCcGSJchXM4n$h>)aX%4;8y$Sdd9fV_iOa%YcFcg2- zuY`NnH@zW7y0=omm-S#h-CHZ*i`&}Lz#mp{RAGD{W?sgDFH2U z_9A5A#~Cw;Ft~vf12_1FWY$Tcgd7|RWxOQJ6{S|NHi_=d&s1ul-hFV6WL9oBfbPy9d@IiK=I7dfByhKK7{H*zNJ z+cy$T)+clbN8T54+MIFfIs+aJJf*+X0VA#eNxG8MUUcD$htQv zp$NIQ1~-i`5PjtlHcP>~gnMzfMx}Xb7V2PwB-Kk}&9Z{H;v6^yUeIj!O>I^23V4aM zQd9h*{!FdIxk3=A=1{VywrRv{!R5n!MRs-xo?zl!Cgw~ra^Z^AikN&9ZWK$-K9i*4 z+HFjKgbizab!ap$-tZf`O(57l!f5>U(piLmRS|wrf}jA3WA)4;!L>tPq)9IYQU}e< z0bZC?6`y)p)JW_Hr|ykS$4(~8u#G2=$U@F|hOI0#pEq`tEv<0ge%rWlQYeEXv`$@! z+o21$=z@$BS7hsL$U%$_8D?_Ep5=q#L@GzM3y$-7le!8$cwUR9O(G4hoKM+=2WtBk z_onm_n=BcGe{ir-V1WlTMMha=)!sMh19DbP(L}GRjHIYz;X%EnM*j4g2LALC&-=8$ z=lH0Syccps1Bi+-u^dnwjTu8o01uqi80HU}D1a`cRSDLC3Y<|q0Z|LoQkYv0c6*7=rwHpP`8NSX-3RdvpkoN8V35WKs_{Au1|WV4Zu4Daqz2sKdC48nkQhIy0*J5X!#l zVwkiW23ZjjXOTokaBC4tvNGj7K8b0^5mRMO$-WXGoI0b($mXqI_LC5i>Ds3Q1wt?) zdk_nZMFI)+5Cyd%BIvP)> zUQ5~EKSubnaOZV6-#IMlTT8gl62UH<(VfJp_f4k!GaP94FN2n~f|lh0dd#p1nP@Bt z(Q>Si$<+&ZMzwQW<=CwjdzDnIjY=^j#UV{b+%pIJ zsaQ30?#e`jZFmb6Zwa%xARQCB)K!qHR*>u8dzqkfC8BLe!P=4Vc1$8}#o2`~I-_$j z$^<=TG!dR=!RD-kpEZMFX29lPRtw=$JE2hTQv$$B2Ifd<6RmFBz~g5$gMHDn^*pPLR|M*=Sr}6Rk*)I$7OnDzCQR64n^~^ZI zw6Dk4|cbH_P!+=4)ty$n3_ZQ_bJk!t#A&Wzd|GFp%N11`Kc<;LFat5b1%b!xO3YBRa7 zZBS0Qt2(_^#|c8Szq^{nJ{tQ*@c5~Dq}l!y|7nU|KJ}5&XdMa@d6GPf$0j1orCN5p zN4>R{EEu|f+RMbDDG{Peg(G!r8OmjS?w2AaJ2ZbokGRRwSCmijGivKDRR?V`$UoaW zfraM~G(V8c7e(dXdSbxRi0&Zyo_k{SY!cicurn0%K(_(fFlhA6l4^9l0M;;EXJ~yt z`xxC(@)i(Hj0#7+a?f>Te<}xdR`OH|J2z26Jzvrt-U)~+rG5k)$z-{lsHr?)_I#VT z@q60hV9&uybunRUGMEV3_(FHukaWlyM)~>nE(jP<>(UJ>mzb zLYeOg+Q+w?$h|>=4*~}A4_H1tXBR77 zy*7lr8|fz|hdJ&+rMd|wpY{r_%_Rki{gg{ACLt+~Mk6WDGOLw3fq#2}KRNKB{&gOz zYK%!gqhu8h2fYh;6-rkRNTBcsEiHg23=_RaTOYa0*l<3uHhsu8<0z z6bTWLAv=S?$A~s=Fenj9#zGWGM7$w^;~5p>QkMhjo1k1{NDg*}8WKqi5+s6ZM#yyt z#{}s@e|2I(c_Mx3j|6;sa6|qAJq!rEhl>29TKtCmiME(e{QHpv*Py5*HMb!4b}6|K z@@&ejA;IIv|Hauk#)uY0S-Nc7d}Z6VZQC|p*|u%lwr$(?E7#Oa_e?T9e>#)gtKjgD{Luu$0lV}^fkY+{ z`0GGpOIIFhh30^)N4FDGUO3jdG6YCl**S{%BQ zLDG8q1`aZL9O?uIZuE!xq!khQjN3n6spCD{E#_=ES$zD_7K3&I`Csi>f?Pkt=`6Qa zRq}d6X7`8mTDtQPu>H5!t<6*2`+d*mSC|OxwHnA8KoR6%sp?RN!jRG^lLTT({V?@7 zCkVWHRZTqGC?Z6XhYon>St@Q^k@7mZ0 zguqF)V=rm;vAi^wV1;g?sqBh{OS*S$rhpuYAxUUlsAP}<9Y_h zfst+dM%V{7`hqg&>Vihc&?34&2*XY0X{E9<>p5oVFZx2(k;KFz(1DR(_Ey*j!td2+ zRNb*XY4(XOr`Z|U5*I387fh=pqN+TIZ1>cKzMAx{a(&2KxWKpIKj5AZBe^g~`$!i> zTSt1V2*6B5eYfHr0EiPa!HGt5cOMctYDVD(@H_OAF7Ii{?Qt&x&TGgz2*#g{(We}F zmPKIX-1@awnRMuPpRLiU?Z4`w(YCSgtF$`;0Zbk!Ny>!A^l3Z9qk|NVLNT3fqf3a1 zkRQraA&ky3pc+!v;Cz8*<`efl>3?)=`k`sudq8LF_cYM9O!^n8-5WsJH10rvO z$JC{WR|&(rEJbUJ@L)-oJ7U%4&6!Ks#3Z9jb=%m5bL66HdqhfC64bRdMMK((h4Zoi zp=);sMi+e))^9`F>P3-T$g$OrE#tYpmp1M|7kwB6b3OHIq+LI1baIEzJv?@LgXZwY zvrAriduZdwL!US#TE8&Fbd!Mdji+OImC~g=nuO`uk{W*aZb&t~Ga=P8xJ%Z}7{4^x zP?PSNm{faYA=RTAvS}D_8PE+JUp>83d$R)D)xV3@%@}3#u%O+wzN69Q)c8Z6YWI9+ zZ>-wXZ&EB*jcnr6U#$-oBVH(^cGozj|e|D<1?*n&*AMg zXIu{B^RGs2|D;?*!oX+JxLjtJUQh1*L*r*wD*T-W>6aj{&)zY9#Cy&WzQ>z~kANm0 z>zhcTui=9O>5no5AJf|@X|M6ajyH%cYIP`%3CJs@6vH_neWu`-0=~f5+bGg@}%+x>0`#^P383x zMro6b2_wqdaz|;CbjsDjhb4MCyuohEpoetJqH@u6%3b9`8J3aC5z1cfk@O3CrD(P# z5G9$X1*HpnAsNOcV^Sj>dOXW8ku>k+%fQTl;&^>8DT}{EXts9ggT^hv2lx6?PU-{%8=49b8;d_v(&_c zVhuJdz`^Mfnz@N*d6Hf8>Fekaf}!5RlN%E3Z{cNKi$T3$(O}=oa*g{Gh>35laDAhA zc7dLty0CdO;lADSH_w5ux1m?|j|pzYu;gT~g>P*FN6uzQlTk43H_?WuqBXaqjBRNK z-OT(({{~fb4bQ97E$qhdOsi_UskM(f9|JTs$V_jPo~UrlVzFe7;Gr-W7&@qPzwU9I zuu7%Xk#Ce24kd`0i_py~Ry1myY2nYK#cIXPvQ1$XHOgObH>&IAL7~z?fE-2=;?13p zNPaHg5=c*T1`t{Y7Hw?E*X%?PLfsIo4Hbf#Oi%f8^QcBL?RM~TnYL@O*9Cos8*QQD zB37qsqs5u0yf>sH7wCffb3K(%k0%DcfEUaTaGL&W!U$X8=&5?{oqpYur352!$e%?_!7!|?nh2$>6bkD{c6}X=D9rwg!*#K3xj)y+nKZ_O zRNV~V`OgtYXI-T3|(uKE;yh^Eq_t#3S zF<*dRZW!sq&)0Ou!RePapL^LbV-LbGqDW#Hk}pZ)(v)FQW<>2$m0?nTxMUsXF``I@ z-Mn;fnUXJCw-ipPU&fJ=QF)^AMEKXZ>@9^;A{!=U1&nK;7?BG*i*@J|*n8oTehNlF zAg0c*-2N;abW5*{1|w!{im?bWg;EVVJq9xfeY9UFhw~bmg(hNTBjLVpyUtKy9I`<% zxEQT`cua;`rF_VDITVTHc>XMeej$aJrdc>UfV*FD*|I#}l3Io8p|bFlrdb+q@>n4j z{Bi|qS-&hfMYCAeB!e>vWl6D8g<&zumkwHHqR9>}Vl8PYVWunwOOw{Pd~u1IlyM15 zD!XRJ4{#HxZYjNDO3`XrV?3D+SE++TH==4>QJ@*lek^N){*9@K%rzIHTLI5L{tc4} zS1Nc2CzEEmKob_VWyv%C8Vt2wIg@i)@tP8<4>F8qIiHn?uwGfZ=#0k2P^=4u;srsl zXBf2$VjZXp#+D!)i3Y&M;jhOH?lWitSgcUty4@W=9yKP$2Lwt7R>4z;>Yh&^B#~t z)3~JS(vweHw-kIqB&1_qE+zb_G=zqxc@b%d&3jv6U*M9^BNc>{uda{uU^)_uenW?K z-bC}JhAe}_0(wrPIs(H+$Zw*Hi9iEI}lnSI-t)dp= zf>KJSx(1L5$@u;Pf>e{nrFz4(?2_80`%abpDeSk854FJa9)fKJ-A~X%y0xQUj$J$$ z6^hW^G&v62$~Fjmz6iE|*hn-#y@%>FkS%_uQ@xKy@0duRH-PIdETSg6=BNKBGb|W4 z%Pbr1s%~kzAy`XHs@;q zMq&1~jK758M4Z-nuf}elWVZv8M>X~iUlOCt_f{uoLt77<>6RY6N-+jf?eX79(nGLb z_|nioUEj>2i^eMRXc4x})(;CI>4i8SGfCGcnZG2=Fj2{30fHDBaXD-jM2ZClU*dOY zX^QC9TYdm^&DBp5a2krufWm1Aq#JGx3ZR%uP1bE!acSz~aS5DcJPBL0h%yx(f}-vG z(EKT7Yrv$=!+)}2wGJ~PmPg=Jmm1B;Hp$>UH)Zr_|AqpR3;C~|mob@qkSgR-t75#GhfRiMwdvDoBtM-A zxEe63u`l)uO^iz;Ghv9^{ba%9kpFePwRDZfngOzSu7evR%dZTeGVI7B>LD0D3DY&I zixvjLVn&V{`dH605=yU@lub?w+oQ4INS9q|%^>fYngLwA@CB~0GJ4 z#Sv5Kwjf$G01fR(F+0z?c%+>!-@g&PC;rlBBsc3uf8Oa=nG=g-wRJymFOzgmyhkTe zX=zFH@$SMgvX9Lzrm7)>nJ#0@mW~>3=bXF;qZru_QsiB7J&79G3doNM?$^g2TVs{NzZdWjfl&Y3i}~t z2?On7F}?O@rnUu>wxRX~mpH>nuFP4|riDuvFM-RdGrQ$rBy|jDx5TWhy&uU-N7aKF z$=_maHO+dc8#DnBy)?9KhtO#S=Ad(^;(!K10tvU&*Js^9c6W&Rk$}skVvuAsq!W%@ z<|TbGPc@{A8zsq8tKZ^$!RgHD$|NQ95c?`c=TcU(iI#G_pgT(&mB5+I#8GW&Ipwg2 zp}~{C6j_mqvmmMl!&JWD(-A{G}KGeEj%4udL> zC{v1QJ}Y=B5`|%7C(4(fi*%ksAIgRN73E{wSakD;&13!_80)N7b7%;tcF#WGKVGc* zjr|G`@7HZsrtKqWUKRxfe&=j|LvM>EB3>4&c$hi%?!6R?x|xH^BV+EoB09_~c9ph7#NK)K zj>`nOOWIxEr@NK=FxYTg2ANtCH=CKPN~t$QM8-uW8Wb{`kqbDJdxE>6EYNw%cje|6 z-)WxE%hVT-X`DTvzt9oN=l(>9e_no2x{3w*C#Fz@8M{%gNEJ#x z>tybYIh8iw!x?zGbo1;_N2F}YhdCgRxQTjqR*xKX{X3C;BSwlcXr=}boUA`qIO#9GpD9xt52XRn(QOvM(;4kBmKKuUb{nst!JW-+&cR%@Dth>VC6TW6Lpn=(l^LN zu0T178$8@G!Pv*jZcr+oF2?O)%+OV6caeMp!M7?C9EetAHM!x=u^B+tv75M zW8Jt(PhsW1`Kh9KG+tp1`uT#Qbi76sFcn}ajur4l&KpxrovTcmTped_aBaiWUtiuD zt8nUWbE>R9l(7`CiSpBxE0)qhCMea?Z27xK5i3(G0g&kN24w$qq0<>R#z6ZM=-14` ziGmREy>@u53Nz#geX?v|e3idIRyd{rxespAra0`9Fbzrpt7Qn0mN|6PiMD2JGHahT zk-QVOjwG(;^<@4KV_G8lXmmR0liNE6CC9EpJvNn^g_3=E6po2m|GjrXG7qHHParSo ztWtd?hFprOhF^ncU3vV{C?6~*1dB!TXQa6E@y#k3<@=t}-QW`@82P;HO5mP8dlR#Y zw=i3_`ZY8)Zdvg`Qi>(W3qtS8BF~dyJo)5%oDdo3BXxiPE2ZQh@;nfxAhA@H@;)v(1|bmM(D2{9%aO_ z_4!BD6>F;9hg0YI0xpXNKC<15f?@wHBHx z`gL9o8VqDNq+F`Bw#mX{>*Za7botkdYBg_0j>H4P7Lte^@j12MJ0T>0L;HeZKW$VW%csnJAs%MyxcYa# zsCo8jG{26I=pbfM30c5wiZ>enYlFrY0mH#LwpqYxx;_4t)}@i^L*7M25b#x??I!Ac zQx`&{zzy1p%Mud+p_Z4v$@`jr)pM}@qaeLpG=z2g*XPJv=j&YNntBsXZt_06AbTa( zC{q4Ah24IE-nF%aaa8o+XHGARM0|=B$$(aUPvJh3txyE1JKVlGx60Ue{#&>_a`{x( zPOW@y@YOrzt{V_^lB|*m(TdH;Bdodbp>OC9e{!hpzI23#-?8n!c%buAZZ*p59N=Vz z9&NG2{>|VxUi@a0aE!0b4GBlj;#NjKwA0t@LmG+VLMn2(Xe~+uGp}ray6+>O= zeji3j%9Nx#UTkY4QWNQ#2Bapkiz;JGte+GIfIJ>t1TN4iu&%2rkh)>UI&i%EM+vH{ z>3vRrqOR8UC5oWnc&VG>7P|M_+X=(=$XG@&oaqLpD}k% z{@xqDKu0V;dj8&?dIY)OzEDT#`j&iPae6_hUoiA<9DbijexHnfpU{5CsC`E)YgcrD zb*q47yJt%utMoU$L}2(uY=B3*z+-lRW4=IfyI|nA0P?rL`~DkW(4ucJg5KC{K7cY_ zkT|~gSU>LPUYH}|w=y9BkBvD0DNrGRhrK{XfVa3nCcw8x(kI}Dd=6JXZhd)Q0=ZK` z@UhP9styByxLJF@D>MQ#GXTep?(I7NtlNtcCS3B&wv4M9|Rp>@>7WnSaK~O6RExoF8wXxKRXiS#7?pXY;t*7ncwZ3 zxn%M;I!tm2UPZUizjsSzf{VX#;h%MJAa6!+fIABBg05#b4glKSW30Wzb}WF@+Y6LF zx&fDnINF#(U!XnkW=Oig^BSjl&b)`&j4uvUjWeq zs8e9?^y~=OXYJyxYJCDYeu%wC0NVv7_C!E-$g3e=SUY&yD0s_vFGStFYMmiCX*>2_ zV6!r+C~ZU<3VRtl5kPE31iNto-a=3huy9AkDli^x0N)%~pSFI!EnvN4zENPk`+rt* z@YXqTNw^{E_!67v$=2{*-jLt@z08@coqYvw0+VW69ih;H$zG_m_!DKRRow(s9pjmx zA|s?aEUvB9dZcW~j6i(b7Tr|)Xp99+?Ok1cTpNH1RC`=>mN4j{zCxy~GHgyV$8P|4 z2!h0TqdGLS1H`lg*aD^Qo;reX93aPU3JiO>@K=w~*ugcbSvYJl4XtAi$s7}Wh{Wnx z`fs04*L;Xpb2lTmv(x-<3J|-dEmEFXrHUb&bwGoALF>jp>;Tfc;7j_7BdzH5;L#6P z)CGy(%&`WUET9Z^0P&&i@#IDyA)EZ zn;~&|&I*eOFXBLjKITqXO@qbAfyD?-@j)Q`M2AK7@=BLMUW=!_3GNpLj&+5EafQTn zG8N=}o#q6~jvDya2|w5X@3Q#ippyEc09FS@BiL1|e$gD9VM7F0r)fTa$Xc>15=pRM ztyFo2bz2%Vrry6v!}`j)({z>Mnx>`unn1`CcwPMrha&TgWES)qTK0o`SGClIw+x;A z8u~9fM|GrB)(FX)xP9-Lx3=YP$v&AI0f~Dz)jO4AJ5{Qq)T4R!;n+{(jIHxLVrL>A zeFe^0rya^J)~EBYUc9$5oqh70^Q9#w$p{hle#AzEmsR-WtU1HT?n&piu2sf& z+u%1wDPPMbe*633B`bL6Ud4(dmt7Gy&XdcyXBXC)me89wr_2$PUno;~)GAR?wulzH zIQk=JM+WvescnH5yYTLT>Bb;Un`X;GWLJ*vG3=Nw@tE@Fxl&BS0o=@fGiv3GQY(RY7O?CLFde%7k!lntJ`ei-rD0D3-LZ~0Cf`)*W1%-FAMgZV zPlWG?+T)}*O>h6I)swD>2Tm#_LYHujx;<2~U5Wgg>F;6*VtT$p9W4pp3ntgEZUAk! zcQ}_B-Q2~E%?!N%J$uIujsSxCh4u|zwnX?P4B}3gI-d=(NeXnP*a7HoOZyqH*BI3W zP7yPwR0BN5N8Umu!#(}7m>lS?LRP@K1-jji7%+cJyI2K5t6`)f;{JVY@AI zOG>6IaN`wwY5d>3s*fM-(Z@N_jzsE1V0pzqa`%6rno6k71uMak8FA7$wO?k~3nKIU ztO<;%E8eP_U)VHakEA+zE|pEHqKOxPlNvF!?hPre&ljKH1niWP6@nu{vL*n^OynexG+-K42HV z(8vcskazq!zBjQkyIirBFCfPo^z~Uj0ogAljL}&Su->83!FZ5YRO8KBqDh}aC^8R;yHFVC*K<7!+ae5}V~j;>T+kgdHeUev zFE`=PSi)dAbD$q!Bz6e8Ck7S*jR+!~ArvKTiVjT^i*jW_M`H8*Z=GPRPZ%}AQ01{+ z%{LU|gal%i{#7X&;$M$js}E~s|CEt&q`j9Hjg^(X8EB*b-&BOcQ~o9Wa9BZ zkck^4z9tv}5048v@RQ448iI)xU;4R^QUKk2%EYaS#22cctEHFqalJR<=48d6h@bxg z^#vmV5nB1p(Z>GfXgU8|fyn>taEtu!AuRugrLMGVg)D&Z-6GL_#4S_RqH1GfLtKQ| zMJ|G$R1ky$rG}cs`%08KdDL;-p!Gs)ap_A!9s&Oi_^oho#iF8sI5jw3n{9W}xxQYz z%j*kR7rv>I)ku~{GWyKuYT6BbTU(3UM`aXP-5cjl*$;6pG zPW9zjqU~=*rx|!G#*ey1vK=J1wXBl9kzC#u!(XH_5y{2I`8u(ey`jCp^YNqM|u!f1)p{Y9eU z%d3DoeJrUTNu)cyjQD5^EslxDUbmjhx~VpCmIjzB3aM~tQRT9>Mm@2^xS^*Xn8ICuraM$!~G%b)jR2a+xfV0dI|pFd4}-= zYgQD)-YF@>bwjgvOTF5mt?OjjDkRp^y&3+?33uRwd)o&L#> z4?p=Hme(VOC-&)Hi{O>p)ulHIephydw|Fn$E$$jSc~f>319?iu%zZxU0BeCOgpo2D z>cSn2%!#&7%=wG6d~k08nB6Y~`bZ0jy(}9bJ33AjJn(=e`+7}^;oPE#m76>S<#>w< znSHrwTqJ;e6$RvK(|u1c1Yd2PYp zjeqV8xaYy$9ffE9lpiJiECb*hk^6itkICIX#q!BNOnptJe{T-iCC8wdFH1I$NgFRp zRvwET^7O0<611?Qo=0XrG%Z_&LRy<@Sgk4i*9;fQJO_i$i zAR;=SjvhTIhY5tE+Gu7qB(V-2p@_52MM+gYmC5T^?jSTFk#L({pL?#8Snu7GB%Q`% zc==r6ZQO+^xw8M$wk$cK7#`P5i+UZQ-j&)*iUYfuy0DRa(;S9*4e7cTZr@Z|ZrK@7 z%duiYF=YuWR!vjBovmt^xsFL#)W(9wNW3{MtiHpOH+ut{XflWr^slSK;K*;_wcx}y z^Z`Ty#gR$`OQ)zs!0a#2zBW+%3vm- zUs;J<;$`GT8mSd3_=uiV5=GT3skC4mL%BkkF-MzJJ93D@NLU}nHI!Jj)8ZfHk&9k- zlDAsZAkM17zIxqp1uQTjm2KzFEaa$p)0{e%RB2}YfwOK5lS$)2Pc}k{_L}4aHyuuN z=@ml&gr9&>y5Z7p1DfS4u2g2oF4M`BeAu|Mf}Y+il%fY~KFxg+6TkCMhWwBed-ve@ zP_#jKG{>O=5K)G|&l83_Ne$bbW0#<-_cbW479;Q4YVklkEmi(LJlJ;_pT%pVfA3x` z*0<^2?HSV@eAgHTOp}L8e;?m3LRSy$JNn1`wbuV2onsfeUMeVTHdupe%6p& zhfsgiFy5HJ&{Z=YQ7g^sDsS0Ns$M^zKrsn{U ziBI@7o$+)IH6Ls<$X}=oF##oX%nGFKD<~b+*7S%qfA^D{u*>xR1W^qQ>oQ6e8A`mE ze9J%HRt`Lm8}cql{f%Vhf+0|OVoCx+%az4YQZ@Ax>P>VFlO0CZX(q@dKLR1+;bqLxt`&EUeh zO3sfegzQT*WP4JMgQ)WkxVUGR6?O!x>?c@OAvC;n=7xA~`uPY_fOCE#TZfPUZzeo5 z6pAGo)-q`Tk7IdKLavhl6f{{&ZA~(ZOodHc@~rZa2`uugSLb}j`fS@2$9l1sR5_v} zVMi4@mUPH=#Qs!i2{R&#aYV21;WI^w4?>R~MT^QTh!M+N`x4GHIEGC{ULz?IreSOouD=qq)f@0z`8)by6Zt zlWr|~#yV+vlkKEfXgjzo{huZwicHw5Y3Uosks&nFs5}^uM6WX=3)?4GYjhoJ1e#wk z=|oCOHtiQ=>Tr1}^murxNMVFTbbrkd72-Iih7KlY7;e2a1x<3P(>MDNDI5Q0mK}6% z=aLL!t6)tc|8f#tqR7J4i6RpX7-yn|kn#n=WK6ANXr2W$e(@_jYyjv+n-cr4YyK3%j@&cAY=LZ(i+@E9BrjB)u@dkBA`KO4) zp{4Q{=#48RPo;EUu8;thCmM4Y4Bui3XM|%gjpV8#SJ>9U087LICGp>t!cJt~eS3yC zc0Ga&`JoTwihPDt9a5_4c>P485MdOrTnv~T)3$*d~xA+Y}kTgBG6V*s)}iKGVc}1gG`* zgB-zOE`TesU^`P3^rE^W3_1_cv>Qmz7BeNN50DC1*&kR1 z;@Vg<6c^m)>{%=MF$mp0^BR4ST7xTFQ~juk)thlL${B$hKd_G^bsZrn4sQh!lx{v` zDTNK$xgfo33F?9~7cLxMu(Mf0kk~@in1!;`;na}@g~wSE#xvVf^B0G0>c7bDj`%2BqC&PV=E82`l_^AKK6p5|!un^BjI=DPjU_ZX znNWxDqtjwF6HCj=W8OR5uTbcoLRdmvbHhM%V^DVQG1K;MzQkwNp;NHUxwtG zXgBM;8Ef`I&u!sd_ET9En-QNanK%CPZfdOLOn zVRz9ZKs&cMZ|L|r;mVd!)Z$=~cU((n?h`)2D){(6dJaBeIoyHEwq3E;>7d)wZ`T2M z1RplMk-zRk_xx;;;yiD?8C>`r$A>Ii$MHURx>8WQivJd^8nCDO;M}>!^8$1Jc^7#h zzt!g+RJ-%AOy!e)+>3UFdq&u0=4Th&@t#D7uvxWf3~K#}w6)m(VRh?%MwxGBU>iGD zJ=Oe<9HV$jJhIV60PB887zI%)Bw4GbM>iHx$0I?){A%hK&!Bac^$R#?F|hUkQp0tj zJSX>uO6VLU^zt{-^&qTm2VQvyA#}XUb^z;Ld=6#6TS{la|ge8m~y=7es)C zE%*l!%JSLdK^%9bNU%gjiY0o5Yptu^RY|qZRY9|l zkLt(nhpwR@kZ3QRQ>xP~$GJj%kAr4#c)(xoi_20!RsZ?eq-m(Nr}1K?5t*w+ zoA68O#oV2)M33~~hqH9wF=tI*GH1=eGG|S{t;8nsaC1Yi?C7(5Zw$75p>dA{E1Q@@ zWDNXXpyEQcg10#BF4}M?i}#<1O_!_T8}gTP?t>WenCsV#SZiLw zOgYhe3f$ZgAKct{vfb!e%h#-!;5N0L61f;&x=gyWSE8PxeO`(epLOoMeZLqb2YFUd z*slaH{=rmGBFxUlMMsc|4C_)Ri<2qk)Z{-7_bbMUnia_8+lHK`q3w-?i7gE|eH50r zv`nXK-CQQQO`bedmnGNMjB6R%Oj*H<1=}f?8QCdR^vxEP?Ss-M-Oi-#JC4^~i4Cg9 zjkuVRA2CkVQOOVF75y`lgTjS<#B31E_$3Xm91;--nP}r(`=rqZk5T`@|+L0!XRKZ zNxr5sA77#EB%}YiXc|95ff!!OPAz5xoRY|cepW@5wOT-GTpSTKtnLc(Z@fbVrc$ue zN5z7vN|{bq7y7_v52}Uwvul`y?G6$v*=~ld?$2bNL~PJQnLFdG9<$Y`Gq?)ljk`N{ zCj%UMPXil^>8=gs4zx?EZy5;P3Dy%R#^Sx&_wVj6EFb-y(C1iRqT{8KyRu*VvjOn$ zPaDi93ZIb=WK*S!$DyXlfhJpS!VUeM)2E>R4F(qm=e9+#RO^Z(&L-s3txN}xGLOd$ zXK*MQ6IJ4f2UG?Vk5>r_Lt>jr(wK!lBCy8VR7D_o^C{2l3>?>N-!H-&c=8wTSqu9K zCTI0p?Z4ZfvhvgI&$kyFR9v%1`PX&Ig8nb@pPegrv~gh zxXZ$Aw}<~qHt4){$5e;93G)g4V>*FLj0V$1P~02#1CjOO`k3dRdZ*_vVpp;ZapTE% zIE8OEfQjykEqbyUE*7A&_sXCfGtD>wBkDzEhB=v7RXTEDN34-5PMFdtM1m%XaVUdP zve@xb?Y)I@e`Gn9#@Hy0*IyKNM8Op>l*ONdcA}BoMI}ZLdei}+LL4UTZEVfj$q|v( zj)O~HXJ0kyj6xCS^mgU-lE-2ebTRJfiqQ`DUeM04mH z9$WGOk;n%23Te${r)?W=>ng@aGCAU{D5huA)Fp}uqZFga{y+l#aF*suWcHj!x*p%+ znSi}k$1C0$?Y&)Qwvp_zeYK`w8AFJtA+SJu`JhXCJFYz)%IqUuW1uzez0k(m5QJ^R z(6e@ag{EcEy>sJHhy^=}MM6nR0TWGa@Mg}2SHEEBsWYVNLha+TcqdI4xm`5%;t0%A z&3QpIC>D}%?&-)X-5ak#Y7f$Xt(l`|NnxTALX~V$5~+YgUI9OI$)mBrj7PN}T~qft z_aabFz)EQ`9Q%IlukqhWD23P(orNoi zLHJ@5o?*`?EQlklK;(=-xE^Gp#O*h>F(fp{N<&Vt5t|S=$B|uEjxSo^w*VAFl~?8W zn@3zjk>~Xr2QJIY`dBJIt1FP^t1Bym z!bdZKo-9SNAK*nShx#Dy%3ufR7QLy4LYHqYV(${Jr0!9}4Vg@8_8WcG8rePcp|dsc z<^9lFe{?mpwAwy=)+6Bs)+A}wn?aS-Et^fXQ|i6}A<@*pS{ z?b00{Ec$&cDz!YP!^aTn0ceWuc<_JA$Kz~G(iJvbiPfw)NvQWRX_aXJ%$k>}|! zF+yBCSOwd1qTp|lZMq=PT5Ai8LhT1&Icp-F5_Hl5ta8$SQA6B8$HlutnAsXj;1l+; z{WT7m&$w;}vgRJ0`p`{&NY=eIh+ZSC;Xob0Z<5q+ zp!Vvv2&(tR0lomYXejJp_RIlBfnF^UlH0@%y4k{N_j?F#MpsQ9Vb{44`q%>5W9&fh z@D+a9J`H?{Cs1It)jn(iKt*GLR|S)6Egd!$>?mrM2?3 zudV+?o7ZCQA0=GJt2PVI1emC9Ii^AEJ%M2st2H7DwszK~cC;l5pa+Q^zFGWjFpr8RJ46=iBnU7;+P5Rz@r=(t3` zFxoguWJNP7v*yJ)Wm94^QdqJOX`3m_i0C#I<-f?n<_if)O)7*AN*e1T`ZtV;*KUY$-LS|x`v3;pTOh(& zozu2oVhv@D1$XUCGLaZWZRVm4q@7r&b-;zpC9O4BYhimE_`OW@w}8WxJqG5-ib|~Q zO?Gk%Rbql13rlJOn(1z>`u7M{|7 zVF%|DD7qH2whw30LbBbKC}-ZCO@()hvNRX4EV!@1d`c?kEqS4=Up6^;Rej;sG%98H zqUhgQ8$j>;Jy_F)xe!;O(5T%#m;acBE)u6tELl+#94?JI8NG-5gtepw11XS%Q}i#& z?v?nvXkP-?cSMhwyZEqHv2XW|dAn;yDYx+O)?ILr&zU>WjO9~l)af;~Z-9Z6!N0w* zI0H^|`bJe5X`$DJI~JY!Q*1Qy0p@2|3hTS{(B#b_zjQYbVphwnfdF;$}%oC7v1*UT2F?6 zBWTUSJzSSk-uH4UT1Oh$$*(hn!whyXH92hrp>$g4GAUu-e_U(tNMztzJgttUo?n0Y zGG5t(?1cQhrDCIa)S2rIl}RW3YHFfFO+g4%lCY#(=|))+l0&k&in#W6!*=2hGEPdz z@*!r{R59@glg~QBBAFUnU8&5o!unU;%CtZdlX}R+*KeO4mi38~o`Y4HI;yl2mvkjj zK-;r1=vQHK;HGOjXbYumDdJZ^Ff=~JQy?u-7t3H)2hG~UN2#3va42dom*atCinh;$ zknSl=j4LU3i%d9aH|n5vLsN-SSTP}iL12q^!i6N18@l!BZ<#59<1;*V({!y$G0(4x zMOS|CR?zlAjJNe){YVMtqx6oqylNLbRm~wn#Ja{2o-+zfPY0kdk7;p5R5;a3qCQlg z)G%h3*^n@W8vv1UQk#WB)!j&Q9MoD{V1_M0%k_W-P@Z&w3jii&AUcKcY%}_oKqV!N z+}uo;V>kuOn+#K@wl0P!^qsheMx6u-36>5|0_#RmV<@?g+q-xocXC(%!r^%(-^`!V zqIGBoD`I1*-XQQin&KalDoA4=#)=u2r}-js#yFTtC6#Bkr$X$oCM^u|#j;Y2Tq_-8 zFS4037GWG&jkRt5PRNvKYv|s|Xt_w%P%ARd;v*9}nI>4;FArK3R^t@ApCJd=a*S?R zQ64dC^gY;Odx#mI#`|l9d0BObEY4{8RXHrfPT%LeA5}oDNxw{@P={Yn< zw}}lI%l5{7EK>+OS2eMhBKF; zd1Q??AA!Gg@;|pHxH?;eEv&DmIG>X`-ZLZUb%tmm(P|AGf2V1!%QLyor0od4F_i2w zo(UI)R#e;(%I@KMYyd~`T9QPwT1q^Ojo`KXM18oM0!%z9-Y+787Z*ZU9fZB@+3Y8l zea_lUo>)hH@mIE6Ouzck2cJF_;k$C}lLI&g8d9T{v~I+piJLn=N>cw<(*pehr{QL! z))q8w{^IKScb~CNgdN3I?~K%wS5gSg*MENw^8=Z9=Fd&yT`#qr5v$35Se`1z>~3XW zK4p~V+G_dennLI2*HNT7l*#YC{#6n$Z?>PZwR&8Htrl>9r=_DtG=|5CTp^x}C3dtM z!)K`itXak_qH&7tU0@!2?v$r~H%d#V@&t_r!5hQW;P!?wR&Twe8}t6jbDs)w;cWz^pbXUl}kT8}YqG~b??dgqh#i});y&6wB5VvU04!vbWZ ziUJEu+6G%`V*wIxiEMtg^4R?euXLWy+L|bT>;*PgCkz9gv4Q`sYk_TCg7&$p8-dlf z0pln9&$QY3mpt*it)H7GpqvihB7fpch<#Q&!mE#&5F~llG6tItzZ>r6mKEF}I9VS9;SGA;UinlH zno(~*KHp|!=Ub$3R;H8HZRT`aVrOH*A4`nCJ}^7iw)v(@&DMckHR>{*!F~VQl#A~j z9~6maM?J=e)j`FnexcLA)N~DTRLhJcKZcR?F<7a#D8rsrYr^wJq|2S4!}cI z=s7UGD-&BvSp7TtqU$uC9%9f2yV+$GWoe{L6HYBzzC34#p1eL!aC9=UenvaZ2t?(K zKz{V>2@?bw?c$C=OZlOE{eZuJJrL+y)lBxQVAYB zrIN3r2_snvJX`g+p5<7Y0UPa4uNL1P5mFQs&^!60NBue0hoh-$N~KH1LnH~~0DVDk z2Brg#z;cmB^qwTD!s1$6dkLvGcFQEe^`1IfQ`f{4;O@w|8=P4EFP9&1}3m}wbRi)Z!=eOcYq zq?1_pfgoxlYQI#>Xlhu{hhmr5Setqf7d;=hUdejm)&Pg&bshAuBJ*SW_{@+O9F@v- zaX0M}pR2Y+z#NY21##HeH_-aNtYK4@3MRz!(DMzMc1|bt@qf_vbQ^A6V#Z3B zZV#*ot+wS83P0xq;i$ZVIXx$|6SMIlX%QT73rAvK{|G0nW(TDyZaICwFeS6q?VWSI zH>32a58E28RRt_zc~AJ~O)H|(c7(TUy?LVX3@$K4LXesKmph6od2yWLFJC=cT47p$ zM&PueM%P9J4TCVDLZg8R>+=(*QDLD4J)hxEWKY4{_mt1dq%cs@xr`TmR2V6 zA}^2Pl#p)TRUX9Mdm=TQxfL<4UDEusYp0s!mnzOB+BK)9K9YBF~!n_Fx`(;###;dK--2t7HGKVr#Gx_(si1@e#4(XR!LKpit_9 zt4m==KZaI$og4f4@>F$QO@myb%B@Q?*ye(6bmkkCb!Yf*ce@ph{a7<(Gwxk%R@apd z$rqzn@})B<8tSFZjb;^r+H!d+)6-lF9d3-h#Z?Hk9c;e%k<;sjfh#wnH8ZL){&TO= zVqELYi_;|{$)t-;4GN>Ib;;OS+{ElWt^m@@4v*HAK3}p0>sFS<2V**B^2Xijl=xqj zn=_Ry$v|Cvo}LGEm4a?kxdt++pG*5%W zY15OsPfl;qni)|Y3`SXT)X5sr*96h10yPalpFMX9w#M%kS`Dr!%8 zixNet;6z6G0rSGqy2YNJ6D5jL^@ofqmOLWr@KHs1UK| Date: Tue, 27 Apr 2021 10:19:30 -0300 Subject: [PATCH 199/698] fixing flake8 --- faraday_plugins/plugins/repo/nmap/plugin.py | 31 +++++++++---------- .../plugins/repo/openvas/plugin.py | 10 +++--- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/faraday_plugins/plugins/repo/nmap/plugin.py b/faraday_plugins/plugins/repo/nmap/plugin.py index ec4a92b0..ea2abdb0 100644 --- a/faraday_plugins/plugins/repo/nmap/plugin.py +++ b/faraday_plugins/plugins/repo/nmap/plugin.py @@ -1,25 +1,24 @@ +import os +import re +from io import BytesIO + """ Faraday Penetration Test IDE Copyright (C) 2013 Infobyte LLC (http://www.infobytesec.com/) See the file 'doc/LICENSE' for the license information """ - -import re -import os -from io import BytesIO -import xml.etree.ElementTree as ET -ETREE_VERSION = ET.VERSION from lxml import etree from lxml.etree import XMLParser from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import get_severity_from_cvss +import xml.etree.ElementTree as ET +ETREE_VERSION = ET.VERSION ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] current_path = os.path.abspath(os.getcwd()) - class NmapXmlParser: """ The objective of this class is to parse an xml file generated by @@ -55,7 +54,7 @@ def parse_xml(self, xml_output): magical_parser = XMLParser(recover=True) return etree.parse(BytesIO(xml_output), magical_parser) except SyntaxError as err: - #logger.error("SyntaxError: %s." % (err)) + # logger.error("SyntaxError: %s." % (err)) return None def get_hosts(self, tree): @@ -237,7 +236,6 @@ def get_os_guesses(self): ostype = service.get("ostype", "unknown") yield ("%s" % ostype, 0) - def top_os_guess(self): """ @return The most accurate os_guess_id or 'unknown'. @@ -376,11 +374,11 @@ def __init__(self, script_node, service_table, vulnerability_table): self.table[e.get("key")] = str(e.text) self.name = self.table["id"] - + self.desc = script_node.get("id") + "-" + self.table["id"] if self.table["is_exploit"] == 'true': self.desc += " *EXPLOIT*" - + self.refs = ["https://vulners.com/" + self.table["type"] + "/" + self.table["id"]] self.refs.append("CVSS: " + self.table["cvss"]) self.response = "" @@ -417,7 +415,7 @@ def __init__(self, script_node): self.name = script_node.get("id") self.desc = script_node.get("output") - self.refs = self.parse_output(self.desc) + self.refs = self.parse_output(self.desc) self.response = "" for k in script_node.findall("elem"): self.response += "\n" + str(k.get('key')) + ": " + str(k.text) @@ -542,7 +540,7 @@ def parseOutputString(self, output): description=srvname) for v in port.vulns: - + desc = v.desc refs = v.refs @@ -556,14 +554,14 @@ def parseOutputString(self, output): severity = "unclassified" if re.search(r"Couldn't", desc): severity = "unclassified" - + if v.web: v_id = self.createAndAddVulnWebToService( h_id, s_id, v.name, desc=desc, - response = v.response if v.response else "", + response=v.response if v.response else "", ref=refs, severity=severity, website=minterfase, @@ -595,7 +593,6 @@ def processCommandString(self, username, current_path, command_string): r"-oX %s" % self._output_file_path, command_string) + def createPlugin(ignore_info=False): return NmapPlugin(ignore_info=ignore_info) - - diff --git a/faraday_plugins/plugins/repo/openvas/plugin.py b/faraday_plugins/plugins/repo/openvas/plugin.py index 4f3f2033..54122f61 100644 --- a/faraday_plugins/plugins/repo/openvas/plugin.py +++ b/faraday_plugins/plugins/repo/openvas/plugin.py @@ -1,18 +1,18 @@ +import re +from collections import defaultdict +from copy import copy """ Faraday Penetration Test IDE Copyright (C) 2013 Infobyte LLC (http://www.infobytesec.com/) See the file 'doc/LICENSE' for the license information """ -import re -from collections import defaultdict -from copy import copy -import xml.etree.ElementTree as ET -ETREE_VERSION = ET.VERSION from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import filter_services +import xml.etree.ElementTree as ET +ETREE_VERSION = ET.VERSION ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] From 7055d11ee9b623e7970cf1a9df575a4179c40091 Mon Sep 17 00:00:00 2001 From: ChriZzn <25209291+ChriZzn@users.noreply.github.com> Date: Tue, 27 Apr 2021 16:03:48 +0200 Subject: [PATCH 200/698] Update plugin.py --- faraday_plugins/plugins/repo/nmap/plugin.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/faraday_plugins/plugins/repo/nmap/plugin.py b/faraday_plugins/plugins/repo/nmap/plugin.py index 61e4e33f..19eaae02 100644 --- a/faraday_plugins/plugins/repo/nmap/plugin.py +++ b/faraday_plugins/plugins/repo/nmap/plugin.py @@ -326,7 +326,9 @@ def get_state(self): state = self.get_attrib_from_subnode('state', 'state') reason = self.get_attrib_from_subnode('state', 'reason') reason_ttl = self.get_attrib_from_subnode('state', 'reason_ttl') - + #Workaround for NMAP UDP Scans: + if state == "open|filtered" and reason == "no-response": + state = "closed" return (state if state else 'unknown', reason if reason else 'unknown', reason_ttl if reason_ttl else 'unknown') From 4843d5613939d3ce1dc5ba17340a94010b3f5901 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Tue, 27 Apr 2021 11:41:52 -0300 Subject: [PATCH 201/698] fix nmap port status --- CHANGELOG/current/fix_nmap_port_status.md | 1 + faraday_plugins/plugins/repo/nmap/plugin.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 CHANGELOG/current/fix_nmap_port_status.md diff --git a/CHANGELOG/current/fix_nmap_port_status.md b/CHANGELOG/current/fix_nmap_port_status.md new file mode 100644 index 00000000..52a24744 --- /dev/null +++ b/CHANGELOG/current/fix_nmap_port_status.md @@ -0,0 +1 @@ +Fix port stats in nmap diff --git a/faraday_plugins/plugins/repo/nmap/plugin.py b/faraday_plugins/plugins/repo/nmap/plugin.py index 61e4e33f..a3e02d8a 100644 --- a/faraday_plugins/plugins/repo/nmap/plugin.py +++ b/faraday_plugins/plugins/repo/nmap/plugin.py @@ -295,6 +295,7 @@ class Port: @param port_node A port_node taken from an nmap xml tree """ + PORT_STATES = {'filtered': 'closed', 'open|filtered': 'closed', 'open': 'open'} def __init__(self, port_node): self.node = port_node @@ -323,7 +324,7 @@ def get_state(self): @return (state, reason, reason_ttl) or ('unknown','unknown','unknown') """ - state = self.get_attrib_from_subnode('state', 'state') + state = self.PORT_STATES.get(self.get_attrib_from_subnode('state', 'state'), 'open') reason = self.get_attrib_from_subnode('state', 'reason') reason_ttl = self.get_attrib_from_subnode('state', 'reason_ttl') From bfac30067e1b65d0a3752959eae40305c0a9e2f2 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Tue, 27 Apr 2021 12:58:55 -0300 Subject: [PATCH 202/698] use PR from github --- faraday_plugins/plugins/repo/nmap/plugin.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/faraday_plugins/plugins/repo/nmap/plugin.py b/faraday_plugins/plugins/repo/nmap/plugin.py index aab5cd63..04a4090c 100644 --- a/faraday_plugins/plugins/repo/nmap/plugin.py +++ b/faraday_plugins/plugins/repo/nmap/plugin.py @@ -295,7 +295,7 @@ class Port: @param port_node A port_node taken from an nmap xml tree """ - PORT_STATES = {'filtered': 'closed', 'open|filtered': 'closed', 'open': 'open'} + def __init__(self, port_node): self.node = port_node @@ -324,11 +324,11 @@ def get_state(self): @return (state, reason, reason_ttl) or ('unknown','unknown','unknown') """ - state = self.PORT_STATES.get(self.get_attrib_from_subnode('state', 'state'), 'open') + state = self.get_attrib_from_subnode('state', 'state') reason = self.get_attrib_from_subnode('state', 'reason') reason_ttl = self.get_attrib_from_subnode('state', 'reason_ttl') #Workaround for NMAP UDP Scans: - if state == "open|filtered" and reason == "no-response": + if state in ["open|filtered", "filtered"] and reason == "no-response": state = "closed" return (state if state else 'unknown', reason if reason else 'unknown', From cbe121470e2ebc50d13232ab55690768e7587ff7 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Tue, 27 Apr 2021 13:20:16 -0300 Subject: [PATCH 203/698] =?UTF-8?q?update=20nmap=20service=20port=C2=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- faraday_plugins/plugins/repo/nmap/plugin.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/faraday_plugins/plugins/repo/nmap/plugin.py b/faraday_plugins/plugins/repo/nmap/plugin.py index 04a4090c..8232f171 100644 --- a/faraday_plugins/plugins/repo/nmap/plugin.py +++ b/faraday_plugins/plugins/repo/nmap/plugin.py @@ -296,6 +296,7 @@ class Port: @param port_node A port_node taken from an nmap xml tree """ + PORT_STATUS_FIX = {"filtered": "closed", "open|filtered": "closed" } def __init__(self, port_node): self.node = port_node @@ -324,12 +325,11 @@ def get_state(self): @return (state, reason, reason_ttl) or ('unknown','unknown','unknown') """ - state = self.get_attrib_from_subnode('state', 'state') + state = self.PORT_STATUS_FIX.get(self.get_attrib_from_subnode('state', 'state'), + self.get_attrib_from_subnode('state', 'state')) reason = self.get_attrib_from_subnode('state', 'reason') reason_ttl = self.get_attrib_from_subnode('state', 'reason_ttl') - #Workaround for NMAP UDP Scans: - if state in ["open|filtered", "filtered"] and reason == "no-response": - state = "closed" + return (state if state else 'unknown', reason if reason else 'unknown', reason_ttl if reason_ttl else 'unknown') From 711e22a0efd46b9f8c6ad75f0b4f4ef90f497e29 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Tue, 27 Apr 2021 13:52:50 -0300 Subject: [PATCH 204/698] update appscan --- faraday_plugins/plugins/repo/appscan/plugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/faraday_plugins/plugins/repo/appscan/plugin.py b/faraday_plugins/plugins/repo/appscan/plugin.py index ed755f19..9e76a027 100644 --- a/faraday_plugins/plugins/repo/appscan/plugin.py +++ b/faraday_plugins/plugins/repo/appscan/plugin.py @@ -258,10 +258,10 @@ def parseOutputString(self, output): for issue in parser.issues: host = issue.pop("host") port = issue.pop("port") - issue.pop("os") service_name = issue.pop("service_name") ip = resolve_hostname(host) - host_id = self.createAndAddHost(ip, hostnames=host) + host_os = issue.pop("os") + host_id = self.createAndAddHost(ip, hostnames=host, os=host_os) service_id = self.createAndAddServiceToHost(host_id, service_name, ports=port) self.createAndAddVulnWebToService(host_id=host_id, service_id=service_id, **issue) From bb28f6a5b07ffcd680562457f12c646139d09b19 Mon Sep 17 00:00:00 2001 From: Manuel Jose Sotomayor Torrealba Date: Wed, 28 Apr 2021 10:21:30 -0300 Subject: [PATCH 205/698] add changeLog --- CHANGELOG/current/clean_code.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 CHANGELOG/current/clean_code.md diff --git a/CHANGELOG/current/clean_code.md b/CHANGELOG/current/clean_code.md new file mode 100644 index 00000000..d306b2ee --- /dev/null +++ b/CHANGELOG/current/clean_code.md @@ -0,0 +1 @@ +FIX unused import, innecesary list compression and unused variables \ No newline at end of file From 76fcace1d023bf1dcc8bae8593d03c1fa7229a8b Mon Sep 17 00:00:00 2001 From: Manuel Jose Sotomayor Torrealba Date: Sun, 2 May 2021 20:06:04 -0300 Subject: [PATCH 206/698] FIX metasploit report when the web-site-id is null --- ...hen_import_report_of_metasploit_with_faraday_plugins.md | 1 + faraday_plugins/plugins/repo/metasploit/plugin.py | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 CHANGELOG/current/error_when_import_report_of_metasploit_with_faraday_plugins.md diff --git a/CHANGELOG/current/error_when_import_report_of_metasploit_with_faraday_plugins.md b/CHANGELOG/current/error_when_import_report_of_metasploit_with_faraday_plugins.md new file mode 100644 index 00000000..989f5f0e --- /dev/null +++ b/CHANGELOG/current/error_when_import_report_of_metasploit_with_faraday_plugins.md @@ -0,0 +1 @@ +FIX metasploit report when the web-site-id is null \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/metasploit/plugin.py b/faraday_plugins/plugins/repo/metasploit/plugin.py index 8d6d0372..dfe2c849 100644 --- a/faraday_plugins/plugins/repo/metasploit/plugin.py +++ b/faraday_plugins/plugins/repo/metasploit/plugin.py @@ -211,7 +211,11 @@ def __init__(self, item_node, services): self.query = self.get_text_from_subnode('query') self.request = self.get_text_from_subnode('request') self.category = self.get_text_from_subnode('category-id') - self.service_id = services[self.get_text_from_subnode('web-site-id')] + web_id = self.get_text_from_subnode('web-site-id') + self.service_id = None + if web_id: + self.service_id = services[web_id] + self.isWeb = True def get_text_from_subnode(self, subnode_xpath_expr): @@ -220,6 +224,7 @@ def get_text_from_subnode(self, subnode_xpath_expr): @return An attribute value """ + sub_node = self.node.find(subnode_xpath_expr) if sub_node is not None: if sub_node.text is not None: From 73c9b227b7c56d33b2ae7492bdcf2ffb4b3ed7d3 Mon Sep 17 00:00:00 2001 From: Manuel Jose Sotomayor Torrealba Date: Tue, 4 May 2021 09:51:21 -0300 Subject: [PATCH 207/698] cleaning ETREE_VERSION --- .../plugins/repo/acunetix/plugin.py | 26 +----- .../plugins/repo/dnsenum/plugin.py | 31 +------- faraday_plugins/plugins/repo/impact/plugin.py | 14 +--- faraday_plugins/plugins/repo/junit/plugin.py | 10 +-- .../plugins/repo/metasploit/plugin.py | 52 ++++-------- .../plugins/repo/netsparker/plugin.py | 8 +- .../plugins/repo/netsparkercloud/plugin.py | 14 +--- .../plugins/repo/nexpose_full/plugin.py | 7 -- faraday_plugins/plugins/repo/nmap/plugin.py | 31 +------- .../plugins/repo/openvas/plugin.py | 30 +------ .../plugins/repo/qualysguard/plugin.py | 9 +-- faraday_plugins/plugins/repo/retina/plugin.py | 13 +-- faraday_plugins/plugins/repo/w3af/plugin.py | 35 +------- faraday_plugins/plugins/repo/wapiti/plugin.py | 79 +++++++------------ faraday_plugins/plugins/repo/zap/plugin.py | 36 ++------- 15 files changed, 77 insertions(+), 318 deletions(-) diff --git a/faraday_plugins/plugins/repo/acunetix/plugin.py b/faraday_plugins/plugins/repo/acunetix/plugin.py index 939b4e2d..08582807 100644 --- a/faraday_plugins/plugins/repo/acunetix/plugin.py +++ b/faraday_plugins/plugins/repo/acunetix/plugin.py @@ -4,8 +4,6 @@ See the file 'doc/LICENSE' for the license information """ -import re -import xml.etree.ElementTree as ET from urllib.parse import urlsplit from lxml import etree @@ -13,10 +11,6 @@ from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import resolve_hostname -ETREE_VERSION = ET.VERSION - -ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] - __author__ = "Francisco Amato" __copyright__ = "Copyright (c) 2013, Infobyte LLC" __credits__ = ["Francisco Amato"] @@ -81,26 +75,8 @@ def get_attrib_from_subnode(xml_node, subnode_xpath_expr, attrib_name): @return An attribute value """ - global ETREE_VERSION - node = None - - if ETREE_VERSION[0] <= 1 and ETREE_VERSION[1] < 3: - - match_obj = re.search("([^\@]+?)\[\@([^=]*?)=\'([^\']*?)\'", subnode_xpath_expr) - - if match_obj is not None: - node_to_find = match_obj.group(1) - xpath_attrib = match_obj.group(2) - xpath_value = match_obj.group(3) - for node_found in xml_node.findall(node_to_find): - if node_found.attrib[xpath_attrib] == xpath_value: - node = node_found - break - else: - node = xml_node.find(subnode_xpath_expr) - else: - node = xml_node.find(subnode_xpath_expr) + node = xml_node.find(subnode_xpath_expr) if node is not None: return node.get(attrib_name) diff --git a/faraday_plugins/plugins/repo/dnsenum/plugin.py b/faraday_plugins/plugins/repo/dnsenum/plugin.py index bd8416ef..ac7fbe58 100644 --- a/faraday_plugins/plugins/repo/dnsenum/plugin.py +++ b/faraday_plugins/plugins/repo/dnsenum/plugin.py @@ -4,14 +4,10 @@ See the file 'doc/LICENSE' for the license information """ -from faraday_plugins.plugins.plugin import PluginBase import re -import os import xml.etree.ElementTree as ET -ETREE_VERSION = ET.VERSION - -ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] +from faraday_plugins.plugins.plugin import PluginBase __author__ = "Francisco Amato" __copyright__ = "Copyright (c) 2013, Infobyte LLC" @@ -63,7 +59,6 @@ def get_items(self, tree): """ @return items A list of Host instances """ - bugtype = '' node = tree.findall('testdata')[0] for hostnode in node.findall('host'): @@ -76,26 +71,8 @@ def get_attrib_from_subnode(xml_node, subnode_xpath_expr, attrib_name): @return An attribute value """ - global ETREE_VERSION - node = None - - if ETREE_VERSION[0] <= 1 and ETREE_VERSION[1] < 3: - - match_obj = re.search( - "([^\@]+?)\[\@([^=]*?)=\'([^\']*?)\'", subnode_xpath_expr) - if match_obj is not None: - node_to_find = match_obj.group(1) - xpath_attrib = match_obj.group(2) - xpath_value = match_obj.group(3) - for node_found in xml_node.findall(node_to_find): - if node_found.attrib[xpath_attrib] == xpath_value: - node = node_found - break - else: - node = xml_node.find(subnode_xpath_expr) - else: - node = xml_node.find(subnode_xpath_expr) + node = xml_node.find(subnode_xpath_expr) if node is not None: return node.get(attrib_name) @@ -170,7 +147,7 @@ def parseOutputString(self, output): parser = DnsenumXmlParser(output) for item in parser.items: - h_id = self.createAndAddHost(item.ip, hostnames=[item.hostname]) + self.createAndAddHost(item.ip, hostnames=[item.hostname]) del parser @@ -190,5 +167,3 @@ def processCommandString(self, username, current_path, command_string): def createPlugin(ignore_info=False): return DnsenumPlugin(ignore_info=ignore_info) - - diff --git a/faraday_plugins/plugins/repo/impact/plugin.py b/faraday_plugins/plugins/repo/impact/plugin.py index 440a2fd1..ff0c3fdf 100644 --- a/faraday_plugins/plugins/repo/impact/plugin.py +++ b/faraday_plugins/plugins/repo/impact/plugin.py @@ -4,14 +4,10 @@ See the file 'doc/LICENSE' for the license information """ -import re -from faraday_plugins.plugins.plugin import PluginXMLFormat import xml.etree.ElementTree as ET -ETREE_VERSION = ET.VERSION - -ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] +from faraday_plugins.plugins.plugin import PluginXMLFormat __author__ = "Francisco Amato" __copyright__ = "Copyright (c) 2013, Infobyte LLC" @@ -99,7 +95,6 @@ def __init__(self, item_node, parent=None): agentip = node.get('name').split("/")[1] if self.ip == agentip: - self.agentip = agentip self.ipfrom = self.get_text_from_subnode( @@ -223,7 +218,7 @@ def parseOutputString(self, output): mapped_services = {} mapped_ports = {} for item in parser.items: - os_string = f"{item.os} {item.arch }" + os_string = f"{item.os} {item.arch}" h_id = self.createAndAddHost(item.ip, os=os_string, hostnames=[item.host]) for service in item.services: @@ -277,10 +272,5 @@ def parseOutputString(self, output): del parser - - - def createPlugin(ignore_info=False): return ImpactPlugin(ignore_info=ignore_info) - - diff --git a/faraday_plugins/plugins/repo/junit/plugin.py b/faraday_plugins/plugins/repo/junit/plugin.py index df1a551e..639a4dbf 100644 --- a/faraday_plugins/plugins/repo/junit/plugin.py +++ b/faraday_plugins/plugins/repo/junit/plugin.py @@ -5,13 +5,10 @@ """ import os -from lxml import etree -from faraday_plugins.plugins.plugin import PluginXMLFormat -import xml.etree.ElementTree as ET -ETREE_VERSION = ET.VERSION +from lxml import etree -ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] +from faraday_plugins.plugins.plugin import PluginXMLFormat current_path = os.path.abspath(os.getcwd()) @@ -61,7 +58,7 @@ def __init__(self, xml_output): self.items = [data for data in self.get_items(tree)] else: self.items = [] - + def parse_xml(self, xml_output): """ Open and parse an xml file. @@ -127,7 +124,6 @@ def __init__(self, *arg, **kwargs): self._current_output = None def parseOutputString(self, output): - parser = JunitXmlParser(output) for item in parser.items: h_id = self.createAndAddHost(item.host, os="Linux") diff --git a/faraday_plugins/plugins/repo/metasploit/plugin.py b/faraday_plugins/plugins/repo/metasploit/plugin.py index 299b3c68..9394469d 100644 --- a/faraday_plugins/plugins/repo/metasploit/plugin.py +++ b/faraday_plugins/plugins/repo/metasploit/plugin.py @@ -3,14 +3,12 @@ Copyright (C) 2013 Infobyte LLC (http://www.infobytesec.com/) See the file 'doc/LICENSE' for the license information """ +import xml.etree.ElementTree as ET + from faraday_plugins.plugins.plugin import PluginXMLFormat -import re -import xml.etree.ElementTree as ET ETREE_VERSION = ET.VERSION -ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] - __author__ = "Francisco Amato" __copyright__ = "Copyright (c) 2013, Infobyte LLC" __credits__ = ["Francisco Amato"] @@ -71,7 +69,6 @@ def get_items(self, tree, webVulns): """ @return items A list of Host instances """ - bugtype = "" for node in tree.findall('hosts/host'): yield Host(node, webVulns) @@ -80,7 +77,6 @@ def get_vulns(self, tree, services): """ @return items A list of WebVuln instances """ - bugtype = "" for node in tree.findall('web_vulns/web_vuln'): yield WebVuln(node, services) @@ -91,26 +87,8 @@ def get_attrib_from_subnode(xml_node, subnode_xpath_expr, attrib_name): @return An attribute value """ - global ETREE_VERSION - node = None - - if ETREE_VERSION[0] <= 1 and ETREE_VERSION[1] < 3: - - match_obj = re.search( - "([^\@]+?)\[\@([^=]*?)=\'([^\']*?)\'", subnode_xpath_expr) - if match_obj is not None: - node_to_find = match_obj.group(1) - xpath_attrib = match_obj.group(2) - xpath_value = match_obj.group(3) - for node_found in xml_node.findall(node_to_find): - if node_found.attrib[xpath_attrib] == xpath_value: - node = node_found - break - else: - node = xml_node.find(subnode_xpath_expr) - else: - node = xml_node.find(subnode_xpath_expr) + node = xml_node.find(subnode_xpath_expr) if node is not None: return node.get(attrib_name) @@ -330,7 +308,6 @@ def __init__(self, *arg, **kwargs): self.options = None self.target = None - def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it from @@ -343,7 +320,7 @@ def parseOutputString(self, output): self.hostnames = [] if item.host: self.hostnames = [item.host] - + h_id = self.createAndAddHost(item.ip, os=item.os, hostnames=self.hostnames) if item.id + "_" in item.notesByService: @@ -351,15 +328,15 @@ def parseOutputString(self, output): self.createAndAddNoteToHost(h_id, n.ntype, n.data) for v in item.vulnsByHost: - v_id = self.createAndAddVulnToHost( + self.createAndAddVulnToHost( h_id, v.name, v.desc, ref=v.refs) for s in item.services: s_id = self.createAndAddServiceToHost(h_id, s['name'], - protocol=s['proto'], - ports=[s['port']], - status=s['state'], - description=s['info']) + protocol=s['proto'], + ports=[s['port']], + status=s['state'], + description=s['info']) if item.id + "_" + s['id'] in item.notesByService: for n in item.notesByService[item.id + "_" + s['id']]: @@ -370,18 +347,19 @@ def parseOutputString(self, output): for c in item.credsByService[s['port']]: self.createAndAddCredToService( h_id, s_id, c.user, c.passwd) - self.createAndAddVulnToService(h_id, s_id, "Weak Credentials", "[metasploit found the following credentials]\nuser:%s\npass:%s" % ( - c.user, c.passwd), severity="high") + self.createAndAddVulnToService(h_id, s_id, "Weak Credentials", + "[metasploit found the following credentials]\nuser:%s\npass:%s" % ( + c.user, c.passwd), severity="high") for v in item.vulnsByService[s['id']]: if v.isWeb: - v_id = self.createAndAddVulnWebToService(h_id, s_id, v.name, v.desc, + self.createAndAddVulnWebToService(h_id, s_id, v.name, v.desc, severity=v.risk, website=v.host, path=v.path, request=v.request, method=v.method, pname=v.pname, params=v.params, query=v.query, category=v.category) else: - v_id = self.createAndAddVulnToService( + self.createAndAddVulnToService( h_id, s_id, v.name, v.desc, ref=v.refs) del parser @@ -395,5 +373,3 @@ def _isIPV4(self, ip): def createPlugin(ignore_info=False): return MetasploitPlugin(ignore_info=ignore_info) - - diff --git a/faraday_plugins/plugins/repo/netsparker/plugin.py b/faraday_plugins/plugins/repo/netsparker/plugin.py index 01c5e7a6..5be374af 100644 --- a/faraday_plugins/plugins/repo/netsparker/plugin.py +++ b/faraday_plugins/plugins/repo/netsparker/plugin.py @@ -5,14 +5,12 @@ """ import re -from bs4 import BeautifulSoup -from faraday_plugins.plugins.plugin import PluginXMLFormat -from faraday_plugins.plugins.plugins_utils import resolve_hostname import xml.etree.ElementTree as ET -ETREE_VERSION = ET.VERSION -ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] +from bs4 import BeautifulSoup +from faraday_plugins.plugins.plugin import PluginXMLFormat +from faraday_plugins.plugins.plugins_utils import resolve_hostname __author__ = "Francisco Amato" __copyright__ = "Copyright (c) 2013, Infobyte LLC" diff --git a/faraday_plugins/plugins/repo/netsparkercloud/plugin.py b/faraday_plugins/plugins/repo/netsparkercloud/plugin.py index 0416d750..aadfaf30 100644 --- a/faraday_plugins/plugins/repo/netsparkercloud/plugin.py +++ b/faraday_plugins/plugins/repo/netsparkercloud/plugin.py @@ -5,14 +5,11 @@ """ import re +import xml.etree.ElementTree as ET from urllib.parse import urlparse + from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import resolve_hostname -import xml.etree.ElementTree as ET -ETREE_VERSION = ET.VERSION - -ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] - __author__ = "Francisco Amato" __copyright__ = "Copyright (c) 2013, Infobyte LLC" @@ -24,7 +21,6 @@ __status__ = "Development" - def get_urls(string): if isinstance(string, bytes): string_decode = string.decode("utf-8") @@ -84,6 +80,7 @@ class Item: @param item_node A item_node taken from an netsparkercloud xml tree """ + def re_map_severity(self, severity): if severity == "Important": return "high" @@ -114,7 +111,7 @@ def __init__(self, item_node, encoding="ascii"): self.response = self.get_text_from_subnode("content") self.extra = [] for v in item_node.findall("extra-information/info"): - self.extra.append(v.get('name') + ":" + v.get('value') ) + self.extra.append(v.get('name') + ":" + v.get('value')) self.node = item_node.find("classification") self.owasp = self.get_text_from_subnode("owasp") @@ -200,8 +197,5 @@ def parseOutputString(self, output): del parser - - - def createPlugin(ignore_info=False): return NetsparkerCloudPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/nexpose_full/plugin.py b/faraday_plugins/plugins/repo/nexpose_full/plugin.py index 3c528203..22359c98 100644 --- a/faraday_plugins/plugins/repo/nexpose_full/plugin.py +++ b/faraday_plugins/plugins/repo/nexpose_full/plugin.py @@ -9,10 +9,6 @@ from faraday_plugins.plugins.plugin import PluginXMLFormat -ETREE_VERSION = ET.VERSION - -ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] - __author__ = "Micaela Ranea Sanchez" __copyright__ = "Copyright (c) 2013, Infobyte LLC" __credits__ = ["Francisco Amato", "Federico Kirschbaum", @@ -116,7 +112,6 @@ def parse_tests_type(self, node, vulnsDefinitions): for tests in node.findall('tests'): for test in tests.iter('test'): - vuln = dict() if test.get('id').lower() in vulnsDefinitions: vuln = vulnsDefinitions[test.get('id').lower()].copy() key = test.get('key', '') @@ -314,7 +309,5 @@ def parseOutputString(self, output): del parser - - def createPlugin(ignore_info=False): return NexposeFullPlugin(ignore_info=ignore_info) diff --git a/faraday_plugins/plugins/repo/nmap/plugin.py b/faraday_plugins/plugins/repo/nmap/plugin.py index 91d1938d..bc756c4e 100644 --- a/faraday_plugins/plugins/repo/nmap/plugin.py +++ b/faraday_plugins/plugins/repo/nmap/plugin.py @@ -12,10 +12,7 @@ from lxml.etree import XMLParser from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import get_severity_from_cvss -import xml.etree.ElementTree as ET -ETREE_VERSION = ET.VERSION -ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] current_path = os.path.abspath(os.getcwd()) @@ -71,30 +68,8 @@ def get_attrib_from_subnode(xml_node, subnode_xpath_expr, attrib_name): @return An attribute value """ - global ETREE_VERSION - node = None - if ETREE_VERSION[0] <= 1 and ETREE_VERSION[1] < 3: - - match_obj = re.search( - "([^\@]+?)\[\@([^=]*?)=\'([^\']*?)\'", - subnode_xpath_expr) - - if match_obj is not None: - - node_to_find = match_obj.group(1) - xpath_attrib = match_obj.group(2) - xpath_value = match_obj.group(3) - - for node_found in xml_node.findall(node_to_find): - if node_found.attrib[xpath_attrib] == xpath_value: - node = node_found - break - else: - node = xml_node.find(subnode_xpath_expr) - - else: - node = xml_node.find(subnode_xpath_expr) + node = xml_node.find(subnode_xpath_expr) if node is not None: return node.get(attrib_name) @@ -288,7 +263,7 @@ class Port: @param port_node A port_node taken from an nmap xml tree """ - PORT_STATUS_FIX = {"filtered": "closed", "open|filtered": "closed" } + PORT_STATUS_FIX = {"filtered": "closed", "open|filtered": "closed"} def __init__(self, port_node): self.node = port_node @@ -318,7 +293,7 @@ def get_state(self): @return (state, reason, reason_ttl) or ('unknown','unknown','unknown') """ state = self.PORT_STATUS_FIX.get(self.get_attrib_from_subnode('state', 'state'), - self.get_attrib_from_subnode('state', 'state')) + self.get_attrib_from_subnode('state', 'state')) reason = self.get_attrib_from_subnode('state', 'reason') reason_ttl = self.get_attrib_from_subnode('state', 'reason_ttl') diff --git a/faraday_plugins/plugins/repo/openvas/plugin.py b/faraday_plugins/plugins/repo/openvas/plugin.py index 54122f61..6612fbe7 100644 --- a/faraday_plugins/plugins/repo/openvas/plugin.py +++ b/faraday_plugins/plugins/repo/openvas/plugin.py @@ -1,6 +1,7 @@ import re from collections import defaultdict from copy import copy + """ Faraday Penetration Test IDE Copyright (C) 2013 Infobyte LLC (http://www.infobytesec.com/) @@ -12,9 +13,6 @@ from faraday_plugins.plugins.plugins_utils import filter_services import xml.etree.ElementTree as ET -ETREE_VERSION = ET.VERSION -ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] - __author__ = "Francisco Amato" __copyright__ = "Copyright (c) 2013, Infobyte LLC" @@ -130,28 +128,8 @@ def get_attrib_from_subnode(xml_node, subnode_xpath_expr, attrib_name): @return An attribute value """ - global ETREE_VERSION - node = None - - if ETREE_VERSION[0] <= 1 and ETREE_VERSION[1] < 3: - - match_obj = re.search( - "([^\@]+?)\[\@([^=]*?)=\'([^\']*?)\'", - subnode_xpath_expr) - - if match_obj is not None: - node_to_find = match_obj.group(1) - xpath_attrib = match_obj.group(2) - xpath_value = match_obj.group(3) - for node_found in xml_node.findall(node_to_find): - if node_found.attrib[xpath_attrib] == xpath_value: - node = node_found - break - else: - node = xml_node.find(subnode_xpath_expr) - else: - node = xml_node.find(subnode_xpath_expr) + node = xml_node.find(subnode_xpath_expr) if node is not None: return node.get(attrib_name) @@ -330,7 +308,7 @@ def report_belongs_to(self, **kwargs): with open(report_path) as f: output = f.read() return re.search("OpenVAS", output) is not None \ - or re.search('', output) is not None\ + or re.search('', output) is not None \ or re.search('', output) is not None return False @@ -440,5 +418,3 @@ def _isIPV4(self, ip): def createPlugin(ignore_info=False): return OpenvasPlugin(ignore_info=ignore_info) - - diff --git a/faraday_plugins/plugins/repo/qualysguard/plugin.py b/faraday_plugins/plugins/repo/qualysguard/plugin.py index 736d78ef..c5398615 100644 --- a/faraday_plugins/plugins/repo/qualysguard/plugin.py +++ b/faraday_plugins/plugins/repo/qualysguard/plugin.py @@ -4,13 +4,9 @@ See the file 'doc/LICENSE' for the license information """ import re -from faraday_plugins.plugins.plugin import PluginXMLFormat - import xml.etree.ElementTree as ET -ETREE_VERSION = ET.VERSION - -ETREE_VERSION = [int(i) for i in ETREE_VERSION.split('.')] +from faraday_plugins.plugins.plugin import PluginXMLFormat __author__ = 'Francisco Amato' __copyright__ = 'Copyright (c) 2013, Infobyte LLC' @@ -350,7 +346,6 @@ def parseOutputString(self, output): parser = QualysguardXmlParser(output) - for item in parser.items: h_id = self.createAndAddHost( item.ip, @@ -417,5 +412,3 @@ def parseOutputString(self, output): def createPlugin(ignore_info=False): return QualysguardPlugin(ignore_info=ignore_info) - - diff --git a/faraday_plugins/plugins/repo/retina/plugin.py b/faraday_plugins/plugins/repo/retina/plugin.py index 4e86ca29..f71c5f47 100644 --- a/faraday_plugins/plugins/repo/retina/plugin.py +++ b/faraday_plugins/plugins/repo/retina/plugin.py @@ -5,13 +5,9 @@ """ import re -from faraday_plugins.plugins.plugin import PluginXMLFormat - import xml.etree.ElementTree as ET -ETREE_VERSION = ET.VERSION - -ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] +from faraday_plugins.plugins.plugin import PluginXMLFormat __author__ = "Francisco Amato" __copyright__ = "Copyright (c) 2013, Infobyte LLC" @@ -111,7 +107,7 @@ def get_text_from_subnode(self, subnode_xpath_expr): return None -class Results(): +class Results: def __init__(self, issue_node): self.node = issue_node @@ -176,13 +172,12 @@ def __init__(self, *arg, **kwargs): self.framework_version = "1.0.0" self.options = None - def parseOutputString(self, output): parser = RetinaXmlParser(output) for item in parser.items: hostname = item.hostname if item.hostname else None - h_id = self.createAndAddHost(item.ip, item.os,hostnames=[hostname]) + h_id = self.createAndAddHost(item.ip, item.os, hostnames=[hostname]) if not item.netbiosname == 'N/A': self.createAndAddNoteToHost( @@ -219,5 +214,3 @@ def parseOutputString(self, output): def createPlugin(ignore_info=False): return RetinaPlugin(ignore_info=ignore_info) - - diff --git a/faraday_plugins/plugins/repo/w3af/plugin.py b/faraday_plugins/plugins/repo/w3af/plugin.py index a18f205c..bddab88a 100644 --- a/faraday_plugins/plugins/repo/w3af/plugin.py +++ b/faraday_plugins/plugins/repo/w3af/plugin.py @@ -5,14 +5,11 @@ """ import re +import xml.etree.ElementTree as ET from urllib.parse import urlparse + from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import resolve_hostname -import xml.etree.ElementTree as ET -ETREE_VERSION = ET.VERSION - -ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] - __author__ = "Francisco Amato" __copyright__ = "Copyright (c) 2013, Infobyte LLC" @@ -67,7 +64,6 @@ def get_items(self, tree): """ @return items A list of Host instances """ - bugtype = "" if len(tree.findall('scan-info')) == 0: scaninfo = tree.findall('scaninfo')[0] @@ -98,26 +94,7 @@ def get_attrib_from_subnode(xml_node, subnode_xpath_expr, attrib_name): @return An attribute value """ - global ETREE_VERSION - node = None - - if ETREE_VERSION[0] <= 1 and ETREE_VERSION[1] < 3: - - match_obj = re.search( - "([^\@]+?)\[\@([^=]*?)=\'([^\']*?)\'", subnode_xpath_expr) - if match_obj is not None: - node_to_find = match_obj.group(1) - xpath_attrib = match_obj.group(2) - xpath_value = match_obj.group(3) - for node_found in xml_node.findall(node_to_find): - if node_found.attrib[xpath_attrib] == xpath_value: - node = node_found - break - else: - node = xml_node.find(subnode_xpath_expr) - - else: - node = xml_node.find(subnode_xpath_expr) + node = xml_node.find(subnode_xpath_expr) if node is not None: return node.get(attrib_name) @@ -220,22 +197,18 @@ def __init__(self, *arg, **kwargs): } def parseOutputString(self, output): - parser = W3afXmlParser(output) ip = resolve_hostname(parser.host) h_id = self.createAndAddHost(ip, hostnames=[parser.host]) s_id = self.createAndAddServiceToHost(h_id, "http", "tcp", ports=[parser.port], status="open") for item in parser.items: - v_id = self.createAndAddVulnWebToService(h_id, s_id, item.name, + self.createAndAddVulnWebToService(h_id, s_id, item.name, item.detail, pname=item.param, path=item.url, website=parser.host, severity=item.severity, method=item.method, request=item.req, resolution=item.resolution, ref=item.ref, response=item.resp) del parser - def createPlugin(ignore_info=False): return W3afPlugin(ignore_info=ignore_info) - - diff --git a/faraday_plugins/plugins/repo/wapiti/plugin.py b/faraday_plugins/plugins/repo/wapiti/plugin.py index 50472f9c..d98915cb 100644 --- a/faraday_plugins/plugins/repo/wapiti/plugin.py +++ b/faraday_plugins/plugins/repo/wapiti/plugin.py @@ -5,14 +5,11 @@ """ import re +import xml.etree.ElementTree as ET from urllib.parse import urlparse + from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import resolve_hostname -import xml.etree.ElementTree as ET -ETREE_VERSION = ET.VERSION - -ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] - __author__ = "Francisco Amato" __copyright__ = "Copyright (c) 2013, Infobyte LLC" @@ -67,31 +64,14 @@ def get_items(self, tree): yield Item(tree) - def get_attrib_from_subnode(xml_node, subnode_xpath_expr, attrib_name): """ Finds a subnode in the item node and the retrieves a value from it @return An attribute value """ - global ETREE_VERSION - node = None - - if ETREE_VERSION[0] <= 1 and ETREE_VERSION[1] < 3: - match_obj = re.search( - "([^\@]+?)\[\@([^=]*?)=\'([^\']*?)\'", subnode_xpath_expr) - if match_obj is not None: - node_to_find = match_obj.group(1) - xpath_attrib = match_obj.group(2) - xpath_value = match_obj.group(3) - for node_found in xml_node.findall(node_to_find): - if node_found.attrib[xpath_attrib] == xpath_value: - node = node_found - break - else: - node = xml_node.find(subnode_xpath_expr) - else: - node = xml_node.find(subnode_xpath_expr) + + node = xml_node.find(subnode_xpath_expr) if node is not None: return node.get(attrib_name) return None @@ -142,7 +122,7 @@ def get_url(self, item_node): target = self.get_info(item_node, 'target') return urlparse(target) - def get_info(self, item_node,name): + def get_info(self, item_node, name): path = item_node.findall('report_infos/info') for item in path: @@ -165,8 +145,8 @@ def get_vulns(self, item_node): for vuln in vulns_node: vulns_dict = {} vulns_dict['id'] = vuln.attrib['name'] - vulns_dict['description'] = self.get_text_from_subnode(vuln,'description') - vulns_dict['solution'] = self.get_text_from_subnode(vuln,'solution') + vulns_dict['description'] = self.get_text_from_subnode(vuln, 'description') + vulns_dict['solution'] = self.get_text_from_subnode(vuln, 'solution') vulns_dict['references'] = self.get_references(vuln) vulns_dict['entries'] = self.get_entries(vuln) vulns_list.append(vulns_dict) @@ -177,22 +157,22 @@ def get_references(self, node): refs = node.findall('references/reference') references_list = [] for ref in refs: - references_list.append('Title: ' + self.get_text_from_subnode(ref,'title')) - references_list.append('URL: ' + self.get_text_from_subnode(ref,'url')) + references_list.append('Title: ' + self.get_text_from_subnode(ref, 'title')) + references_list.append('URL: ' + self.get_text_from_subnode(ref, 'url')) return references_list - def get_entries(self,node): + def get_entries(self, node): entries = node.findall('entries/entry') entries_list = [] for entry in entries: entries_dict = {} - entries_dict['method'] = self.get_text_from_subnode(entry,'method') - entries_dict['path'] = self.get_text_from_subnode(entry,'path') + entries_dict['method'] = self.get_text_from_subnode(entry, 'method') + entries_dict['path'] = self.get_text_from_subnode(entry, 'path') entries_dict['level'] = self.severity_format(entry) - entries_dict['parameter'] = self.get_text_from_subnode(entry,'parameter') - entries_dict['http_request'] = self.get_text_from_subnode(entry,'http_request') - entries_dict['curl_command'] = self.get_text_from_subnode(entry,'curl_command') + entries_dict['parameter'] = self.get_text_from_subnode(entry, 'parameter') + entries_dict['http_request'] = self.get_text_from_subnode(entry, 'http_request') + entries_dict['curl_command'] = self.get_text_from_subnode(entry, 'curl_command') entries_list.append(entries_dict) return entries_list @@ -283,13 +263,12 @@ def report_belongs_to(self, **kwargs): return re.search("Wapiti", output) is not None return False - def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it from the xml where it expects it to be present. """ - + parser = WapitiXmlParser(output) for item in parser.items: host_id = self.createAndAddHost(item.ip, hostnames=[item.hostname]) @@ -301,17 +280,17 @@ def parseOutputString(self, output): for vuln in item.vulns: for entry in vuln['entries']: vuln_id = self.createAndAddVulnWebToService(host_id, - service_id, - vuln['id'], - desc=vuln['description'], - ref=vuln['references'], - resolution=vuln['solution'], - severity=entry['level'], - website=entry['curl_command'], - path=entry['path'], - request=entry['http_request'], - method=entry['method'], - params=entry['parameter']) + service_id, + vuln['id'], + desc=vuln['description'], + ref=vuln['references'], + resolution=vuln['solution'], + severity=entry['level'], + website=entry['curl_command'], + path=entry['path'], + request=entry['http_request'], + method=entry['method'], + params=entry['parameter']) def processCommandString(self, username, current_path, command_string): """ @@ -333,11 +312,9 @@ def processCommandString(self, username, current_path, command_string): self.port = host.group(11) if self.protocol == 'https': self.port = 443 - self.logger.debug("host = %s, port = %s",self.host, self.port) + self.logger.debug("host = %s, port = %s", self.host, self.port) return "%s -o %s -f xml \n" % (command_string, self._output_file_path) def createPlugin(ignore_info=False): return WapitiPlugin(ignore_info=ignore_info) - - diff --git a/faraday_plugins/plugins/repo/zap/plugin.py b/faraday_plugins/plugins/repo/zap/plugin.py index f244f608..cf6cc168 100644 --- a/faraday_plugins/plugins/repo/zap/plugin.py +++ b/faraday_plugins/plugins/repo/zap/plugin.py @@ -4,17 +4,12 @@ See the file 'doc/LICENSE' for the license information """ import re +import xml.etree.ElementTree as ET from urllib.parse import urlparse from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import resolve_hostname -import xml.etree.ElementTree as ET -ETREE_VERSION = ET.VERSION - -ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] - - __author__ = "Francisco Amato" __copyright__ = "Copyright (c) 2013, Infobyte LLC" __credits__ = ["Francisco Amato"] @@ -84,37 +79,15 @@ def get_attrib_from_subnode(xml_node, subnode_xpath_expr, attrib_name): @return An attribute value """ - global ETREE_VERSION - node = None - - if ETREE_VERSION[0] <= 1 and ETREE_VERSION[1] < 3: - - match_obj = re.search( - "([^\@]+?)\[\@([^=]*?)=\'([^\']*?)\'", - subnode_xpath_expr) - if match_obj is not None: - - node_to_find = match_obj.group(1) - xpath_attrib = match_obj.group(2) - xpath_value = match_obj.group(3) - - for node_found in xml_node.findall(node_to_find): - - if node_found.attrib[xpath_attrib] == xpath_value: - node = node_found - break - else: - node = xml_node.find(subnode_xpath_expr) - - else: - node = xml_node.find(subnode_xpath_expr) + node = xml_node.find(subnode_xpath_expr) if node is not None: return node.get(attrib_name) return None + def strip_tags(data): """ Remove html tags from a string @@ -123,6 +96,7 @@ def strip_tags(data): clean = re.compile('<.*?>') return re.sub(clean, '', data) + class Site: def __init__(self, item_node): @@ -307,7 +281,7 @@ def parseOutputString(self, output): resolution=strip_tags(item.resolution), data=instance["data"], pname=instance["pname"], - external_id="ZAP-"+str(item.id) + external_id="ZAP-" + str(item.id) ) del parser From ba12e064a935c5a0317bc78ad16c3a5b29032720 Mon Sep 17 00:00:00 2001 From: Manuel Jose Sotomayor Torrealba Date: Tue, 4 May 2021 20:37:16 +0000 Subject: [PATCH 208/698] add attribute command for plugins of all command --- ...bute_command_for_plugins_of_all_command.md | 3 + faraday_plugins/plugins/plugin.py | 60 +++++++++++-------- faraday_plugins/plugins/repo/dirb/plugin.py | 4 +- .../plugins/repo/dirsearch/plugin.py | 3 +- faraday_plugins/plugins/repo/dnsmap/plugin.py | 6 +- .../plugins/repo/dnswalk/plugin.py | 8 +-- faraday_plugins/plugins/repo/ping/plugin.py | 10 +--- tests/commands.json | 55 +++++++++++++++-- tests/test_cli.py | 9 +++ tests/test_commands.py | 3 + 10 files changed, 110 insertions(+), 51 deletions(-) create mode 100644 CHANGELOG/current/add-attribute_command_for_plugins_of_all_command.md diff --git a/CHANGELOG/current/add-attribute_command_for_plugins_of_all_command.md b/CHANGELOG/current/add-attribute_command_for_plugins_of_all_command.md new file mode 100644 index 00000000..1b2533a8 --- /dev/null +++ b/CHANGELOG/current/add-attribute_command_for_plugins_of_all_command.md @@ -0,0 +1,3 @@ +- add attribute "command" for the pluggins of each command +- adding test in test_command +- change some regex in self._command_regex \ No newline at end of file diff --git a/faraday_plugins/plugins/plugin.py b/faraday_plugins/plugins/plugin.py index 90cd541f..83dcc3ad 100644 --- a/faraday_plugins/plugins/plugin.py +++ b/faraday_plugins/plugins/plugin.py @@ -4,27 +4,26 @@ See the file 'doc/LICENSE' for the license information """ +import hashlib +import logging import os +import re import shutil import tempfile - -from collections import defaultdict - -import pytz -import re import uuid -import logging -import simplejson as json import zipfile +from collections import defaultdict from datetime import datetime -import hashlib +import pytz +import simplejson as json logger = logging.getLogger("faraday").getChild(__name__) VALID_SERVICE_STATUS = ("open", "closed", "filtered") VULN_SKIP_FIELDS_TO_HASH = ['run_date'] + class PluginBase: # TODO: Add class generic identifier class_signature = "PluginBase" @@ -41,6 +40,7 @@ def __init__(self, ignore_info=False): self.name = None self.description = "" self._command_regex = None + self.command = None self._output_file_path = None self._use_temp_file = False self._delete_temp_file = False @@ -102,6 +102,7 @@ def align_string_based_vulns(severity): if severity[0:3] in sev: return sev return severity + severity = align_string_based_vulns(severity) # Transform numeric severity into desc severity numeric_severities = {"0": "info", @@ -170,7 +171,6 @@ def save_host_vuln_cache(self, host_id, vuln): def _get_dict_hash(d, keys): return hash(frozenset(map(lambda x: (x, d.get(x, None)), keys))) - @classmethod def get_host_cache_id(cls, host): cache_id = cls._get_dict_hash(host, ['ip']) @@ -187,14 +187,17 @@ def get_host_service_cache_id(cls, host_id, service): def get_service_vuln_cache_id(cls, host_id, service_id, vuln): vuln_copy = vuln.copy() vuln_copy.update({"host_cache_id": host_id, "service_cache_id": service_id}) - cache_id = cls._get_dict_hash(vuln_copy, ['host_cache_id', 'service_cache_id', 'name', 'desc', 'website', 'path', 'pname', 'method']) + cache_id = cls._get_dict_hash(vuln_copy, + ['host_cache_id', 'service_cache_id', 'name', 'desc', 'website', 'path', 'pname', + 'method']) return cache_id @classmethod def get_host_vuln_cache_id(cls, host_id, vuln): vuln_copy = vuln.copy() vuln_copy.update({"host_cache_id": host_id}) - cache_id = cls._get_dict_hash(vuln_copy, ['host_cache_id', 'name', 'desc', 'website', 'path', 'pname', 'method']) + cache_id = cls._get_dict_hash(vuln_copy, + ['host_cache_id', 'name', 'desc', 'website', 'path', 'pname', 'method']) return cache_id def save_cache(self, obj): @@ -228,7 +231,7 @@ def getSettings(self): for param, (param_type, value) in self._settings.items(): yield param, value - def get_ws(self): # TODO Borrar + def get_ws(self): # TODO Borrar return "" def getSetting(self, name): @@ -249,8 +252,17 @@ def canParseCommandString(self, current_input): This method can be overriden in the plugin implementation if a different kind of check is needed """ - return (self._command_regex is not None and - self._command_regex.match(current_input.strip()) is not None) + if (self._command_regex is not None and + self._command_regex.match(current_input.strip()) is not None): + self.command = self.get_command(current_input) + return True + + def get_command(self, current_input: str) -> str: + command = self._command_regex.findall(current_input)[0] + if isinstance(command, tuple): + return "".join(command).strip() + + return command.strip() def processCommandString(self, username, current_path, command_string): """ @@ -334,15 +346,15 @@ def createAndAddHost(self, name, os="unknown", hostnames=None, mac=None, descrip tags = [] if isinstance(tags, str): tags = [tags] - host = {"ip": name, "os": os, "hostnames": hostnames, "description": description, "mac": mac, + host = {"ip": name, "os": os, "hostnames": hostnames, "description": description, "mac": mac, "credentials": [], "services": [], "vulnerabilities": [], "tags": tags} host_id = self.save_host_cache(host) return host_id def createAndAddServiceToHost(self, host_id, name, - protocol="tcp", ports=None, - status="open", version="unknown", - description="", tags=None): + protocol="tcp", ports=None, + status="open", version="unknown", + description="", tags=None): if ports: if isinstance(ports, list): ports = int(ports[0]) @@ -412,7 +424,8 @@ def createAndAddVulnToService(self, host_id, service_id, name, desc="", tags = [tags] vulnerability = {"name": name, "desc": desc, "severity": self.normalize_severity(severity), "refs": ref, "external_id": external_id, "type": "Vulnerability", "resolution": resolution, "data": data, - "custom_fields": custom_fields, "status": status, "impact": impact, "policyviolations": policyviolations, + "custom_fields": custom_fields, "status": status, "impact": impact, + "policyviolations": policyviolations, "easeofresolution": easeofresolution, "confirmed": confirmed, "tags": tags } if run_date: @@ -426,7 +439,8 @@ def createAndAddVulnWebToService(self, host_id, service_id, name, desc="", response="", method="", pname="", params="", query="", category="", data="", external_id=None, confirmed=False, status="", easeofresolution=None, impact=None, - policyviolations=None, status_code=None, custom_fields=None, run_date=None, tags=None): + policyviolations=None, status_code=None, custom_fields=None, run_date=None, + tags=None): if params is None: params = "" if response is None: @@ -476,7 +490,6 @@ def createAndAddVulnWebToService(self, host_id, service_id, name, desc="", def createAndAddNoteToHost(self, host_id, name, text): return None - def createAndAddNoteToService(self, host_id, service_id, name, text): return None @@ -492,7 +505,7 @@ def createAndAddCredToService(self, host_id, service_id, username, password): def get_data(self): self.vulns_data["command"]["tool"] = self.id - self.vulns_data["command"]["command"] = self.id + self.vulns_data["command"]["command"] = self.command if self.command else self.id self.vulns_data["command"]["duration"] = (datetime.now() - self.start_date).microseconds return self.vulns_data @@ -529,6 +542,7 @@ def get_summary(self): summary['vuln_hashes'].append(dict_hash) return summary + # TODO Borrar class PluginTerminalOutput(PluginBase): def __init__(self): @@ -667,5 +681,3 @@ def report_belongs_to(self, files_in_zip=None, **kwargs): match = bool(self.files_list & files_in_zip) self.logger.debug("Files List Match: [%s =/in %s] -> %s", files_in_zip, self.files_list, match) return match - - diff --git a/faraday_plugins/plugins/repo/dirb/plugin.py b/faraday_plugins/plugins/repo/dirb/plugin.py index 5de14209..e6b51a30 100644 --- a/faraday_plugins/plugins/repo/dirb/plugin.py +++ b/faraday_plugins/plugins/repo/dirb/plugin.py @@ -26,8 +26,8 @@ def __init__(self, *arg, **kwargs): self.plugin_version = "0.0.1" self.version = "2.22" self.regexpUrl = r'((http[s]?)\:\/\/([\w\.]+)[.\S]+)' - self._command_regex = re.compile(r'^(?:sudo dirb|dirb|\.\/dirb|sudo \.\/dirb)\s+(?:(http[s]?)' - r'\:\/\/([\w\.]+)[.\S]+)') + self._command_regex = re.compile(r'^(sudo dirb|dirb|\.\/dirb|sudo \.\/dirb)\s+.*?') + self.text = [] def getPort(self, host, proto): diff --git a/faraday_plugins/plugins/repo/dirsearch/plugin.py b/faraday_plugins/plugins/repo/dirsearch/plugin.py index 196e372f..980ce133 100644 --- a/faraday_plugins/plugins/repo/dirsearch/plugin.py +++ b/faraday_plugins/plugins/repo/dirsearch/plugin.py @@ -59,7 +59,7 @@ def __init__(self, *arg, **kwargs): self.name = "dirsearch" self.plugin_version = "0.0.1" self.version = "0.0.1" - self._command_regex = re.compile(r'^(sudo )?(python[0-9\.]? )?dirsearch(\.py)\s+?') + self._command_regex = re.compile(r'^(sudo )?(python[0-9\.]? )?(dirsearch\.py)\s+?') self.addSetting("Ignore 403", str, "1") self._use_temp_file = True self._temp_file_extension = "json" @@ -67,7 +67,6 @@ def __init__(self, *arg, **kwargs): def parseOutputString(self, output): self.parse_json(output) - @property def should_ignore_403(self): val = self.getSetting('Ignore 403') diff --git a/faraday_plugins/plugins/repo/dnsmap/plugin.py b/faraday_plugins/plugins/repo/dnsmap/plugin.py index 6fe6352b..14fffb09 100644 --- a/faraday_plugins/plugins/repo/dnsmap/plugin.py +++ b/faraday_plugins/plugins/repo/dnsmap/plugin.py @@ -3,10 +3,10 @@ Copyright (C) 2013 Infobyte LLC (http://www.infobytesec.com/) See the file 'doc/LICENSE' for the license information """ -from faraday_plugins.plugins.plugin import PluginBase import re from collections import defaultdict +from faraday_plugins.plugins.plugin import PluginBase __author__ = "Francisco Amato" __copyright__ = "Copyright (c) 2013, Infobyte LLC" @@ -104,9 +104,9 @@ def __init__(self, *arg, **kwargs): self._use_temp_file = True self._temp_file_extension = "txt" - def canParseCommandString(self, current_input): if self._command_regex.match(current_input.strip()): + self.command = self.get_command(current_input) return True else: return False @@ -139,5 +139,3 @@ def processCommandString(self, username, current_path, command_string): def createPlugin(ignore_info=False): return DnsmapPlugin(ignore_info=ignore_info) - - diff --git a/faraday_plugins/plugins/repo/dnswalk/plugin.py b/faraday_plugins/plugins/repo/dnswalk/plugin.py index 4851d7a4..1f2b58c7 100644 --- a/faraday_plugins/plugins/repo/dnswalk/plugin.py +++ b/faraday_plugins/plugins/repo/dnswalk/plugin.py @@ -5,12 +5,10 @@ """ import re -import os from faraday_plugins.plugins.plugin import PluginBase from faraday_plugins.plugins.plugins_utils import resolve_hostname - __author__ = "Francisco Amato" __copyright__ = "Copyright (c) 2013, Infobyte LLC" __credits__ = ["Francisco Amato"] @@ -42,7 +40,6 @@ def __init__(self, output): for line in lists: mregex = re.search("WARN: ([\w\.]+) ([\w]+) ([\w\.]+):", line) if mregex is not None: - item = { 'host': mregex.group(1), 'ip': mregex.group(3), @@ -63,7 +60,6 @@ def __init__(self, output): self.items.append(item) - class DnswalkPlugin(PluginBase): """ Example plugin to parse dnswalk output. @@ -80,9 +76,9 @@ def __init__(self, *arg, **kwargs): self._command_regex = re.compile( r'^(sudo dnswalk|dnswalk|\.\/dnswalk)\s+.*?') - def canParseCommandString(self, current_input): if self._command_regex.match(current_input.strip()): + self.command = self.get_command(current_input) return True else: return False @@ -115,5 +111,3 @@ def parseOutputString(self, output): def createPlugin(ignore_info=False): return DnswalkPlugin(ignore_info=ignore_info) - - diff --git a/faraday_plugins/plugins/repo/ping/plugin.py b/faraday_plugins/plugins/repo/ping/plugin.py index 80ff3a83..f4c5e7c2 100644 --- a/faraday_plugins/plugins/repo/ping/plugin.py +++ b/faraday_plugins/plugins/repo/ping/plugin.py @@ -4,9 +4,10 @@ See the file 'doc/LICENSE' for the license information """ -from faraday_plugins.plugins.plugin import PluginBase import re +from faraday_plugins.plugins.plugin import PluginBase + __author__ = "Facundo de GuzmĂĄn, Esteban Guillardoy" __copyright__ = "Copyright (c) 2013, Infobyte LLC" __credits__ = ["Facundo de GuzmĂĄn", "Esteban Guillardoy"] @@ -35,10 +36,9 @@ def parseOutputString(self, output): reg = re.search(r"PING ([\w\.-:]+)( |)\(([\w\.:]+)\)", output) if re.search("0 received|unknown host", output) is None and reg is not None: - ip_address = reg.group(3) hostname = reg.group(1) - h_id = self.createAndAddHost(ip_address, hostnames=[hostname]) + self.createAndAddHost(ip_address, hostnames=[hostname]) return True def _isIPV4(self, ip): @@ -48,9 +48,5 @@ def _isIPV4(self, ip): return False - def createPlugin(ignore_info=False): return CmdPingPlugin(ignore_info=ignore_info) - - - diff --git a/tests/commands.json b/tests/commands.json index 19ff1ef8..33300200 100644 --- a/tests/commands.json +++ b/tests/commands.json @@ -1,8 +1,53 @@ { "commands": [ - {"plugin_id": "ping", "command": "ping -c4 faradaysec.com"}, - {"plugin_id": "whois", "command": "whois fradaysec.com"}, - {"plugin_id": "nmap", "command": "nmap fradaysec.com"}, - {"plugin_id": "skipfish", "command": "skipfish http://fradaysec.com"} + {"plugin_id": "ping", "command": "ping -c4 faradaysec.com", "command_result": "ping"}, + {"plugin_id": "whois", "command": "whois fradaysec.com", "command_result": "whois"}, + {"plugin_id": "nmap", "command": "nmap fradaysec.com", "command_result": "nmap"}, + {"plugin_id": "skipfish", "command": "skipfish http://fradaysec.com", "command_result": "skipfish"}, + {"plugin_id": "sslyze_json", "command": "sslyze www.google.com --json_out=x.json", "command_result": "sslyze"}, + {"plugin_id": "Amap", "command": "amap www.google.com", "command_result": "amap"}, + {"plugin_id": "arp-scan", "command": "arp-scan www.google.com", "command_result": "arp-scan"}, + {"plugin_id": "Beef", "command": "beef www.google.com", "command_result": "beef"}, + {"plugin_id": "brutexss", "command": "brutexss www.google.com", "command_result": "brutexss"}, + {"plugin_id": "dig", "command": "dig www.google.com", "command_result": "dig"}, + {"plugin_id": "dirsearch", "command": "python3 dirsearch.py -u https://target", "command_result": "python3 dirsearch.py"}, + + {"plugin_id": "Dnsenum", "command": "dnsenum www.google.com", "command_result": "Dnsenum"}, + {"plugin_id": "Dnsmap", "command": "dnsmap www.google.com", "command_result": "Dnsmap"}, + {"plugin_id": "Dnsrecon", "command": "dnsrecon www.google.com", "command_result": "Dnsrecon"}, + {"plugin_id": "Dnswalk", "command": "dnswalk www.google.com", "command_result": "Dnswalk"}, + {"plugin_id": "Fierce", "command": "fierce www.google.com", "command_result": "Fierce"}, + {"plugin_id": "fruitywifi", "command": "fruitywifi www.google.com", "command_result": "fruitywifi"}, + {"plugin_id": "ftp", "command": "ftp www.google.com", "command_result": "ftp"}, + {"plugin_id": "Goohost", "command": "goohost.sh www.google.com", "command_result": "goohost.sh"}, + {"plugin_id": "Hping3", "command": "hping3 www.google.com", "command_result": "Hping3"}, + {"plugin_id": "Hydra", "command": "hydra www.google.com", "command_result": "Hydra"}, + {"plugin_id": "Lynis", "command": "lynis www.google.com", "command_result": "Lynis"}, + {"plugin_id": "Medusa", "command": "medusa www.google.com", "command_result": "Medusa"}, + {"plugin_id": "Ndiff", "command": "ndiff www.google.com", "command_result": "Ndiff"}, + {"plugin_id": "Netdiscover", "command": "netdiscover www.google.com", "command_result": "Netdiscover"}, + {"plugin_id": "nextnet", "command": "nextnet www.google.com", "command_result": "nextnet"}, + {"plugin_id": "Nikto", "command": "nikto www.google.com", "command_result": "Nikto"}, + {"plugin_id": "Nmap", "command": "nmap www.google.com", "command_result": "Nmap"}, + {"plugin_id": "pasteAnalyzer", "command": "pasteAnalyzer www.google.com", "command_result": "pasteAnalyzer"}, + {"plugin_id": "peepingtom", "command": "./peepingtom.py www.google.com", "command_result": "./peepingtom.py"}, + {"plugin_id": "propecia", "command": "propecia www.google.com", "command_result": "propecia"}, + {"plugin_id": "rdpscan", "command": "rdpscan www.google.com", "command_result": "rdpscan"}, + {"plugin_id": "Reverseraider", "command": "./reverseraider www.google.com", "command_result": "./reverseraider"}, + {"plugin_id": "Skipfish", "command": "skipfish www.google.com", "command_result": "Skipfish"}, + {"plugin_id": "sshdefaultscan", "command": "./sshdefaultscan.py www.google.com", "command_result": "./sshdefaultscan.py"}, + {"plugin_id": "Telnet", "command": "telnet www.google.com", "command_result": "telnet"}, + {"plugin_id": "Theharvester", "command": "./theHarvester.py www.google.com", "command_result": "./theharvester.py"}, + {"plugin_id": "Traceroute", "command": "traceroute www.google.com", "command_result": "Traceroute"}, + {"plugin_id": "W3af", "command": "w3af www.google.com", "command_result": "W3af"}, + {"plugin_id": "Wapiti", "command": "wapiti www.google.com", "command_result": "Wapiti"}, + {"plugin_id": "Wcscan", "command": "wcscan www.google.com", "command_result": "Wcscan"}, + {"plugin_id": "Webfuzzer", "command": "webfuzzer www.google.com", "command_result": "Webfuzzer"}, + {"plugin_id": "Wfuzz", "command": "wfuzz www.google.com", "command_result": "Wfuzz"}, + {"plugin_id": "whois", "command": "whois www.google.com", "command_result": "whois"}, + {"plugin_id": "X1", "command": "./x1 www.google.com", "command_result": "./x1"}, + {"plugin_id": "xsssniper", "command": "xsssniper www.google.com", "command_result": "xsssniper"}, + {"plugin_id": "dirb", "command": "dirb google.com", "command_result": "dirb"}, + {"plugin_id": "Arachni", "command": "arachni www.google.com", "command_result": "Arachni"} ] -} \ No newline at end of file +} diff --git a/tests/test_cli.py b/tests/test_cli.py index 4d7d9c22..82a160fc 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -37,6 +37,15 @@ def test_process_command(): assert summary['hosts'] == 1 +def test_process_command_ping(): + runner = CliRunner() + result = runner.invoke(process_command, args=['ping -c 1 www.google.com']) + assert result.exit_code == 0 + summary = json.loads(result.output.strip()) + + assert summary['command']["command"] == 'ping' + + def test_process_command_to_file(): runner = CliRunner() with runner.isolated_filesystem() as file_system: diff --git a/tests/test_commands.py b/tests/test_commands.py index 4ca25dd7..d5f5f238 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -20,7 +20,10 @@ def 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() From 396672f5e048da20b70a0b253ceeb9cffeaaedb7 Mon Sep 17 00:00:00 2001 From: Manuel Jose Sotomayor Torrealba Date: Tue, 4 May 2021 20:52:32 +0000 Subject: [PATCH 209/698] adding remedy into resolution --- CHANGELOG/current/issue_in_netsparker.md | 1 + .../plugins/repo/netsparker/plugin.py | 29 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) create mode 100644 CHANGELOG/current/issue_in_netsparker.md diff --git a/CHANGELOG/current/issue_in_netsparker.md b/CHANGELOG/current/issue_in_netsparker.md new file mode 100644 index 00000000..e4e055f1 --- /dev/null +++ b/CHANGELOG/current/issue_in_netsparker.md @@ -0,0 +1 @@ +ADD remedy into resolution \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/netsparker/plugin.py b/faraday_plugins/plugins/repo/netsparker/plugin.py index e4fb5947..092c7291 100644 --- a/faraday_plugins/plugins/repo/netsparker/plugin.py +++ b/faraday_plugins/plugins/repo/netsparker/plugin.py @@ -9,13 +9,9 @@ from faraday_plugins.plugins.plugin import PluginXMLFormat from faraday_plugins.plugins.plugins_utils import resolve_hostname -try: - import xml.etree.cElementTree as ET - import xml.etree.ElementTree as ET_ORIG - ETREE_VERSION = ET_ORIG.VERSION -except ImportError: - import xml.etree.ElementTree as ET - ETREE_VERSION = ET.VERSION + +import xml.etree.ElementTree as ET +ETREE_VERSION = ET.VERSION ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] @@ -83,12 +79,7 @@ class Item: @param item_node A item_node taken from an netsparker xml tree """ - def re_map_severity(self, severity): - if severity == "Important": - return "high" - return severity - - def __init__(self, item_node, encoding="ascii"): + def __init__(self, item_node): self.node = item_node self.url = self.get_text_from_subnode("url") @@ -118,7 +109,8 @@ def __init__(self, item_node, encoding="ascii"): self.param = self.get_text_from_subnode("vulnerableparameter") self.paramval = self.get_text_from_subnode("vulnerableparametervalue") self.reference = self.get_text_from_subnode("externalReferences") - self.resolution = self.get_text_from_subnode("actionsToTake") + remedy = self.get_text_from_subnode("remedy") + self.resolution = self.get_text_from_subnode("actionsToTake") + remedy if remedy else "" self.request = self.get_text_from_subnode("rawrequest") self.response = self.get_text_from_subnode("rawresponse") self.kvulns = [] @@ -167,6 +159,12 @@ def __init__(self, item_node, encoding="ascii"): repr(self.paramval) if self.paramval else "" self.data += "\nExtra: " + "\n".join(self.extra) if self.extra else "" + @staticmethod + def re_map_severity(severity): + if severity == "Important": + return "high" + return severity + def get_text_from_subnode(self, subnode_xpath_expr): """ Finds a subnode in the host node and the retrieves a value from it. @@ -208,6 +206,7 @@ def parseOutputString(self, output): ports=[str(i.port)], status="open") first = False + if i.resolution is not None: resolution = BeautifulSoup(i.resolution, "lxml").text else: @@ -221,7 +220,7 @@ def parseOutputString(self, output): name = i.name else: name = i.name_title - v_id = self.createAndAddVulnWebToService(h_id, s_id, name, ref=i.ref, website=i.hostname, + self.createAndAddVulnWebToService(h_id, s_id, name, ref=i.ref, website=i.hostname, severity=i.severity, desc=desc, path=i.url, method=i.method, request=i.request, response=i.response, resolution=resolution, pname=i.param, data=i.data) From 244b10cc3b011904bb43b4da3f90bbb631c9c598 Mon Sep 17 00:00:00 2001 From: Manuel Jose Sotomayor Torrealba Date: Tue, 4 May 2021 23:16:13 -0300 Subject: [PATCH 210/698] removing latests ETREE_VERSION --- faraday_plugins/plugins/repo/burp/plugin.py | 46 ++++--------------- .../plugins/repo/dnsrecon/plugin.py | 28 +---------- .../plugins/repo/maltego/plugin.py | 4 -- .../plugins/repo/metasploit/plugin.py | 5 +- faraday_plugins/plugins/repo/nikto/plugin.py | 41 ++--------------- faraday_plugins/plugins/repo/wcscan/plugin.py | 15 +----- faraday_plugins/plugins/repo/x1/plugin.py | 4 -- 7 files changed, 19 insertions(+), 124 deletions(-) diff --git a/faraday_plugins/plugins/repo/burp/plugin.py b/faraday_plugins/plugins/repo/burp/plugin.py index 72c24fae..22bc77dd 100644 --- a/faraday_plugins/plugins/repo/burp/plugin.py +++ b/faraday_plugins/plugins/repo/burp/plugin.py @@ -4,19 +4,14 @@ See the file 'doc/LICENSE' for the license information """ -import re -import os import base64 -from bs4 import BeautifulSoup, Comment -from faraday_plugins.plugins.plugin import PluginXMLFormat -from urllib.parse import urlsplit -import distutils.util #pylint: disable=import-error - +import distutils.util # pylint: disable=import-error import xml.etree.ElementTree as ET -ETREE_VERSION = ET.VERSION +from urllib.parse import urlsplit -ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] +from bs4 import BeautifulSoup, Comment +from faraday_plugins.plugins.plugin import PluginXMLFormat __author__ = "Francisco Amato" __copyright__ = "Copyright (c) 2013, Infobyte LLC" @@ -72,7 +67,6 @@ def get_items(self, tree): """ @return items A list of Host instances """ - bugtype = '' for node in tree.findall('issue'): yield Item(node) @@ -84,27 +78,7 @@ def get_attrib_from_subnode(xml_node, subnode_xpath_expr, attrib_name): @return An attribute value """ - global ETREE_VERSION - node = None - - if ETREE_VERSION[0] <= 1 and ETREE_VERSION[1] < 3: - - match_obj = re.search( - "([^\@]+?)\[\@([^=]*?)=\'([^\']*?)\'", subnode_xpath_expr) - if match_obj is not None: - - node_to_find = match_obj.group(1) - xpath_attrib = match_obj.group(2) - xpath_value = match_obj.group(3) - for node_found in xml_node.findall(node_to_find): - if node_found.attrib[xpath_attrib] == xpath_value: - node = node_found - break - else: - node = xml_node.find(subnode_xpath_expr) - - else: - node = xml_node.find(subnode_xpath_expr) + node = xml_node.find(subnode_xpath_expr) if node is not None: return node.get(attrib_name) @@ -159,8 +133,8 @@ def __init__(self, item_node): self.background = background self.external_id = external_id.text - - def do_clean(self, value): + @staticmethod + def do_clean(value): myreturn = "" if value is not None: @@ -216,7 +190,6 @@ def __init__(self, *arg, **kwargs): self._current_output = None self.target = None - def parseOutputString(self, output): parser = BurpXmlParser(output) @@ -242,7 +215,7 @@ def parseOutputString(self, output): data = self.removeHtml(data) resolution = self.removeHtml(item.remediation) if item.remediation else "" - v_id = self.createAndAddVulnWebToService( + self.createAndAddVulnWebToService( h_id, s_id, item.name, @@ -258,7 +231,6 @@ def parseOutputString(self, output): del parser - def removeHtml(self, markup): soup = BeautifulSoup(markup, "html.parser") @@ -289,5 +261,3 @@ def removeHtml(self, markup): def createPlugin(ignore_info=False): return BurpPlugin(ignore_info=ignore_info) - - diff --git a/faraday_plugins/plugins/repo/dnsrecon/plugin.py b/faraday_plugins/plugins/repo/dnsrecon/plugin.py index 2b2ac0c8..41e1d4d3 100644 --- a/faraday_plugins/plugins/repo/dnsrecon/plugin.py +++ b/faraday_plugins/plugins/repo/dnsrecon/plugin.py @@ -3,13 +3,10 @@ Copyright (C) 2013 Infobyte LLC (http://www.infobytesec.com/) See the file 'doc/LICENSE' for the license information """ -from faraday_plugins.plugins.plugin import PluginBase import re import xml.etree.ElementTree as ET -ETREE_VERSION = ET.VERSION - -ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] +from faraday_plugins.plugins.plugin import PluginBase __author__ = "Francisco Amato" __copyright__ = "Copyright (c) 2013, Infobyte LLC" @@ -72,27 +69,8 @@ def get_attrib_from_subnode(xml_node, subnode_xpath_expr, attrib_name): @return An attribute value """ - global ETREE_VERSION - node = None - - if ETREE_VERSION[0] <= 1 and ETREE_VERSION[1] < 3: - - match_obj = re.search( - "([^\@]+?)\[\@([^=]*?)=\'([^\']*?)\'", subnode_xpath_expr) - if match_obj is not None: - - node_to_find = match_obj.group(1) - xpath_attrib = match_obj.group(2) - xpath_value = match_obj.group(3) - for node_found in xml_node.findall(node_to_find): - if node_found.attrib[xpath_attrib] == xpath_value: - node = node_found - break - else: - node = xml_node.find(subnode_xpath_expr) - else: - node = xml_node.find(subnode_xpath_expr) + node = xml_node.find(subnode_xpath_expr) if node is not None: return node.get(attrib_name) @@ -236,5 +214,3 @@ def processCommandString(self, username, current_path, command_string): def createPlugin(ignore_info=False): return DnsreconPlugin(ignore_info=ignore_info) - - diff --git a/faraday_plugins/plugins/repo/maltego/plugin.py b/faraday_plugins/plugins/repo/maltego/plugin.py index 4b185db4..f0ce98c9 100755 --- a/faraday_plugins/plugins/repo/maltego/plugin.py +++ b/faraday_plugins/plugins/repo/maltego/plugin.py @@ -9,10 +9,6 @@ from faraday_plugins.plugins.plugin import PluginZipFormat from faraday_plugins.plugins.plugins_utils import resolve_hostname -ETREE_VERSION = ET.VERSION - -ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] - __author__ = "Ezequiel Tavella" __copyright__ = "Copyright (c) 2015, Infobyte LLC" __credits__ = ["Ezequiel Tavella"] diff --git a/faraday_plugins/plugins/repo/metasploit/plugin.py b/faraday_plugins/plugins/repo/metasploit/plugin.py index 9394469d..dab79f92 100644 --- a/faraday_plugins/plugins/repo/metasploit/plugin.py +++ b/faraday_plugins/plugins/repo/metasploit/plugin.py @@ -7,8 +7,6 @@ from faraday_plugins.plugins.plugin import PluginXMLFormat -ETREE_VERSION = ET.VERSION - __author__ = "Francisco Amato" __copyright__ = "Copyright (c) 2013, Infobyte LLC" __credits__ = ["Francisco Amato"] @@ -364,7 +362,8 @@ def parseOutputString(self, output): del parser - def _isIPV4(self, ip): + @staticmethod + def _isIPV4(ip): if len(ip.split(".")) == 4: return True else: diff --git a/faraday_plugins/plugins/repo/nikto/plugin.py b/faraday_plugins/plugins/repo/nikto/plugin.py index 89c36185..652db7a7 100644 --- a/faraday_plugins/plugins/repo/nikto/plugin.py +++ b/faraday_plugins/plugins/repo/nikto/plugin.py @@ -4,15 +4,11 @@ See the file 'doc/LICENSE' for the license information """ import re -from html.parser import HTMLParser -from faraday_plugins.plugins.plugin import PluginXMLFormat -from faraday_plugins.plugins import plugins_utils - import xml.etree.ElementTree as ET -ETREE_VERSION = ET.VERSION - -ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] +from html.parser import HTMLParser +from faraday_plugins.plugins import plugins_utils +from faraday_plugins.plugins.plugin import PluginXMLFormat __author__ = "Francisco Amato" __copyright__ = "Copyright (c) 2013, Infobyte LLC" @@ -79,28 +75,8 @@ def get_attrib_from_subnode(xml_node, subnode_xpath_expr, attrib_name): @return An attribute value """ - global ETREE_VERSION - node = None - - if ETREE_VERSION[0] <= 1 and ETREE_VERSION[1] < 3: - - match_obj = re.search( - "([^\@]+?)\[\@([^=]*?)=\'([^\']*?)\'", subnode_xpath_expr) - if match_obj is not None: - node_to_find = match_obj.group(1) - xpath_attrib = match_obj.group(2) - xpath_value = match_obj.group(3) - for node_found in xml_node.findall(node_to_find): - - if node_found.attrib[xpath_attrib] == xpath_value: - node = node_found - break - else: - node = xml_node.find(subnode_xpath_expr) - - else: - node = xml_node.find(subnode_xpath_expr) + node = xml_node.find(subnode_xpath_expr) if node is not None: return node.get(attrib_name) @@ -295,8 +271,6 @@ def __init__(self, *arg, **kwargs): "-vhost+": "Virtual host (for Host header)", } - - def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it from @@ -324,8 +298,7 @@ def parseOutputString(self, output): ) for item in host.items: - - v_id = self.createAndAddVulnWebToService( + self.createAndAddVulnWebToService( h_id, s_id, name=item.desc, @@ -337,8 +310,6 @@ def parseOutputString(self, output): del parser - - def processCommandString(self, username, current_path, command_string): """ Adds the -oX parameter to get xml output to the command string that the @@ -357,5 +328,3 @@ def processCommandString(self, username, current_path, command_string): def createPlugin(ignore_info=False): return NiktoPlugin(ignore_info=ignore_info) - - diff --git a/faraday_plugins/plugins/repo/wcscan/plugin.py b/faraday_plugins/plugins/repo/wcscan/plugin.py index 5a228411..fcc041bb 100644 --- a/faraday_plugins/plugins/repo/wcscan/plugin.py +++ b/faraday_plugins/plugins/repo/wcscan/plugin.py @@ -3,16 +3,10 @@ Copyright (C) 2013 Infobyte LLC (http://www.infobytesec.com/) See the file 'doc/LICENSE' for the license information """ -from faraday_plugins.plugins.plugin import PluginBase import re -import os -import sys -import random import xml.etree.ElementTree as ET -ETREE_VERSION = ET.VERSION - -ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] +from faraday_plugins.plugins.plugin import PluginBase __author__ = "Morgan Lemarechal" __copyright__ = "Copyright 2014, Faraday Project" @@ -86,7 +80,6 @@ def __init__(self, *arg, **kwargs): self._temp_file_extension = "xml" self.xml_arg_re = re.compile(r"^.*(--xml\s*[^\s]+).*$") - def parseOutputString(self, output): """ This method will discard the output the shell sends, it will read it from @@ -109,9 +102,7 @@ def parseOutputString(self, output): if parser.scaninfo[file]['type'] == "webconfig": vuln_name = f"{parser.scaninfo[file]['file']}: {str(parser.result[file][vuln][3])}" vuln_description = f"{str(parser.result[file][vuln][3])} : {str(parser.result[file][vuln][2])} = {str(parser.result[file][vuln][0])}\n{str(parser.result[file][vuln][1])}" - v_id = self.createAndAddVulnToService(h_id, s_id, vuln_name, desc=vuln_description, severity=0) - - + self.createAndAddVulnToService(h_id, s_id, vuln_name, desc=vuln_description, severity=0) def processCommandString(self, username, current_path, command_string): """ @@ -129,5 +120,3 @@ def processCommandString(self, username, current_path, command_string): def createPlugin(ignore_info=False): return WcscanPlugin(ignore_info=ignore_info) - - diff --git a/faraday_plugins/plugins/repo/x1/plugin.py b/faraday_plugins/plugins/repo/x1/plugin.py index acaf9146..f307372b 100644 --- a/faraday_plugins/plugins/repo/x1/plugin.py +++ b/faraday_plugins/plugins/repo/x1/plugin.py @@ -10,10 +10,6 @@ from faraday_plugins.plugins.plugin import PluginXMLFormat -ETREE_VERSION = ET.VERSION - -ETREE_VERSION = [int(i) for i in ETREE_VERSION.split(".")] - current_path = os.path.abspath(os.getcwd()) __author__ = "Francisco Amato" From 73fe62095317b998de63ea95282eb6a70e9cb30f Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Wed, 5 May 2021 20:10:29 -0300 Subject: [PATCH 211/698] add hostnames if host is already cached --- CHANGELOG/current/add_hostnames_to_cached_host.md | 1 + faraday_plugins/plugins/plugin.py | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 CHANGELOG/current/add_hostnames_to_cached_host.md diff --git a/CHANGELOG/current/add_hostnames_to_cached_host.md b/CHANGELOG/current/add_hostnames_to_cached_host.md new file mode 100644 index 00000000..69bdad0c --- /dev/null +++ b/CHANGELOG/current/add_hostnames_to_cached_host.md @@ -0,0 +1 @@ +[FIX] add hostnames if host is already cached diff --git a/faraday_plugins/plugins/plugin.py b/faraday_plugins/plugins/plugin.py index 83dcc3ad..3b6a8ae3 100644 --- a/faraday_plugins/plugins/plugin.py +++ b/faraday_plugins/plugins/plugin.py @@ -126,6 +126,9 @@ def save_host_cache(self, host): self._hosts_cache[cache_id] = obj_uuid else: obj_uuid = self._hosts_cache[cache_id] + if host['hostnames']: + chached_host = self.get_from_cache(obj_uuid) + chached_host['hostnames'] = list(set(chached_host['hostnames'] + host['hostnames'])) return obj_uuid def save_service_cache(self, host_id, service): From 5e64f31ed5ccab026039207734149cb09088d44d Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Thu, 6 May 2021 18:21:55 -0300 Subject: [PATCH 212/698] Add version and change list_plugins style --- CHANGELOG/current/change_list_plugins.md | 1 + faraday_plugins/commands.py | 22 ++++++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 CHANGELOG/current/change_list_plugins.md diff --git a/CHANGELOG/current/change_list_plugins.md b/CHANGELOG/current/change_list_plugins.md new file mode 100644 index 00000000..5bf08716 --- /dev/null +++ b/CHANGELOG/current/change_list_plugins.md @@ -0,0 +1 @@ +Add version and change list_plugins style diff --git a/faraday_plugins/commands.py b/faraday_plugins/commands.py index a498fa31..2fd61dcf 100644 --- a/faraday_plugins/commands.py +++ b/faraday_plugins/commands.py @@ -7,7 +7,9 @@ import subprocess import shlex import getpass +from tabulate import tabulate +from faraday_plugins import __version__ from faraday_plugins.plugins.manager import PluginsManager, ReportAnalyzer, CommandAnalyzer from faraday_plugins.plugins.plugin import PluginByExtension @@ -21,8 +23,10 @@ root_logger.addHandler(out_hdlr) root_logger.setLevel(logging.DEBUG) +CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help']) -@click.group() +@click.group(context_settings=CONTEXT_SETTINGS) +@click.version_option(__version__, '-v', '--version') def cli(): pass @@ -31,8 +35,10 @@ def cli(): @click.option('-cpf', '--custom-plugins-folder', type=str) def list_plugins(custom_plugins_folder): plugins_manager = PluginsManager(custom_plugins_folder) - click.echo(click.style("Available Plugins:", fg="cyan")) + 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" @@ -40,10 +46,14 @@ def list_plugins(custom_plugins_folder): 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")) + 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")) @cli.command() From a5890b2510246c862e15c6cecb06f82d01b45012 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Fri, 7 May 2021 11:33:38 -0300 Subject: [PATCH 213/698] fix missing requirement --- setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 72afa27c..3e21e762 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,8 @@ 'beautifulsoup4', 'pytz', 'python-dateutil', - 'colorama' + 'colorama', + 'tabulate' ] From ee210b2fb65fa0db9593e289a15c88bb32bee27f Mon Sep 17 00:00:00 2001 From: Federico Lopez L Date: Sun, 9 May 2021 23:58:58 -0300 Subject: [PATCH 214/698] Added SonarQube API report --- .../plugins/repo/sonarqubeapi/__init__.py | 5 + .../plugins/repo/sonarqubeapi/plugin.py | 104 ++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 faraday_plugins/plugins/repo/sonarqubeapi/__init__.py create mode 100644 faraday_plugins/plugins/repo/sonarqubeapi/plugin.py diff --git a/faraday_plugins/plugins/repo/sonarqubeapi/__init__.py b/faraday_plugins/plugins/repo/sonarqubeapi/__init__.py new file mode 100644 index 00000000..5b699288 --- /dev/null +++ b/faraday_plugins/plugins/repo/sonarqubeapi/__init__.py @@ -0,0 +1,5 @@ +""" +Faraday Penetration Test IDE +Copyright (C) 2013 Infobyte LLC (http://www.infobytesec.com/) +See the file 'doc/LICENSE' for the license information +""" \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/sonarqubeapi/plugin.py b/faraday_plugins/plugins/repo/sonarqubeapi/plugin.py new file mode 100644 index 00000000..11ca5f6a --- /dev/null +++ b/faraday_plugins/plugins/repo/sonarqubeapi/plugin.py @@ -0,0 +1,104 @@ +""" +Faraday Penetration Test IDE +Copyright (C) 2021 Infobyte LLC (http://www.infobytesec.com/) +See the file 'doc/LICENSE' for the license information + +""" +import json +from faraday_plugins.plugins.plugin import PluginJsonFormat +from datetime import datetime + +VULNERABILITY = "VULNERABILITY" + +# ATTENTION: The following mappings are created following the common sense in order to integrate F! with SQ. You +# can see what term means in the following website: https://docs.sonarqube.org/latest/user-guide/issues/ +SEVERITIES = { + 'INFO': 'unclassified', + 'MINOR': 'low', + 'MAJOR': 'medium', + 'CRITICAL': 'high', + 'BLOCKER': 'critical' +} +STATUSES = { + 'OPEN': 'open', + 'CONFIRMED': 'opened', + 'REOPENED': 're-opened', + 'CLOSED': 'closed', + 'RESOLVED': 'closed' +} + + +class SonarQubeAPIParser: + def __init__(self, json_output): + json_data = json.loads(json_output) + + self.vulns = self._parse_vulns(json_data) + + def _parse_vulns(self, json_data): + vulns = [] + + for issue in json_data['issues']: + if issue['type'] != VULNERABILITY: + continue + + name = issue['rule'] + path = issue['component'] + severity = SEVERITIES[issue['severity']] + message = issue['message'] + status = STATUSES[issue['status']] + tags = issue['tags'] + creation_date = datetime.strptime(issue['creationDate'], '%Y-%m-%dT%H:%M:%S%z') + + vulns.append( + {'name': name, 'path': path, 'message': message, 'severity': severity, "status": status, 'tags': tags, + 'creation_date': creation_date}) + + return vulns + + +class SonarQubeAPIPlugin(PluginJsonFormat): + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) + self.identifier_tag = "sonarqube-api" + self.id = "SonarQubeAPI" + self.name = "SonarQube API Plugin" + self.plugin_version = "0.0.1" + + def report_belongs_to(self, **kwargs): + if super().report_belongs_to(**kwargs): + report_path = kwargs.get("report_path", "") + with open(report_path) as f: + output = f.read() + json_data = json.loads(output) + + has_total = json_data.get('total', None) is not None + has_p = json_data.get('p', None) is not None + has_ps = json_data.get('ps', None) is not None + has_paging = json_data.get('paging', None) is not None + has_effort_total = json_data.get('effortTotal', None) is not None + has_issues = json_data.get('issues', None) is not None + has_components = json_data.get('components', None) is not None + has_facets = json_data.get('facets', None) is not None + + return has_total and has_p and has_ps and has_paging and has_effort_total and has_issues and has_components and has_facets + + return False + + def parseOutputString(self, output, debug=False): + parser = SonarQubeAPIParser(output) + for vuln in parser.vulns: + host_id = self.createAndAddHost(vuln['path']) + + self.createAndAddVulnToHost( + host_id=host_id, + name=vuln['name'], + desc=vuln['message'], + status=vuln['status'], + run_date=vuln['creation_date'], + severity=vuln['severity'], + tags=vuln['tags'] + ) + + +def createPlugin(ignore_info=False): + return SonarQubeAPIPlugin(ignore_info=ignore_info) From c3da9c4c02e8983f9c2772eaca6626a894b8194b Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Mon, 10 May 2021 12:47:32 -0300 Subject: [PATCH 215/698] fix sonarquebe PR --- .../plugins/repo/sonarqubeapi/plugin.py | 56 +++++++++---------- 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/faraday_plugins/plugins/repo/sonarqubeapi/plugin.py b/faraday_plugins/plugins/repo/sonarqubeapi/plugin.py index 11ca5f6a..5ae56d73 100644 --- a/faraday_plugins/plugins/repo/sonarqubeapi/plugin.py +++ b/faraday_plugins/plugins/repo/sonarqubeapi/plugin.py @@ -7,6 +7,7 @@ import json from faraday_plugins.plugins.plugin import PluginJsonFormat from datetime import datetime +import dateutil VULNERABILITY = "VULNERABILITY" @@ -36,22 +37,32 @@ def __init__(self, json_output): def _parse_vulns(self, json_data): vulns = [] - + components = {item['key']: + {'name': item['name'], 'longName': item['longName']} + for item in json_data['components'] } for issue in json_data['issues']: if issue['type'] != VULNERABILITY: continue - name = issue['rule'] - path = issue['component'] + component = issue['component'] + path = components[component]['longName'] + vuln_description = f"Issue found in line {issue['line']} of {path}" + project = f"Project: {issue['project']}" severity = SEVERITIES[issue['severity']] message = issue['message'] status = STATUSES[issue['status']] tags = issue['tags'] - creation_date = datetime.strptime(issue['creationDate'], '%Y-%m-%dT%H:%M:%S%z') - + external_id = issue['rule'] + creation_date = dateutil.parser.parse(issue['creationDate']) + data = [] if not issue['flows'] else ["Flows:"] + for flow in issue['flows']: + for location in flow['locations']: + location_message = f"\"{location['msg']}\" in line {location['textRange']['startLine']} " \ + f"of {components[component]['longName']}" + data.append(location_message) vulns.append( - {'name': name, 'path': path, 'message': message, 'severity': severity, "status": status, 'tags': tags, - 'creation_date': creation_date}) + {'name': message, 'description': vuln_description, 'project': project, 'path': path, 'severity': severity, 'status': status, 'tags': tags, + 'creation_date': creation_date, 'data': "\n".join(data), 'external_id': external_id}) return vulns @@ -59,44 +70,27 @@ def _parse_vulns(self, json_data): class SonarQubeAPIPlugin(PluginJsonFormat): def __init__(self, *arg, **kwargs): super().__init__(*arg, **kwargs) - self.identifier_tag = "sonarqube-api" - self.id = "SonarQubeAPI" + self.json_keys = {'total', 'effortTotal', 'issues', 'components', 'facets'} + self.id = "sonarqubeAPI" self.name = "SonarQube API Plugin" self.plugin_version = "0.0.1" - def report_belongs_to(self, **kwargs): - if super().report_belongs_to(**kwargs): - report_path = kwargs.get("report_path", "") - with open(report_path) as f: - output = f.read() - json_data = json.loads(output) - - has_total = json_data.get('total', None) is not None - has_p = json_data.get('p', None) is not None - has_ps = json_data.get('ps', None) is not None - has_paging = json_data.get('paging', None) is not None - has_effort_total = json_data.get('effortTotal', None) is not None - has_issues = json_data.get('issues', None) is not None - has_components = json_data.get('components', None) is not None - has_facets = json_data.get('facets', None) is not None - - return has_total and has_p and has_ps and has_paging and has_effort_total and has_issues and has_components and has_facets - - return False def parseOutputString(self, output, debug=False): parser = SonarQubeAPIParser(output) for vuln in parser.vulns: - host_id = self.createAndAddHost(vuln['path']) + host_id = self.createAndAddHost(vuln['path'], description=vuln['project']) self.createAndAddVulnToHost( host_id=host_id, name=vuln['name'], - desc=vuln['message'], + desc=vuln['description'], status=vuln['status'], run_date=vuln['creation_date'], severity=vuln['severity'], - tags=vuln['tags'] + tags=vuln['tags'], + data=vuln['data'], + external_id=vuln['external_id'] ) From cbaab95d89dc6a1b90758525dce1a274788b1560 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Mon, 10 May 2021 12:49:59 -0300 Subject: [PATCH 216/698] add sonarqube plugin --- CHANGELOG/current/add_sonarqube.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 CHANGELOG/current/add_sonarqube.md diff --git a/CHANGELOG/current/add_sonarqube.md b/CHANGELOG/current/add_sonarqube.md new file mode 100644 index 00000000..330d55cb --- /dev/null +++ b/CHANGELOG/current/add_sonarqube.md @@ -0,0 +1 @@ +Add Sonarqube plugin From 47eb1a4cb43fc8a360d06cb81319834717f9e045 Mon Sep 17 00:00:00 2001 From: Manuel Jose Sotomayor Torrealba Date: Thu, 13 May 2021 22:23:19 -0300 Subject: [PATCH 217/698] get more data --- ...n_get_more_data_of_the_reports_of_openvas.md | 1 + faraday_plugins/plugins/repo/openvas/plugin.py | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 CHANGELOG/current/we_can_get_more_data_of_the_reports_of_openvas.md diff --git a/CHANGELOG/current/we_can_get_more_data_of_the_reports_of_openvas.md b/CHANGELOG/current/we_can_get_more_data_of_the_reports_of_openvas.md new file mode 100644 index 00000000..407f217a --- /dev/null +++ b/CHANGELOG/current/we_can_get_more_data_of_the_reports_of_openvas.md @@ -0,0 +1 @@ +ADD cvss_base, cpe, threat, severity into references \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/openvas/plugin.py b/faraday_plugins/plugins/repo/openvas/plugin.py index 6612fbe7..cfcd964c 100644 --- a/faraday_plugins/plugins/repo/openvas/plugin.py +++ b/faraday_plugins/plugins/repo/openvas/plugin.py @@ -1,7 +1,6 @@ import re from collections import defaultdict from copy import copy - """ Faraday Penetration Test IDE Copyright (C) 2013 Infobyte LLC (http://www.infobytesec.com/) @@ -146,13 +145,17 @@ class Item: def __init__(self, item_node, hosts): self.node = item_node self.host = self.get_text_from_subnode('host') + self.threat = self.get_text_from_subnode('threat') self.subnet = self.get_text_from_subnode('subnet') if self.subnet == '': self.subnet = self.host self.port = None self.severity = self.severity_mapper() + self.severity_nr = self.get_text_from_subnode("severity") self.service = "Unknown" self.protocol = "" + self.cpe = self.node.findall("detection/result/details/detail") + self.cpe = self.cpe[0].findtext("value") if self.cpe else None port_string = self.get_text_from_subnode('port') info = port_string.split("/") self.protocol = "".join(filter(lambda x: x.isalpha() or x in ("-", "_"), info[1])) @@ -168,6 +171,7 @@ def __init__(self, item_node, hosts): self.nvt = self.node.findall('nvt')[0] self.node = self.nvt self.id = self.node.get('oid') + self.cvss_base = self.get_text_from_subnode("cvss_base") self.name = self.get_text_from_subnode('name') self.cve = self.get_text_from_subnode('cve') if self.get_text_from_subnode('cve') != "NOCVE" else "" self.bid = self.get_text_from_subnode('bid') if self.get_text_from_subnode('bid') != "NOBID" else "" @@ -345,6 +349,14 @@ def parseOutputString(self, output): ref.append(item.xref) if item.tags and item.cvss_vector: ref.append(item.cvss_vector) + if item.cvss_base: + ref.append(f"CVSS_BASE: {item.cvss_base}") + if item.cpe: + ref.append(f"{item.cpe}") + if item.threat: + ref.append(f"THREAT: {item.threat}") + if item.severity_nr: + ref.append(f"SEVERITY NUMBER: {item.severity_nr}") if item.subnet in ids: h_id = ids[item.host] @@ -409,7 +421,8 @@ def parseOutputString(self, output): data=item.data) del parser - def _isIPV4(self, ip): + @staticmethod + def _isIPV4(ip): if len(ip.split(".")) == 4: return True else: From dd982b3ded31c9a0198ac3eafffcd3236de00ac0 Mon Sep 17 00:00:00 2001 From: Emilio <2672328-ekio_jp@users.noreply.gitlab.com> Date: Fri, 14 May 2021 15:01:51 +0000 Subject: [PATCH 218/698] Fixup sslyze y version --- CHANGELOG/current/fixup_sslyze.md | 2 ++ faraday_plugins/plugins/plugin.py | 2 +- .../plugins/repo/sslyzejson/plugin.py | 22 +++++++++---------- 3 files changed, 13 insertions(+), 13 deletions(-) create mode 100644 CHANGELOG/current/fixup_sslyze.md diff --git a/CHANGELOG/current/fixup_sslyze.md b/CHANGELOG/current/fixup_sslyze.md new file mode 100644 index 00000000..279e498c --- /dev/null +++ b/CHANGELOG/current/fixup_sslyze.md @@ -0,0 +1,2 @@ +fixup ssylze +sacar unknown de version= diff --git a/faraday_plugins/plugins/plugin.py b/faraday_plugins/plugins/plugin.py index 3b6a8ae3..0edbed3d 100644 --- a/faraday_plugins/plugins/plugin.py +++ b/faraday_plugins/plugins/plugin.py @@ -356,7 +356,7 @@ def createAndAddHost(self, name, os="unknown", hostnames=None, mac=None, descrip def createAndAddServiceToHost(self, host_id, name, protocol="tcp", ports=None, - status="open", version="unknown", + status="open", version="", description="", tags=None): if ports: if isinstance(ports, list): diff --git a/faraday_plugins/plugins/repo/sslyzejson/plugin.py b/faraday_plugins/plugins/repo/sslyzejson/plugin.py index 33d05f2c..9156900a 100644 --- a/faraday_plugins/plugins/repo/sslyzejson/plugin.py +++ b/faraday_plugins/plugins/repo/sslyzejson/plugin.py @@ -7,6 +7,7 @@ import re import json from faraday_plugins.plugins.plugin import PluginJsonFormat +from faraday_plugins.plugins.plugins_utils import resolve_hostname __author__ = "Blas Moyano" __copyright__ = "Copyright (c) 2020, Infobyte LLC" @@ -71,18 +72,15 @@ def get_vuln(self, scan_result): def get_host(self, server_location): port = server_location.get('port', None) - protocol = '' - if port is not None: - if port == 443: - protocol = 'https' - else: - protocol = 'http' + hostname = server_location.get('hostname', None) + ip = server_location.get('ip_address', resolve_hostname(hostname)) json_host = { - "url": server_location.get('hostname', None), - "ip": server_location.get('ip_address', '0.0.0.0'), + "name": 'https', + "ip": ip, + "hostname": hostname, "port": port, - "protocol": protocol + "protocol": 'tcp' } return json_host @@ -178,17 +176,17 @@ def parseOutputString(self, output): parser = SslyzeJsonParser(output) for info_sslyze in parser.list_vul: - info_sslyze['host_info'].get('url') + info_sslyze['host_info'].get('hostname') host_id = self.createAndAddHost( info_sslyze['host_info'].get('ip'), os="unknown", hostnames=[ - info_sslyze['host_info'].get('url') + info_sslyze['host_info'].get('hostname') ] ) service_id = self.createAndAddServiceToHost( host_id, - name=info_sslyze['host_info'].get('protocol'), + name=info_sslyze['host_info'].get('name'), protocol=info_sslyze['host_info'].get('protocol'), ports=[ info_sslyze['host_info'].get('port') From 1943bd14cda9ae432a4bd95e13faa7b7406ee4af Mon Sep 17 00:00:00 2001 From: Emilio <2672328-ekio_jp@users.noreply.gitlab.com> Date: Fri, 14 May 2021 15:12:01 +0000 Subject: [PATCH 219/698] add Naabu plugin --- CHANGELOG/current/add_naabu_plugin.md | 1 + .../plugins/repo/naabu/__init__.py | 0 faraday_plugins/plugins/repo/naabu/plugin.py | 71 +++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 CHANGELOG/current/add_naabu_plugin.md create mode 100644 faraday_plugins/plugins/repo/naabu/__init__.py create mode 100644 faraday_plugins/plugins/repo/naabu/plugin.py diff --git a/CHANGELOG/current/add_naabu_plugin.md b/CHANGELOG/current/add_naabu_plugin.md new file mode 100644 index 00000000..99102b7c --- /dev/null +++ b/CHANGELOG/current/add_naabu_plugin.md @@ -0,0 +1 @@ +Add Naabu plugin diff --git a/faraday_plugins/plugins/repo/naabu/__init__.py b/faraday_plugins/plugins/repo/naabu/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/faraday_plugins/plugins/repo/naabu/plugin.py b/faraday_plugins/plugins/repo/naabu/plugin.py new file mode 100644 index 00000000..a737c960 --- /dev/null +++ b/faraday_plugins/plugins/repo/naabu/plugin.py @@ -0,0 +1,71 @@ +""" +Faraday Plugins +Copyright (c) 2021 Faraday Security LLC (https://www.faradaysec.com/) +See the file 'doc/LICENSE' for the license information + +""" +import socket +import json +import re +from faraday_plugins.plugins.plugin import PluginMultiLineJsonFormat + +__author__ = 'Emilio Couto' +__copyright__ = 'Copyright (c) 2021, Faraday Security LLC' +__credits__ = ['Emilio Couto'] +__license__ = '' +__version__ = '0.0.1' +__maintainer__ = 'Emilio Couto' +__email__ = 'ecouto@faradaysec.com' +__status__ = 'Development' + + +class NaabuPlugin(PluginMultiLineJsonFormat): + """ + Parse Naabu (from Project Discovery) scanner JSON output + """ + + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) + self.id = 'naabu' + self.name = 'Naabu' + self.plugin_version = '0.1' + self.version = '2.0.3' + self.json_keys = {'host', 'ip', 'port'} + self._command_regex = re.compile(r'^(sudo naabu|naabu|\.\/nmap)\s+.*?') + + def parseOutputString(self, output, debug=False): + for host_json in filter(lambda x: x != '', output.split('\n')): + host_dict = json.loads(host_json) + host = host_dict.get('host') + ip = host_dict.get('ip') + port = host_dict.get('port') + try: + service = socket.getservbyport(port) + except socket.error: + service = 'Unknown service on port ' + str(port) + host_id = self.createAndAddHost( + name=ip, + hostnames=[host]) + self.createAndAddServiceToHost( + host_id, + name=service, + ports=port, + protocol='tcp', + status='open', + version='', + description='') + + def processCommandString(self, username, current_path, command_string): + """ + Adds the -oX parameter to get xml output to the command string that the + user has set. + """ + super().processCommandString(username, current_path, command_string) + if " -json" not in command_string: + command_string += " -json" + if " -silent" not in command_string: + command_string += " -silent" + return command_string + +def createPlugin(ignore_info=False): + return NaabuPlugin(ignore_info=ignore_info) From 3efeae2a9b85873c87d242699de466df47d5c03a Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Fri, 14 May 2021 12:28:39 -0300 Subject: [PATCH 220/698] ready for release 1.4.6 --- .../add-attribute_command_for_plugins_of_all_command.md | 0 CHANGELOG/{current => 1.4.6}/add_hostnames_to_cached_host.md | 0 CHANGELOG/{current => 1.4.6}/add_naabu_plugin.md | 0 CHANGELOG/{current => 1.4.6}/add_sonarqube.md | 0 CHANGELOG/{current => 1.4.6}/change_list_plugins.md | 0 CHANGELOG/{current => 1.4.6}/clean_code.md | 0 CHANGELOG/1.4.6/date.md | 1 + ...rror_when_import_report_of_metasploit_with_faraday_plugins.md | 0 CHANGELOG/{current => 1.4.6}/fix_nmap_port_status.md | 0 CHANGELOG/{current => 1.4.6}/fixup_sslyze.md | 0 CHANGELOG/{current => 1.4.6}/issue_in_netsparker.md | 0 CHANGELOG/{current => 1.4.6}/update_nuclei.md | 0 .../when_import_report_of_nessus_we_can_get_more_data.md | 0 ...hen_import_reports_of_owasp_and_zap_we_might_get_more_data.md | 0 14 files changed, 1 insertion(+) rename CHANGELOG/{current => 1.4.6}/add-attribute_command_for_plugins_of_all_command.md (100%) rename CHANGELOG/{current => 1.4.6}/add_hostnames_to_cached_host.md (100%) rename CHANGELOG/{current => 1.4.6}/add_naabu_plugin.md (100%) rename CHANGELOG/{current => 1.4.6}/add_sonarqube.md (100%) rename CHANGELOG/{current => 1.4.6}/change_list_plugins.md (100%) rename CHANGELOG/{current => 1.4.6}/clean_code.md (100%) create mode 100644 CHANGELOG/1.4.6/date.md rename CHANGELOG/{current => 1.4.6}/error_when_import_report_of_metasploit_with_faraday_plugins.md (100%) rename CHANGELOG/{current => 1.4.6}/fix_nmap_port_status.md (100%) rename CHANGELOG/{current => 1.4.6}/fixup_sslyze.md (100%) rename CHANGELOG/{current => 1.4.6}/issue_in_netsparker.md (100%) rename CHANGELOG/{current => 1.4.6}/update_nuclei.md (100%) rename CHANGELOG/{current => 1.4.6}/when_import_report_of_nessus_we_can_get_more_data.md (100%) rename CHANGELOG/{current => 1.4.6}/when_import_reports_of_owasp_and_zap_we_might_get_more_data.md (100%) diff --git a/CHANGELOG/current/add-attribute_command_for_plugins_of_all_command.md b/CHANGELOG/1.4.6/add-attribute_command_for_plugins_of_all_command.md similarity index 100% rename from CHANGELOG/current/add-attribute_command_for_plugins_of_all_command.md rename to CHANGELOG/1.4.6/add-attribute_command_for_plugins_of_all_command.md diff --git a/CHANGELOG/current/add_hostnames_to_cached_host.md b/CHANGELOG/1.4.6/add_hostnames_to_cached_host.md similarity index 100% rename from CHANGELOG/current/add_hostnames_to_cached_host.md rename to CHANGELOG/1.4.6/add_hostnames_to_cached_host.md diff --git a/CHANGELOG/current/add_naabu_plugin.md b/CHANGELOG/1.4.6/add_naabu_plugin.md similarity index 100% rename from CHANGELOG/current/add_naabu_plugin.md rename to CHANGELOG/1.4.6/add_naabu_plugin.md diff --git a/CHANGELOG/current/add_sonarqube.md b/CHANGELOG/1.4.6/add_sonarqube.md similarity index 100% rename from CHANGELOG/current/add_sonarqube.md rename to CHANGELOG/1.4.6/add_sonarqube.md diff --git a/CHANGELOG/current/change_list_plugins.md b/CHANGELOG/1.4.6/change_list_plugins.md similarity index 100% rename from CHANGELOG/current/change_list_plugins.md rename to CHANGELOG/1.4.6/change_list_plugins.md diff --git a/CHANGELOG/current/clean_code.md b/CHANGELOG/1.4.6/clean_code.md similarity index 100% rename from CHANGELOG/current/clean_code.md rename to CHANGELOG/1.4.6/clean_code.md diff --git a/CHANGELOG/1.4.6/date.md b/CHANGELOG/1.4.6/date.md new file mode 100644 index 00000000..8c3ac607 --- /dev/null +++ b/CHANGELOG/1.4.6/date.md @@ -0,0 +1 @@ +May 14th, 2021 diff --git a/CHANGELOG/current/error_when_import_report_of_metasploit_with_faraday_plugins.md b/CHANGELOG/1.4.6/error_when_import_report_of_metasploit_with_faraday_plugins.md similarity index 100% rename from CHANGELOG/current/error_when_import_report_of_metasploit_with_faraday_plugins.md rename to CHANGELOG/1.4.6/error_when_import_report_of_metasploit_with_faraday_plugins.md diff --git a/CHANGELOG/current/fix_nmap_port_status.md b/CHANGELOG/1.4.6/fix_nmap_port_status.md similarity index 100% rename from CHANGELOG/current/fix_nmap_port_status.md rename to CHANGELOG/1.4.6/fix_nmap_port_status.md diff --git a/CHANGELOG/current/fixup_sslyze.md b/CHANGELOG/1.4.6/fixup_sslyze.md similarity index 100% rename from CHANGELOG/current/fixup_sslyze.md rename to CHANGELOG/1.4.6/fixup_sslyze.md diff --git a/CHANGELOG/current/issue_in_netsparker.md b/CHANGELOG/1.4.6/issue_in_netsparker.md similarity index 100% rename from CHANGELOG/current/issue_in_netsparker.md rename to CHANGELOG/1.4.6/issue_in_netsparker.md diff --git a/CHANGELOG/current/update_nuclei.md b/CHANGELOG/1.4.6/update_nuclei.md similarity index 100% rename from CHANGELOG/current/update_nuclei.md rename to CHANGELOG/1.4.6/update_nuclei.md diff --git a/CHANGELOG/current/when_import_report_of_nessus_we_can_get_more_data.md b/CHANGELOG/1.4.6/when_import_report_of_nessus_we_can_get_more_data.md similarity index 100% rename from CHANGELOG/current/when_import_report_of_nessus_we_can_get_more_data.md rename to CHANGELOG/1.4.6/when_import_report_of_nessus_we_can_get_more_data.md diff --git a/CHANGELOG/current/when_import_reports_of_owasp_and_zap_we_might_get_more_data.md b/CHANGELOG/1.4.6/when_import_reports_of_owasp_and_zap_we_might_get_more_data.md similarity index 100% rename from CHANGELOG/current/when_import_reports_of_owasp_and_zap_we_might_get_more_data.md rename to CHANGELOG/1.4.6/when_import_reports_of_owasp_and_zap_we_might_get_more_data.md From 2df7599a3ec0ad76d92248254527152bc9dd74b7 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Fri, 14 May 2021 12:29:00 -0300 Subject: [PATCH 221/698] ready for release 1.4.6 --- RELEASE.md | 16 ++++++++++++++++ faraday_plugins/__init__.py | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/RELEASE.md b/RELEASE.md index 7df7467a..471af5cb 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,3 +1,19 @@ +1.4.6 [May 14th, 2021]: +--- + * [FIX] add hostnames if host is already cached + * Add Naabu plugin + * Add Sonarqube plugin + * Add version and change list_plugins style + * [FIX] unused import, innecesary list compression and unused variables + * [FIX] metasploit report when the web-site-id is null + * [FIX] port stats in nmap + * [FIX] ssylze +sacar unknown de version= + * ADD remedy into resolution + * Support for nuclei 2.3.0 + * ADD cve, cvss3_base_score, cvss3_vector, exploit_available when import nessus and change the structure of external_id to NESSUS-XXX + * ADD more data like attack, params, uri, method, WASC, CWE and format externail_id + 1.4.5 [Apr 15th, 2021]: --- * Add Bandit plugin diff --git a/faraday_plugins/__init__.py b/faraday_plugins/__init__.py index 5e235ead..adf1ed52 100644 --- a/faraday_plugins/__init__.py +++ b/faraday_plugins/__init__.py @@ -1 +1 @@ -__version__ = '1.4.5' +__version__ = '1.4.6' From ac0a79965ec3607a5323dceb4fd593edf86833f4 Mon Sep 17 00:00:00 2001 From: Manuel Jose Sotomayor Torrealba Date: Mon, 17 May 2021 09:13:37 -0300 Subject: [PATCH 222/698] add long --- faraday_plugins/plugins/repo/w3af/plugin.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/faraday_plugins/plugins/repo/w3af/plugin.py b/faraday_plugins/plugins/repo/w3af/plugin.py index bddab88a..33d332b5 100644 --- a/faraday_plugins/plugins/repo/w3af/plugin.py +++ b/faraday_plugins/plugins/repo/w3af/plugin.py @@ -123,7 +123,9 @@ def __init__(self, item_node): self.detail = self.node.text.strip('\n').strip() self.resolution = self.get_text_from_subnode('fix-guidance') self.fix_effort = self.get_text_from_subnode('fix-effort') - self.longdetail = self.get_text_from_subnode('description') + self.longdetail = self.get_text_from_subnode('long-description') + if self.longdetail: + self.detail = f"{self.detail}\n{self.longdetail}" self.severity = self.node.get('severity') self.method = self.node.get('method') self.ref = [] @@ -134,6 +136,8 @@ def __init__(self, item_node): self.req = self.resp = '' for tx in self.node.findall('http-transactions/http-transaction'): + import ipdb; + ipdb.set_trace() if tx.find('http-request'): hreq = tx.find('http-request') else: From e0c56a73c02a89c6e68228ec961768ed20cd446f Mon Sep 17 00:00:00 2001 From: vilavalen00 Date: Mon, 17 May 2021 12:04:16 -0300 Subject: [PATCH 223/698] fix acunetix url parser --- CHANGELOG/current/fix_acunetix_url_parser.md | 1 + faraday_plugins/plugins/repo/acunetix/plugin.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 CHANGELOG/current/fix_acunetix_url_parser.md diff --git a/CHANGELOG/current/fix_acunetix_url_parser.md b/CHANGELOG/current/fix_acunetix_url_parser.md new file mode 100644 index 00000000..89fe358b --- /dev/null +++ b/CHANGELOG/current/fix_acunetix_url_parser.md @@ -0,0 +1 @@ +fix acunetix url parser diff --git a/faraday_plugins/plugins/repo/acunetix/plugin.py b/faraday_plugins/plugins/repo/acunetix/plugin.py index 08582807..390afc9e 100644 --- a/faraday_plugins/plugins/repo/acunetix/plugin.py +++ b/faraday_plugins/plugins/repo/acunetix/plugin.py @@ -97,7 +97,6 @@ def __init__(self, item_node): self.host = None # Use the port in the URL if it is defined, or 80 or 443 by default self.port = url_data.port or (443 if url_data.scheme == "https" else 80) - self.ip = resolve_hostname(self.host) self.os = self.get_text_from_subnode('Os') self.banner = self.get_text_from_subnode('Banner') @@ -119,6 +118,8 @@ def get_text_from_subnode(self, subnode_xpath_expr): def get_url(self, node): url = self.get_text_from_subnode('StartURL') + if not url.startswith('http'): + url = f'http://{url}' url_data = urlsplit(url) if not url_data.scheme: # Getting url from subnode 'Crawler' From 1a4ee973fb89b65b389b63ca2d6724ffd3fca2b3 Mon Sep 17 00:00:00 2001 From: Nicolas Rebagliati Date: Mon, 17 May 2021 18:48:30 -0300 Subject: [PATCH 224/698] fix run_date in UTC --- CHANGELOG/current/run_date_utc.md | 1 + faraday_plugins/plugins/plugin.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 CHANGELOG/current/run_date_utc.md diff --git a/CHANGELOG/current/run_date_utc.md b/CHANGELOG/current/run_date_utc.md new file mode 100644 index 00000000..31440832 --- /dev/null +++ b/CHANGELOG/current/run_date_utc.md @@ -0,0 +1 @@ +Use run_date in UTC diff --git a/faraday_plugins/plugins/plugin.py b/faraday_plugins/plugins/plugin.py index 0edbed3d..333dd686 100644 --- a/faraday_plugins/plugins/plugin.py +++ b/faraday_plugins/plugins/plugin.py @@ -55,7 +55,7 @@ def __init__(self, ignore_info=False): self._hosts_cache = {} self._service_cache = {} self._vulns_cache = {} - self.start_date = datetime.now() + self.start_date = datetime.utcnow() self.logger = logger.getChild(self.__class__.__name__) self.open_options = {"mode": "r", "encoding": "utf-8"} self.plugin_version = "0.0" @@ -509,7 +509,7 @@ def createAndAddCredToService(self, host_id, service_id, username, password): def get_data(self): self.vulns_data["command"]["tool"] = self.id self.vulns_data["command"]["command"] = self.command if self.command else self.id - self.vulns_data["command"]["duration"] = (datetime.now() - self.start_date).microseconds + self.vulns_data["command"]["duration"] = (datetime.utcnow() - self.start_date).microseconds return self.vulns_data def get_json(self): From 0f45b6deecd770324c3276115ae28b8a57b0155d Mon Sep 17 00:00:00 2001 From: Emilio Date: Tue, 18 May 2021 10:51:42 +0900 Subject: [PATCH 225/698] [FIX] #184 and enrich vuln info --- faraday_plugins/plugins/repo/sslyzejson/plugin.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/faraday_plugins/plugins/repo/sslyzejson/plugin.py b/faraday_plugins/plugins/repo/sslyzejson/plugin.py index 9156900a..55e82c87 100644 --- a/faraday_plugins/plugins/repo/sslyzejson/plugin.py +++ b/faraday_plugins/plugins/repo/sslyzejson/plugin.py @@ -92,7 +92,11 @@ def get_certification(self, certificate): if not send_certif: json_certif = { "name": "Certificate mismatch", - "desc": f"Certificate does not match server hostname {certificate.get('hostname_used_for_server_name_indication', 'Not hostname')}", + "desc": "The software communicates with a host that provides a certificate, but the software does not properly ensure that the certificate is actually associated with that host.\nEven if a certificate is well-formed, signed, and follows the chain of trust, it may simply be a valid certificate for a different site than the site that the software is interacting with. If the certificate's host-specific data is not properly checked - such as the Common Name (CN) in the Subject or the Subject Alternative Name (SAN) extension of an X.509 certificate - it may be possible for a redirection or spoofing attack to allow a malicious host with a valid certificate to provide data, impersonating a trusted host. In order to ensure data integrity, the certificate must be valid and it must pertain to the site that is being accessed.\nEven if the software attempts to check the hostname, it is still possible to incorrectly check the hostname. For example, attackers could create a certificate with a name that begins with a trusted name followed by a NUL byte, which could cause some string-based comparisons to only examine the portion that contains the trusted name.\nThis weakness can occur even when the software uses Certificate Pinning, if the software does not verify the hostname at the time a certificate is pinned", + "data": f"Certificate does not match server hostname {certificate.get('hostname_used_for_server_name_indication', 'Not hostname')}", + "impact": {"integrity": True}, + "ref": ["https://cwe.mitre.org/data/definitions/297.html"], + "external_id": "CWE-297", "severity": "info" } else: @@ -199,6 +203,10 @@ def parseOutputString(self, output): service_id, name=info_sslyze['certification'].get('name'), desc=info_sslyze['certification'].get('desc'), + data=info_sslyze['certification'].get('data'), + impact=info_sslyze['certification'].get('impact'), + ref=info_sslyze['certification'].get('ref'), + external_id=info_sslyze['certification'].get('external_id'), severity=info_sslyze['certification'].get('info')) if info_sslyze['ciphers']: From aec750f4454c8bd05915d58620faea0995023107 Mon Sep 17 00:00:00 2001 From: Emilio Date: Tue, 18 May 2021 10:55:51 +0900 Subject: [PATCH 226/698] Add CHANGELOG --- CHANGELOG/current/fixup_ssylyze_desc_data.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 CHANGELOG/current/fixup_ssylyze_desc_data.md diff --git a/CHANGELOG/current/fixup_ssylyze_desc_data.md b/CHANGELOG/current/fixup_ssylyze_desc_data.md new file mode 100644 index 00000000..2f3a01c3 --- /dev/null +++ b/CHANGELOG/current/fixup_ssylyze_desc_data.md @@ -0,0 +1 @@ +Add vuln details for Certificate Mismatch and move unique details to data, now vulns can be grupped From 34062d2e5225e101a67b4e3f456bea0f5c181a8d Mon Sep 17 00:00:00 2001 From: Emilio Date: Tue, 18 May 2021 11:59:54 +0900 Subject: [PATCH 227/698] enrich heartbleed, openssl ccs and weak ciphers --- .../plugins/repo/sslyzejson/plugin.py | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/faraday_plugins/plugins/repo/sslyzejson/plugin.py b/faraday_plugins/plugins/repo/sslyzejson/plugin.py index 55e82c87..dd70e936 100644 --- a/faraday_plugins/plugins/repo/sslyzejson/plugin.py +++ b/faraday_plugins/plugins/repo/sslyzejson/plugin.py @@ -146,8 +146,11 @@ def get_heartbleed(self, heartbleed): if heartbleed.get('is_vulnerable_to_heartbleed', False): json_heartbleed = { "name": "OpenSSL Heartbleed", - "desc": "OpenSSL Heartbleed is vulnerable", - "severity": "critical" + "desc": "OpenSSL versions 1.0.1 through 1.0.1f contain a flaw in its implementation of the TLS/DTLS heartbeat functionality. This flaw allows an attacker to retrieve private memory of an application that uses the vulnerable OpenSSL library in chunks of 64k at a time. Note that an attacker can repeatedly leverage the vulnerability to retrieve as many 64k chunks of memory as are necessary to retrieve the intended secrets. The sensitive information that may be retrieved using this vulnerability include:\n\n Primary key material (secret keys)\n Secondary key material (user names and passwords used by vulnerable services)\n Protected content (sensitive data used by vulnerable services)\n Collateral (memory addresses and content that can be leveraged to bypass exploit mitigations)\n Exploit code is publicly available for this vulnerability. Additional details may be found in CERT/CC Vulnerability Note VU#720951.", + "impact": {"confidentiality": True}, + "ref": ["https://nvd.nist.gov/vuln/detail/CVE-2014-0160", "https://heartbleed.com/", "https://us-cert.cisa.gov/ncas/alerts/TA14-098A"], + "external_id": "CVE-2014-0160", + "severity": "high" } return json_heartbleed @@ -156,8 +159,11 @@ def get_openssl_ccs(self, openssl_ccs): if openssl_ccs.get('is_vulnerable_to_ccs_injection', False): json_openssl_ccs = { "name": "OpenSSL CCS Injection", - "desc": "OpenSSL CCS Injection is vulnerable", - "severity": "medium" + "desc": 'OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCipherSpec messages, which allows man-in-the-middle attackers to trigger use of a zero-length master key in certain OpenSSL-to-OpenSSL communications, and consequently hijack sessions or obtain sensitive information, via a crafted TLS handshake, aka the "CCS Injection" vulnerability."', + "impact": {"confidentiality": True, "integrity": True}, + "ref": ["http://ccsinjection.lepidum.co.jp/", "https://nvd.nist.gov/vuln/detail/CVE-2014-0224"], + "external_id": "CVE-2014-0224", + "severity": "high" } return json_openssl_ccs @@ -218,7 +224,11 @@ def parseOutputString(self, output): host_id, service_id, name=ciphers, - desc=f"In protocol [{key}], weak cipher suite: {ciphers}", + desc="The software stores or transmits sensitive data using an encryption scheme that is theoretically sound, but is not strong enough for the level of protection required.", + data=f"In protocol [{key}], weak cipher suite: {ciphers}", + impact={"confidentiality": True}, + ref=["https://cwe.mitre.org/data/definitions/326.html"], + external_id="CWE-326", severity="low") if info_sslyze['heartbleed']: @@ -227,6 +237,9 @@ def parseOutputString(self, output): service_id, name=info_sslyze['heartbleed'].get('name'), desc=info_sslyze['heartbleed'].get('desc'), + impact=info_sslyze['heartbleed'].get('impact'), + ref=info_sslyze['heartbleed'].get('ref'), + external_id=info_sslyze['heartbleed'].get('external_id'), severity=info_sslyze['heartbleed'].get('severity')) if info_sslyze['openssl_ccs']: @@ -235,6 +248,9 @@ def parseOutputString(self, output): service_id, name=info_sslyze['openssl_ccs'].get('name'), desc=info_sslyze['openssl_ccs'].get('desc'), + impact=info_sslyze['openssl_ccs'].get('impact'), + ref=info_sslyze['openssl_ccs'].get('ref'), + external_id=info_sslyze['openssl_ccs'].get('external_id'), severity=info_sslyze['openssl_ccs'].get('severity')) def processCommandString(self, username, current_path, command_string): From ce88b64205d08b195cbbaeac3d30da5c4c639b78 Mon Sep 17 00:00:00 2001 From: Emilio Date: Tue, 18 May 2021 13:53:04 +0900 Subject: [PATCH 228/698] Summarize SSL Weak Ciphers --- .../plugins/repo/sslyzejson/plugin.py | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/faraday_plugins/plugins/repo/sslyzejson/plugin.py b/faraday_plugins/plugins/repo/sslyzejson/plugin.py index dd70e936..c7a6dcbc 100644 --- a/faraday_plugins/plugins/repo/sslyzejson/plugin.py +++ b/faraday_plugins/plugins/repo/sslyzejson/plugin.py @@ -215,21 +215,24 @@ def parseOutputString(self, output): external_id=info_sslyze['certification'].get('external_id'), severity=info_sslyze['certification'].get('info')) + cipherlist = [] if info_sslyze['ciphers']: for k, v in info_sslyze['ciphers'].items(): if len(v) != 0: for ciphers in v: key = k.replace('_cipher_suites', '') - self.createAndAddVulnToService( - host_id, - service_id, - name=ciphers, - desc="The software stores or transmits sensitive data using an encryption scheme that is theoretically sound, but is not strong enough for the level of protection required.", - data=f"In protocol [{key}], weak cipher suite: {ciphers}", - impact={"confidentiality": True}, - ref=["https://cwe.mitre.org/data/definitions/326.html"], - external_id="CWE-326", - severity="low") + cipherlist.append(f"In protocol [{key}], weak cipher suite: {ciphers}") + if cipherlist: + self.createAndAddVulnToService( + host_id, + service_id, + name="SSL/TLS Weak Cipher Suites Supported", + desc="The software stores or transmits sensitive data using an encryption scheme that is theoretically sound, but is not strong enough for the level of protection required.", + data="\n".join(cipherlist), + impact={"confidentiality": True}, + ref=["https://cwe.mitre.org/data/definitions/326.html"], + external_id="CWE-326", + severity="low") if info_sslyze['heartbleed']: self.createAndAddVulnToService( From b16d559d220fe36732182a592f31f378115e86e8 Mon Sep 17 00:00:00 2001 From: Emilio Date: Tue, 18 May 2021 14:06:54 +0900 Subject: [PATCH 229/698] update description --- faraday_plugins/plugins/repo/sslyzejson/plugin.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/faraday_plugins/plugins/repo/sslyzejson/plugin.py b/faraday_plugins/plugins/repo/sslyzejson/plugin.py index c7a6dcbc..0c3aa0bb 100644 --- a/faraday_plugins/plugins/repo/sslyzejson/plugin.py +++ b/faraday_plugins/plugins/repo/sslyzejson/plugin.py @@ -90,14 +90,15 @@ def get_certification(self, certificate): send_certif = certif_deploy[0].get('leaf_certificate_subject_matches_hostname', True) if not send_certif: + why = certif_deploy[0]['received_certificate_chain'][0]['subject']['rfc4514_string'] json_certif = { - "name": "Certificate mismatch", - "desc": "The software communicates with a host that provides a certificate, but the software does not properly ensure that the certificate is actually associated with that host.\nEven if a certificate is well-formed, signed, and follows the chain of trust, it may simply be a valid certificate for a different site than the site that the software is interacting with. If the certificate's host-specific data is not properly checked - such as the Common Name (CN) in the Subject or the Subject Alternative Name (SAN) extension of an X.509 certificate - it may be possible for a redirection or spoofing attack to allow a malicious host with a valid certificate to provide data, impersonating a trusted host. In order to ensure data integrity, the certificate must be valid and it must pertain to the site that is being accessed.\nEven if the software attempts to check the hostname, it is still possible to incorrectly check the hostname. For example, attackers could create a certificate with a name that begins with a trusted name followed by a NUL byte, which could cause some string-based comparisons to only examine the portion that contains the trusted name.\nThis weakness can occur even when the software uses Certificate Pinning, if the software does not verify the hostname at the time a certificate is pinned", - "data": f"Certificate does not match server hostname {certificate.get('hostname_used_for_server_name_indication', 'Not hostname')}", + "name": "SSL/TLS Certificate Mismatch", + "desc": "The software communicates with a host that provides a certificate, but the software does not properly ensure that the certificate is actually associated with that host.", + "data": f"Certificate {why} does not match server hostname {certificate.get('hostname_used_for_server_name_indication', 'Not hostname')}", "impact": {"integrity": True}, "ref": ["https://cwe.mitre.org/data/definitions/297.html"], "external_id": "CWE-297", - "severity": "info" + "severity": "low" } else: json_certif = {} @@ -213,7 +214,7 @@ def parseOutputString(self, output): impact=info_sslyze['certification'].get('impact'), ref=info_sslyze['certification'].get('ref'), external_id=info_sslyze['certification'].get('external_id'), - severity=info_sslyze['certification'].get('info')) + severity=info_sslyze['certification'].get('severity')) cipherlist = [] if info_sslyze['ciphers']: From 1ae48c96e40cc78f4f08931c1a42ea5299c814d2 Mon Sep 17 00:00:00 2001 From: Emilio Date: Tue, 18 May 2021 15:07:40 +0900 Subject: [PATCH 230/698] Add easeofresolution field --- faraday_plugins/plugins/repo/sslyzejson/plugin.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/faraday_plugins/plugins/repo/sslyzejson/plugin.py b/faraday_plugins/plugins/repo/sslyzejson/plugin.py index 0c3aa0bb..9403590e 100644 --- a/faraday_plugins/plugins/repo/sslyzejson/plugin.py +++ b/faraday_plugins/plugins/repo/sslyzejson/plugin.py @@ -213,6 +213,7 @@ def parseOutputString(self, output): data=info_sslyze['certification'].get('data'), impact=info_sslyze['certification'].get('impact'), ref=info_sslyze['certification'].get('ref'), + easeofresolution="trivial", external_id=info_sslyze['certification'].get('external_id'), severity=info_sslyze['certification'].get('severity')) @@ -232,6 +233,7 @@ def parseOutputString(self, output): data="\n".join(cipherlist), impact={"confidentiality": True}, ref=["https://cwe.mitre.org/data/definitions/326.html"], + easeofresolution="trivial", external_id="CWE-326", severity="low") @@ -243,6 +245,7 @@ def parseOutputString(self, output): desc=info_sslyze['heartbleed'].get('desc'), impact=info_sslyze['heartbleed'].get('impact'), ref=info_sslyze['heartbleed'].get('ref'), + easeofresolution="trivial", external_id=info_sslyze['heartbleed'].get('external_id'), severity=info_sslyze['heartbleed'].get('severity')) @@ -254,6 +257,7 @@ def parseOutputString(self, output): desc=info_sslyze['openssl_ccs'].get('desc'), impact=info_sslyze['openssl_ccs'].get('impact'), ref=info_sslyze['openssl_ccs'].get('ref'), + easeofresolution="trivial", external_id=info_sslyze['openssl_ccs'].get('external_id'), severity=info_sslyze['openssl_ccs'].get('severity')) From b7ea064fb78677abfded300c94adc8833ee90483 Mon Sep 17 00:00:00 2001 From: Emilio Date: Tue, 18 May 2021 20:49:46 +0900 Subject: [PATCH 231/698] Add target field --- faraday_plugins/plugins/repo/sslyzejson/plugin.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/faraday_plugins/plugins/repo/sslyzejson/plugin.py b/faraday_plugins/plugins/repo/sslyzejson/plugin.py index 9403590e..dc7134b2 100644 --- a/faraday_plugins/plugins/repo/sslyzejson/plugin.py +++ b/faraday_plugins/plugins/repo/sslyzejson/plugin.py @@ -74,13 +74,18 @@ def get_host(self, server_location): port = server_location.get('port', None) hostname = server_location.get('hostname', None) ip = server_location.get('ip_address', resolve_hostname(hostname)) + if port != 443: + url = 'https://' + hostname + ':' + port + else: + url = 'https://' + hostname json_host = { "name": 'https', "ip": ip, "hostname": hostname, "port": port, - "protocol": 'tcp' + "protocol": 'tcp', + "url": url } return json_host @@ -215,6 +220,7 @@ def parseOutputString(self, output): ref=info_sslyze['certification'].get('ref'), easeofresolution="trivial", external_id=info_sslyze['certification'].get('external_id'), + target=info_sslyze['host_info'].get('url'), severity=info_sslyze['certification'].get('severity')) cipherlist = [] @@ -235,6 +241,7 @@ def parseOutputString(self, output): ref=["https://cwe.mitre.org/data/definitions/326.html"], easeofresolution="trivial", external_id="CWE-326", + target=info_sslyze['host_info'].get('url'), severity="low") if info_sslyze['heartbleed']: @@ -247,6 +254,7 @@ def parseOutputString(self, output): ref=info_sslyze['heartbleed'].get('ref'), easeofresolution="trivial", external_id=info_sslyze['heartbleed'].get('external_id'), + target=info_sslyze['host_info'].get('url'), severity=info_sslyze['heartbleed'].get('severity')) if info_sslyze['openssl_ccs']: @@ -259,6 +267,7 @@ def parseOutputString(self, output): ref=info_sslyze['openssl_ccs'].get('ref'), easeofresolution="trivial", external_id=info_sslyze['openssl_ccs'].get('external_id'), + target=info_sslyze['host_info'].get('url'), severity=info_sslyze['openssl_ccs'].get('severity')) def processCommandString(self, username, current_path, command_string): From 297d8f96885765475d6363721b0e3fda205ea6dd Mon Sep 17 00:00:00 2001 From: Emilio Date: Tue, 18 May 2021 23:56:23 +0900 Subject: [PATCH 232/698] Add target to createAndAddVulnToService --- faraday_plugins/plugins/plugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/faraday_plugins/plugins/plugin.py b/faraday_plugins/plugins/plugin.py index 0edbed3d..ff6a2bae 100644 --- a/faraday_plugins/plugins/plugin.py +++ b/faraday_plugins/plugins/plugin.py @@ -410,7 +410,7 @@ def createAndAddVulnToHost(self, host_id, name, desc="", ref=None, def createAndAddVulnToService(self, host_id, service_id, name, desc="", ref=None, severity="", resolution="", data="", external_id=None, run_date=None, custom_fields=None, policyviolations=None, impact=None, status="", - confirmed=False, easeofresolution=None, tags=None): + confirmed=False, easeofresolution=None, target=None, tags=None): if ref is None: ref = [] if status == "": @@ -429,7 +429,7 @@ def createAndAddVulnToService(self, host_id, service_id, name, desc="", "external_id": external_id, "type": "Vulnerability", "resolution": resolution, "data": data, "custom_fields": custom_fields, "status": status, "impact": impact, "policyviolations": policyviolations, - "easeofresolution": easeofresolution, "confirmed": confirmed, "tags": tags + "easeofresolution": easeofresolution, "target": target, "confirmed": confirmed, "tags": tags } if run_date: vulnerability["run_date"] = self.get_utctimestamp(run_date) From 4b6a58d379e3a7f3e18bee1b15621b63a80224e4 Mon Sep 17 00:00:00 2001 From: Manuel Jose Sotomayor Torrealba Date: Wed, 19 May 2021 14:55:57 -0300 Subject: [PATCH 233/698] ADD more data to plugins arachni and w3af --- ...-when-parse_the_xml_of_arachni_and_w3af.md | 1 + .../plugins/repo/arachni/plugin.py | 97 ++++++++++++------- faraday_plugins/plugins/repo/w3af/plugin.py | 14 +-- 3 files changed, 72 insertions(+), 40 deletions(-) create mode 100644 CHANGELOG/current/many-error-when-parse_the_xml_of_arachni_and_w3af.md diff --git a/CHANGELOG/current/many-error-when-parse_the_xml_of_arachni_and_w3af.md b/CHANGELOG/current/many-error-when-parse_the_xml_of_arachni_and_w3af.md new file mode 100644 index 00000000..b390c4e6 --- /dev/null +++ b/CHANGELOG/current/many-error-when-parse_the_xml_of_arachni_and_w3af.md @@ -0,0 +1 @@ +ADD more data to plugins arachni and w3af \ No newline at end of file diff --git a/faraday_plugins/plugins/repo/arachni/plugin.py b/faraday_plugins/plugins/repo/arachni/plugin.py index 8bba46d0..e0977e41 100755 --- a/faraday_plugins/plugins/repo/arachni/plugin.py +++ b/faraday_plugins/plugins/repo/arachni/plugin.py @@ -21,12 +21,12 @@ class ArachniXmlParser: def __init__(self, xml_output): + self.tree = self.parse_xml(xml_output) if self.tree: self.issues = self.getIssues(self.tree) self.plugins = self.getPlugins(self.tree) self.system = self.getSystem(self.tree) - else: self.system = None self.issues = None @@ -74,6 +74,21 @@ def __init__(self, issue_node): self.parameters = self.getParameters() self.request = self.getRequest() self.response = self.getResponse() + self.data = self.getData() + + def getData(self): + name = self.node.findtext('check/name', '') + description = self.node.findtext('check/description', '') + author = self.node.findtext('check/description', '') + data = "" + if name: + data += f'\nname: {name}' + if description: + data += f'\ndescription: {description}' + if author: + data += f'\nauthor: {author}' + + return data def getDesc(self, tag): @@ -136,23 +151,50 @@ def getRequest(self): # Get data about request. try: - - raw_data = self.node.find('page').find('request').find('raw') + request = self.node.find('page/request') + raw_data = request.find('raw') data = raw_data.text + if not data: + data = self.contruct_request(request) return data - except: return 'None' + @staticmethod + def contruct_request(request): + data = request.findtext("method", "").upper() + data += f" {request.findtext('url', '')}" + for h in request.findall('headers/header'): + data += "\n%s: %s" % (h.get('name'), h.get('value')) + if request.findtext('body',""): + data += "\n%s" % request.findtext('body',"") + return data + + @staticmethod + def construct_response(request): + data = "" + if request.findtext("code", ""): + data += f'\ncode: {request.findtext("code", "")}' + if request.findtext("ip_address", ""): + data += f'\nip_address: {request.findtext("ip_address", "")}' + if request.findtext("time", ""): + data += f'\ntime: {request.findtext("time", "")}' + if request.findtext("return_code", ""): + data += f'\nreturn_code: {request.findtext("return_code", "")}' + if request.findtext("return_message", ""): + data += f'\nreturn_message: {request.findtext("return_message", "")}' + return data + def getResponse(self): - # Get data about response. try: - - raw_data = self.node.find('page').find('response').find('raw_headers') + request = self.node.find('page/response') + raw_data = request.find('raw_headers') data = raw_data.text + if not data: + data = self.contruct_request(request) + data += self.construct_response(request) return data - except: return 'None' @@ -178,7 +220,6 @@ def __init__(self, node, tag_exists): self.version = self.getDesc('version') self.start_time = self.getDesc('start_datetime') self.finish_time = self.getDesc('finish_datetime') - self.note = self.getNote() def getUrl(self): @@ -254,6 +295,14 @@ def __init__(self, plugins_node): except Exception: self.ip = None + @staticmethod + def get_value(name, node): + x = node.find(name) + if x: + return x.text + else: + return "" + def getHealthmap(self): # Get info about healthmap @@ -272,19 +321,10 @@ def getHealthmap(self): else: list_urls.append(f"Without Issues: {url.text}") - def get_value(name, node=None): - if not node: - node = healthmap_tree - x = healthmap_tree.find(name) - if x: - return x.text - else: - return "" - try: - plugin_name = get_value('name') - description = get_value('description') - results = get_value('results') + plugin_name = get_value('name', healthmap_tree) + description = get_value('description', healthmap_tree) + results = get_value('results', healthmap_tree) total = get_value('total', results) with_issues = get_value('with_issues', results) without_issues = get_value('without_issues', results) @@ -303,19 +343,9 @@ def getWaf(self): # Get info about waf plugin. waf_tree = self.plugins_node.find('waf_detector') - - def get_value(name, node=None): - if not node: - node = waf_tree - x = waf_tree.find(name) - if x: - return x.text - else: - return "" - try: - plugin_name = get_value('name') - description = get_value('description') + plugin_name = get_value('name', waf_tree) + description = get_value('description', waf_tree) results = waf_tree.find('results') message = get_value('message', results) status = get_value('status', results) @@ -424,6 +454,7 @@ def parseOutputString(self, output): service_id, name=issue.name, desc=description, + data=issue.data, resolution=resol, ref=references, severity=issue.severity, diff --git a/faraday_plugins/plugins/repo/w3af/plugin.py b/faraday_plugins/plugins/repo/w3af/plugin.py index 33d332b5..6fded1ed 100644 --- a/faraday_plugins/plugins/repo/w3af/plugin.py +++ b/faraday_plugins/plugins/repo/w3af/plugin.py @@ -124,8 +124,6 @@ def __init__(self, item_node): self.resolution = self.get_text_from_subnode('fix-guidance') self.fix_effort = self.get_text_from_subnode('fix-effort') self.longdetail = self.get_text_from_subnode('long-description') - if self.longdetail: - self.detail = f"{self.detail}\n{self.longdetail}" self.severity = self.node.get('severity') self.method = self.node.get('method') self.ref = [] @@ -136,8 +134,7 @@ def __init__(self, item_node): self.req = self.resp = '' for tx in self.node.findall('http-transactions/http-transaction'): - import ipdb; - ipdb.set_trace() + if tx.find('http-request'): hreq = tx.find('http-request') else: @@ -152,12 +149,15 @@ def __init__(self, item_node): for h in hreq.findall('headers/header'): self.req += "\n%s: %s" % (h.get('field'), h.get('content')) + if hreq.findtext('body',""): + self.req += "\n%s" % hreq.findtext('body',"") + self.resp = hres.find('status').text for h in hres.findall('headers/header'): self.resp += "\n%s: %s" % (h.get('field'), h.get('content')) - if hres.find('body'): - self.resp += "\n%s" % hres.find('body').text + if hres.findtext('body',""): + self.resp += "\n%s" % hres.findtext('body',"") def do_clean(self, value): myreturn = "" @@ -208,7 +208,7 @@ def parseOutputString(self, output): for item in parser.items: self.createAndAddVulnWebToService(h_id, s_id, item.name, - item.detail, pname=item.param, path=item.url, website=parser.host, + item.detail, pname=item.param,data=item.longdetail, path=item.url, website=parser.host, severity=item.severity, method=item.method, request=item.req, resolution=item.resolution, ref=item.ref, response=item.resp) del parser From 70a3a7d5c856065f5b54d37c634043104abe09e5 Mon Sep 17 00:00:00 2001 From: Manuel Jose Sotomayor Torrealba Date: Wed, 19 May 2021 15:13:19 -0300 Subject: [PATCH 234/698] adding self to method --- .../plugins/repo/arachni/plugin.py | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/faraday_plugins/plugins/repo/arachni/plugin.py b/faraday_plugins/plugins/repo/arachni/plugin.py index e0977e41..667f02ec 100755 --- a/faraday_plugins/plugins/repo/arachni/plugin.py +++ b/faraday_plugins/plugins/repo/arachni/plugin.py @@ -322,13 +322,13 @@ def getHealthmap(self): list_urls.append(f"Without Issues: {url.text}") try: - plugin_name = get_value('name', healthmap_tree) - description = get_value('description', healthmap_tree) - results = get_value('results', healthmap_tree) - total = get_value('total', results) - with_issues = get_value('with_issues', results) - without_issues = get_value('without_issues', results) - issue_percentage = get_value('issue_percentage', results) + plugin_name = self.get_value('name', healthmap_tree) + description = self.get_value('description', healthmap_tree) + results = self.get_value('results', healthmap_tree) + total = self.get_value('total', results) + with_issues = self.get_value('with_issues', results) + without_issues = self.get_value('without_issues', results) + issue_percentage = self.get_value('issue_percentage', results) urls = '\n'.join(list_urls) result = (f"Plugin Name: {plugin_name}\nDescription: {description}\nStatistics:\nTotal: {total}" @@ -344,11 +344,11 @@ def getWaf(self): # Get info about waf plugin. waf_tree = self.plugins_node.find('waf_detector') try: - plugin_name = get_value('name', waf_tree) - description = get_value('description', waf_tree) + plugin_name = self.get_value('name', waf_tree) + description = self.get_value('description', waf_tree) results = waf_tree.find('results') - message = get_value('message', results) - status = get_value('status', results) + message = self.get_value('message', results) + status = self.get_value('status', results) result = (f"Plugin Name: {plugin_name}\nDescription: {description}\nResults:" f"\nMessage: {message}\nStatus: {status}") return result From 22ec60a374cd6dbe1e7d6c71f10899b23c2b6758 Mon Sep 17 00:00:00 2001 From: Emilio Date: Fri, 21 May 2021 09:51:58 +0900 Subject: [PATCH 235/698] Change sslyze plugin to use createAndAddVulnWebToService() --- faraday_plugins/plugins/plugin.py | 4 ++-- .../plugins/repo/sslyzejson/plugin.py | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/faraday_plugins/plugins/plugin.py b/faraday_plugins/plugins/plugin.py index ff6a2bae..0edbed3d 100644 --- a/faraday_plugins/plugins/plugin.py +++ b/faraday_plugins/plugins/plugin.py @@ -410,7 +410,7 @@ def createAndAddVulnToHost(self, host_id, name, desc="", ref=None, def createAndAddVulnToService(self, host_id, service_id, name, desc="", ref=None, severity="", resolution="", data="", external_id=None, run_date=None, custom_fields=None, policyviolations=None, impact=None, status="", - confirmed=False, easeofresolution=None, target=None, tags=None): + confirmed=False, easeofresolution=None, tags=None): if ref is None: ref = [] if status == "": @@ -429,7 +429,7 @@ def createAndAddVulnToService(self, host_id, service_id, name, desc="", "external_id": external_id, "type": "Vulnerability", "resolution": resolution, "data": data, "custom_fields": custom_fields, "status": status, "impact": impact, "policyviolations": policyviolations, - "easeofresolution": easeofresolution, "target": target, "confirmed": confirmed, "tags": tags + "easeofresolution": easeofresolution, "confirmed": confirmed, "tags": tags } if run_date: vulnerability["run_date"] = self.get_utctimestamp(run_date) diff --git a/faraday_plugins/plugins/repo/sslyzejson/plugin.py b/faraday_plugins/plugins/repo/sslyzejson/plugin.py index dc7134b2..19517664 100644 --- a/faraday_plugins/plugins/repo/sslyzejson/plugin.py +++ b/faraday_plugins/plugins/repo/sslyzejson/plugin.py @@ -210,7 +210,7 @@ def parseOutputString(self, output): ) if info_sslyze['certification']: - self.createAndAddVulnToService( + self.createAndAddVulnWebToService( host_id, service_id, name=info_sslyze['certification'].get('name'), @@ -220,7 +220,7 @@ def parseOutputString(self, output): ref=info_sslyze['certification'].get('ref'), easeofresolution="trivial", external_id=info_sslyze['certification'].get('external_id'), - target=info_sslyze['host_info'].get('url'), + website=info_sslyze['host_info'].get('url'), severity=info_sslyze['certification'].get('severity')) cipherlist = [] @@ -231,7 +231,7 @@ def parseOutputString(self, output): key = k.replace('_cipher_suites', '') cipherlist.append(f"In protocol [{key}], weak cipher suite: {ciphers}") if cipherlist: - self.createAndAddVulnToService( + self.createAndAddVulnWebToService( host_id, service_id, name="SSL/TLS Weak Cipher Suites Supported", @@ -241,11 +241,11 @@ def parseOutputString(self, output): ref=["https://cwe.mitre.org/data/definitions/326.html"], easeofresolution="trivial", external_id="CWE-326", - target=info_sslyze['host_info'].get('url'), + website=info_sslyze['host_info'].get('url'), severity="low") if info_sslyze['heartbleed']: - self.createAndAddVulnToService( + self.createAndAddVulnWebToService( host_id, service_id, name=info_sslyze['heartbleed'].get('name'), @@ -254,11 +254,11 @@ def parseOutputString(self, output): ref=info_sslyze['heartbleed'].get('ref'), easeofresolution="trivial", external_id=info_sslyze['heartbleed'].get('external_id'), - target=info_sslyze['host_info'].get('url'), + website=info_sslyze['host_info'].get('url'), severity=info_sslyze['heartbleed'].get('severity')) if info_sslyze['openssl_ccs']: - self.createAndAddVulnToService( + self.createAndAddVulnWebToService( host_id, service_id, name=info_sslyze['openssl_ccs'].get('name'), @@ -267,7 +267,7 @@ def parseOutputString(self, output): ref=info_sslyze['openssl_ccs'].get('ref'), easeofresolution="trivial", external_id=info_sslyze['openssl_ccs'].get('external_id'), - target=info_sslyze['host_info'].get('url'), + website=info_sslyze['host_info'].get('url'), severity=info_sslyze['openssl_ccs'].get('severity')) def processCommandString(self, username, current_path, command_string): From 00f021330ff52d98a4f7b0a41ca399cb08d65185 Mon Sep 17 00:00:00 2001 From: Valentin Vila Date: Wed, 16 Jun 2021 14:56:26 +0000 Subject: [PATCH 236/698] Resolve "Add Shodan plugin" --- CHANGELOG/current/add_shodan_plugin.md | 1 + .../plugins/repo/shodan/__init__.py | 6 + faraday_plugins/plugins/repo/shodan/plugin.py | 107 ++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 CHANGELOG/current/add_shodan_plugin.md create mode 100644 faraday_plugins/plugins/repo/shodan/__init__.py create mode 100644 faraday_plugins/plugins/repo/shodan/plugin.py diff --git a/CHANGELOG/current/add_shodan_plugin.md b/CHANGELOG/current/add_shodan_plugin.md new file mode 100644 index 00000000..5b2c4c79 --- /dev/null +++ b/CHANGELOG/current/add_shodan_plugin.md @@ -0,0 +1 @@ +add shodan plugin diff --git a/faraday_plugins/plugins/repo/shodan/__init__.py b/faraday_plugins/plugins/repo/shodan/__init__.py new file mode 100644 index 00000000..d8862701 --- /dev/null +++ b/faraday_plugins/plugins/repo/shodan/__init__.py @@ -0,0 +1,6 @@ +""" +Faraday Penetration Test IDE +Copyright (C) 2021 Infobyte LLC (http://www.infobytesec.com/) +See the file 'doc/LICENSE' for the license information + +""" diff --git a/faraday_plugins/plugins/repo/shodan/plugin.py b/faraday_plugins/plugins/repo/shodan/plugin.py new file mode 100644 index 00000000..d4842550 --- /dev/null +++ b/faraday_plugins/plugins/repo/shodan/plugin.py @@ -0,0 +1,107 @@ +""" +Faraday Penetration Test IDE +Copyright (C) 2013 Infobyte LLC (http://www.infobytesec.com/) +See the file 'doc/LICENSE' for the license information + +""" +import re +import json +import argparse +import shlex +import gzip +import os +import shutil + +from faraday_plugins.plugins.plugin import PluginMultiLineJsonFormat + +__author__ = "Valentin Vila" +__copyright__ = "Copyright (c) 2021, Faraday" +__credits__ = ["Valentin Vila"] +__license__ = "" +__version__ = "1.0.0" +__maintainer__ = "Valentin Vila" +__email__ = "vvila@faradaysec.com" +__status__ = "Development" + + +class ShodanPlugin(PluginMultiLineJsonFormat): + """ + This plugin handles the Shodan tool. + Detects the output of the tool + and adds the information to Faraday. + """ + + def __init__(self, *arg, **kwargs): + super().__init__(*arg, **kwargs) + self.id = "shodan" + self.name = "Shodan" + self.plugin_version = "0.0.1" + self.version = "1.0.0" + self._command_regex = re.compile(r'^shodan\s+(?P