Import upstream version 1.5.1
Kali Janitor
2 years ago
0 | cwe, capec, references, tags, impact, resolution, easeofresolution |
0 | add os openvas⏎ |
0 | Jul 27th, 2021 |
0 | [FIX] Fix improt of CSV with big fields |
0 | Fix sslyze json bug with port |
0 | Only show report name in command data |
0 | 1.5.1 [Jul 27th, 2021]: | |
1 | --- | |
2 | * cwe, capec, references, tags, impact, resolution, easeofresolution | |
3 | * add os openvas | |
4 | * [FIX] Fix improt of CSV with big fields | |
5 | * Fix sslyze json bug with port | |
6 | * Only show report name in command data | |
7 | ||
0 | 8 | 1.5.0 [Jun 28th, 2021]: |
1 | 9 | --- |
2 | 10 | * Add Nipper Plugin |
5 | 5 | import shlex |
6 | 6 | import subprocess |
7 | 7 | import sys |
8 | from pathlib import Path | |
8 | 9 | |
9 | 10 | import click |
10 | 11 | from tabulate import tabulate |
79 | 80 | if not plugin: |
80 | 81 | click.echo(click.style(f"Failed to detect report: {report_file}", fg="red"), err=True) |
81 | 82 | return |
82 | plugin.processReport(report_file, getpass.getuser()) | |
83 | plugin.processReport(Path(report_file), getpass.getuser()) | |
83 | 84 | if summary: |
84 | 85 | click.echo(json.dumps(plugin.get_summary(), indent=4)) |
85 | 86 | else: |
13 | 13 | import zipfile |
14 | 14 | from collections import defaultdict |
15 | 15 | from datetime import datetime |
16 | from pathlib import Path | |
16 | 17 | |
17 | 18 | import pytz |
18 | 19 | import simplejson as json |
276 | 277 | params = " ".join(command_string.split()[2:]) |
277 | 278 | else: |
278 | 279 | params = " ".join(command_string.split()[1:]) |
279 | self.vulns_data["command"]["params"] = params | |
280 | self.vulns_data["command"]["params"] = params if not self.ignore_info else f"{params} (Info ignored)" | |
280 | 281 | self.vulns_data["command"]["user"] = username |
281 | 282 | self.vulns_data["command"]["import_source"] = "shell" |
282 | 283 | if self._use_temp_file: |
299 | 300 | |
300 | 301 | def processOutput(self, command_output): |
301 | 302 | if self.has_custom_output(): |
302 | self._parse_filename(self.get_custom_file_path()) | |
303 | self._parse_filename(Path(self.get_custom_file_path())) | |
303 | 304 | else: |
304 | 305 | self.parseOutputString(command_output) |
305 | 306 | |
306 | def _parse_filename(self, filename): | |
307 | with open(filename, **self.open_options) as output: | |
307 | def _parse_filename(self, filename: Path): | |
308 | with filename.open(**self.open_options) as output: | |
308 | 309 | self.parseOutputString(output.read()) |
309 | 310 | if self._delete_temp_file: |
310 | 311 | try: |
311 | if os.path.isfile(filename): | |
312 | if filename.is_file(): | |
312 | 313 | os.remove(filename) |
313 | elif os.path.isdir(filename): | |
314 | elif filename.is_dir(): | |
314 | 315 | shutil.rmtree(filename) |
315 | 316 | except Exception as e: |
316 | 317 | self.logger.error("Error on delete file: (%s) [%s]", filename, e) |
317 | 318 | |
318 | def processReport(self, filepath, user="faraday"): | |
319 | if os.path.isfile(filepath): | |
320 | self.vulns_data["command"]["params"] = filepath if not self.ignore_info else f"{filepath} (Info ignored)" | |
319 | def processReport(self, filepath: Path, user="faraday"): | |
320 | if type(filepath) == str: # TODO workaround for compatibility, remove in the future | |
321 | filepath = Path(filepath) | |
322 | if filepath.is_file(): | |
323 | self.vulns_data["command"]["params"] = filepath.name if not self.ignore_info else f"{filepath.name} (Info ignored)" | |
321 | 324 | self.vulns_data["command"]["user"] = user |
322 | 325 | self.vulns_data["command"]["import_source"] = "report" |
323 | 326 | self._parse_filename(filepath) |
565 | 568 | def processOutput(self, term_output): |
566 | 569 | # we discard the term_output since it's not necessary |
567 | 570 | # for this type of plugins |
568 | self.processReport(self._output_file_path) | |
571 | self.processReport(Path(self._output_file_path)) | |
569 | 572 | |
570 | 573 | |
571 | 574 | class PluginByExtension(PluginBase): |
2 | 2 | Copyright (C) 2013 Infobyte LLC (http://www.infobytesec.com/) |
3 | 3 | See the file 'doc/LICENSE' for the license information |
4 | 4 | """ |
5 | import sys | |
5 | 6 | import re |
6 | 7 | import csv |
7 | 8 | from ast import literal_eval |
59 | 60 | |
60 | 61 | def parse_csv(self, output): |
61 | 62 | items = [] |
63 | csv.field_size_limit(sys.maxsize) | |
62 | 64 | reader = csv.DictReader(output, delimiter=',') |
63 | 65 | obj_to_import = self.check_objects_to_import(reader.fieldnames) |
64 | 66 | if not obj_to_import: |
4 | 4 | |
5 | 5 | """ |
6 | 6 | import socket |
7 | import re | |
7 | 8 | import json |
8 | 9 | import dateutil |
9 | 10 | from collections import defaultdict |
15 | 16 | __copyright__ = "Copyright (c) 2021, Infobyte LLC" |
16 | 17 | __credits__ = ["Nicolas Rebagliati"] |
17 | 18 | __license__ = "" |
18 | __version__ = "0.0.1" | |
19 | __version__ = "1.0.0" | |
19 | 20 | __maintainer__ = "Nicolas Rebagliati" |
20 | 21 | __email__ = "[email protected]" |
21 | 22 | __status__ = "Development" |
30 | 31 | super().__init__(*arg, **kwargs) |
31 | 32 | self.id = "nuclei" |
32 | 33 | self.name = "Nuclei" |
33 | self.plugin_version = "0.1" | |
34 | self.version = "2.3.0" | |
34 | self.plugin_version = "1.0.0" | |
35 | self.version = "2.3.8" | |
35 | 36 | self.json_keys = {"matched", "templateID", "host"} |
36 | 37 | |
37 | 38 | def parseOutputString(self, output, debug=False): |
59 | 60 | description='web server') |
60 | 61 | matched = vuln_dict.get('matched') |
61 | 62 | matched_data = urlparse(matched) |
62 | references = [f"author: {vuln_dict['info'].get('author', '')}"] | |
63 | reference = vuln_dict["info"].get('reference', []) | |
64 | if reference: | |
65 | if isinstance(reference, str): | |
66 | if re.match('^- ', reference): | |
67 | reference = list(filter(None, [re.sub('^- ','', elem) for elem in reference.split('\n')])) | |
68 | else: | |
69 | reference = [reference] | |
70 | references = vuln_dict["info"].get('references', []) | |
71 | if references: | |
72 | if isinstance(references, str): | |
73 | if re.match('^- ', references): | |
74 | references = list(filter(None, [re.sub('^- ','', elem) for elem in references.split('\n')])) | |
75 | else: | |
76 | references = [references] | |
77 | cwe = vuln_dict['info'].get('cwe', []) | |
78 | capec = vuln_dict['info'].get('capec', []) | |
79 | refs = list(set(reference + references + cwe + capec)).sort() | |
80 | tags = vuln_dict['info'].get('tags', '').split(',') | |
81 | impact = vuln_dict['info'].get('impact') | |
82 | resolution = vuln_dict['info'].get('resolution', '') | |
83 | easeofresolution = vuln_dict['info'].get('easeofresolution') | |
63 | 84 | request = vuln_dict.get('request', '') |
64 | 85 | if request: |
65 | 86 | method = request.split(" ")[0] |
78 | 99 | service_id, |
79 | 100 | name=name, |
80 | 101 | desc=vuln_dict["info"].get("description", name), |
81 | ref=references, | |
102 | ref=refs, | |
82 | 103 | severity=vuln_dict["info"].get('severity'), |
104 | tags=tags, | |
105 | impact=impact, | |
106 | resolution=resolution, | |
107 | easeofresolution=easeofresolution, | |
83 | 108 | website=host, |
84 | 109 | request=request, |
85 | 110 | response=vuln_dict.get('response', ''), |
321 | 321 | from the xml where it expects it to be present. |
322 | 322 | """ |
323 | 323 | parser = OpenvasXmlParser(output, self.logger) |
324 | web = False | |
325 | 324 | ids = {} |
326 | 325 | # The following threats values will not be taken as vulns |
327 | 326 | self.ignored_severities = ['Log', 'Debug'] |
328 | 327 | for ip, values in parser.hosts.items(): |
329 | 328 | # values contains: ip details and ip hostnames |
329 | os_report = values['details'].get('best_os_txt') | |
330 | 330 | h_id = self.createAndAddHost( |
331 | 331 | ip, |
332 | os_report[0] if os_report else '', | |
332 | 333 | hostnames=values['hostnames'] |
333 | 334 | ) |
334 | 335 | ids[ip] = h_id |
74 | 74 | hostname = server_location.get('hostname', None) |
75 | 75 | ip = server_location.get('ip_address', resolve_hostname(hostname)) |
76 | 76 | if port != 443: |
77 | url = 'https://' + hostname + ':' + port | |
77 | url = f"https://{hostname}:{port}" | |
78 | 78 | else: |
79 | url = 'https://' + hostname | |
79 | url = f"https://{hostname}" | |
80 | 80 | |
81 | 81 | json_host = { |
82 | 82 | "name": 'https', |
1 | 1 | import socket |
2 | 2 | import json |
3 | 3 | import pytest |
4 | from pathlib import Path | |
4 | 5 | from faraday_plugins.plugins.manager import PluginsManager, ReportAnalyzer |
5 | 6 | from faraday_plugins.plugins.plugin import PluginBase |
6 | 7 | from faraday.server.api.modules.bulk_create import BulkCreateSchema |
44 | 45 | if not plugin_json: |
45 | 46 | plugin = get_plugin_from_cache(report_file) |
46 | 47 | if plugin: |
47 | plugin.processReport(report_file) | |
48 | plugin.processReport(Path(report_file)) | |
48 | 49 | plugin_json = json.loads(plugin.get_json()) |
49 | 50 | REPORTS_JSON_CACHE[report_file] = plugin_json |
50 | 51 | else: |