Skip to content

Commit

Permalink
Merge branch 'tkt_217_cisco_cybervision_agent' into 'dev'
Browse files Browse the repository at this point in the history
CyberVision crash cwe

Closes #217

See merge request faradaysec/cloud/faraday_agent_dispatcher!166
  • Loading branch information
Diego Nadares committed Jun 26, 2024
2 parents f9cd732 + 98b35cf commit 0fb3a18
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,34 @@
import os
import sys
import json
import time
import datetime
import requests
from urllib3.exceptions import InsecureRequestWarning
from faraday_agent_dispatcher.utils.severity_utils import severity_from_score

API_BASE = "/api/3.0/"
API_BASE = "/api/3.0"


def log(msg, end="\n"):
print(msg, file=sys.stderr, flush=True, end=end)


def parse_date(date_str):
try:
return datetime.datetime.strptime(date_str, "%Y-%m-%dT%H:%M:%SZ").timestamp()
except ValueError:
return ""


def cybervision_report_composer(url, token, preset_list, asset_tags, vuln_tags):
req_headers = {"accept": "application/json", "x-token-id": token}
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
presets_queue = []
presets_id = {}

# STAGE 1 - get preset list
req_url = f"{url}{API_BASE}presets"
req_url = f"{url}{API_BASE}/presets"
try:
resp = requests.get(req_url, headers=req_headers, timeout=20, verify=False).json()
except TimeoutError:
Expand All @@ -35,26 +43,58 @@ def cybervision_report_composer(url, token, preset_list, asset_tags, vuln_tags):
if preset["label"] == req_preset:
presets_id[preset["label"]] = preset["id"]
presets_queue.append(preset["id"])
presets_id_inv = {v: k for k, v in presets_id.items()}

# STAGE 2 - get all vulns per preset
presets_vuln_collection = {}
step_c = 1
step_s = 100

for _id in presets_queue: # post to update to latest computed data
req_refresh_url = f"{url}{API_BASE}/presets/{_id}/refreshData"
try:
resp = requests.post(req_refresh_url, headers=req_headers, timeout=20, verify=False)
except TimeoutError:
log("Can't reach Cyber Vision: connection timed out")
sys.exit(1)

for _id in presets_queue:
serv_c = 0
while True: # wait until data is ready
req_test_url = f"{url}{API_BASE}/presets/{_id}/visualisations/vulnerability-list?page=1&size=5"
try:
resp = requests.get(req_test_url, headers=req_headers, timeout=20, verify=False)
if "Service unavailable" in resp.content.decode("UTF-8"):
if serv_c == 0:
log(f"Preset {presets_id_inv[_id]} data is not ready, waiting...")
serv_c += 1
else:
log(f"Preset {presets_id_inv[_id]} data is ready!")
serv_c = 0
break
if serv_c >= 60:
break
except TimeoutError:
log("Can't reach Cyber Vision: connection timed out")
sys.exit(1)
time.sleep(1)

if serv_c >= 60:
log(f"Error: Preset {presets_id_inv[_id]} took many time to refresh data")
continue

step_c = 1
presets_vuln_collection[_id] = []
while True:
req_url = f"{url}{API_BASE}presets/{_id}/visualisations/" f"vulnerability-list?page={step_c}&size={step_s}"
while True: # paged data fetch
req_url = f"{url}{API_BASE}/presets/{_id}/visualisations/vulnerability-list?page={step_c}&size={step_s}"
try:
resp = requests.get(req_url, headers=req_headers, timeout=20, verify=False)
if resp.content.decode("UTF-8") == "Service unavailable: data is not available yet":
raise ValueError(resp.content.decode("UTF-8"))
resp = resp.json()
except TimeoutError:
log("Can't reach Cyber Vision: connection timed out")
sys.exit(1)
except ValueError as ve:
log(f"{str(ve)} at preset {_id}")
log(f"{str(ve)} at preset {presets_id_inv[_id]}")
break
if "error" in resp:
log(f"API Error: {resp['error']}")
Expand All @@ -67,6 +107,9 @@ def cybervision_report_composer(url, token, preset_list, asset_tags, vuln_tags):
# STAGE 3 - processing vulns
hosts = {}
for pres_data in presets_id.items():
if not pres_data[1] in presets_vuln_collection.keys():
log(f"Error: No vulnerabilities loaded for {pres_data[0]} ({pres_data[1]})")
continue
for vuln_pack in presets_vuln_collection[pres_data[1]]:
for vuln in vuln_pack:
if not vuln["device"]["label"] in hosts:
Expand Down Expand Up @@ -94,10 +137,9 @@ def cybervision_report_composer(url, token, preset_list, asset_tags, vuln_tags):
"data": vuln["fullDescription"],
"status": "open",
"cve": [x["cve"] for i, x in enumerate(vuln_pack) if x["title"] == vuln["title"]],
"run_date": datetime.datetime.strptime(
vuln["publishTime"], "%Y-%m-%dT%H:%M:%SZ"
).timestamp(),
"run_date": parse_date(vuln["publishTime"]),
"tags": vuln_tags,
"cwe": [],
}
)
data = {"hosts": [x[1] for x in hosts.items()]}
Expand Down
4 changes: 2 additions & 2 deletions faraday_agent_dispatcher/utils/severity_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ def severity_from_score(score: float, max_score: float):
return "medium"
if max_score * 0.7 <= score < max_score * 0.9:
return "high"
if max_score * 0.9 <= score < max_score:
if max_score * 0.9 <= score <= max_score:
return "critical"
return ""
return "unclassified"

0 comments on commit 0fb3a18

Please sign in to comment.