check-msdefender 1.1.13__py3-none-any.whl → 1.1.15__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.
- check_msdefender/__init__.py +1 -1
- check_msdefender/core/nagios.py +1 -4
- check_msdefender/services/products_service.py +30 -17
- {check_msdefender-1.1.13.dist-info → check_msdefender-1.1.15.dist-info}/METADATA +5 -4
- {check_msdefender-1.1.13.dist-info → check_msdefender-1.1.15.dist-info}/RECORD +8 -8
- {check_msdefender-1.1.13.dist-info → check_msdefender-1.1.15.dist-info}/WHEEL +1 -1
- {check_msdefender-1.1.13.dist-info → check_msdefender-1.1.15.dist-info}/entry_points.txt +0 -0
- {check_msdefender-1.1.13.dist-info → check_msdefender-1.1.15.dist-info}/licenses/LICENSE +0 -0
check_msdefender/__init__.py
CHANGED
check_msdefender/core/nagios.py
CHANGED
|
@@ -129,12 +129,9 @@ class NagiosPlugin:
|
|
|
129
129
|
DefenderSummary(details),
|
|
130
130
|
)
|
|
131
131
|
|
|
132
|
-
# Set verbosity
|
|
133
|
-
check.verbosity = verbose
|
|
134
|
-
|
|
135
132
|
# Run check and return exit code instead of exiting
|
|
136
133
|
try:
|
|
137
|
-
check.main()
|
|
134
|
+
check.main(verbose=verbose)
|
|
138
135
|
return 0 # If main() doesn't exit, it's OK
|
|
139
136
|
except SystemExit as e:
|
|
140
137
|
return int(e.code) if e.code is not None else 0
|
|
@@ -6,6 +6,7 @@ from datetime import datetime
|
|
|
6
6
|
from check_msdefender.core.exceptions import ValidationError
|
|
7
7
|
from check_msdefender.core.logging_config import get_verbose_logger
|
|
8
8
|
|
|
9
|
+
|
|
9
10
|
class DetailObject:
|
|
10
11
|
def __init__(self, software: str, data: str, score: int):
|
|
11
12
|
self.software = software
|
|
@@ -13,6 +14,7 @@ class DetailObject:
|
|
|
13
14
|
self.score = score
|
|
14
15
|
self.paths: list[str] = []
|
|
15
16
|
|
|
17
|
+
|
|
16
18
|
class ProductsService:
|
|
17
19
|
"""Service for checking installed products on machines."""
|
|
18
20
|
|
|
@@ -55,7 +57,7 @@ class ProductsService:
|
|
|
55
57
|
product for product in all_products if product.get("deviceId") == target_machine_id
|
|
56
58
|
]
|
|
57
59
|
|
|
58
|
-
self.logger.info(f"Found {len(products)}
|
|
60
|
+
self.logger.info(f"Found {len(products)} vulnerabilities for machine {target_dns_name}")
|
|
59
61
|
|
|
60
62
|
# Group vulnerabilities by software
|
|
61
63
|
software_vulnerabilities = {}
|
|
@@ -80,7 +82,7 @@ class ProductsService:
|
|
|
80
82
|
"paths": set(),
|
|
81
83
|
"registryPaths": set(),
|
|
82
84
|
"max_cvss": 0,
|
|
83
|
-
"severities":
|
|
85
|
+
"severities": [],
|
|
84
86
|
}
|
|
85
87
|
|
|
86
88
|
cve_info = {"cve_id": cve_id, "severity": severity}
|
|
@@ -90,7 +92,7 @@ class ProductsService:
|
|
|
90
92
|
software_vulnerabilities[software_key]["max_cvss"] = max(
|
|
91
93
|
software_vulnerabilities[software_key]["max_cvss"], cvss_score
|
|
92
94
|
)
|
|
93
|
-
software_vulnerabilities[software_key]["severities"].
|
|
95
|
+
software_vulnerabilities[software_key]["severities"].append(severity)
|
|
94
96
|
|
|
95
97
|
# Count vulnerabilities by severity
|
|
96
98
|
critical_count = 0
|
|
@@ -119,11 +121,9 @@ class ProductsService:
|
|
|
119
121
|
details = []
|
|
120
122
|
total_score = 0
|
|
121
123
|
if software_vulnerabilities:
|
|
122
|
-
summary_line = f"{len(products)} total CVEs (Critical: {critical_count}, High: {high_count}, Medium: {medium_count}, Low: {low_count}), {len(vulnerable_software)} vulnerable software"
|
|
123
|
-
details.append(summary_line)
|
|
124
124
|
|
|
125
125
|
detail_objects = []
|
|
126
|
-
|
|
126
|
+
|
|
127
127
|
# Add software details
|
|
128
128
|
for software in list(software_vulnerabilities.values()):
|
|
129
129
|
score = 0
|
|
@@ -131,7 +131,15 @@ class ProductsService:
|
|
|
131
131
|
cve_count = len(software["cves"])
|
|
132
132
|
unique_cves = list(set(cve["cve_id"] for cve in software["cves"]))
|
|
133
133
|
cve_list = ", ".join(unique_cves[:5]) # Show first 5 CVEs
|
|
134
|
-
severities = "
|
|
134
|
+
severities = ""
|
|
135
|
+
# Count severities
|
|
136
|
+
severity_counts = {"Critical": 0, "High": 0, "Medium": 0, "Low": 0}
|
|
137
|
+
for sev in software["severities"]:
|
|
138
|
+
severity_counts[sev] += 1
|
|
139
|
+
severities = ", ".join(
|
|
140
|
+
f"{key}: {value}" for key, value in severity_counts.items() if value > 0
|
|
141
|
+
)
|
|
142
|
+
|
|
135
143
|
for cve in software["cves"]:
|
|
136
144
|
severity = cve["severity"].lower()
|
|
137
145
|
if severity == "critical":
|
|
@@ -148,8 +156,8 @@ class ProductsService:
|
|
|
148
156
|
|
|
149
157
|
detail_object = DetailObject(
|
|
150
158
|
software=f"{software['name']} {software['version']} ({software['vendor']})",
|
|
151
|
-
data=f"{score}
|
|
152
|
-
score=score
|
|
159
|
+
data=f"Score: {score}, CVEs: {cve_count} ({severities}), ({cve_list})",
|
|
160
|
+
score=score,
|
|
153
161
|
)
|
|
154
162
|
|
|
155
163
|
total_score += score
|
|
@@ -159,7 +167,7 @@ class ProductsService:
|
|
|
159
167
|
detail_object.paths.append(f" - {path}")
|
|
160
168
|
|
|
161
169
|
# Indicate if more paths exist
|
|
162
|
-
if
|
|
170
|
+
if len(software["paths"]) > 4:
|
|
163
171
|
detail_object.paths.append(f" - .. (+{len(software['paths']) - 4} more)")
|
|
164
172
|
|
|
165
173
|
# Add registry paths if available (limit to 4)
|
|
@@ -167,19 +175,26 @@ class ProductsService:
|
|
|
167
175
|
detail_object.paths.append(f" - {registry_path}")
|
|
168
176
|
|
|
169
177
|
# Indicate if more registry paths exist
|
|
170
|
-
if
|
|
171
|
-
detail_object.paths.append(
|
|
178
|
+
if len(software["registryPaths"]) > 4:
|
|
179
|
+
detail_object.paths.append(
|
|
180
|
+
f" - .. (+{len(software['registryPaths']) - 4} more)"
|
|
181
|
+
)
|
|
172
182
|
|
|
173
183
|
# Collect detail objects for sorting
|
|
174
184
|
detail_objects.append(detail_object)
|
|
175
185
|
|
|
186
|
+
summary_line = f"{len(vulnerable_software)} vulnerable products, score: {total_score}"
|
|
187
|
+
details.append(summary_line)
|
|
188
|
+
details.append("")
|
|
189
|
+
|
|
176
190
|
# Sort detail objects by score descending
|
|
177
191
|
detail_objects.sort(key=lambda x: x.score, reverse=True)
|
|
178
|
-
|
|
192
|
+
|
|
179
193
|
# Limit to top 10
|
|
180
194
|
for detail_object in detail_objects[:10]:
|
|
181
|
-
details.append(f"{detail_object.software} {detail_object.data}")
|
|
195
|
+
details.append(f"{detail_object.software} - {detail_object.data}")
|
|
182
196
|
details.extend(detail_object.paths)
|
|
197
|
+
details.append("")
|
|
183
198
|
|
|
184
199
|
# Determine the value based on severity:
|
|
185
200
|
# - Critical vulnerabilities trigger critical threshold
|
|
@@ -198,9 +213,7 @@ class ProductsService:
|
|
|
198
213
|
}
|
|
199
214
|
|
|
200
215
|
self.logger.info(
|
|
201
|
-
f"Products analysis complete: {len(
|
|
202
|
-
f"(Critical: {critical_count}, High: {high_count}, Medium: {medium_count}, Low: {low_count}), "
|
|
203
|
-
f"{len(vulnerable_software)} vulnerable software"
|
|
216
|
+
f"Products analysis complete: {len(vulnerable_software)} vulnerable products, score: {total_score}"
|
|
204
217
|
)
|
|
205
218
|
self.logger.method_exit("get_result", result)
|
|
206
219
|
return result
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: check-msdefender
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.15
|
|
4
4
|
Summary: A Nagios plugin for monitoring Microsoft Defender API endpoints
|
|
5
5
|
Keywords: nagios,monitoring,microsoft,graph,api,azure
|
|
6
6
|
Author-Email: ldvchosal <ldvchosal@github.com>
|
|
@@ -10,16 +10,17 @@ Classifier: Intended Audience :: System Administrators
|
|
|
10
10
|
Classifier: License :: OSI Approved :: MIT License
|
|
11
11
|
Classifier: Operating System :: OS Independent
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
14
13
|
Classifier: Programming Language :: Python :: 3.10
|
|
15
14
|
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
17
|
Classifier: Topic :: System :: Monitoring
|
|
17
18
|
Classifier: Topic :: System :: Systems Administration
|
|
18
19
|
Project-URL: Homepage, https://github.com/lduchosal/check_msdefender
|
|
19
20
|
Project-URL: Bug Reports, https://github.com/lduchosal/check_msdefender/issues
|
|
20
21
|
Project-URL: Source, https://github.com/lduchosal/check_msdefender
|
|
21
22
|
Project-URL: Documentation, https://github.com/lduchosal/check_msdefender/blob/main/README.md
|
|
22
|
-
Requires-Python: >=3.
|
|
23
|
+
Requires-Python: >=3.10
|
|
23
24
|
Requires-Dist: nagiosplugin>=1.4.0
|
|
24
25
|
Requires-Dist: azure-identity>=1.12.0
|
|
25
26
|
Requires-Dist: click<9.0,>=8.0
|
|
@@ -27,7 +28,7 @@ Description-Content-Type: text/markdown
|
|
|
27
28
|
|
|
28
29
|
# 🛡️ Check MS Defender
|
|
29
30
|
|
|
30
|
-
[](https://python.org)
|
|
31
32
|
[](https://opensource.org/licenses/MIT)
|
|
32
33
|
[](https://github.com/lduchosal/check_msdefender)
|
|
33
34
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
check_msdefender-1.1.
|
|
2
|
-
check_msdefender-1.1.
|
|
3
|
-
check_msdefender-1.1.
|
|
4
|
-
check_msdefender-1.1.
|
|
5
|
-
check_msdefender/__init__.py,sha256=
|
|
1
|
+
check_msdefender-1.1.15.dist-info/METADATA,sha256=0Ej_lBiTikJylgInCRd3zN6nxQ2Xaq6bjD9SIRUbb_M,14853
|
|
2
|
+
check_msdefender-1.1.15.dist-info/WHEEL,sha256=tsUv_t7BDeJeRHaSrczbGeuK-TtDpGsWi_JfpzD255I,90
|
|
3
|
+
check_msdefender-1.1.15.dist-info/entry_points.txt,sha256=OqVzHI1PaD9V22g0K7BhA2nYv4O-pH8mcLzuGdsk5rM,79
|
|
4
|
+
check_msdefender-1.1.15.dist-info/licenses/LICENSE,sha256=kW3DwIsKc9HVYdS4f4tI6sLo-EPqBQbz-WmuvHU4Nak,1065
|
|
5
|
+
check_msdefender/__init__.py,sha256=YPYbGzHfZi1zGqFV2AdZK6pbMzIakQDgN7-VWJ5XKdg,161
|
|
6
6
|
check_msdefender/__main__.py,sha256=TuNsRSdnkQm9OdBTAwD5aB2zV_Irc50WgylVWhrfnLY,124
|
|
7
7
|
check_msdefender/check_msdefender.py,sha256=OO4Tg2DBW28AT-2LOH-qJM2pE5TPcF615BF7HjyZsmA,137
|
|
8
8
|
check_msdefender/cli/__init__.py,sha256=NWaS5ZI9_252AcReugF_WGPMOvQ_B7sC_s3pSrGujcI,291
|
|
@@ -23,7 +23,7 @@ check_msdefender/core/config.py,sha256=IoWBL_DB110F4i6hFfli6iFDBXx57dHh32lCuLkcg
|
|
|
23
23
|
check_msdefender/core/defender.py,sha256=JChnsyKD2grSMlxSDHEbTd4Al8pW-_8TAN8-1JsINR4,10389
|
|
24
24
|
check_msdefender/core/exceptions.py,sha256=X4s_XM64SEVSs-4mGKqnF8xXwGFY3E0buvkgRNuCCX4,600
|
|
25
25
|
check_msdefender/core/logging_config.py,sha256=Rd1F-IDXTx7yckrI8kyx2Ht20f5OcArPCAXb44BOmbg,4084
|
|
26
|
-
check_msdefender/core/nagios.py,sha256=
|
|
26
|
+
check_msdefender/core/nagios.py,sha256=BvO37EFaB3PnWbuYGVI5d85ICugQEy31G5wEtogheEs,6260
|
|
27
27
|
check_msdefender/services/__init__.py,sha256=_fiKXxcz263IghXn9BnUWDKPgedhUPoSakEN3tBd2SU,44
|
|
28
28
|
check_msdefender/services/alerts_service.py,sha256=poKZw1WKphmtPPnuMDrGRuPQbRLjLDZpo2rhFCh7TDc,4034
|
|
29
29
|
check_msdefender/services/detail_service.py,sha256=tXfb6H2dhrTZ5y85H8W58GA8CvA-7aUwMIbNdcqECw0,3381
|
|
@@ -31,6 +31,6 @@ check_msdefender/services/lastseen_service.py,sha256=LiNVeUbAoMzowMvE90P7zCtKFHB
|
|
|
31
31
|
check_msdefender/services/machines_service.py,sha256=KLRwltpYtwg_qtW6BGIxlH-PB9LcnEyW-i3C4RGSD30,3238
|
|
32
32
|
check_msdefender/services/models.py,sha256=CDmQ5vU0-GawIalqXjXNk3rry6gsyjv6eSlW2NiXwQ0,979
|
|
33
33
|
check_msdefender/services/onboarding_service.py,sha256=RIOsvALCoKV0YqnCHKYRkelSPrO-F-6vNBLlto4MpiI,2686
|
|
34
|
-
check_msdefender/services/products_service.py,sha256=
|
|
34
|
+
check_msdefender/services/products_service.py,sha256=JzwAFb2aDW_-X83IQTdDhsa8CQD_s68gMGX298e2XWA,9060
|
|
35
35
|
check_msdefender/services/vulnerabilities_service.py,sha256=LuRRQlFt-K82tGUhLCx_QCOp4CbBgSp7fktmeSSoa9o,6838
|
|
36
|
-
check_msdefender-1.1.
|
|
36
|
+
check_msdefender-1.1.15.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|