Import upstream version 1.5.5
Kali Janitor
2 years ago
0 | Adding support for running nuclei through command / faraday-cli |
0 | Sep 7th, 2021 |
0 | Fix missing references in nuclei |
0 | Oct 19th, 2021 |
0 | Update nuclei parser |
0 | Oct 21st, 2021 |
0 | Merge PR from github |
5 | 5 | |
6 | 6 | ## Commands |
7 | 7 | |
8 | > List Plugins | |
8 | ### List Plugins | |
9 | 9 | |
10 | 10 | List all plugins and if its compatible with command or/and report |
11 | 11 | |
17 | 17 | faraday-plugins list-plugins |
18 | 18 | ``` |
19 | 19 | |
20 | > Test autodetect plugin from command | |
20 | ### Test autodetect plugin from command | |
21 | 21 | |
22 | 22 | ```shell script |
23 | 23 | faraday-plugins detect-command "ping -c 4 www.google.com" |
25 | 25 | Faraday Plugin: ping |
26 | 26 | ``` |
27 | 27 | |
28 | > Test process command with plugin | |
28 | ### Test process command with plugin | |
29 | 29 | |
30 | 30 | Optional params: |
31 | 31 | |
66 | 66 | } |
67 | 67 | ``` |
68 | 68 | |
69 | > Test autodetect plugin from report | |
69 | ### Test autodetect plugin from report | |
70 | 70 | |
71 | 71 | ```shell script |
72 | 72 | faraday-plugins detect-report /path/to/report.xml |
74 | 74 | Faraday Plugin: Nmap |
75 | 75 | ``` |
76 | 76 | |
77 | ||
78 | > Test report with plugin | |
77 | ### Test report with plugin | |
79 | 78 | |
80 | 79 | Optional params: |
81 | 80 | |
135 | 134 | } |
136 | 135 | ``` |
137 | 136 | |
138 | > Plugin Logger | |
137 | ## Plugin Logger | |
139 | 138 | |
140 | To use it you must call ```self.logger.debug("some message")``` | |
139 | To use it you must call `self.logger.debug("some message")` | |
141 | 140 | |
142 | 141 | ```shell script |
143 | 142 | export PLUGIN_DEBUG=1 |
155 | 154 | ... |
156 | 155 | ``` |
157 | 156 | |
158 | ||
159 | > More documentation here https://github.com/infobyte/faraday/wiki/Basic-plugin-development | |
157 | More documentation here https://github.com/infobyte/faraday/wiki/Basic-plugin-development |
0 | 1.5.5 [Oct 21st, 2021]: | |
1 | --- | |
2 | * Merge PR from github | |
3 | ||
4 | 1.5.4 [Oct 19th, 2021]: | |
5 | --- | |
6 | * Update nuclei parser | |
7 | ||
8 | 1.5.3 [Sep 7th, 2021]: | |
9 | --- | |
10 | * Adding support for running nuclei through command / faraday-cli | |
11 | * Fix missing references in nuclei | |
12 | ||
0 | 13 | 1.5.2 [Aug 9th, 2021]: |
1 | 14 | --- |
2 | 15 | * add new structure acunetix |
273 | 273 | command that it's going to be executed. |
274 | 274 | """ |
275 | 275 | self._current_path = current_path |
276 | if command_string.startswith("sudo"): | |
276 | if command_string.startswith(("sudo","python","python3")): | |
277 | 277 | params = " ".join(command_string.split()[2:]) |
278 | 278 | else: |
279 | 279 | params = " ".join(command_string.split()[1:]) |
31 | 31 | super().__init__(*arg, **kwargs) |
32 | 32 | self.id = "nuclei" |
33 | 33 | self.name = "Nuclei" |
34 | self.plugin_version = "1.0.0" | |
34 | self.plugin_version = "1.0.1" | |
35 | 35 | self.version = "2.3.8" |
36 | 36 | self.json_keys = {"matched", "templateID", "host"} |
37 | self._command_regex = re.compile(r'^(sudo nuclei|nuclei|\.\/nuclei|^.*?nuclei)\s+.*?') | |
38 | self.xml_arg_re = re.compile(r"^.*(-o\s*[^\s]+).*$") | |
39 | self._use_temp_file = True | |
40 | self._temp_file_extension = "json" | |
37 | 41 | |
38 | 42 | def parseOutputString(self, output, debug=False): |
39 | 43 | for vuln_json in filter(lambda x: x != '', output.split("\n")): |
61 | 65 | matched = vuln_dict.get('matched') |
62 | 66 | matched_data = urlparse(matched) |
63 | 67 | reference = vuln_dict["info"].get('reference', []) |
64 | if reference: | |
68 | if not reference: | |
69 | reference = [] | |
70 | else: | |
65 | 71 | if isinstance(reference, str): |
66 | 72 | if re.match('^- ', reference): |
67 | reference = list(filter(None, [re.sub('^- ','', elem) for elem in reference.split('\n')])) | |
73 | reference = list(filter(None, [re.sub('^- ', '', elem) for elem in reference.split('\n')])) | |
68 | 74 | else: |
69 | 75 | reference = [reference] |
70 | 76 | references = vuln_dict["info"].get('references', []) |
71 | 77 | if references: |
72 | 78 | if isinstance(references, str): |
73 | 79 | if re.match('^- ', references): |
74 | references = list(filter(None, [re.sub('^- ','', elem) for elem in references.split('\n')])) | |
80 | references = list(filter(None, [re.sub('^- ', '', elem) for elem in references.split('\n')])) | |
75 | 81 | else: |
76 | 82 | references = [references] |
83 | else: | |
84 | references = [] | |
77 | 85 | cwe = vuln_dict['info'].get('cwe', []) |
78 | 86 | capec = vuln_dict['info'].get('capec', []) |
79 | refs = list(set(reference + references + cwe + capec)).sort() | |
80 | tags = vuln_dict['info'].get('tags', '').split(',') | |
87 | refs = sorted(list(set(reference + references + cwe + capec))) | |
88 | tags = vuln_dict['info'].get('tags', []) | |
89 | if isinstance(tags, str): | |
90 | tags = tags.split(',') | |
81 | 91 | impact = vuln_dict['info'].get('impact') |
82 | 92 | resolution = vuln_dict['info'].get('resolution', '') |
83 | 93 | easeofresolution = vuln_dict['info'].get('easeofresolution') |
87 | 97 | else: |
88 | 98 | method = "" |
89 | 99 | data = [f"Matched: {vuln_dict.get('matched')}", |
90 | f"Tags: {vuln_dict['info'].get('tags')}", | |
100 | f"Tags: {vuln_dict['info'].get('tags', '')}", | |
91 | 101 | f"Template ID: {vuln_dict['templateID']}"] |
92 | 102 | |
93 | 103 | name = vuln_dict["info"].get("name") |
116 | 126 | external_id=f"NUCLEI-{vuln_dict.get('templateID', '')}", |
117 | 127 | run_date=run_date |
118 | 128 | ) |
119 | ||
120 | ||
129 | ||
130 | def processCommandString(self, username, current_path, command_string): | |
131 | """ | |
132 | Adds the -oX parameter to get xml output to the command string that the | |
133 | user has set. | |
134 | """ | |
135 | super().processCommandString(username, current_path, command_string) | |
136 | arg_match = self.xml_arg_re.match(command_string) | |
137 | if arg_match is None: | |
138 | return re.sub(r"(^.*?nuclei)", | |
139 | r"\1 --json -irr -o %s" % self._output_file_path, | |
140 | command_string) | |
141 | else: | |
142 | return re.sub(arg_match.group(1), | |
143 | r"--json -irr -o %s" % self._output_file_path, | |
144 | command_string) | |
121 | 145 | |
122 | 146 | |
123 | 147 | def createPlugin(ignore_info=False): |
0 | 0 | import json |
1 | 1 | import os |
2 | 2 | import re |
3 | from tempfile import NamedTemporaryFile | |
3 | import pytest | |
4 | 4 | from click.testing import CliRunner |
5 | 5 | from faraday_plugins.commands import list_plugins, detect_command, process_command, detect_report, process_report |
6 | 6 | |
21 | 21 | assert result.output.strip() == "Failed to detect command: invalid_command" |
22 | 22 | |
23 | 23 | |
24 | @pytest.mark.skip(reason="issue with docker image") | |
24 | 25 | def test_detect_command(): |
25 | 26 | runner = CliRunner() |
26 | 27 | result = runner.invoke(detect_command, args=['ping -c 1 www.google.com']) |
28 | 29 | assert result.output.strip() == "Faraday Plugin: ping" |
29 | 30 | |
30 | 31 | |
32 | @pytest.mark.skip(reason="issue with docker image") | |
31 | 33 | def test_process_command(): |
32 | 34 | runner = CliRunner() |
33 | 35 | result = runner.invoke(process_command, args=['ping -c 1 www.google.com', '--summary']) |
34 | assert result.exit_code == 0 | |
36 | assert result.exit_code == 0, result.output | |
35 | 37 | summary = json.loads(result.output.strip()) |
36 | 38 | assert summary['hosts'] == 1 |
37 | 39 | |
38 | 40 | |
41 | @pytest.mark.skip(reason="issue with docker image") | |
39 | 42 | def test_process_command_ping(): |
40 | 43 | runner = CliRunner() |
41 | 44 | result = runner.invoke(process_command, args=['ping -c 1 www.google.com']) |
42 | assert result.exit_code == 0 | |
45 | assert result.exit_code == 0, result.output | |
43 | 46 | summary = json.loads(result.output.strip()) |
44 | 47 | |
45 | 48 | assert summary['command']["command"] == 'ping' |
46 | 49 | |
47 | 50 | |
51 | @pytest.mark.skip(reason="issue with docker image") | |
48 | 52 | def test_process_command_to_file(): |
49 | 53 | runner = CliRunner() |
50 | 54 | with runner.isolated_filesystem() as file_system: |
51 | 55 | output_file = os.path.join(file_system, "test.json") |
52 | 56 | result = runner.invoke(process_command, args=['ping -c 1 www.google.com', '-o', output_file]) |
53 | assert result.exit_code == 0 | |
57 | assert result.exit_code == 0, result.output | |
54 | 58 | assert os.path.isfile(output_file) |
55 | 59 | with open(output_file) as f: |
56 | 60 | vuln_json = json.load(f) |