New upstream version 1.8.1
Sophie Brun
1 year, 4 months ago
0 | [FIX] Nuclei's plugin check if the cwe is null and add retrocompability for newer versions for wpscan plugin |
0 | [ADD] Add cvss2/3 and cwe to faraday_csv plugin |
0 | [Add] Now nexpose_full plugin use severity from reports |
0 | [FIX] Now plugins check if the ref is empty |
0 | Nov 28th, 2022 |
0 | 1.8.0 [Oct 26th, 2022]: | |
0 | 1.8.1 [Nov 28th, 2022]: | |
1 | --- | |
2 | * [FIX] Nuclei's plugin check if the cwe is null and add retrocompability for newer versions for wpscan plugin | |
3 | * [ADD] Add cvss2/3 and cwe to faraday_csv plugin | |
4 | * [Add] Now nexpose_full plugin use severity from reports | |
5 | * [FIX] Now plugins check if the ref is empty | |
6 | ||
7 | 1.8.0: | |
1 | 8 | --- |
2 | 9 | * [Add] Add invicti plugin |
3 | 10 | * [Add] Add nessus_sc plugin |
425 | 425 | """ |
426 | 426 | Change reference struct from list of strings to a list of dicts with the form of {name, type} |
427 | 427 | """ |
428 | if not ref: | |
429 | return [] | |
428 | 430 | refs = [] |
429 | if ref: | |
430 | for r in ref: | |
431 | if isinstance(r, dict): | |
432 | refs.append(r) | |
433 | else: | |
434 | refs.append({'name': r, 'type': 'other'}) | |
431 | for r in ref: | |
432 | if isinstance(r, dict): | |
433 | refs.append(r) | |
434 | else: | |
435 | if r.strip(): | |
436 | refs.append({'name': r.strip(), 'type': 'other'}) | |
435 | 437 | return refs |
436 | 438 | |
437 | 439 | def createAndAddVulnToHost(self, host_id, name, desc="", ref=None, |
49 | 49 | "custom_fields", |
50 | 50 | "website", |
51 | 51 | "path", |
52 | "cwe", | |
53 | "cvss2_base_score", | |
54 | "cvss2_vector_string", | |
55 | "cvss3_base_score", | |
56 | "cvss3_vector_string", | |
52 | 57 | "request", |
53 | 58 | "response", |
54 | 59 | "method", |
293 | 298 | tags=item['service_tags'] |
294 | 299 | ) |
295 | 300 | if item['row_with_vuln']: |
301 | cvss2 = { | |
302 | "base_score": item['cvss2_base_score'], | |
303 | } | |
304 | if item['cvss2_vector_string']: | |
305 | cvss2["vector_string"]= item['cvss2_vector_string'] | |
306 | cvss3 = { | |
307 | "base_score": item['cvss3_base_score'], | |
308 | } | |
309 | if item['cvss3_vector_string']: | |
310 | cvss3["vector_string"]= item['cvss3_vector_string'] | |
296 | 311 | if not item['web_vulnerability'] and not s_id: |
297 | 312 | self.createAndAddVulnToHost( |
298 | 313 | h_id, |
309 | 324 | impact=item['impact'], |
310 | 325 | policyviolations=item['policyviolations'], |
311 | 326 | cve=item['cve'], |
327 | cwe=item['cwe'], | |
328 | cvss2=cvss2, | |
329 | cvss3=cvss3, | |
312 | 330 | custom_fields=item['custom_fields'], |
313 | 331 | tags=item['tags'] |
314 | 332 | ) |
329 | 347 | impact=item['impact'], |
330 | 348 | policyviolations=item['policyviolations'], |
331 | 349 | cve=item['cve'], |
350 | cwe=item['cwe'], | |
351 | cvss2=cvss2, | |
352 | cvss3=cvss3, | |
332 | 353 | custom_fields=item['custom_fields'], |
333 | 354 | tags=item['tags'] |
334 | 355 | ) |
357 | 378 | impact=item['impact'], |
358 | 379 | policyviolations=item['policyviolations'], |
359 | 380 | cve=item['cve'], |
381 | cwe=item['cwe'], | |
382 | cvss2=cvss2, | |
383 | cvss3=cvss3, | |
360 | 384 | status_code=item['status_code'] or None, |
361 | 385 | custom_fields=item['custom_fields'], |
362 | 386 | tags=item['tags'] |
39 | 39 | self.items = self.get_items(tree, self.vulns) |
40 | 40 | else: |
41 | 41 | self.items = [] |
42 | ||
43 | @staticmethod | |
44 | def get_severity_from_report(score): | |
45 | try: | |
46 | if type(score) != float: | |
47 | score = float(score) | |
48 | ||
49 | cvss_ranges = [(0.0, 3.4, 'med'), | |
50 | (3.5, 7.4, 'high'), | |
51 | (7.5, 10.1, 'critical')] | |
52 | for (lower, upper, severity) in cvss_ranges: | |
53 | if lower <= score < upper: | |
54 | return severity | |
55 | except ValueError: | |
56 | return 'unclassified' | |
42 | 57 | |
43 | 58 | @staticmethod |
44 | 59 | def parse_xml(xml_output): |
142 | 157 | 'name': vulnDef.get('title'), |
143 | 158 | 'refs': [], |
144 | 159 | 'resolution': "", |
145 | 'severity': "", | |
160 | 'severity': self.get_severity_from_report(vulnDef.get('severity')), | |
146 | 161 | 'tags': list(), |
147 | 162 | 'is_web': vid.startswith('http-'), |
148 | 163 | 'risk': vulnDef.get('riskScore'), |
96 | 96 | if cve: |
97 | 97 | cve = [x.upper() for x in cve] |
98 | 98 | |
99 | # TODO CVSSv2, CVSSv3, CWE and CAPEC | |
100 | #cvssv2 = vuln_dict['info'].get('classification', {}).get('cvss-score') | |
101 | #cvssv3 = vuln_dict['info'].get('classification', {}).get('cvss-metrics') | |
99 | vector_string = vuln_dict['info'].get('classification', {}).get('cvss-metrics') | |
100 | cvss3 = {"vector_string": vector_string} if vector_string else None | |
102 | 101 | cwe = vuln_dict['info'].get('classification', {}).get('cwe-id', []) |
103 | cwe = [x.upper() for x in cwe] | |
102 | if cwe: | |
103 | cwe = [x.upper() for x in cwe] | |
104 | 104 | #capec = vuln_dict['info'].get('metadata', {}).get('capec', []) |
105 | 105 | #if isinstance(capec, str): |
106 | 106 | # capec = capec.upper().split(',') |
161 | 161 | path=matched_data.path, |
162 | 162 | data="\n".join(data), |
163 | 163 | external_id=f"NUCLEI-{vuln_dict.get('template-id', '')}", |
164 | run_date=run_date | |
164 | run_date=run_date, | |
165 | cvss3=cvss3 | |
165 | 166 | ) |
166 | 167 | |
167 | 168 | def processCommandString(self, username, current_path, command_string): |
173 | 174 | command_string) |
174 | 175 | else: |
175 | 176 | return re.sub(arg_match.group(1), |
176 | r"--json -irr -o %s" % self._output_file_path, | |
177 | r" --json -irr -o %s" % self._output_file_path, | |
177 | 178 | command_string) |
178 | 179 | |
179 | 180 | def canParseCommandString(self, current_input): |
53 | 53 | self.name = "WPscan" |
54 | 54 | self.plugin_version = "0.2" |
55 | 55 | self.version = "3.4.5" |
56 | self.json_keys = {"target_url", "effective_url", "interesting_findings"} | |
56 | self.json_keys = [{"target_url", "effective_url", "interesting_findings"}, | |
57 | {"target_url", "effective_url", "plugins"}] | |
57 | 58 | self._command_regex = re.compile(r'^(sudo wpscan|wpscan)\s+.*?') |
58 | 59 | self._use_temp_file = True |
59 | 60 | self._temp_file_extension = "json" |
73 | 74 | for user, data in parser.json_data.get('users', {}).items(): |
74 | 75 | self.createAndAddCredToService(host_id, service_id, user, "") |
75 | 76 | main_theme = parser.json_data.get("main_theme", {}) |
76 | for vuln in main_theme.get("vulnerabilities", []): | |
77 | wpvulndb = ",".join(vuln['references'].get('wpvulndb', [])) | |
78 | self.createAndAddVulnWebToService(host_id, service_id, vuln['title'], ref=vuln['references'].get('url', []), | |
79 | severity='unclassified', external_id=wpvulndb) | |
77 | if main_theme: | |
78 | for vuln in main_theme.get("vulnerabilities", []): | |
79 | wpvulndb = ",".join(vuln['references'].get('wpvulndb', [])) | |
80 | self.createAndAddVulnWebToService(host_id, service_id, vuln['title'], ref=vuln['references'].get('url', []), | |
81 | severity='unclassified', external_id=wpvulndb) | |
80 | 82 | for plugin, plugin_data in parser.json_data.get("plugins", {}).items(): |
81 | 83 | for vuln in plugin_data['vulnerabilities']: |
82 | 84 | wpvulndb = ",".join(vuln['references'].get('wpvulndb', [])) |
85 | cve = ["CVE-"+ cve for cve in vuln['references'].get('cve')] if vuln['references'].get('cve') else [] | |
83 | 86 | self.createAndAddVulnWebToService(host_id, service_id, f"{plugin}: {vuln['title']}", |
84 | 87 | ref=vuln['references'].get('url', []), |
85 | severity='unclassified', external_id=wpvulndb) | |
88 | severity='unclassified', external_id=wpvulndb, cve=cve) | |
86 | 89 | for vuln in parser.json_data.get("interesting_findings", []): |
87 | 90 | if vuln['to_s'].startswith('http'): |
88 | 91 | vuln_name = f"{vuln['type']}: {vuln['to_s']}" |