StellarCyber
Fetches and mirrors in Cases from Stellar Cyber to XSOAR. In addition, provides a command to update Case severity/status/assignee/tags, and a command to query an Alert.
Analytics & SIEM · Stellar Cyber
Details
| ID | StellarCyber |
|---|---|
| Provider | Stellar Cyber |
| Category | Analytics & SIEM |
| From Version | 6.10.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
README
Fetches and mirrors in Cases from Stellar Cyber to XSOAR. In addition, provides a command to update Case severity/status/assignee/tags, and a command to query an Alert.
This integration was integrated and tested with version >= 4.3.7/5.0.4 of StellarCyber.
Configure Stellar Cyber in Cortex
| Parameter | Description | Required |
|---|---|---|
| Fetch incidents | ||
| Incident type | ||
| Mirroring Direction | If set to Incoming, will mirror Cases from Stellar Cyber to XSOAR. If set to None, will not mirror Cases from Stellar Cyber to XSOAR. Default is None. | False |
| Stellar Cyber Host (e.g. example.stellarcyber.cloud) | Your Stellar Cyber Host FQDN. | True |
| API User (Email Address) | True | |
| API Key | True | |
| First fetch time | The period of time to look back for initial pull of cases. (<number> <time unit>, i.e. 1 day, 5 hours, 30 minutes, etc.) | False |
| Trust any certificate (not secure) | False | |
| Use system proxy settings | If set to true, will use the system proxy settings. | False |
| Incidents Fetch Interval | The interval in minutes for fetching incidents from Stellar Cyber. | False |
| Optional - Tenant ID | Supply a Tenant ID to restrict Fetch and Mirror operations to a specific Tenant. If not supplied, all Tenants will be included. | False |
| Maximum number of incidents per fetch | The maximum number of incidents to fetch per fetch. | False |
Incident Mirroring
You can enable incident mirroring between Cortex XSOAR incidents and Stellar Cyber corresponding events (available from Cortex XSOAR version 6.0.0).
To set up the mirroring:
- Enable Fetching incidents in your instance configuration.
-
In the Mirroring Direction integration parameter, select in which direction the incidents should be mirrored:
Option Description None Turns off incident mirroring. Incoming Any changes in Stellar Cyber events (mirroring incoming fields) will be reflected in Cortex XSOAR incidents.
Newly fetched incidents will be mirrored in the chosen direction. However, this selection does not affect existing incidents.
Important Note: To ensure the mirroring works as expected, mappers are required, both for incoming and outgoing, to map the expected fields in Cortex XSOAR and Stellar Cyber.
Commands
You can execute these commands from the 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.
stellar-get-alert
Retrieve an alert from Stellar Cyber.
Base Command
stellar-get-alert
Input
| Argument Name | Description | Required |
|---|---|---|
| alert_id | The ID of the alert to retrieve. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| StellarCyber.Alert.alert_id | String | ID of the Stellar Cyber Alert. |
| StellarCyber.Alert.alert_index | String | Index of the Stellar Cyber Alert. |
| StellarCyber.Alert.alert_metadata.description | String | Description of the Stellar Cyber Alert. |
| StellarCyber.Alert.alert_metadata.display_name | String | Display Name of the Stellar Cyber Alert. |
| StellarCyber.Alert.alert_metadata.framework_version | String | Framework Version of the Stellar Cyber Alert. |
| StellarCyber.Alert.alert_metadata.name | String | Name of the Stellar Cyber Alert. |
| StellarCyber.Alert.alert_metadata.scope | String | Scope of the Stellar Cyber Alert. |
| StellarCyber.Alert.alert_metadata.tactic.id | String | Tactic ID of the Stellar Cyber Alert. |
| StellarCyber.Alert.alert_metadata.tactic.name | String | Tactic Name of the Stellar Cyber Alert. |
| StellarCyber.Alert.alert_metadata.tags | String | Tags of the Stellar Cyber Alert. |
| StellarCyber.Alert.alert_metadata.technique.id | String | Technique ID of the Stellar Cyber Alert. |
| StellarCyber.Alert.alert_metadata.technique.name | String | Technique Name of the Stellar Cyber Alert. |
| StellarCyber.Alert.alert_metadata.ttps.tactic.id | String | Tactic ID of the Stellar Cyber Alert. |
| StellarCyber.Alert.alert_metadata.ttps.tactic.name | String | Tactic Name of the Stellar Cyber Alert. |
| StellarCyber.Alert.alert_metadata.ttps.technique.id | String | Technique ID of the Stellar Cyber Alert. |
| StellarCyber.Alert.alert_metadata.ttps.technique.name | String | Technique Name of the Stellar Cyber Alert. |
| StellarCyber.Alert.alert_metadata.xdr_killchain_stage | String | XDR Killchain Stage. |
| StellarCyber.Alert.alert_metadata.xdr_killchain_version | String | XDR Killchain Version. |
| StellarCyber.Alert.alert_url | String | URL to the Stellar Cyber Alert. |
| StellarCyber.Alert.description | String | Description of the Stellar Cyber Alert. |
| StellarCyber.Alert.detected_field | String | Detected Field(s) of the Stellar Cyber Alert. |
| StellarCyber.Alert.detected_value | String | Detected Value(s) of the Stellar Cyber Alert. |
| StellarCyber.Alert.display_name | String | Display Name of the Stellar Cyber Alert. |
| StellarCyber.Alert.tenant_id | String | Tenant ID of the Stellar Cyber Alert. |
| StellarCyber.Alert.tenant_name | String | Tenant Name of the Stellar Cyber Alert. |
| StellarCyber.Alert.xdr_tactic_id | String | XDR Tactic ID of the Stellar Cyber Alert. |
| StellarCyber.Alert.xdr_tactic_name | String | XDR Tactic Name of the Stellar Cyber Alert. |
| StellarCyber.Alert.xdr_technique_id | String | XDR Technique ID of the Stellar Cyber Alert. |
| StellarCyber.Alert.xdr_technique_name | String | XDR Technique Name of the Stellar Cyber Alert. |
stellar-update-case
Update the severity, status, assignee, or tags of a Case in Stellar Cyber.
Base Command
stellar-update-case
Input
| Argument Name | Description | Required |
|---|---|---|
| stellar_case_id | The ID of the Case to update. | Required |
| stellar_case_severity | The severity to set the Case to in Stellar Cyber. Possible values are: Low, Medium, High, Critical. | Optional |
| stellar_case_status | The status to set the Case to. Possible values are: New, In Progress, Resolved, Cancelled. | Optional |
| stellar_case_assignee | The email or username in to assign to Case in Stellar Cyber. | Optional |
| stellar_case_tags_add | List of tags to add to Case in Stellar Cyber. | Optional |
| stellar_case_tags_remove | List of tags to add remove from Case in Stellar Cyber. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| StellarCyber.Case.Update._id | String | Case ID. |
| StellarCyber.Case.Update.assignee | String | Case Assignee. |
| StellarCyber.Case.Update.created_at | Date | Case Created Timestamp. |
| StellarCyber.Case.Update.created_by | String | Case Created By. |
| StellarCyber.Case.Update.cust_id | String | Case Tenant ID. |
| StellarCyber.Case.Update.modified_at | Date | Case Modified Timestamp. |
| StellarCyber.Case.Update.modified_by | String | Case Modified By. |
| StellarCyber.Case.Update.name | String | Case Name. |
| StellarCyber.Case.Update.size | Number | Case Size (Number of Alerts). |
| StellarCyber.Case.Update.status | String | Case Status. |
| StellarCyber.Case.Update.tags | Unknown | Case Tags. |
| StellarCyber.Case.Update.ticket_id | Number | Case Ticket ID. |
| StellarCyber.Case.Update.version | Number | Case Version. |
| StellarCyber.Case.Update.priority | String | Case Priority. |
| StellarCyber.Case.Update.incident_score | Number | Case Score. |
| StellarCyber.Case.Update.assignee_name | String | Case Assignee Name. |
get-remote-data
Gets remote data from a remote incident. This method is only used for debugging purposes and will not update the current incident.
Base Command
get-remote-data
Input
| Argument Name | Description | Required |
|---|---|---|
| id | The remote incident ID. | Required |
| lastUpdate | UTC timestamp in seconds. The incident is only updated if it was modified after the last update time. Default is 0. | Optional |
Context Output
There is no context output for this command.
get-modified-remote-data
Available from Cortex XSOAR version 6.1.0. This command queries for incidents that were modified since the last update. This method is only used for debugging purposes.
Base Command
get-modified-remote-data
Input
| Argument Name | Description | Required |
|---|---|---|
| lastUpdate | UTC timestamp in seconds. The incident is only updated if it was modified after the last update time. | Required |
Context Output
There is no context output for this command.
Configuration parameters
isFetch— Fetch incidentsincidentType— Incident typemirror_direction— Mirroring Directionstellar_dp— Stellar Cyber Host (e.g. example.stellarcyber.cloud) (required)credentials— API User (Email Address) (required)first_fetch— First fetch timeinsecure— Trust any certificate (not secure)proxy— Use system proxy settingsincidentFetchInterval— Incidents Fetch Intervaltenantid— Optional - Tenant IDmax_fetch— Maximum number of incidents per fetch
Commands (4)
-
get-modified-remote-dataAvailable from Cortex XSOAR version 6.1.0. This command queries for incidents that were modified since the last update. This method is only used for debugging purposes.
-
get-remote-dataGets remote data from a remote incident. This method is only used for debugging purposes and will not update the current incident.
-
stellar-get-alertRetrieve an alert from Stellar Cyber.
-
stellar-update-caseUpdate the severity, status, assignee, or tags of a Case in Stellar Cyber.
import pytest from CommonServerPython import * from StellarCyber import ( Client, get_alert_command, update_case_command, fetch_incidents, get_modified_remote_data_command, get_remote_data_command, demisto_alert_normalization, get_xsoar_severity, ) SERVER_URL = "https://test.example.com" def util_load_json(path): with open(path) as f: return json.loads(f.read()) @pytest.fixture() def client(): return Client(dp_host="test.example.com", username="test", password="test", verify=True, proxy=False, tenantid=None) def test_get_alert_command(client, requests_mock): args = {"alert_id": "1710883791406342b1f41b2247774d60bf035a6f98e5ff21"} mock_response_get_alert = util_load_json("./test_data/outputs/get_alert.json") mock_results = util_load_json("./test_data/outputs/get_alert_command.json") mock_token = {"data": {"access_token": "example", "expiration_utc": time.ctime(time.time() + 10000)}} requests_mock.post(f"{SERVER_URL}/connect/api/v1/access_token", json=mock_token) requests_mock.get(f"{SERVER_URL}/connect/api/data/aella-ser-*/_search?q=_id:{args['alert_id']}", json=mock_response_get_alert) results = get_alert_command(client=client, args=args) assert results.outputs_prefix == "StellarCyber.Alert" assert results.outputs_key_field == "alert_id" assert results.outputs == mock_results.get("outputs") def test_update_case_command(client, requests_mock): args = {"stellar_case_id": "65f340d9b190d36b26ad2bdc", "stellar_case_status": "New"} mock_response_update_case = util_load_json("./test_data/outputs/update_case.json") mock_results = util_load_json("./test_data/outputs/update_case_command.json") mock_token = {"data": {"access_token": "example", "expiration_utc": time.ctime(time.time() + 10000)}} requests_mock.post(f"{SERVER_URL}/connect/api/v1/access_token", json=mock_token) requests_mock.post(f'{SERVER_URL}/connect/api/v1/incidents?id={args["stellar_case_id"]}', json=mock_response_update_case) results = update_case_command(client=client, args=args) assert results.outputs_prefix == "StellarCyber.Case.Update" assert results.outputs_key_field == "_id" assert results.outputs == mock_results.get("outputs") def test_fetch_incidents(client, requests_mock): mock_token = {"data": {"access_token": "example", "expiration_utc": time.ctime(time.time() + 10000)}} mock_new_incidents = util_load_json("./test_data/outputs/get_new_incidents.json") mock_case_summary = util_load_json("./test_data/outputs/get_incident_summary.json") mock_response_get_alert = util_load_json("./test_data/outputs/get_alert.json") params = {"first_fetch": "3 days", "max_fetch": 200, "mirror_direction": "None"} test_incident_id = "65f9d988b190d36b26ad2e02" test_alert_id = "1710883791406342b1f41b2247774d60bf035a6f98e5ff21" mock_response_fetch_incidents = util_load_json("./test_data/outputs/fetch_incidents.json") requests_mock.post(f"{SERVER_URL}/connect/api/v1/access_token", json=mock_token) requests_mock.get(f"{SERVER_URL}/connect/api/v1/incidents", json=mock_new_incidents) requests_mock.get(f"{SERVER_URL}/connect/api/v1/cases/{test_incident_id}/summary", json=mock_case_summary) requests_mock.get( f"{SERVER_URL}/connect/api/data/stellar-index-v1-ser-5593fbd8b0444b1eaef5a89589d788d2-64486c346020c889507f32ae-2024.03.07-000033/_search?q=_id:{test_alert_id}", # noqa: E501 json=mock_response_get_alert, ) results = fetch_incidents(client, params) assert results == mock_response_fetch_incidents def test_get_modified_remote_data_command(client, requests_mock): args = {"lastUpdate": "2021-05-01T00:00:00"} mock_get_updated_cases = util_load_json("./test_data/outputs/get_new_incidents.json") mock_token = {"data": {"access_token": "example", "expiration_utc": time.ctime(time.time() + 10000)}} requests_mock.post(f"{SERVER_URL}/connect/api/v1/access_token", json=mock_token) requests_mock.get(f"{SERVER_URL}/connect/api/v1/incidents", json=mock_get_updated_cases) results = get_modified_remote_data_command(client=client, args=args) assert results.modified_incident_ids == ["7443:6aeb2aae7d8d4ef0820136f42d107db4"] # type: ignore def test_get_remote_data_command(client, requests_mock): args = {"id": "7443:6aeb2aae7d8d4ef0820136f42d107db4", "lastUpdate": "2021-05-01T00:00:00"} mock_get_updated_case = util_load_json("./test_data/outputs/get_new_incidents.json") mock_case_summary = util_load_json("./test_data/outputs/get_incident_summary.json") mock_response_get_alert = util_load_json("./test_data/outputs/get_alert.json") mock_command_response = util_load_json("./test_data/outputs/fetch_incidents.json") mock_command_response = json.loads(mock_command_response[0].get("rawJSON")) del mock_command_response["mirror_direction"] del mock_command_response["mirror_id"] del mock_command_response["mirror_instance"] mock_token = {"data": {"access_token": "example", "expiration_utc": time.ctime(time.time() + 10000)}} test_incident_id = "65f9d988b190d36b26ad2e02" test_alert_id = "1710883791406342b1f41b2247774d60bf035a6f98e5ff21" requests_mock.post(f"{SERVER_URL}/connect/api/v1/access_token", json=mock_token) requests_mock.get(f"{SERVER_URL}/connect/api/v1/incidents", json=mock_get_updated_case) requests_mock.get(f"{SERVER_URL}/connect/api/v1/cases/{test_incident_id}/summary", json=mock_case_summary) requests_mock.get( f"{SERVER_URL}/connect/api/data/stellar-index-v1-ser-5593fbd8b0444b1eaef5a89589d788d2-64486c346020c889507f32ae-2024.03.07-000033/_search?q=_id:{test_alert_id}", # noqa: E501 json=mock_response_get_alert, ) results = get_remote_data_command(client=client, args=args) # print(results.mirrored_object) assert results.mirrored_object == mock_command_response # type: ignore def test_demisto_alert_normalization(): test_alert = { "xdr_event": { "tactic": {"name": "Test Tactic", "id": "TTA-001"}, "technique": {"name": "Test Technique", "id": "TTE-001"}, "display_name": "Test Display Name", "description": "Test Description", }, "tenantid": "", "tenant_name": "Test Tenant", "detected_field": "test_field", "detected_value": "Test Value", } test_alert_id = "1710883791406342b1f41b2247774d60bf035a6f98e5ff21" test_alert_index = "aella-ser-*" test_dp_host = "test.example.com" results = demisto_alert_normalization(test_alert, test_alert_id, test_alert_index, test_dp_host) assert results.get("alert_id") == test_alert_id assert results.get("alert_index") == test_alert_index def test_get_xsoar_severity(): test_severity = "High" results = get_xsoar_severity(test_severity) assert results == 3