Skip to content

Commit bd49712

Browse files
🎉 Implement Cycognito parser (#12558)
* 🎉 Implement Cycognito parser * ruff * fix unittests * update * update * update
1 parent 99052d7 commit bd49712

File tree

8 files changed

+844
-0
lines changed

8 files changed

+844
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
title: "Cycognito"
3+
toc_hide: true
4+
---
5+
Import report in JSON returned from Cycognito API. In order to do this, just use the /v1/issues endpoint.
6+
7+
### Sample Scan Data
8+
Sample Cycognito scans can be found [here](https://github.com/DefectDojo/django-DefectDojo/tree/master/unittests/scans/cycognito).

dojo/settings/settings.dist.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,6 +1345,7 @@ def saml2_attrib_map_format(din):
13451345
"Red Hat Satellite": ["description", "severity"],
13461346
"Qualys Hacker Guardian Scan": ["title", "severity", "description"],
13471347
"Cyberwatch scan (Galeax)": ["title", "description", "severity"],
1348+
"Cycognito Scan": ["title", "severity"],
13481349
}
13491350

13501351
# Override the hardcoded settings here via the env var

dojo/tools/cycognito/__init__.py

Whitespace-only changes.

dojo/tools/cycognito/parser.py

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
import json
2+
from datetime import datetime
3+
4+
from dojo.models import Endpoint, Finding
5+
6+
7+
class CycognitoParser:
8+
def get_scan_types(self):
9+
return ["Cycognito Scan"]
10+
11+
def get_label_for_scan_types(self, scan_type):
12+
return "Cycognito Scan"
13+
14+
def get_description_for_scan_types(self, scan_type):
15+
return "Support Cycognito issues from returned JSON over API."
16+
17+
def get_findings(self, file, test):
18+
data = json.load(file)
19+
findings = []
20+
for vulnerability in data:
21+
description = ""
22+
mitigation = ""
23+
impact = ""
24+
confidence = vulnerability.get("confidence", None)
25+
affected_asset = vulnerability.get("affected_asset", None)
26+
package = vulnerability.get("package", None)
27+
exploitation_availability = vulnerability.get("exploitation_availability", None)
28+
tools = vulnerability.get("tools", None)
29+
continent = vulnerability.get("continent", None)
30+
references = vulnerability.get("references", None)
31+
tech_owners = vulnerability.get("tech_owners", None)
32+
teams = vulnerability.get("teams", None)
33+
potential_threat = vulnerability.get("potential_threat", None)
34+
attacker_interest = vulnerability.get("attacker_interest", None)
35+
tags = vulnerability.get("tags", None)
36+
base_severity_score = vulnerability.get("base_severity_score", None)
37+
vulnid = vulnerability.get("id", None)
38+
remediation_method = vulnerability.get("remediation_method", None)
39+
issue_id = vulnerability.get("issue_id", None)
40+
first_detected = vulnerability.get("first_detected", None)
41+
summary = vulnerability.get("summary", None)
42+
exploitation_complexity = vulnerability.get("exploitation_complexity", None)
43+
underground_activity = vulnerability.get("underground_activity", None)
44+
resolved_at = vulnerability.get("resolved_at", None)
45+
snooze_expiration = vulnerability.get("snooze_expiration", None)
46+
attractiveness_label = vulnerability.get("attractiveness_label", None)
47+
affected_ptr_domains = vulnerability.get("affected_ptr_domains", None)
48+
affected_asset_tags = vulnerability.get("affected_asset_tags", None)
49+
advisories = vulnerability.get("advisories", None)
50+
environments = vulnerability.get("environments", None)
51+
locations = vulnerability.get("locations", None)
52+
region = vulnerability.get("region", None)
53+
detection_complexity = vulnerability.get("detection_complexity", None)
54+
port = vulnerability.get("port", None)
55+
remediation_effort = vulnerability.get("remediation_effort", None)
56+
exploitation_method = vulnerability.get("exploitation_method", None)
57+
attractiveness = vulnerability.get("attractiveness", None)
58+
title = vulnerability.get("title", None)
59+
platforms = vulnerability.get("platforms", None)
60+
exploitation_score = vulnerability.get("exploitation_score", None)
61+
base_severity = vulnerability.get("base_severity", None)
62+
issue_type = vulnerability.get("issue_type", None)
63+
organizations = vulnerability.get("organizations", None)
64+
business_units = vulnerability.get("business_units", None)
65+
cve_ids = vulnerability.get("cve_ids", None)
66+
comment = vulnerability.get("comment", None)
67+
evidence = vulnerability.get("evidence", None)
68+
remediation_steps = vulnerability.get("remediation_steps", None)
69+
potential_impact = vulnerability.get("potential_impact", None)
70+
if confidence is not None:
71+
description += "**confidence:** " + str(confidence) + "\n"
72+
if affected_asset is not None:
73+
description += "**affected_asset:** " + str(affected_asset) + "\n"
74+
if package is not None:
75+
description += "**package:** " + str(package) + "\n"
76+
if exploitation_availability is not None and not "None":
77+
description += "**exploitation_availability:** " + str(exploitation_availability) + "\n"
78+
if tools and tools is not None:
79+
description += "**tools:** " + str(tools) + "\n"
80+
if continent and continent is not None:
81+
description += "**continent:** " + str(", ".join(continent)) + "\n"
82+
if tech_owners and tech_owners is not None:
83+
description += "**tech_owners:** " + str(tech_owners) + "\n"
84+
if teams and teams is not None:
85+
description += "**teams:** " + str(teams) + "\n"
86+
if potential_threat and potential_threat is not None:
87+
description += "**potential_threat:** " + str(potential_threat) + "\n"
88+
if attacker_interest is not None and not "None":
89+
description += "**attacker_interest:** " + str(attacker_interest) + "\n"
90+
if tags and tags is not None:
91+
description += "**tags:** " + str(tags) + "\n"
92+
if base_severity_score is not None:
93+
description += "**base_severity_score:** " + str(base_severity_score) + "\n"
94+
if vulnid is not None:
95+
description += "**id:** " + str(vulnid) + "\n"
96+
if remediation_method is not None:
97+
mitigation += "**remediation_method:** " + str(remediation_method) + "\n"
98+
if issue_id is not None:
99+
description += "**issue_id:** " + str(issue_id) + "\n"
100+
if summary is not None:
101+
description += "**summary:** " + str(summary) + "\n"
102+
if exploitation_complexity is not None and exploitation_complexity != "unknown":
103+
description += "**exploitation_complexity:** " + str(exploitation_complexity) + "\n"
104+
if underground_activity is not None:
105+
description += "**underground_activity:** " + str(underground_activity) + "\n"
106+
if resolved_at is not None:
107+
description += "**resolved_at:** " + str(resolved_at) + "\n"
108+
if snooze_expiration is not None:
109+
description += "**snooze_expiration:** " + str(snooze_expiration) + "\n"
110+
if attractiveness_label is not None:
111+
description += "**attractiveness_label:** " + str(attractiveness_label) + "\n"
112+
if affected_ptr_domains and affected_ptr_domains is not None:
113+
description += "**affected_ptr_domains:** " + str(", ".join(affected_ptr_domains)) + "\n"
114+
if affected_asset_tags and affected_asset_tags is not None:
115+
description += "**affected_asset_tags:** " + "" + "\n"
116+
if advisories and advisories is not None:
117+
description += "**advisories:** " + str(advisories) + "\n"
118+
if environments and environments is not None:
119+
description += "**environments:** " + str(", ".join(environments)) + "\n"
120+
if locations and locations is not None:
121+
description += "**locations:** " + str(", ".join(locations)) + "\n"
122+
if region and region is not None:
123+
description += "**region:** " + str(", ".join(region)) + "\n"
124+
if detection_complexity is not None:
125+
description += "**detection_complexity:** " + str(detection_complexity) + "\n"
126+
if port is not None:
127+
description += "**port:** " + str(port) + "\n"
128+
if remediation_effort is not None:
129+
mitigation += "**remediation_effort:** " + str(remediation_effort) + "\n"
130+
if exploitation_method is not None and exploitation_method != "unknown":
131+
description += "**exploitation_method:** " + str(exploitation_method) + "\n"
132+
if attractiveness is not None:
133+
description += "**attractiveness:** " + str(attractiveness) + "\n"
134+
if platforms is not None:
135+
description += "**platforms:** " + str(", ".join(platforms)) + "\n"
136+
if exploitation_score is not None:
137+
description += "**exploitation_score:** " + str(exploitation_score) + "\n"
138+
if issue_type is not None:
139+
description += "**issue_type:** " + str(issue_type) + "\n"
140+
if organizations is not None:
141+
description += "**organizations:** " + str(", ".join(organizations)) + "\n"
142+
if business_units is not None:
143+
description += "**business_units:** " + str(", ".join(business_units)) + "\n"
144+
if comment is not None:
145+
description += "**comment:** " + str(comment) + "\n"
146+
if evidence is not None:
147+
description += "**evidence:** " + str(evidence) + "\n"
148+
if remediation_steps is not None:
149+
mitigation += "**remediation_steps:** " + str("\n ".join(remediation_steps)) + "\n"
150+
if potential_impact and potential_impact is not None:
151+
impact = "**potential_impact:** " + str(", ".join(potential_impact)) + "\n"
152+
finding = Finding(
153+
title=title,
154+
test=test,
155+
description=description,
156+
severity=base_severity.capitalize(),
157+
references=str("\n".join(references)),
158+
date=datetime.strptime(first_detected, "%Y-%m-%dT%H:%M:%S.%fZ").strftime("%Y-%m-%d"),
159+
dynamic_finding=True,
160+
mitigation=mitigation,
161+
impact=impact,
162+
)
163+
if cve_ids and cve_ids is not None:
164+
finding.unsaved_vulnerability_ids = []
165+
for cve_id in cve_ids:
166+
finding.unsaved_vulnerability_ids.append(cve_id)
167+
finding.unsaved_endpoints = []
168+
finding.unsaved_endpoints.append(Endpoint(host=affected_asset.replace("ip/", "").replace("webapp/", "").replace("cert/", "").replace("domain/", "")))
169+
findings.append(finding)
170+
return findings

0 commit comments

Comments
 (0)