Skip to content

Commit

Permalink
Cybersixgill aa mssp multi tenancy issue (demisto#28535) (demisto#28635)
Browse files Browse the repository at this point in the history
* Passing Organization ID where applicable.

* Generated and updated changelogs

* Updated docker image tag

* Added full stop in changelogs file.

* Fixing CI issues

* CVSS score is none

* MAX_DAYS_BACK 30

* Added known_words section and release notes rewording

* Added known_words section and release notes rewording

Co-authored-by: syed-loginsoft <97145640+syed-loginsoft@users.noreply.github.com>
Co-authored-by: Menachem Weinfeld <mmhw770@gmail.com>
  • Loading branch information
3 people authored and xsoar-bot committed Oct 5, 2023
1 parent 5e5d536 commit 4f817e7
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 21 deletions.
2 changes: 2 additions & 0 deletions Packs/Cybersixgill-ActionableAlerts/.pack-ignore
Expand Up @@ -19,3 +19,5 @@ ignore=IF115
[file:CybersixgillActionableAlertStatusUpdate.yml]
ignore=BA124

[known_words]
Cybersixgill
Expand Up @@ -49,7 +49,7 @@ def get_incident_init_params():


def item_to_incidents(item_info, sixgill_alerts_client):
incident: Dict[str, Any] = dict()
incident: Dict[str, Any] = {}
incidents = []
items = []
# get fields that are shared in case of sub alerts
Expand Down Expand Up @@ -130,8 +130,10 @@ def get_alert_content(content_item, item_info, incident, sixgill_alerts_client):
content_item['content'] = f'https://portal.cybersixgill.com/#/cve/{cve_id}'
additional_info = item_info.get("additional_info", {})
incident['CustomFields']['cve'] = cve_id
incident['CustomFields']['cybersixgillcvss31'] = additional_info.get("nvd", {}).get("v3", {}).get("current", -1)
incident['CustomFields']['cybersixgillcvss20'] = additional_info.get("nvd", {}).get("v2", {}).get("current", -1)
cybersixgillcvss31 = additional_info.get("nvd", {}).get("v3", {}).get("current")
cybersixgillcvss20 = additional_info.get("nvd", {}).get("v2", {}).get("current")
incident['CustomFields']['cybersixgillcvss31'] = cybersixgillcvss31 or -1
incident['CustomFields']['cybersixgillcvss20'] = cybersixgillcvss20 or -1
incident['CustomFields']['cybersixgilldvescore'] = additional_info.get("score", {}).get("current")
attributes = []
for attribute in additional_info.get("attributes", []):
Expand All @@ -141,7 +143,8 @@ def get_alert_content(content_item, item_info, incident, sixgill_alerts_client):
incident['CustomFields']['cybersixgillattributes'] = attributes
elif es_id == "Not Applicable":
content = sixgill_alerts_client.get_actionable_alert_content(actionable_alert_id=item_info.get('id'),
fetch_only_current_item=True)
fetch_only_current_item=True,
organization_id=demisto.params().get('org_id', None))
content_items = content.get('items')
if content_items:
for item in content_items:
Expand Down Expand Up @@ -175,16 +178,16 @@ def get_alert_content(content_item, item_info, incident, sixgill_alerts_client):
aggregate_alert_id = None
content = sixgill_alerts_client.get_actionable_alert_content(actionable_alert_id=item_info.get('id'),
aggregate_alert_id=aggregate_alert_id,
fetch_only_current_item=True)
fetch_only_current_item=True,
organization_id=demisto.params().get('org_id', None))
# get item full content
content = content.get('items', None)
if content:
if content[0].get('_id'):
es_items = content[0].get('_source')
if es_items:
content_item['title'] = es_items.get('title')
content_item['content'] = es_items.get('content')
content_item['creator'] = es_items.get('creator')
if content and content[0].get('_id'):
es_items = content[0].get('_source')
if es_items:
content_item['title'] = es_items.get('title')
content_item['content'] = es_items.get('content')
content_item['creator'] = es_items.get('creator')


''' COMMANDS + REQUESTS FUNCTIONS '''
Expand Down Expand Up @@ -240,7 +243,8 @@ def fetch_incidents():
incidents = []
for item in items:
try:
item_info = sixgill_alerts_client.get_actionable_alert(actionable_alert_id=item.get('id'))
item_info = sixgill_alerts_client.get_actionable_alert(actionable_alert_id=item.get('id'),
organization_id=demisto.params().get('org_id', None))
item_info['date'] = item.get('date')
new_incidents = item_to_incidents(item_info, sixgill_alerts_client)
incidents.extend(new_incidents)
Expand Down Expand Up @@ -289,7 +293,8 @@ def update_alert_status():
verify=VERIFY)

res = sixgill_alerts_client.update_actionable_alert(actionable_alert_id=alert_id, json_body=alert_body,
sub_alert_indexes=aggregate_alert_id)
sub_alert_indexes=aggregate_alert_id,
organization_id=demisto.params().get('org_id', None))

if res.get('status') == 200:
demisto.results("Actionable alert status updated")
Expand All @@ -313,4 +318,4 @@ def update_alert_status():
update_alert_status()

except Exception as e:
return_error("Failed to execute {} command. Error: {}".format(demisto.command(), str(e)))
return_error(f"Failed to execute {demisto.command()} command. Error: {str(e)}")
Expand Up @@ -109,7 +109,7 @@ script:
name: alert_status
- description: The aggregate alert id.
name: aggregate_alert_id
dockerimage: demisto/sixgill:1.0.0.50510
dockerimage: demisto/sixgill:1.0.0.66910
isfetch: true
runonce: false
script: '-'
Expand Down
Expand Up @@ -14,7 +14,7 @@
"status": {"name": "in_treatment", "user": "60b604a048ce2cb294629a2d"},
"threat_level": "imminent",
"threats": ["Brand Protection", "Data Leak"],
"title": "Your organization was potentially targeted " "by a ransomware group",
"title": "Your organization was potentially targeted by a ransomware group",
"user_id": "5d233575f8db38787dbe24b6",
},
{
Expand Down Expand Up @@ -219,7 +219,23 @@
"cybersixgillcvss31": -1,
"cybersixgilldvescore": None,
},
"alert_name": "Your organization was potentially targeted by a ransomware " "group",
"alert_name": "Your organization was potentially targeted by a ransomware group",
"content": "text",
"date": "2021-11-08 06:01:05",
"id": "6188bd21017198385e228437",
"read": True,
"severity": 1,
"site": "rw_everest",
"status": {"name": "in_treatment", "user": "60b604a048ce2cb294629a2d"},
"threat_level": "imminent",
"threats": ["Brand Protection", "Data Leak"],
"title": "Your organization was potentially targeted by a ransomware group",
"user_id": "5d233575f8db38787dbe24b6",
}

expected_alert_output_es_id_na = {
"CustomFields": {},
"alert_name": "Your organization was potentially targeted by a ransomware group",
"content": "text",
"date": "2021-11-08 06:01:05",
"id": "6188bd21017198385e228437",
Expand All @@ -234,10 +250,10 @@
}


class MockedResponse(object):
class MockedResponse:
def __init__(self, status_code):
self.status_code = status_code
self.ok = True if self.status_code == 200 else False
self.ok = self.status_code == 200


def get_incidents_list():
Expand Down Expand Up @@ -293,6 +309,23 @@ def get_content_with_cve_id():
return content_info_item


def get_content_es_id_na():
content_info_item = copy.deepcopy(info_item)
content_info_item["es_id"] = "Not Applicable"

return content_info_item


def get_content_item_es_id_na():
cloned_content_item = copy.deepcopy(content_item)
cloned_content_item["content"]["items"][1]["Additional Keywords"] = "Items"
cloned_content_item["content"]["items"][1]['Repository name'] = "Repository name"
cloned_content_item["content"]["items"][1]['Customer Keywords'] = "Customer Keywords"
cloned_content_item["content"]["items"][1]['GitURL'] = "GitURL"

return cloned_content_item["content"]


def test_test_module_raise_exception(mocker):
mocker.patch.object(demisto, "params", return_value=init_params())
mocker.patch("requests.sessions.Session.send", return_value=MockedResponse(400))
Expand Down Expand Up @@ -348,6 +381,29 @@ def test_fetch_incidents(mocker):
assert incidents == expected_alert_output


def test_fetch_incidents_no_last_run(mocker):
mocker.patch.object(demisto, "params", return_value=init_params())
mocker.patch.object(
demisto, "getLastRun", return_value={}
)
mocker.patch.object(demisto, "incidents")

from sixgill.sixgill_actionable_alert_client import SixgillActionableAlertClient

mocker.patch.object(
SixgillActionableAlertClient,
"get_actionable_alerts_bulk",
return_value=[],
)

from CybersixgillActionableAlerts import fetch_incidents
fetch_incidents()
assert demisto.incidents.call_count == 1
incidents = demisto.incidents.call_args[0][0]

assert len(incidents) == 0


def test_update_alert_status(mocker):
mocker.patch.object(demisto, "params", return_value=init_params())
mocker.patch.object(demisto, "args", return_value=init_args())
Expand Down Expand Up @@ -387,3 +443,27 @@ def test_get_alert_content(mocker):
)
assert alert_content is None
assert incident == expected_alert_output_with_custom_fields


def test_get_alert_content_es_id_na(mocker):

from sixgill.sixgill_actionable_alert_client import SixgillActionableAlertClient

mocker.patch.object(
SixgillActionableAlertClient,
"get_actionable_alert_content",
return_value=get_content_item_es_id_na(),
)

from CybersixgillActionableAlerts import get_alert_content

content = get_content()
incident = get_incident()
alert_content = get_alert_content(
content,
get_content_es_id_na(),
incident,
SixgillActionableAlertClient,
)
assert alert_content is None
assert incident == expected_alert_output_es_id_na
6 changes: 6 additions & 0 deletions Packs/Cybersixgill-ActionableAlerts/ReleaseNotes/1_2_1.md
@@ -0,0 +1,6 @@

#### Integrations

##### Cybersixgill Actionable Alerts
- Updated the Docker image to: *demisto/sixgill:1.0.0.66910*.
- Fixed an issue where Organization ID passed from UI was not used for all API calls.
2 changes: 1 addition & 1 deletion Packs/Cybersixgill-ActionableAlerts/pack_metadata.json
Expand Up @@ -2,7 +2,7 @@
"name": "Cybersixgill Actionable Alerts",
"description": "The integration allow retrieving Cybersixgill's actionable alerts based on organization assets",
"support": "partner",
"currentVersion": "1.2.0",
"currentVersion": "1.2.1",
"author": "Cybersixgill",
"url": "https://www.cybersixgill.com/",
"email": "getstarted@cybersixgill.com",
Expand Down

0 comments on commit 4f817e7

Please sign in to comment.