SafeBreach v2 Deprecated
Deprecated. No available replacement.
Data Enrichment & Threat Intelligence · SafeBreach - Breach and Attack Simulation platform · Feed
Details
| ID | SafeBreach v2 |
|---|---|
| Provider | SafeBreach |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 5.5.0 |
| Docker Image | demisto/python3:3.10.12.63474 |
| Supported Modules | Agentix XSIAM |
README
Deprecated. No available replacement.
Configure SafeBreach v2 (Deprecated) for Cortex XSOAR Integration
- Open the Navigation bar → … → CLI Console
- Type config accounts to find out the account id
- Use the id as the accountId parameter in Cortex XSOAR configuration
- Type config apikeys to list existing API keys \
OR \
Add a new one by typing: **config apikeys add –name ** - Use the generated API token as apiKey parameter in Cortex XSOAR configuration
- Use your SafeBreach Management URL as the url parameter in Cortex XSOAR configuration
Configure SafeBreach v2 (Deprecated) on Cortex XSOAR
- Navigate to Settings > Integrations > Servers & Services.
- Search for SafeBreach v2 (Deprecated).
-
Click Add instance to create and configure a new integration instance.
Parameter Description Required SafeBreach Managment URL For example, https://yourorg.safebreach.com True Account ID Obtained with “config accounts” SafeBreach command True API Key Generated with “config apikeys add” SafeBreach command True Insight Category Insight Data Type Non Behavioral Indicator Reputation Non-Behavioral Indicator from this integration instance will be marked with this reputation Behavioral Reputation Behavioral Indicator from this integration instance will be marked with this reputation Indicators Limit The maximum number of indicators to generate. The default is 1000. Fetch indicators Source Reliability Reliability of the source providing the intelligence data True Traffic Light Protocol Color The Traffic Light Protocol (TLP) designation to apply to indicators fetched from the feed Feed Fetch Interval Bypass exclusion list When selected, the exclusion list is ignored for indicators from this feed. This means that if an indicator from this feed is on the exclusion list, the indicator might still be added to the system. Trust any certificate (not secure) Use system proxy settings Indicator Reputation Indicators from this integration instance will be marked with this reputation Tags Supports CSV values. - Click Test to validate the URLs, token, and connection.
Commands
You can execute these commands from the Cortex XSOAR CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
Configuration parameters
url— SafeBreach Managment URL (required)accountId— Account ID (required)apiKey— API Key (required)insightCategory— Insight CategoryinsightDataType— Insight Data TypenonBehavioralReputation— Non Behavioral Indicator ReputationbehavioralReputation— Behavioral ReputationindicatorLimit— Indicators Limitfeed— Fetch indicatorsfeedReliability— Source Reliability (required)tlp_color— Traffic Light Protocol ColorfeedExpirationPolicy—feedFetchInterval— Feed Fetch IntervalfeedBypassExclusionList— Bypass exclusion listfeedExpirationInterval—insecure— Trust any certificate (not secure)proxy— Use system proxy settingsfeedReputation— Indicator ReputationfeedTags— Tags
Commands (7)
-
safebreach-get-indicatorsDeprecatedFetches SafeBreach Insights from which indicators are extracted, creating new indicators or updating existing indicators.
-
safebreach-get-insightsDeprecatedGets SafeBreach Insights for all security control categories.
-
safebreach-get-remediation-dataDeprecatedGets remediation data for a specific SafeBreach Insight.
-
safebreach-get-simulationDeprecatedGet SafeBreach simulation
-
safebreach-get-test-statusDeprecatedGets the status of a SafeBreach test for tracking progress of a run.
-
safebreach-rerun-insightDeprecatedReruns a specific SafeBreach Insight related simulations in your environment.
-
safebreach-rerun-simulationDeprecatedReruns a specific SafeBreach simulation in your environment.
import json import pytest import demistomock as demisto from CommonServerPython import * from SafeBreach_v2 import get_insights_command, get_remediation_data_command, rerun_simulation_command, \ get_safebreach_simulation_command, get_indicators_command, insight_rerun_command, Client MOCK_URL = "https://safebreach-fake-api.com" MOCK_ACCOUNT_ID = '1234567' MOCK_API_KEY = 'a1b2c3d4e5' INSIGHT_ID = '9' SIMULATION_ID = '8fae303defd52a7745044ce2ba54a391' client = Client( base_url=MOCK_URL, api_key=MOCK_API_KEY, account_id=MOCK_ACCOUNT_ID, proxies=handle_proxy(), verify=False, tags=['tag1', 'tag2'], ) def load_test_data(json_path): with open(json_path) as f: return json.load(f) REMEDATION_DATA_LIST = load_test_data('./test_data/remediation_data.json') GET_INSIGHTS_LIST = load_test_data('./test_data/insights.json') SIMULATION = load_test_data('./test_data/simulation.json') NODES = load_test_data('./test_data/nodes.json') REMEDATION_DATA_LIST_UNVAILD_STRING = load_test_data('./test_data/remediation_data_with_unvaild_string.json') def test_get_insights(requests_mock, mocker): requests_mock.get(f'{MOCK_URL}/api/data/v1/accounts/{MOCK_ACCOUNT_ID}/insights?type=actionBased', json=GET_INSIGHTS_LIST) requests_mock.get( f'{MOCK_URL}/api/config/v1/accounts/{MOCK_ACCOUNT_ID}/nodes?details=true&deleted=true&assets=true', json=NODES) mocker.patch.object(demisto, 'args', return_value={'insightIds': [9]}) mocker.patch.object(demisto, 'results') mocker.patch.object(demisto, 'params', return_value={'url': MOCK_URL}) res = get_insights_command(client, demisto.args(), True) assert demisto.results.call_count == 1 outputs = demisto.results.call_args[0][0] context = outputs['EntryContext'] fake_safebreach_context = { "Id": 9, "Category": 'Endpoint', "Severity": "High" } assert fake_safebreach_context['Id'] == context['SafeBreach.Insight(val.Id == obj.Id)'][0]['Id'] assert fake_safebreach_context['Category'] == context['SafeBreach.Insight(val.Id == obj.Id)'][0]['Category'] assert fake_safebreach_context['Severity'] == context['SafeBreach.Insight(val.Id == obj.Id)'][0]['Severity'] assert len(res) == 1 def test_get_remediation_data(requests_mock, mocker): mocker.patch.object(demisto, 'args', return_value={'insightId': INSIGHT_ID}) mocker.patch.object(demisto, 'results') mocker.patch.object(demisto, 'params', return_value={'url': MOCK_URL}) requests_mock.get(f'{MOCK_URL}/api/data/v1/accounts/{MOCK_ACCOUNT_ID}/insights?type=actionBased', json=GET_INSIGHTS_LIST) requests_mock.get(f'{MOCK_URL}/api/data/v1/accounts/{MOCK_ACCOUNT_ID}/insights/{INSIGHT_ID}/remediation', json=REMEDATION_DATA_LIST) requests_mock.get( f'{MOCK_URL}/api/config/v1/accounts/{MOCK_ACCOUNT_ID}/nodes?details=true&deleted=true&assets=true', json=NODES) get_remediation_data_command(client, demisto.args(), True) assert demisto.results.call_count == 1 outputs = demisto.results.call_args[0][0] context = outputs['EntryContext'] sha256_to_check = '109c702578b261d0eda01506625423f5a2b8cc107b0d8dfad84d39fb02bfa5cb' assert context['SafeBreach.Insight(val.Id == obj.Id)'][0]['Id'] == INSIGHT_ID assert context['SafeBreach.Insight(val.Id == obj.Id)'][0]['RawRemediationData'][0]['type'] == 'SHA256' assert context['SafeBreach.Insight(val.Id == obj.Id)'][0]['RawRemediationData'][0]['value'] == sha256_to_check assert context['File(val.SHA256 == obj.SHA256)'][0]['SHA256'] == sha256_to_check assert context['DBotScore(val.Indicator == obj.Indicator)'][0]['Indicator'] == sha256_to_check def test_rerun_insight(requests_mock, mocker): mocker.patch.object(demisto, 'args', return_value={'insightIds': '9'}) mocker.patch.object(demisto, 'results') response = { "data": { "name": "Insight (XSOAR) - Test", "moveIds": [ 1, 2, 3, 4, ], "nodeIds": ['nodeID1', 'nodeID2'], "draft": False, "ranBy": -1, "ranFrom": "UI", "isRerun": True, "assetIds": [], "moveSetIds": [], "force": True, "queueId": 107, "runId": "1584966046845.34", "pauseDuration": 0, "pausePeriods": [], "totalJobs": 0 } } requests_mock.post(f'{MOCK_URL}/api/orch/v1/accounts/{MOCK_ACCOUNT_ID}/queue', json=response) requests_mock.get(f'{MOCK_URL}/api/data/v1/accounts/{MOCK_ACCOUNT_ID}/insights?type=actionBased', json=GET_INSIGHTS_LIST) insight_rerun_command(client, demisto.args()) assert demisto.results.call_count == 1 outputs = demisto.results.call_args[0][0] context = outputs['EntryContext'] assert context['SafeBreach.Insight(val.Id == obj.Id)'][0]['Id'] == int(INSIGHT_ID) assert context['SafeBreach.Insight(val.Id == obj.Id)'][0]['Rerun'][0]['Id'] == response['data']['runId'] def test_get_indicators(requests_mock, mocker): mocker.patch.object(demisto, 'args', return_value={'limit': '10'}) mocker.patch.object(demisto, 'results') mocker.patch.object(demisto, 'params', return_value={'url': MOCK_URL}) for insight_id in [5, 6, 8, 9, 13, 14, 17]: requests_mock.get(f'{MOCK_URL}/api/data/v1/accounts/{MOCK_ACCOUNT_ID}/insights/{insight_id}/remediation', json=REMEDATION_DATA_LIST) requests_mock.get( f'{MOCK_URL}/api/data/v1/accounts/{MOCK_ACCOUNT_ID}/insights?type=actionBased', json=GET_INSIGHTS_LIST) requests_mock.get( f'{MOCK_URL}/api/config/v1/accounts/{MOCK_ACCOUNT_ID}/nodes?details=true&deleted=true&assets=true', json=NODES) insight_category = ['Endpoint', 'Web'] insight_data_type = ['Hash', 'Domain'] hash_to_search = '109c702578b261d0eda01506625423f5a2b8cc107b0d8dfad84d39fb02bfa5cb' res = get_indicators_command(client, insight_category, insight_data_type, 'AMBER', demisto.args()) assert demisto.results.call_count == 0 assert res[0]['value'] == hash_to_search assert res[0]['type'] == 'File' def test_get_indicators_exception(requests_mock, mocker): mocker.patch.object(demisto, 'args', return_value={'limit': '10'}) mocker.patch.object(demisto, 'results') mocker.patch.object(demisto, 'params', return_value={'url': MOCK_URL}) for insight_id in [5, 6, 8, 9, 13, 14, 17]: requests_mock.get(f'{MOCK_URL}/api/data/v1/accounts/{MOCK_ACCOUNT_ID}/insights/{insight_id}/remediation', json=REMEDATION_DATA_LIST_UNVAILD_STRING) requests_mock.get( f'{MOCK_URL}/api/data/v1/accounts/{MOCK_ACCOUNT_ID}/insights?type=actionBased', json=GET_INSIGHTS_LIST) requests_mock.get( f'{MOCK_URL}/api/config/v1/accounts/{MOCK_ACCOUNT_ID}/nodes?details=true&deleted=true&assets=true', json=NODES) insight_category = ['Endpoint', 'Web'] insight_data_type = ['Hash', 'Domain'] hash_to_search = '0000000000000000000000000000000000000000000000000000000000000000' res = get_indicators_command(client, insight_category, insight_data_type, 'AMBER', demisto.args()) assert demisto.results.call_count == 0 assert res[0]['value'] == hash_to_search assert res[0]['type'] == 'File' def test_get_simulation(requests_mock, mocker): mocker.patch.object(demisto, 'args', return_value={'simulationId': SIMULATION_ID}) mocker.patch.object(demisto, 'results') requests_mock.get(f'{MOCK_URL}/api/data/v1/accounts/{MOCK_ACCOUNT_ID}/executions/{SIMULATION_ID}', json=SIMULATION) get_safebreach_simulation_command(client, demisto.args()) assert demisto.results.call_count == 1 outputs = demisto.results.call_args[0][0] context = outputs['EntryContext'] assert context['SafeBreach.Simulation(val.Id == obj.Id)']['Id'] == SIMULATION_ID def test_rerun_simulation(requests_mock, mocker): mocker.patch.object(demisto, 'args', return_value={'simulationId': SIMULATION_ID}) mocker.patch.object(demisto, 'results') response = { "data": { "name": "Rerun (Demisto) - Simulation", "moveIds": [ 1, 2, 3, 4, ], "nodeIds": ['nodeID1', 'nodeID2'], "draft": False, "ranBy": -1, "ranFrom": "UI", "isRerun": True, "assetIds": [], "moveSetIds": [], "force": True, "queueId": 107, "runId": "1584966046845.34", "pauseDuration": 0, "pausePeriods": [], "totalJobs": 0 } } requests_mock.post(f'{MOCK_URL}/api/orch/v1/accounts/{MOCK_ACCOUNT_ID}/queue', json=response) requests_mock.get(f'{MOCK_URL}/api/data/v1/accounts/{MOCK_ACCOUNT_ID}/executions/{SIMULATION_ID}', json=SIMULATION) rerun_simulation_command(client, demisto.args()) assert demisto.results.call_count == 1 outputs = demisto.results.call_args[0][0] context = outputs['EntryContext'] assert context['SafeBreach.Simulation(val.Id == obj.Id)']['Id'] == SIMULATION_ID assert context['SafeBreach.Simulation(val.Id == obj.Id)']['Rerun']['Id'] == response['data']['runId'] @pytest.mark.parametrize('tlp_color', ['', None, 'AMBER']) def test_feed_tags_and_tlp_color(requests_mock, mocker, tlp_color): """ Given: - client which has tag params - different values for tlp_color When: - Executing get indicators command on feed Then: - Validate the tags supplied are added to the tags list in addition to the tags that were there before - Validate that trafficlightprotocol indicator type is assigned correctly """ mocker.patch.object(demisto, 'args', return_value={'limit': '10'}) mocker.patch.object(demisto, 'results') mocker.patch.object(demisto, 'params', return_value={'url': MOCK_URL}) for insight_id in [5, 6, 8, 9, 13, 14, 17]: requests_mock.get(f'{MOCK_URL}/api/data/v1/accounts/{MOCK_ACCOUNT_ID}/insights/{insight_id}/remediation', json=REMEDATION_DATA_LIST) requests_mock.get( f'{MOCK_URL}/api/data/v1/accounts/{MOCK_ACCOUNT_ID}/insights?type=actionBased', json=GET_INSIGHTS_LIST) requests_mock.get( f'{MOCK_URL}/api/config/v1/accounts/{MOCK_ACCOUNT_ID}/nodes?details=true&deleted=true&assets=true', json=NODES) insight_category = ['Endpoint', 'Web'] insight_data_type = ['Hash', 'Domain'] res = get_indicators_command(client, insight_category, insight_data_type, tlp_color, demisto.args()) assert all(elem in res[0]['fields']['tags'] for elem in ['tag1', 'tag2']) if tlp_color: assert res[0]['fields']['trafficlightprotocol'] == tlp_color else: assert not res[0]['fields'].get('trafficlightprotocol')