Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🎉 Improvements for wazuh importer #9248

Merged
merged 16 commits into from
Feb 6, 2024
Merged
8 changes: 7 additions & 1 deletion docs/content/en/integrations/parsers/file/wazuh.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
---

Check warning on line 1 in docs/content/en/integrations/parsers/file/wazuh.md

View check run for this annotation

DryRunSecurity / AI-powered Sensitive Files Check

Possible Sensitive File

Our AI-Powered Sensitive File checker believes it has discovered a sensitive file being modified in this PR. Extra care must be taken when modifying a file that is potentially security-sensitive. The following reason was provided: Contains sensitive information about Wazuh integration
title: "Wazuh Scanner"
toc_hide: true
---
Import JSON report.

Import findings from Wazuh. The export from Wazuh can be done via 2 ways. Choose the one which you prefer.

- export the Wazuh findings from API and upload them to DefectDojo as json file. This method may be the easiest one but does export all known vulnerabilities at once. It is not possible to sort them after clients or any other categories. You will receive all vulnerabilities in one engagement.
- export the findings via the script [available here](https://github.com/quirinziessler/wazuh-findings-exporter). The script fetches the findings by Wazuh client groups and saves them as json, ready for upload. You will receive one file per group allowing you to separate the clients via engagements in Wazuh. It also exports the endpoints hostname and displays them in DefectDojo UI.

Independent of your above choice: Have in mind to adjust the max file size via "DD_SCAN_FILE_MAX_SIZE" if you see files larger than the default value of 100MB. Depending on the amount and category of integrated devices, the file size jumps rapidly.
quirinziessler marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 1 addition & 1 deletion dojo/settings/settings.dist.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Django settings for DefectDojo

Check warning on line 1 in dojo/settings/settings.dist.py

View check run for this annotation

DryRunSecurity / AI-powered Sensitive Files Check

Possible Sensitive File

Our AI-Powered Sensitive File checker believes it has discovered a sensitive file being modified in this PR. Extra care must be taken when modifying a file that is potentially security-sensitive. The following reason was provided: Contains sensitive configuration settings
import os
from datetime import timedelta
from celery.schedules import crontab
Expand Down Expand Up @@ -1260,7 +1260,6 @@
'NeuVector (compliance)': ['title', 'vuln_id_from_tool', 'description'],
'Wpscan': ['title', 'description', 'severity'],
'Popeye Scan': ['title', 'description'],
'Wazuh Scan': ['title'],
'Nuclei Scan': ['title', 'cwe', 'severity'],
'KubeHunter Scan': ['title', 'description'],
'kube-bench Scan': ['title', 'vuln_id_from_tool', 'description'],
Expand Down Expand Up @@ -1473,6 +1472,7 @@
'kube-bench Scan': DEDUPE_ALGO_HASH_CODE,
'Threagile risks report': DEDUPE_ALGO_UNIQUE_ID_FROM_TOOL_OR_HASH_CODE,
'Humble Json Importer': DEDUPE_ALGO_HASH_CODE,
'Wazuh Scan': DEDUPE_ALGO_UNIQUE_ID_FROM_TOOL,
'MSDefender Parser': DEDUPE_ALGO_HASH_CODE,
}

Expand Down
82 changes: 44 additions & 38 deletions dojo/tools/wazuh/parser.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import hashlib

Check warning on line 1 in dojo/tools/wazuh/parser.py

View check run for this annotation

DryRunSecurity / AI-powered Sensitive Files Check

Possible Sensitive File

Our AI-Powered Sensitive File checker believes it has discovered a sensitive file being modified in this PR. Extra care must be taken when modifying a file that is potentially security-sensitive. The following reason was provided: Contains sensitive parsing logic for Wazuh
import json
from dojo.models import Finding
from dojo.models import Finding, Endpoint


class WazuhParser(object):
"""
Use Wazuh Vulnerability API to retrieve the findings
The vulnerabilities with condition "Package unfixed" are skipped because there is no fix out yet.
https://github.com/wazuh/wazuh/issues/14560
"""
Expand All @@ -18,54 +18,49 @@
def get_description_for_scan_types(self, scan_type):
return "Wazuh"

def get_findings(self, filename, test):
data = json.load(filename)
# Detect duplications
dupes = dict()
def get_findings(self, file, test):
data = json.load(file)

try:
vulnerability = data[next(iter(data.keys()))]["affected_items"]
except (KeyError, StopIteration):
return list()
if not data:
return []

if vulnerability is None:
return list()
# Detect duplications
dupes = dict()

for item in vulnerability:
# Loop through each element in the list
vulnerabilities = data.get("data", {}).get("affected_items", [])
for item in vulnerabilities:
if (
item["condition"] != "Package unfixed"
and item["severity"] != "Untriaged"
):
id = item.get("cve")
cve = item.get("cve")
package_name = item.get("name")
package_version = item.get("version")
description = item.get("condition")
if item.get("severity") == "Untriaged":
severity = "Info"
else:
severity = item.get("severity")
if item.get("status") == "VALID":
active = True
else:
active = False
severity = item.get("severity").capitalize()
agent_ip = item.get("agent_ip")
links = item.get("external_references")
title = (
item.get("title") + " (version: " + package_version + ")"
)
severity = item.get("severity", "info").capitalize()
cvssv3_score = item.get("cvss3_score")
publish_date = item.get("published")
agent_name = item.get("agent_name")
agent_ip = item.get("agent_ip")
detection_time = item.get("detection_time")

if links:
references = ""
for link in links:
references += f"{link}\n"
references = "\n".join(links)
else:
references = None

if id and id.startswith("CVE"):
vulnerability_id = id
else:
vulnerability_id = None
title = (
item.get("title") + " (version: " + package_version + ")"
)

dupe_key = title
if agent_name:
dupe_key = title + cve + agent_name + package_name + package_version
else:
dupe_key = title + cve + package_name + package_version
dupe_key = hashlib.sha256(dupe_key.encode('utf-8')).hexdigest()

if dupe_key in dupes:
find = dupes[dupe_key]
Expand All @@ -77,14 +72,25 @@
test=test,
description=description,
severity=severity,
active=active,
mitigation="mitigation",
references=references,
static_finding=True,
component_name=package_name,
component_version=package_version,
cvssv3_score=cvssv3_score,
publish_date=publish_date,
unique_id_from_tool=dupe_key,
date=detection_time,
)
if vulnerability_id:
find.unsaved_vulnerability_ids = [vulnerability_id]

# in some cases the agent_ip is not the perfect way on how to identify a host. Thus prefer the agent_name, if existant.
if agent_name:
find.unsaved_endpoints = [Endpoint(host=agent_name)]
elif agent_ip:
find.unsaved_endpoints = [Endpoint(host=agent_ip)]

if id:
find.unsaved_vulnerability_ids = cve

dupes[dupe_key] = find

return list(dupes.values())
29 changes: 29 additions & 0 deletions unittests/scans/wazuh/one_finding_with_endpoint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{

Check warning on line 1 in unittests/scans/wazuh/one_finding_with_endpoint.json

View check run for this annotation

DryRunSecurity / AI-powered Sensitive Files Check

Possible Sensitive File

Our AI-Powered Sensitive File checker believes it has discovered a sensitive file being modified in this PR. Extra care must be taken when modifying a file that is potentially security-sensitive. The following reason was provided: Contains sensitive JSON data for a Wazuh scan
"data": {
"affected_items": [
{
"name": "asdf",
"version": "1",
"cve": "CVE-1234-1234",
"cvss2_score": 0,
"title": "CVE-1234-1234 affects curl",
"published": "2023-12-07",
"architecture": "amd64",
"status": "VALID",
"cvss3_score": 6.5,
"external_references": [
"https://nvd.nist.gov/vuln/detail/CVE-1234-1234",
"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-1234-1234"
],
"updated": "2023-12-24",
"severity": "Medium",
"type": "PACKAGE",
"detection_time": "2023-12-13T22:11:57+00:00",
"condition": "Package less than 2",
"agent_ip": "111.111.111.111",
"agent_name": "agent-1"
}
],
"total_affected_items": 1
}
}
21 changes: 20 additions & 1 deletion unittests/tools/test_wazuh_parser.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from ..dojo_test_case import DojoTestCase

Check warning on line 1 in unittests/tools/test_wazuh_parser.py

View check run for this annotation

DryRunSecurity / AI-powered Sensitive Files Check

Possible Sensitive File

Our AI-Powered Sensitive File checker believes it has discovered a sensitive file being modified in this PR. Extra care must be taken when modifying a file that is potentially security-sensitive. The following reason was provided: Contains sensitive test cases for the Wazuh parser
from dojo.tools.wazuh.parser import WazuhParser
from dojo.models import Test

Expand All @@ -20,7 +20,10 @@
endpoint.clean()
self.assertEqual(1, len(findings))
self.assertEqual("Medium", finding.severity)
self.assertEqual("CVE-1234-123123", finding.unsaved_vulnerability_ids[0])
self.assertEqual("CVE-1234-123123", finding.unsaved_vulnerability_ids)
self.assertEqual("asdf", finding.component_name)
self.assertEqual("4.3.1", finding.component_version)
self.assertEqual(5.5, finding.cvssv3_score)

def test_parse_many_finding(self):
testfile = open("unittests/scans/wazuh/many_findings.json")
Expand All @@ -30,3 +33,19 @@
for endpoint in finding.unsaved_endpoints:
endpoint.clean()
self.assertEqual(6, len(findings))

def test_parse_one_finding_with_endpoint(self):
testfile = open("unittests/scans/wazuh/one_finding_with_endpoint.json")
parser = WazuhParser()
findings = parser.get_findings(testfile, Test())
for finding in findings:
for endpoint in finding.unsaved_endpoints:
endpoint.clean()
self.assertEqual(1, len(findings))
self.assertEqual("Medium", finding.severity)
self.assertEqual("CVE-1234-1234", finding.unsaved_vulnerability_ids)
self.assertEqual(6.5, finding.cvssv3_score)
endpoint = finding.unsaved_endpoints[0]
self.assertEqual("agent-1", endpoint.host)
self.assertEqual("asdf", finding.component_name)
self.assertEqual("1", finding.component_version)
Loading