Skip to content

Commit 1f05282

Browse files
committed
🎉 Implement Cycognito parser
1 parent 1bdd774 commit 1f05282

8 files changed

Lines changed: 832 additions & 0 deletions

File tree

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

0 commit comments

Comments
 (0)