Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cybersixgill aa mssp multi tenancy issue #28535

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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