Skip to content

Commit 65cb49c

Browse files
tenable nessus: parse all fields, except cwe
1 parent 499e4ee commit 65cb49c

File tree

6 files changed

+210
-3
lines changed

6 files changed

+210
-3
lines changed

dojo/tools/tenable/csv_format.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,44 @@ def get_findings(self, filename: str, test: Test):
101101
raw_severity = int_severity
102102
# convert the severity to something dojo likes
103103
severity = self._convert_severity(raw_severity)
104+
105+
epss_score = None
106+
epss_score_string = row.get("EPSS Score") if "EPSS Score" in row else None
107+
# example seen so far are "1234" for an actual score of "0.1234" so let's prepend that instead of "risky" divisions
108+
if epss_score_string:
109+
if "0." not in epss_score_string:
110+
epss_score_string = "0." + epss_score_string
111+
epss_score = float(epss_score_string)
112+
104113
# Other text fields
105114
description = row.get("Synopsis", row.get("definition.synopsis", "N/A"))
115+
116+
severity_justification = f"Severity: {severity}\n"
117+
for field in (
118+
"VPR score",
119+
"EPSS Score",
120+
"Risk Factor",
121+
"STIG Severity",
122+
"CVSS v4.0 Base Score",
123+
"CVSS v4.0 Base+Threat Score",
124+
"CVSS v3.0 Base Score",
125+
"CVSS v3.0 Temporal Score",
126+
"Metasploit",
127+
"Core Impact",
128+
"CANVAS",
129+
"XREF",
130+
):
131+
severity_justification += f"{field}: {row.get(field, 'N/A')}\n"
132+
133+
# cwe = parse_cwe_from_ref(row.get("XREF")) # parsing and storing the CWE would affect dedupe/hash_codes, commentint out for now
134+
106135
mitigation = str(row.get("Solution", row.get("definition.solution", row.get("Steps to Remediate", "N/A"))))
107136
impact = row.get("Description", row.get("definition.description", "N/A"))
108-
references = row.get("See Also", row.get("definition.see_also", "N/A"))
137+
references = ""
138+
references += row.get("References") if "References" in row else ""
139+
references += row.get("See Also", row.get("definition.see_also", "N/A"))
109140
references += "\nTenable Plugin ID: " + row.get("Plugin", "N/A")
141+
references += "\nPlugin Information: " + row.get("Plugin Information", "N/A")
110142
references += "\nPlugin Publication Date: " + row.get("Plugin Publication Date", "N/A")
111143
references += "\nPlugin Modification Date: " + row.get("Plugin Modification Date", "N/A")
112144
# Determine if the current row has already been processed
@@ -126,9 +158,12 @@ def get_findings(self, filename: str, test: Test):
126158
test=test,
127159
description=description,
128160
severity=severity,
161+
# cwe=cwe,
162+
epss_score=epss_score,
129163
mitigation=mitigation,
130164
impact=impact,
131165
references=references,
166+
severity_justification=severity_justification,
132167
)
133168

134169
# manage CVSS vector (only v3.x for now)

dojo/tools/tenable/utils.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
# import contextlib
3+
4+
5+
# def parse_cwe_from_ref(xref):
6+
# if xref:
7+
# for ref in xref.split(";"):
8+
# key_value = ref.split(":")
9+
# if len(key_value) == 2 and key_value[0] == "CWE":
10+
# with contextlib.suppress(ValueError, TypeError):
11+
# return int(key_value[1])
12+
# return 0

dojo/tools/tenable/xml_format.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,15 @@ def get_findings(self, filename: str, test: Test) -> list:
199199
if cwe_element_text is not None:
200200
cwe = cwe_element_text
201201

202+
# parsing and storing the CWE would affect dedupe/hash_codes, commentint out for now
203+
# if not cwe:
204+
# for ref in item.iter("xref"):
205+
# ref_text = self.safely_get_element_text(ref)
206+
# if ref_text is not None:
207+
# cwe = parse_cwe_from_ref(ref_text)
208+
# if cwe > 0:
209+
# break
210+
202211
cvssv3 = None
203212
cvssv3_element_text = self.safely_get_element_text(
204213
item.find("cvss3_vector"),

tests/import_scanner_test.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# ruff: noqa: F821
21
import logging
32
import os
43
import re
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
Plugin ID,CVE,CVSS v2.0 Base Score,Risk,Host,Protocol,Port,Name,Synopsis,Description,Solution,See Also,Plugin Output,STIG Severity,CVSS v4.0 Base Score,CVSS v4.0 Base+Threat Score,CVSS v3.0 Base Score,CVSS v2.0 Temporal Score,CVSS v3.0 Temporal Score,VPR Score,EPSS Score,Risk Factor,BID,XREF,MSKB,Plugin Publication Date,Plugin Modification Date,Metasploit,Core Impact,CANVAS
2+
42873,CVE-2016-2183,50,High,192.168.0.100,tcp,3389,SSL Medium Strength Cipher Suites Supported (SWEET32),The remote service supports the use of medium strength SSL ciphers.,"The remote host supports the use of SSL ciphers that offer medium
3+
strength encryption. Nessus regards medium strength as any encryption
4+
that uses key lengths at least 64 bits and less than 112 bits, or
5+
else that uses the 3DES encryption suite.
6+
7+
Note that it is considerably easier to circumvent medium strength
8+
encryption if the attacker is on the same physical network.","Reconfigure the affected application if possible to avoid use of
9+
medium strength ciphers.","http://www.nessus.org/u?df5555f5
10+
https://sweet32.info","Medium Strength Ciphers (> 64-bit and < 112-bit key, or 3DES)
11+
12+
Name Code KEX Auth Encryption MAC
13+
---------------------- ---------- --- ---- --------------------- ---
14+
DES-CBC3-SHA 0x00, 0x0A RSA RSA 3DES-CBC(168) SHA1
15+
16+
The fields above are :
17+
18+
{Tenable ciphername}
19+
{Cipher ID code}
20+
Kex={key exchange}
21+
Auth={authentication}
22+
Encrypt={symmetric encryption method}
23+
MAC={message authentication code}
24+
{export flag}",,,,75,,,51,3833,Medium,,,,23/11/2009,12/02/2025,,,
25+
11213,CVE-2003-1567,50,Medium,192.168.0.100,tcp,443,HTTP TRACE / TRACK Methods Allowed,Debugging functions are enabled on the remote web server.,"The remote web server supports the TRACE and/or TRACK methods. TRACE
26+
and TRACK are HTTP methods that are used to debug web server
27+
connections.",Disable these HTTP methods. Refer to the plugin output for more information.,"http://www.nessus.org/u?e979b5cb
28+
http://www.apacheweek.com/issues/03-01-24
29+
https://download.oracle.com/sunalerts/1000718.1.html","To disable these methods, add the following lines for each virtual
30+
host in your configuration file :
31+
32+
RewriteEngine on
33+
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
34+
RewriteRule .* - [F]
35+
36+
Alternatively, note that Apache versions 1.3.34, 2.0.55, and 2.2
37+
support disabling the TRACE method natively via the 'TraceEnable'
38+
directive.
39+
40+
Nessus sent the following TRACE request : \n\n------------------------------ snip ------------------------------\nTRACE /Nessus2034861839.html HTTP/1.1
41+
Connection: Close
42+
Host: 192.168.0.100
43+
Pragma: no-cache
44+
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
45+
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*
46+
Accept-Language: en
47+
Accept-Charset: iso-8859-1,*,utf-8
48+
49+
------------------------------ snip ------------------------------\n\nand received the following response from the remote server :\n\n------------------------------ snip ------------------------------\nHTTP/1.1 200 OK
50+
Date: Tue, 01 Apr 2025 07:32:30 GMT
51+
Server: Apache/2.4.37 (rocky) OpenSSL/1.1.1k
52+
Keep-Alive: timeout=5, max=100
53+
Connection: Keep-Alive
54+
Transfer-Encoding: chunked
55+
Content-Type: message/http
56+
57+
58+
TRACE /Nessus2034861839.html HTTP/1.1
59+
Connection: Keep-Alive
60+
Host: 192.168.0.101
61+
Pragma: no-cache
62+
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
63+
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*
64+
Accept-Language: en
65+
Accept-Charset: iso-8859-1,*,utf-8
66+
67+
------------------------------ snip ------------------------------\n",,,,53,37,46,40,8269,Medium,9506;9561;11604;33374;37995,CERT:288308;CERT:867593;CWE:16;CWE:200,,23/01/2003,09/04/2024,,,
68+
187315,CVE-2023-48795,54,Medium,192.168.0.100,tcp,22,SSH Terrapin Prefix Truncation Weakness (CVE-2023-48795),The remote SSH server is vulnerable to a mitm prefix truncation attack.,"The remote SSH server is vulnerable to a man-in-the-middle prefix truncation weakness known as Terrapin. This can
69+
allow a remote, man-in-the-middle attacker to bypass integrity checks and downgrade the connection's security.
70+
71+
Note that this plugin only checks for remote SSH servers that support either ChaCha20-Poly1305 or CBC with
72+
Encrypt-then-MAC and do not support the strict key exchange countermeasures. It does not check for vulnerable software
73+
versions.",Contact the vendor for an update with the strict key exchange countermeasures or disable the affected algorithms.,https://terrapin-attack.com/,"Supports following ChaCha20-Poly1305 Client to Server algorithm : [email protected]
74+
Supports following Encrypt-then-MAC Client to Server algorithm : [email protected]
75+
Supports following Encrypt-then-MAC Client to Server algorithm : [email protected]
76+
Supports following Encrypt-then-MAC Client to Server algorithm : [email protected]
77+
Supports following Encrypt-then-MAC Client to Server algorithm : [email protected]
78+
Supports following Encrypt-then-MAC Client to Server algorithm : [email protected]
79+
Supports following ChaCha20-Poly1305 Server to Client algorithm : [email protected]
80+
Supports following Encrypt-then-MAC Server to Client algorithm : [email protected]
81+
Supports following Encrypt-then-MAC Server to Client algorithm : [email protected]
82+
Supports following Encrypt-then-MAC Server to Client algorithm : [email protected]
83+
Supports following Encrypt-then-MAC Server to Client algorithm : [email protected]
84+
Supports following Encrypt-then-MAC Server to Client algorithm : [email protected]",,,,59,42,53,61,7957,Medium,,,,27/12/2023,29/01/2024,,,
85+
200162,CVE-2024-4577,100,Critical,192.168.0.101,tcp,8080,PHP 8.2.x < 8.2.20 Multiple Vulnerabilities,The version PHP running on the remote web server is affected by multiple vulnerabilities.,"The version of PHP installed on the remote host is prior to 8.2.20. It is, therefore, affected by multiple
86+
vulnerabilities as referenced in the Version 8.2.20 advisory.
87+
88+
- In PHP versions 8.1.* before 8.1.29, 8.2.* before 8.2.20, 8.3.* before 8.3.8, when using Apache and PHP-
89+
CGI on Windows, if the system is set up to use certain code pages, Windows may use Best-Fit behavior to
90+
replace characters in command line given to Win32 API functions. PHP CGI module may misinterpret those
91+
characters as PHP options, which may allow a malicious user to pass options to PHP binary being run, and
92+
thus reveal the source code of scripts, run arbitrary PHP code on the server, etc. (CVE-2024-4577)
93+
94+
- In PHP versions 8.1.* before 8.1.29, 8.2.* before 8.2.20, 8.3.* before 8.3.8, due to a code logic error,
95+
filtering functions such as filter_var when validating URLs (FILTER_VALIDATE_URL) for certain types of
96+
URLs the function will result in invalid user information (username + password part of URLs) being treated
97+
as valid user information. This may lead to the downstream code accepting invalid URLs as valid and
98+
parsing them incorrectly. (CVE-2024-5458)
99+
100+
- In PHP versions 8.1.* before 8.1.29, 8.2.* before 8.2.20, 8.3.* before 8.3.8, the fix for CVE-2024-1874
101+
does not work if the command name includes trailing spaces. Original issue: when using proc_open() command
102+
with array syntax, due to insufficient escaping, if the arguments of the executed command are controlled
103+
by a malicious user, the user can supply arguments that would execute arbitrary commands in Windows shell.
104+
(CVE-2024-5585)
105+
106+
Note that Nessus has not tested for these issues but has instead relied only on the application's self-reported version
107+
number.",Upgrade to PHP version 8.2.20 or later.,http://php.net/ChangeLog-8.php#8.2.20,"URL : http://192.168.0.101:8080/ (8.2.18 under X-Powered-By: PHP/8.2.18)
108+
Installed version : 8.2.18
109+
Fixed version : 8.2.20",I,,,98,87,94,96,9438,Critical,,CISA-KNOWN-EXPLOITED:2024/07/03;IAVA:2024-A-0330-S,,06/06/2024,23/10/2024,TRUE,TRUE,TRUE
110+
200798,CVE-2024-23443,61,Medium,192.168.0.101,tcp,5601,Kibana < 7.17.22 / 8.0.x < 8.14 (ESA-2024-11),The remote host is missing a security update.,"The version of Kibana installed on the remote host is prior to 7.17.22 or 8.14. It is, therefore, affected by a
111+
vulnerability as referenced in the ESA-2024-11 advisory.
112+
113+
- A high-privileged user, allowed to create custom osquery packs 17 could affect the availability of Kibana
114+
by uploading a maliciously crafted osquery pack.
115+
116+
Note that Nessus has not tested for this issue but has instead relied only on the application's self-reported version
117+
number.",Upgrade to Kibana version 7.17.22 / 8.14 or later.,http://www.nessus.org/u?064dcada,"URL : https://192.168.0.101:5601/
118+
Installed version : 7.13.2
119+
Fixed version : 7.17.22",II,,,49,45,43,36,2783,Medium,,IAVB:2024-B-0080-S,,21/06/2024,20/8/2024,,,

unittests/tools/test_tenable_parser.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
from dojo.models import Engagement, Finding, Product, Test
23
from dojo.tools.tenable.parser import TenableParser
34
from unittests.dojo_test_case import DojoTestCase, get_unit_tests_scans_path
@@ -100,6 +101,32 @@ def test_parse_some_findings_csv2_all_nessus_legacy(self):
100101
self.assertEqual(1, len(finding.unsaved_vulnerability_ids))
101102
self.assertEqual("CVE-2004-2761", finding.unsaved_vulnerability_ids[0])
102103

104+
def test_parse_findings_all_nessus(self):
105+
"""Test that use a report with all columns selected in generate CSV Report 2025-04-14"""
106+
with open(get_unit_tests_scans_path("tenable/nessus") / "nessus-template.csv", encoding="utf-8") as testfile:
107+
parser = TenableParser()
108+
findings = parser.get_findings(testfile, self.create_test())
109+
for finding in findings:
110+
for endpoint in finding.unsaved_endpoints:
111+
endpoint.clean()
112+
self.assertEqual(5, len(findings))
113+
finding = findings[0]
114+
self.assertEqual("SSL Medium Strength Cipher Suites Supported (SWEET32)", finding.title)
115+
self.assertIn(finding.severity, Finding.SEVERITIES)
116+
self.assertEqual("High", finding.severity)
117+
self.assertEqual(1, len(finding.unsaved_vulnerability_ids))
118+
self.assertEqual(["CVE-2016-2183"], finding.unsaved_vulnerability_ids)
119+
self.assertEqual(0, finding.cwe)
120+
self.assertEqual(0.3833, finding.epss_score)
121+
finding = findings[1]
122+
self.assertEqual("HTTP TRACE / TRACK Methods Allowed", finding.title)
123+
self.assertIn(finding.severity, Finding.SEVERITIES)
124+
self.assertEqual("Medium", finding.severity)
125+
self.assertEqual(["CVE-2003-1567"], finding.unsaved_vulnerability_ids)
126+
self.assertEqual(0, finding.cwe)
127+
# self.assertEqual(16, finding.cwe)
128+
self.assertEqual(0.8269, finding.epss_score)
129+
103130
def test_parse_some_findings_csv_bytes_nessus_legacy(self):
104131
"""This tests is designed to test the parser with different read modes"""
105132
with open(get_unit_tests_scans_path("tenable/nessus") / "nessus_many_vuln2-all.csv", encoding="utf-8") as testfile:
@@ -180,9 +207,12 @@ def test_parse_many_findings_xml_nessus_was_legacy(self):
180207
finding = findings[i]
181208
self.assertEqual("http", finding.unsaved_endpoints[0].protocol)
182209
self.assertIsNone(finding.cwe)
210+
183211
finding = findings[0]
184212
self.assertEqual("High", finding.severity)
185213
self.assertEqual("Cross-Site Scripting (XSS)", finding.title)
214+
self.assertEqual(None, finding.cwe)
215+
# self.assertEqual(79, finding.cwe)
186216

187217
def test_parse_one_findings_xml_nessus_was_legacy(self):
188218
with open(get_unit_tests_scans_path("tenable/nessus_was") / "nessus_was_one_vuln.xml", encoding="utf-8") as testfile:
@@ -194,7 +224,8 @@ def test_parse_one_findings_xml_nessus_was_legacy(self):
194224
self.assertEqual(1, len(findings))
195225
finding = findings[0]
196226
self.assertEqual("http", finding.unsaved_endpoints[0].protocol)
197-
self.assertIsNone(finding.cwe)
227+
self.assertEqual(None, finding.cwe)
228+
# self.assertEqual(79, finding.cwe)
198229
self.assertEqual("High", finding.severity)
199230
self.assertEqual("Cross-Site Scripting (XSS)", finding.title)
200231

@@ -224,6 +255,7 @@ def test_parse_many_findings_csv_nessus_was_legacy(self):
224255
self.assertEqual("7.1", finding.cvssv3_score)
225256
self.assertEqual("High", finding.severity)
226257
self.assertEqual("http", finding.unsaved_endpoints[0].protocol)
258+
self.assertEqual(0, finding.cwe)
227259

228260
def test_parse_one_findings_csv_nessus_was_legacy(self):
229261
with open(get_unit_tests_scans_path("tenable/nessus_was") / "nessus_was_one_vuln.csv", encoding="utf-8") as testfile:
@@ -318,6 +350,7 @@ def test_parse_issue_11127(self):
318350
reference = """https://www.openssl.org/blog/blog/2016/08/24/sweet32/
319351
https://sweet32.info
320352
Tenable Plugin ID: 42873
353+
Plugin Information: N/A
321354
Plugin Publication Date: Nov 23, 2009 12:00:00 UTC
322355
Plugin Modification Date: Feb 3, 2021 12:00:00 UTC"""
323356
self.assertEqual(reference, findings[0].references)

0 commit comments

Comments
 (0)