regscale-cli 6.20.9.1__py3-none-any.whl → 6.21.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of regscale-cli might be problematic. Click here for more details.
- regscale/_version.py +1 -1
- regscale/core/app/application.py +12 -5
- regscale/core/app/internal/set_permissions.py +58 -27
- regscale/integrations/commercial/defender.py +9 -0
- regscale/integrations/commercial/nessus/scanner.py +2 -0
- regscale/integrations/commercial/sonarcloud.py +35 -36
- regscale/integrations/commercial/synqly/ticketing.py +51 -0
- regscale/integrations/commercial/wizv2/async_client.py +325 -0
- regscale/integrations/commercial/wizv2/constants.py +756 -0
- regscale/integrations/commercial/wizv2/scanner.py +1301 -89
- regscale/integrations/commercial/wizv2/utils.py +280 -36
- regscale/integrations/commercial/wizv2/variables.py +2 -10
- regscale/integrations/integration_override.py +15 -6
- regscale/integrations/scanner_integration.py +221 -37
- regscale/integrations/variables.py +1 -0
- regscale/models/integration_models/amazon_models/inspector_scan.py +32 -57
- regscale/models/integration_models/aqua.py +92 -78
- regscale/models/integration_models/cisa_kev_data.json +47 -4
- regscale/models/integration_models/defenderimport.py +64 -59
- regscale/models/integration_models/ecr_models/ecr.py +100 -147
- regscale/models/integration_models/flat_file_importer/__init__.py +52 -38
- regscale/models/integration_models/ibm.py +29 -47
- regscale/models/integration_models/nexpose.py +156 -68
- regscale/models/integration_models/prisma.py +46 -66
- regscale/models/integration_models/qualys.py +99 -93
- regscale/models/integration_models/snyk.py +229 -158
- regscale/models/integration_models/synqly_models/capabilities.json +1 -1
- regscale/models/integration_models/veracode.py +15 -20
- regscale/models/integration_models/xray.py +276 -82
- regscale/models/regscale_models/__init__.py +13 -0
- regscale/models/regscale_models/classification.py +23 -0
- regscale/models/regscale_models/control_implementation.py +14 -12
- regscale/models/regscale_models/cryptography.py +56 -0
- regscale/models/regscale_models/deviation.py +4 -4
- regscale/models/regscale_models/group.py +3 -2
- regscale/models/regscale_models/interconnection.py +1 -1
- regscale/models/regscale_models/issue.py +140 -41
- regscale/models/regscale_models/milestone.py +40 -0
- regscale/models/regscale_models/property.py +0 -1
- regscale/models/regscale_models/rbac.py +22 -0
- regscale/models/regscale_models/regscale_model.py +29 -18
- regscale/models/regscale_models/team.py +55 -0
- {regscale_cli-6.20.9.1.dist-info → regscale_cli-6.21.0.0.dist-info}/METADATA +1 -1
- {regscale_cli-6.20.9.1.dist-info → regscale_cli-6.21.0.0.dist-info}/RECORD +56 -49
- tests/fixtures/test_fixture.py +58 -2
- tests/regscale/core/test_app.py +5 -3
- tests/regscale/integrations/test_integration_mapping.py +522 -40
- tests/regscale/integrations/test_issue_due_date.py +1 -1
- tests/regscale/integrations/test_property_and_milestone_creation.py +684 -0
- tests/regscale/integrations/test_update_finding_dates.py +336 -0
- tests/regscale/models/test_asset.py +406 -50
- tests/regscale/models/test_report.py +105 -29
- {regscale_cli-6.20.9.1.dist-info → regscale_cli-6.21.0.0.dist-info}/LICENSE +0 -0
- {regscale_cli-6.20.9.1.dist-info → regscale_cli-6.21.0.0.dist-info}/WHEEL +0 -0
- {regscale_cli-6.20.9.1.dist-info → regscale_cli-6.21.0.0.dist-info}/entry_points.txt +0 -0
- {regscale_cli-6.20.9.1.dist-info → regscale_cli-6.21.0.0.dist-info}/top_level.txt +0 -0
|
@@ -2,43 +2,47 @@
|
|
|
2
2
|
Nexpose Scan information
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from pathlib import Path
|
|
6
5
|
from typing import Optional
|
|
7
6
|
|
|
8
7
|
from regscale.core.app.application import Application
|
|
9
8
|
from regscale.core.app.logz import create_logger
|
|
10
|
-
from regscale.core.app.utils.app_utils import epoch_to_datetime,
|
|
9
|
+
from regscale.core.app.utils.app_utils import epoch_to_datetime, is_valid_fqdn
|
|
10
|
+
from regscale.core.utils.date import date_str
|
|
11
|
+
from regscale.integrations.scanner_integration import IntegrationAsset, IntegrationFinding
|
|
11
12
|
from regscale.models import ImportValidater
|
|
12
|
-
from regscale.models.app_models.mapping import Mapping
|
|
13
13
|
from regscale.models.integration_models.flat_file_importer import FlatFileImporter
|
|
14
|
-
from regscale.models.regscale_models import Asset,
|
|
14
|
+
from regscale.models.regscale_models import Asset, IssueSeverity, IssueStatus
|
|
15
15
|
|
|
16
16
|
VULNERABILITY_TITLE = "Vulnerability Title"
|
|
17
17
|
VULNERABILITY_ID = "Vulnerability ID"
|
|
18
18
|
CVSS3_SCORE = "CVSSv3 Score"
|
|
19
|
-
|
|
19
|
+
CVSS2_SCORE = "CVSSv2 Score"
|
|
20
|
+
IP_ADDRESS = "IP_Address"
|
|
21
|
+
FIRST_SEEN = "first_seen"
|
|
22
|
+
SCAN_DATE = "scan_start_time"
|
|
23
|
+
CVE = "CVEs"
|
|
20
24
|
|
|
21
25
|
|
|
22
|
-
class Nexpose(FlatFileImporter):
|
|
26
|
+
class Nexpose(FlatFileImporter): # pylint: disable=too-many-instance-attributes
|
|
23
27
|
"""
|
|
24
|
-
|
|
28
|
+
Nexpose Scan information
|
|
25
29
|
"""
|
|
26
30
|
|
|
27
|
-
def __init__(self, **kwargs):
|
|
31
|
+
def __init__(self, **kwargs): # pylint: disable=R0902
|
|
28
32
|
self.name = kwargs.get("name")
|
|
29
33
|
self.vuln_title = VULNERABILITY_TITLE
|
|
30
34
|
self.vuln_id = VULNERABILITY_ID
|
|
31
35
|
self.cvss3_score = CVSS3_SCORE
|
|
36
|
+
self.first_seen = FIRST_SEEN
|
|
37
|
+
self.scan_date_field = SCAN_DATE
|
|
38
|
+
self.cve = CVE
|
|
32
39
|
self.required_headers = [
|
|
33
|
-
"IP Address",
|
|
34
40
|
"Hostname",
|
|
35
|
-
"OS",
|
|
36
41
|
"Vulnerability Title",
|
|
37
42
|
"Vulnerability ID",
|
|
38
43
|
"CVSSv2 Score",
|
|
39
44
|
"CVSSv3 Score",
|
|
40
45
|
"Description",
|
|
41
|
-
"Proof",
|
|
42
46
|
"Solution",
|
|
43
47
|
"CVEs",
|
|
44
48
|
]
|
|
@@ -60,81 +64,165 @@ class Nexpose(FlatFileImporter):
|
|
|
60
64
|
**kwargs,
|
|
61
65
|
)
|
|
62
66
|
|
|
63
|
-
def create_asset(self, dat: Optional[dict] = None) -> Optional[
|
|
67
|
+
def create_asset(self, dat: Optional[dict] = None) -> Optional[IntegrationAsset]:
|
|
64
68
|
"""
|
|
65
69
|
Create an asset from a row in the Nexpose csv file
|
|
66
70
|
|
|
67
71
|
:param Optional[dict] dat: Data row from CSV file, defaults to None
|
|
68
|
-
:return: RegScale
|
|
69
|
-
:rtype: Optional[
|
|
72
|
+
:return: RegScale IntegrationAsset object, if it has a hostname
|
|
73
|
+
:rtype: Optional[IntegrationAsset]
|
|
70
74
|
"""
|
|
71
75
|
if hostname := self.mapping.get_value(dat, "Hostname"):
|
|
72
|
-
return
|
|
76
|
+
return IntegrationAsset(
|
|
73
77
|
**{
|
|
74
|
-
"id": 0,
|
|
75
78
|
"name": hostname,
|
|
76
|
-
"
|
|
77
|
-
"
|
|
79
|
+
"ip_address": self.mapping.get_value(dat, IP_ADDRESS, "0.0.0.0"),
|
|
80
|
+
"identifier": hostname,
|
|
81
|
+
"other_tracking_number": hostname,
|
|
78
82
|
"status": "Active (On Network)",
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
"
|
|
82
|
-
"scanningTool": self.name,
|
|
83
|
-
"assetOwnerId": self.config["userId"],
|
|
84
|
-
"assetType": "Other",
|
|
83
|
+
"asset_category": "Hardware",
|
|
84
|
+
"asset_type": "Other",
|
|
85
|
+
"scanning_tool": self.name,
|
|
85
86
|
"fqdn": hostname if is_valid_fqdn(hostname) else None,
|
|
86
|
-
"
|
|
87
|
-
"systemAdministratorId": self.config["userId"],
|
|
88
|
-
"parentId": self.attributes.parent_id,
|
|
89
|
-
"parentModule": self.attributes.parent_module,
|
|
87
|
+
"operating_system": Asset.find_os(self.mapping.get_value(dat, "OS")),
|
|
90
88
|
}
|
|
91
89
|
)
|
|
90
|
+
return None
|
|
92
91
|
|
|
93
|
-
|
|
92
|
+
@staticmethod
|
|
93
|
+
def determine_severity_from_cvss_score(cvss_score: float, cvss_version: str = "v3") -> IssueSeverity:
|
|
94
94
|
"""
|
|
95
|
-
|
|
95
|
+
Determine CVSS Severity Text from CVSS Base Score
|
|
96
|
+
|
|
97
|
+
:param float cvss_score: CVSS Base Score
|
|
98
|
+
:param str cvss_version: CVSS version ("v2" or "v3"), defaults to "v3"
|
|
99
|
+
:return: CVSS Severity Text
|
|
100
|
+
:rtype: IssueSeverity
|
|
101
|
+
"""
|
|
102
|
+
results = IssueSeverity.Low
|
|
103
|
+
|
|
104
|
+
if cvss_version.lower() == "v3":
|
|
105
|
+
# CVSSv3 severity ranges
|
|
106
|
+
if 4.0 <= cvss_score <= 6.9:
|
|
107
|
+
results = IssueSeverity.Moderate
|
|
108
|
+
elif 7.0 <= cvss_score <= 8.9:
|
|
109
|
+
results = IssueSeverity.High
|
|
110
|
+
elif cvss_score > 8.9:
|
|
111
|
+
results = IssueSeverity.Critical
|
|
112
|
+
elif cvss_version.lower() == "v2":
|
|
113
|
+
# CVSSv2 severity ranges
|
|
114
|
+
if 4.0 <= cvss_score <= 6.9:
|
|
115
|
+
results = IssueSeverity.Moderate
|
|
116
|
+
elif 7.0 <= cvss_score <= 10.0:
|
|
117
|
+
results = IssueSeverity.High
|
|
118
|
+
# CVSSv2 doesn't have a "Critical" category, High is the highest
|
|
119
|
+
|
|
120
|
+
return results
|
|
121
|
+
|
|
122
|
+
def severity_from_text(self, text_severity: str) -> Optional[IssueSeverity]:
|
|
123
|
+
"""
|
|
124
|
+
Determine severity from text severity
|
|
125
|
+
|
|
126
|
+
:param str text_severity: Text severity
|
|
127
|
+
:return: IssueSeverity or None
|
|
128
|
+
:rtype: Optional[IssueSeverity]
|
|
129
|
+
"""
|
|
130
|
+
if text_severity.lower() == "low":
|
|
131
|
+
return IssueSeverity.Low
|
|
132
|
+
if text_severity.lower() in ["medium", "moderate"]:
|
|
133
|
+
return IssueSeverity.Moderate
|
|
134
|
+
if text_severity.lower() == "high":
|
|
135
|
+
return IssueSeverity.High
|
|
136
|
+
if text_severity.lower() in ["critical", "severe"]:
|
|
137
|
+
return IssueSeverity.Critical
|
|
138
|
+
return None
|
|
139
|
+
|
|
140
|
+
def _determine_severity(self, dat: Optional[dict] = None) -> IssueSeverity:
|
|
141
|
+
"""
|
|
142
|
+
Determine severity using the priority order: text severity > CVSSv3 > CVSSv2 > default
|
|
143
|
+
|
|
144
|
+
:param Optional[dict] dat: Data row from CSV file, defaults to None
|
|
145
|
+
:return: Determined IssueSeverity
|
|
146
|
+
:rtype: IssueSeverity
|
|
147
|
+
"""
|
|
148
|
+
# Default severity
|
|
149
|
+
severity = IssueSeverity.Low
|
|
150
|
+
|
|
151
|
+
# Extract CVSS scores
|
|
152
|
+
cvss3_score = self.mapping.get_value(dat, self.cvss3_score) or 0.0
|
|
153
|
+
cvss2_score = self.mapping.get_value(dat, CVSS2_SCORE) or 0.0
|
|
154
|
+
|
|
155
|
+
# Priority 1: Check for text-based severity (client-specific)
|
|
156
|
+
# This is client specific, need to be able to override the severity source
|
|
157
|
+
text_severity = self.severity_from_text(
|
|
158
|
+
self.mapping.get_value(dat, "adobe_severity")
|
|
159
|
+
) or self.severity_from_text(self.mapping.get_value(dat, "nexpose_severity"))
|
|
160
|
+
|
|
161
|
+
if text_severity:
|
|
162
|
+
severity = text_severity
|
|
163
|
+
else:
|
|
164
|
+
# Priority 2: Use CVSSv3 score if available and valid
|
|
165
|
+
if cvss3_score and cvss3_score > 0:
|
|
166
|
+
severity = self.determine_severity_from_cvss_score(float(cvss3_score), "v3")
|
|
167
|
+
# Priority 3: Fall back to CVSSv2 score if available and valid
|
|
168
|
+
elif cvss2_score and cvss2_score > 0:
|
|
169
|
+
severity = self.determine_severity_from_cvss_score(float(cvss2_score), "v2")
|
|
170
|
+
|
|
171
|
+
return severity
|
|
172
|
+
|
|
173
|
+
def create_vuln(self, dat: Optional[dict] = None, **kwargs) -> Optional[IntegrationFinding]:
|
|
174
|
+
"""
|
|
175
|
+
Create an IntegrationFinding from a row in the Prisma/Nexpose csv file
|
|
96
176
|
|
|
97
177
|
:param Optional[dict] dat: Data row from CSV file, defaults to None
|
|
98
|
-
:
|
|
99
|
-
:
|
|
178
|
+
:param kwargs: Additional keyword arguments
|
|
179
|
+
:return: RegScale IntegrationFinding object or None
|
|
180
|
+
:rtype: Optional[IntegrationFinding]
|
|
100
181
|
"""
|
|
101
|
-
|
|
102
|
-
|
|
182
|
+
regscale_finding = None
|
|
183
|
+
|
|
184
|
+
# Extract basic data
|
|
103
185
|
hostname: str = self.mapping.get_value(dat, "Hostname")
|
|
104
|
-
os: str = self.mapping.get_value(dat, "OS")
|
|
105
186
|
description: str = self.mapping.get_value(dat, "Description")
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
title=description[:255],
|
|
187
|
+
cvss3_score = self.mapping.get_value(dat, self.cvss3_score) or 0.0
|
|
188
|
+
|
|
189
|
+
# Determine severity using priority logic
|
|
190
|
+
severity = self._determine_severity(dat)
|
|
191
|
+
|
|
192
|
+
# Find matching asset
|
|
193
|
+
|
|
194
|
+
# Extract date information
|
|
195
|
+
first_seen = (
|
|
196
|
+
self.mapping.get_value(dat, self.first_seen)
|
|
197
|
+
or self.mapping.get_value(dat, "first_seen")
|
|
198
|
+
or epoch_to_datetime(self.create_epoch)
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
if scan_date := self.mapping.get_value(dat, SCAN_DATE):
|
|
202
|
+
self.scan_date = scan_date
|
|
203
|
+
cvss_score = self.mapping.get_value(dat, CVSS2_SCORE)
|
|
204
|
+
|
|
205
|
+
# Create IntegrationFinding if we have valid data and asset match
|
|
206
|
+
if dat:
|
|
207
|
+
return IntegrationFinding(
|
|
208
|
+
control_labels=[], # Add an empty list for control_labels
|
|
209
|
+
title=self.mapping.get_value(dat, self.vuln_title),
|
|
130
210
|
description=description,
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
211
|
+
cve=self.mapping.get_value(dat, self.cve, "").upper(),
|
|
212
|
+
severity=severity,
|
|
213
|
+
asset_identifier=hostname,
|
|
214
|
+
plugin_name=self.mapping.get_value(dat, self.vuln_title),
|
|
215
|
+
plugin_id=str(self.mapping.get_value(dat, self.vuln_id)),
|
|
216
|
+
cvss_score=cvss_score or 0.0,
|
|
217
|
+
cvss_v3_score=cvss3_score or 0.0,
|
|
218
|
+
cvss_v2_score=cvss_score or 0.0,
|
|
219
|
+
plugin_text=description[:255],
|
|
220
|
+
remediation=self.mapping.get_value(dat, "Solution"),
|
|
221
|
+
category="Hardware",
|
|
222
|
+
status=IssueStatus.Open,
|
|
223
|
+
first_seen=self.scan_date or date_str(first_seen),
|
|
224
|
+
scan_date=date_str(scan_date) or self.scan_date,
|
|
225
|
+
vulnerability_type="Vulnerability Scan",
|
|
226
|
+
baseline=f"{self.name} Host",
|
|
139
227
|
)
|
|
140
|
-
return
|
|
228
|
+
return regscale_finding
|
|
@@ -10,11 +10,10 @@ from typing import Any, List, Optional
|
|
|
10
10
|
from regscale.core.app.application import Application
|
|
11
11
|
from regscale.core.app.logz import create_logger
|
|
12
12
|
from regscale.core.app.utils.app_utils import epoch_to_datetime, get_current_datetime, is_valid_fqdn
|
|
13
|
+
from regscale.integrations.scanner_integration import IntegrationAsset, IntegrationFinding
|
|
13
14
|
from regscale.models import ImportValidater
|
|
14
15
|
from regscale.models.integration_models.flat_file_importer import FlatFileImporter
|
|
15
|
-
from regscale.models.regscale_models import SoftwareInventory
|
|
16
|
-
from regscale.models.regscale_models.asset import Asset
|
|
17
|
-
from regscale.models.regscale_models.vulnerability import Vulnerability
|
|
16
|
+
from regscale.models.regscale_models import Asset, IssueSeverity, IssueStatus, SoftwareInventory, Vulnerability
|
|
18
17
|
|
|
19
18
|
FIX_STATUS = "Fix Status"
|
|
20
19
|
VULNERABILITY_ID = "Vulnerability ID"
|
|
@@ -38,7 +37,7 @@ class Prisma(FlatFileImporter):
|
|
|
38
37
|
|
|
39
38
|
def __init__(self, **kwargs):
|
|
40
39
|
self.name = kwargs.get("name")
|
|
41
|
-
regscale_ssp_id = kwargs.get("
|
|
40
|
+
regscale_ssp_id = kwargs.get("object_id")
|
|
42
41
|
self.image_name = "Id"
|
|
43
42
|
self.vuln_title = CVE_ID
|
|
44
43
|
self.cvss3_score = "CVSS"
|
|
@@ -63,94 +62,75 @@ class Prisma(FlatFileImporter):
|
|
|
63
62
|
ignore_validation=True,
|
|
64
63
|
**kwargs,
|
|
65
64
|
)
|
|
66
|
-
self.create_software_inventory()
|
|
65
|
+
# self.create_software_inventory()
|
|
67
66
|
|
|
68
|
-
def create_asset(self, dat: Optional[dict] = None) ->
|
|
67
|
+
def create_asset(self, dat: Optional[dict] = None) -> IntegrationAsset:
|
|
69
68
|
"""
|
|
70
69
|
Create an asset from a row in the Prisma csv file
|
|
71
70
|
|
|
72
71
|
:param Optional[dict] dat: Data row from CSV file, defaults to None
|
|
73
|
-
:return: RegScale
|
|
74
|
-
:rtype:
|
|
72
|
+
:return: RegScale IntegrationAsset object
|
|
73
|
+
:rtype: IntegrationAsset
|
|
75
74
|
"""
|
|
76
75
|
hostname = self.mapping.get_value(dat, "Hostname")
|
|
77
76
|
distro = self.mapping.get_value(dat, "Distro")
|
|
78
77
|
|
|
79
|
-
return
|
|
78
|
+
return IntegrationAsset(
|
|
80
79
|
**{
|
|
81
|
-
"id": 0,
|
|
82
80
|
"name": hostname,
|
|
83
|
-
"
|
|
84
|
-
"
|
|
81
|
+
"ip_address": self.mapping.get_value(dat, "IP Address"),
|
|
82
|
+
"identifier": hostname,
|
|
83
|
+
"other_tracking_number": hostname,
|
|
85
84
|
"status": "Active (On Network)",
|
|
86
|
-
"
|
|
87
|
-
"
|
|
88
|
-
"
|
|
89
|
-
"scanningTool": self.name,
|
|
90
|
-
"assetOwnerId": self.config["userId"],
|
|
91
|
-
"assetType": "Other",
|
|
85
|
+
"asset_category": "Hardware",
|
|
86
|
+
"asset_type": "Other",
|
|
87
|
+
"scanning_tool": self.name,
|
|
92
88
|
"fqdn": hostname if is_valid_fqdn(hostname) else None,
|
|
93
|
-
"
|
|
94
|
-
"systemAdministratorId": self.config["userId"],
|
|
95
|
-
"parentId": self.attributes.parent_id,
|
|
96
|
-
"parentModule": self.attributes.parent_module,
|
|
89
|
+
"operating_system": Asset.find_os(distro),
|
|
97
90
|
}
|
|
98
91
|
)
|
|
99
92
|
|
|
100
|
-
def create_vuln(self, dat: Optional[dict] = None, **kwargs) -> Optional[
|
|
93
|
+
def create_vuln(self, dat: Optional[dict] = None, **kwargs) -> Optional[IntegrationFinding]:
|
|
101
94
|
"""
|
|
102
|
-
Create a
|
|
95
|
+
Create a IntegrationFinding from a row in the Prisma csv file
|
|
103
96
|
|
|
104
97
|
:param Optional[dict] dat: Data row from CSV file, defaults to None
|
|
105
|
-
:return: RegScale
|
|
106
|
-
:rtype: Optional[
|
|
98
|
+
:return: RegScale IntegrationFinding object or None
|
|
99
|
+
:rtype: Optional[IntegrationFinding]
|
|
107
100
|
"""
|
|
108
101
|
cvss3_score = self.mapping.get_value(dat, self.cvss3_score)
|
|
109
102
|
hostname: str = self.mapping.get_value(dat, "Hostname")
|
|
110
|
-
distro: str = self.mapping.get_value(dat, "Distro")
|
|
111
103
|
cve: str = self.mapping.get_value(dat, CVE_ID)
|
|
112
104
|
description: str = self.mapping.get_value(dat, "Description")
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
lastSeen=epoch_to_datetime(self.create_epoch),
|
|
127
|
-
firstSeen=epoch_to_datetime(self.create_epoch),
|
|
128
|
-
daysOpen=None,
|
|
129
|
-
dns=hostname,
|
|
130
|
-
mitigated=None,
|
|
131
|
-
operatingSystem=(Asset.find_os(distro) if Asset.find_os(distro) else None),
|
|
105
|
+
regscale_finding: Optional[IntegrationFinding] = None
|
|
106
|
+
severity = (
|
|
107
|
+
self.determine_severity(Vulnerability.determine_cvss3_severity_text(float(cvss3_score)))
|
|
108
|
+
if cvss3_score
|
|
109
|
+
else IssueSeverity.NotAssigned
|
|
110
|
+
)
|
|
111
|
+
seen = epoch_to_datetime(self.create_epoch)
|
|
112
|
+
if dat:
|
|
113
|
+
return IntegrationFinding(
|
|
114
|
+
control_labels=[], # Add an empty list for control_labels
|
|
115
|
+
title=self.mapping.get_value(dat, self.vuln_title),
|
|
116
|
+
description=description,
|
|
117
|
+
cve=cve.upper(),
|
|
132
118
|
severity=severity,
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
),
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
lastUpdatedById=config["userId"],
|
|
147
|
-
dateCreated=get_current_datetime(),
|
|
148
|
-
extra_data={
|
|
149
|
-
"solution": self.mapping.get_value(dat, FIX_STATUS),
|
|
150
|
-
"proof": self.mapping.get_value(dat, FIX_STATUS),
|
|
151
|
-
},
|
|
119
|
+
asset_identifier=hostname,
|
|
120
|
+
plugin_name=self.mapping.get_value(dat, self.vuln_title),
|
|
121
|
+
plugin_id=self.mapping.get_value(dat, VULNERABILITY_ID),
|
|
122
|
+
cvss_v3_score=cvss3_score or 0.0,
|
|
123
|
+
plugin_text=description[:255],
|
|
124
|
+
remediation=self.mapping.get_value(dat, "Solution"),
|
|
125
|
+
category="Hardware",
|
|
126
|
+
status=IssueStatus.Open,
|
|
127
|
+
first_seen=seen,
|
|
128
|
+
scan_date=seen,
|
|
129
|
+
vulnerability_type="Vulnerability Scan",
|
|
130
|
+
baseline=f"{self.name} Host",
|
|
131
|
+
recommendation_for_mitigation=self.mapping.get_value(dat, FIX_STATUS),
|
|
152
132
|
)
|
|
153
|
-
return
|
|
133
|
+
return regscale_finding
|
|
154
134
|
|
|
155
135
|
def create_software_inventory(self) -> List[SoftwareInventory]:
|
|
156
136
|
"""
|