Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
Diego Nadares committed May 22, 2024
2 parents bd61b7f + 1e7eaf0 commit 8e4e38e
Show file tree
Hide file tree
Showing 15 changed files with 402 additions and 34 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,6 @@ fabric.properties
logs/*
*/logs/*
*.log.*

# MacOS ds files
.DS_Store
1 change: 1 addition & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ variables:
VAULT_ROLE: 'python-sast-readonly'
VAULT_ADDR: 'https://tluav-lb.faradaysec.com'
VAULT_SECRET_PATH: 'gitlab/SAST'
TYPING_BRANCH: 'dev'

workflow:
rules:
Expand Down
3 changes: 2 additions & 1 deletion .gitlab/ci/testing/.testing-gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
- git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/faradaysec/cloud/faraday_agent_parameters_types.git typing
- cd typing
- if [ -z "$TYPING_BRANCH" ]; then export TYPING_BRANCH="master"; fi
- echo $TYPING_BRANCH
- echo "Using faraday_agent_parameters_type branch -> $TYPING_BRANCH"
- git fetch
- git checkout $TYPING_BRANCH
- pip install .
- cd ..
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG/3.4.0/200.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[FIX] Fix agent websocket token not changing on registration token update #200
1 change: 1 addition & 0 deletions CHANGELOG/3.4.0/214.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[FIX] Resolved the issue where users were unable to execute user-defined templates and pre-defined TenableIO templates. Additionally, fixed the functionality to retrieve completed scan results and relaunch previously created scans. #214
1 change: 1 addition & 0 deletions CHANGELOG/3.4.0/216.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[ADD] Introducing the new Tenable SC agent, now available for integration. This initial version focuses on supporting scan imports. #216
1 change: 1 addition & 0 deletions CHANGELOG/3.4.0/217.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[ADD] Added new agent for Cisco Cyber Vision. Also added severity calc utility. #217
1 change: 1 addition & 0 deletions CHANGELOG/3.4.0/date.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
May 22th, 2024
7 changes: 7 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
3.4.0 [May 22th, 2024]:
---
* [ADD] Introducing the new Tenable SC agent, now available for integration. This initial version focuses on supporting scan imports. #216
* [ADD] Added new agent for Cisco Cyber Vision. Also added severity calc utility. #217
* [FIX] Fix agent websocket token not changing on registration token update #200
* [FIX] Resolved the issue where users were unable to execute user-defined templates and pre-defined TenableIO templates. Additionally, fixed the functionality to retrieve completed scan results and relaunch previously created scans. #214

3.3.0 [Mar 12th, 2024]:
---
* [ADD] Add hotspots option to SonarQube. #197
Expand Down
2 changes: 1 addition & 1 deletion faraday_agent_dispatcher/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@

__author__ = """Faraday Development Team"""
__email__ = "[email protected]"
__version__ = "3.3.0"
__version__ = "3.4.0"
8 changes: 6 additions & 2 deletions faraday_agent_dispatcher/dispatcher_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ async def register(self, registration_token=None):
if not await self.check_connection():
exit(1)

if self.agent_token is None:
if self.agent_token is None or registration_token is not None:
try:
control_registration_token("token", registration_token)
except ValueError as ex:
Expand Down Expand Up @@ -515,7 +515,11 @@ async def create_process(executor: Executor, args: dict, plugin_args: dict):
# Executor Variables
if isinstance(args, dict):
for k in args:
env[f"EXECUTOR_CONFIG_{k.upper()}"] = str(args[k])
# This should allow to correctly get lists from environment with json.loads
if isinstance(args[k], list):
env[f"EXECUTOR_CONFIG_{k.upper()}"] = json.dumps(args[k])
else:
env[f"EXECUTOR_CONFIG_{k.upper()}"] = str(args[k])
else:
logger.error("Args from data received has a not supported type")
raise ValueError("Args from data received has a not supported type")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#!/usr/bin/env python
import os
import sys
import json
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/"


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


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"
try:
resp = requests.get(req_url, headers=req_headers, timeout=20, verify=False).json()
except TimeoutError:
log("Can't reach Cyber Vision: connection timed out")
sys.exit(1)
if "error" in resp:
log(f"API Error: {resp['error']}")
sys.exit(1)
for req_preset in preset_list:
for preset in resp:
if preset["label"] == req_preset:
presets_id[preset["label"]] = preset["id"]
presets_queue.append(preset["id"])

# STAGE 2 - get all vulns per preset
presets_vuln_collection = {}
step_c = 1
step_s = 100
for _id in presets_queue:
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}"
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}")
break
if "error" in resp:
log(f"API Error: {resp['error']}")
break
if len(resp) < 1:
break
presets_vuln_collection[_id].append(resp)
step_c += 1

# STAGE 3 - processing vulns
hosts = {}
for pres_data in presets_id.items():
for vuln_pack in presets_vuln_collection[pres_data[1]]:
for vuln in vuln_pack:
if not vuln["device"]["label"] in hosts:
hosts[vuln["device"]["label"]] = {
"ip": vuln["device"]["label"],
"description": f"Device ID {vuln['device']['id']}",
"mac": "" if not vuln["device"]["mac"] else vuln["device"]["mac"],
"vulnerabilities": [],
"tags": [pres_data[0]] + asset_tags,
}
if not vuln["title"] in [x["name"] for x in hosts[vuln["device"]["label"]]["vulnerabilities"]]:
try:
vuln["cvss"] = float(vuln["cvss"])
except ValueError:
vuln["cvss"] = -1.0
hosts[vuln["device"]["label"]]["vulnerabilities"].append(
{
"name": vuln["title"],
"desc": vuln["summary"],
"severity": severity_from_score(vuln["cvss"], 10.0),
"refs": [{"name": ref["link"], "type": "other"} for ref in vuln["links"]],
"external_id": vuln["id"],
"type": "Vulnerability",
"resolution": vuln["solution"],
"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(),
"tags": vuln_tags,
}
)
data = {"hosts": [x[1] for x in hosts.items()]}
print(json.dumps(data))


def main():
params_cybervision_token = os.getenv("CYBERVISION_TOKEN")
params_cybervision_url = os.getenv("CYBERVISION_HTTPS_URL")
params_cybervision_presets_env = os.getenv("EXECUTOR_CONFIG_CYBERVISION_PRESETS")

params_cybervision_presets = []
if params_cybervision_presets_env:
params_cybervision_presets = json.loads(params_cybervision_presets_env)

if not params_cybervision_url.startswith("https://"):
log("Cyber Vision URL must be HTTPS")
sys.exit(1)

params_vulnerability_tags = os.getenv("AGENT_CONFIG_VULN_TAG") or []
if params_vulnerability_tags:
params_vulnerability_tags = params_vulnerability_tags.split(",")
params_asset_tags = os.getenv("AGENT_CONFIG_HOSTNAME_TAG") or []
if params_asset_tags:
params_asset_tags = params_asset_tags.split(",")

cybervision_report_composer(
params_cybervision_url,
params_cybervision_token,
params_cybervision_presets,
params_asset_tags,
params_vulnerability_tags,
)


if __name__ == "__main__":
main()
Loading

0 comments on commit 8e4e38e

Please sign in to comment.