Cognni
Autonomous detection and investigation of information security incidents and other potential threats.
Utilities · Cognni
Details
| ID | Cognni |
|---|---|
| Provider | Cognni |
| Category | Utilities |
| From Version | 5.0.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
The Cognni connector offers a quick and simple integration with Cortex XSOAR
in order to provide ongoing insights into how your important information is used.
With Cognni, you can autonomously detect information-specific incidents
based on contextual factors, and automatically compile insights to investigate
how incidents occur. This intelligence provides the details you need to remediate
incidents, fast enough to make a difference.
This integration was integrated and tested with version 1.0 of Cognni
Configure Cognni in Cortex
| Parameter | Description | Required |
|---|---|---|
| url | Server URL | True |
| isFetch | Fetch incidents | False |
| incidentType | Incident type | False |
| max_fetch | Maximum number of events per fetch | False |
| apikey | API Key | True |
| min_severity | Minimum severity of alerts to fetch | True |
| first_fetch | First fetch time | False |
| insecure | Trust any certificate (not secure) | False |
| proxy | Use system proxy settings | False |
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.
cognni-get-event
Fetches a single event by ID.
Base Command
cognni-get-event
Input
| Argument Name | Description | Required |
|---|---|---|
| event_id | The ID of the event to fetch. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Cognni.Event.id | String | Event ID. |
| Cognni.Event.date | Date | The date when the event occurred. |
| Cognni.Event.description | String | Description of the event. |
| Cognni.Event.severity | Number | Severity of the event. |
| Cognni.Event.sourceApplication | String | The ID of the application which initiated the event. |
Command Example
!cognni-get-event event_id="9ba7fb56-8ace-4b3d-a1e9-08c466668e57"
Context Example
{
"Cognni": {
"event": {
"id": "9ba7fb56-8ace-4b3d-a1e9-08c466668e57",
"description": "N/A",
"sourceApplication": "Exchange",
"date": "2020-11-25T00:46:14.000Z"
}
}
}
Human Readable Output
Cognni event 9ba7fb56-8ace-4b3d-a1e9-08c466668e57
date description id sourceApplication 2020-11-25T00:46:14.000Z N/A 9ba7fb56-8ace-4b3d-a1e9-08c466668e57 Exchange
cognni-get-insight
Fetches a single insight by ID.
Base Command
cognni-get-insight
Input
| Argument Name | Description | Required |
|---|---|---|
| insight_id | The ID of the insight to fetch. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Cognni.insight.id | String | Insight ID. |
| Cognni.insight.name | String | Name of the insight. |
| Cognni.insight.description | String | Description of the insight. |
| Cognni.insight.severity | Number | Severity of the insight. |
Command Example
!cognni-get-insight insight_id="74a53ab3-3e75-4444-9e7c-0be1e1bc26a9"
Context Example
{
"Cognni": {
"insights": {
"id": "c24405d5-49f5-48b8-b15c-1a1aba540979",
"name": "Medium sensitivity content, Shared to private email address",
"description": null,
"severity": 2
}
}
}
Human Readable Output
Cognni 1 insight
description id name severity c24405d5-49f5-48b8-b15c-1a1aba540979 Medium sensitivity content, Shared to private email address 2
cognni-fetch-insights
Fetches insights according to severity.
Base Command
cognni-fetch-insights
Input
| Argument Name | Description | Required |
|---|---|---|
| min_severity | Minimum severity of insights to fetch. Default is 2. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Cognni.insights.id | String | List of insight IDs. |
| Cognni.insights.name | String | List of insight names. |
| Cognni.insights.description | String | List of insight descriptions. |
| Cognni.insights.severity | Number | List of insight severities. |
Command Example
!cognni-fetch-insights min_severity=2
Context Example
{
"Cognni": {
"insights": [
{
"description": null,
"id": "4539ff6d-c58b-4a2a-a509-f121edbe97d7",
"name": "High sensitive Anonymous share",
"severity": 3
},
{
"description": null,
"id": "0875799c-6077-4f5f-b276-0e7baa2b89ab",
"name": "High sensitive content Shared inside the organization Anomaly",
"severity": 2
},
{
"description": null,
"id": "169b10e0-0970-430b-9709-61ccc312fdd0",
"name": "High Sensitive content Shared Outside the organization Anomaly",
"severity": 3
},
{
"description": null,
"id": "4cf8297f-b311-4cfa-9e8e-935606907e5f",
"name": "High Sensitive content Shared to private email address",
"severity": 3
},
{
"description": null,
"id": "537aa700-0eed-4998-b253-f809e1eacc00",
"name": "High sensitive content Shared to private email Address Anomaly",
"severity": 3
},
{
"description": null,
"id": "df061da3-13c1-4a59-8501-4d26bacd5b83",
"name": "Low Sensitive content Anonymous Share",
"severity": 2
},
{
"description": null,
"id": "c7723427-b075-4259-8fbc-19dab3861b92",
"name": "Low sensitive content Shared to private email address Anomaly",
"severity": 2
},
{
"description": null,
"id": "846c753b-1feb-4d21-ae43-ec81b9725636",
"name": "Medium sensitivity content, Anonymous share",
"severity": 3
},
{
"description": null,
"id": "f964659c-9cc3-4833-b535-0402cd953376",
"name": "Medium sensitivity content Shared outside the organization Anomaly",
"severity": 2
},
{
"description": null,
"id": "c24405d5-49f5-48b8-b15c-1a1aba540979",
"name": "Medium sensitivity content, Shared to private email address",
"severity": 2
},
{
"description": null,
"id": "c925372e-c2d5-4b61-b37e-399263ad58f9",
"name": "Medium sensitivity content Shared to private email Address Anomaly",
"severity": 3
}
]
}
}
Human Readable Output
Cognni 11 insights
description id name severity 4539ff6d-c58b-4a2a-a509-f121edbe97d7 High sensitive Anonymous share 3 0875799c-6077-4f5f-b276-0e7baa2b89ab High sensitive content Shared inside the organization Anomaly 2 169b10e0-0970-430b-9709-61ccc312fdd0 High Sensitive content Shared Outside the organization Anomaly 3 4cf8297f-b311-4cfa-9e8e-935606907e5f High Sensitive content Shared to private email address 3 537aa700-0eed-4998-b253-f809e1eacc00 High sensitive content Shared to private email Address Anomaly 3 df061da3-13c1-4a59-8501-4d26bacd5b83 Low Sensitive content Anonymous Share 2 c7723427-b075-4259-8fbc-19dab3861b92 Low sensitive content Shared to private email address Anomaly 2 846c753b-1feb-4d21-ae43-ec81b9725636 Medium sensitivity content, Anonymous share 3 f964659c-9cc3-4833-b535-0402cd953376 Medium sensitivity content Shared outside the organization Anomaly 2 c24405d5-49f5-48b8-b15c-1a1aba540979 Medium sensitivity content, Shared to private email address 2 c925372e-c2d5-4b61-b37e-399263ad58f9 Medium sensitivity content Shared to private email Address Anomaly 3
Configuration parameters
url— Server URL (required)isFetch— Fetch incidentsincidentType— Incident typeincidentFetchInterval— Incidents Fetch Intervalmax_fetch— Maximum number of events per fetchapikey— API Key (required)min_severity— Minimum severity of alerts to fetch (required)first_fetch— First fetch timeinsecure— Trust any certificate (not secure)proxy— Use system proxy settings
Commands (3)
-
cognni-fetch-insightsFetches insights according to severity.
-
cognni-get-eventFetches a single event by ID.
-
cognni-get-insightFetches a single insight by ID.
import json def util_load_json(path): with open(path, encoding="utf-8") as f: return json.loads(f.read()) def test_fetch_incidents(requests_mock): """Tests the fetch-incidents function""" from Cognni import Client, fetch_incidents mock_response = util_load_json("test_data/fetch_incidents.json") requests_mock.post("https://localhost/intelligence/data/graphql", json=mock_response) client = Client(base_url="https://localhost", verify=False, headers={"Authorization": "Bearer some_api_key"}) first_fetch_time = 1600000000 last_run = {} min_severity = 0 next_run, incidents = fetch_incidents( client=client, events_limit=10, first_fetch_time=first_fetch_time, last_run=last_run, min_severity=min_severity ) assert next_run["last_fetch"] > first_fetch_time assert len(incidents) == 8 def test_get_event_with_special_character(requests_mock): """Tests the get event command when event id contains special characters""" from Cognni import Client, get_event_command mock_response = util_load_json("test_data/get_event_with_special_character.json") requests_mock.post("https://localhost/intelligence/data/graphql", json=mock_response) client = Client(base_url="https://localhost", verify=False, headers={"Authorization": "Bearer some_api_key"}) event_id = "a!@#" args = {"event_id": event_id} response = get_event_command(client, args) # assert response.outputs[0] == mock_response assert response.raw_response is None def test_get_event_with_whitespace(requests_mock): """Tests the get event command when event id contains whitespaces""" from Cognni import Client, get_event_command mock_response = util_load_json("test_data/get_event_with_whitespace.json") requests_mock.post("https://localhost/intelligence/data/graphql", json=mock_response) client = Client(base_url="https://localhost", verify=False, headers={"Authorization": "Bearer some_api_key"}) event_id = "Test with whitespaces" args = {"event_id": event_id} response = get_event_command(client, args) # assert response.outputs[0] == mock_response assert response.raw_response is None def test_get_insight_with_whitespace(requests_mock): """Tests the get insight command when insight id contains whitespaces""" from Cognni import Client, get_insight_command mock_response = util_load_json("test_data/get_insight_with_whitespace.json") requests_mock.post("https://localhost/intelligence/data/graphql", json=mock_response) client = Client(base_url="https://localhost", verify=False, headers={"Authorization": "Bearer some_api_key"}) insight_id = "Test with whitespaces" args = {"insight_id": insight_id} response = get_insight_command(client, args) # assert response.outputs[0] == mock_response assert response.outputs_prefix == "Cognni.insight" assert response.raw_response["id"] is None def test_get_insight_with_special_characters(requests_mock): """Tests the get insight command with unexist insight id""" from Cognni import Client, get_insight_command mock_response = util_load_json("test_data/get_insight_with_special_characters.json") requests_mock.post("https://localhost/intelligence/data/graphql", json=mock_response) client = Client(base_url="https://localhost", verify=False, headers={"Authorization": "Bearer some_api_key"}) insight_id = "a!@#$%^&*()1" args = {"insight_id": insight_id} response = get_insight_command(client, args) assert response.raw_response["id"] is None def test_get_event(requests_mock): """Tests the get event command""" from Cognni import Client, get_event_command mock_response = util_load_json("test_data/get_event.json") requests_mock.post("https://localhost/intelligence/data/graphql", json=mock_response) client = Client(base_url="https://localhost", verify=False, headers={"Authorization": "Bearer some_api_key"}) event_id = "df247df1-dd27-4bba-ac04-bc7d5dbf414c" args = {"event_id": event_id} response = get_event_command(client, args) # assert response.outputs[0] == mock_response assert response.outputs_prefix == "Cognni.event" assert response.raw_response["id"] == event_id def test_get_event_with_unknown_id(requests_mock): from Cognni import Client, get_event_command mock_response = util_load_json("test_data/get_event_with_unknown_id.json") requests_mock.post("https://localhost/intelligence/data/graphql", json=mock_response) client = Client(base_url="https://localhost", verify=False, headers={"Authorization": "Bearer some_api_key"}) event_id = "df247df1-dd27-4bba-ac04-bc7d5dbf414d" args = {"event_id": event_id} response = get_event_command(client, args) # assert response.outputs[0] == mock_response assert response.raw_response is None def test_get_insight(requests_mock): """Tests the get insight command""" from Cognni import Client, get_insight_command mock_response = util_load_json("test_data/get_insight.json") requests_mock.post("https://localhost/intelligence/data/graphql", json=mock_response) client = Client(base_url="https://localhost", verify=False, headers={"Authorization": "Bearer some_api_key"}) insight_id = "740b5296-6d62-41e5-b0d7-1a7d5081f9cb" args = {"insight_id": insight_id} response = get_insight_command(client, args) # assert response.outputs[0] == mock_response assert response.outputs_prefix == "Cognni.insight" assert response.raw_response["id"] == insight_id def test_get_insight_with_unknown_id(requests_mock): from Cognni import Client, get_insight_command mock_response = util_load_json("test_data/get_insight_with_unknown_id.json") requests_mock.post("https://localhost/intelligence/data/graphql", json=mock_response) client = Client(base_url="https://localhost", verify=False, headers={"Authorization": "Bearer some_api_key"}) insight_id = "1234" args = {"insight_id": insight_id} response = get_insight_command(client, args) assert response.raw_response["id"] is None def test_fetch_insights(requests_mock): """Tests the fetch-insights command""" from Cognni import Client, fetch_insights_command mock_response = util_load_json("test_data/fetch_insights.json") requests_mock.post("https://localhost/intelligence/data/graphql", json=mock_response) client = Client(base_url="https://localhost", verify=False, headers={"Authorization": "Bearer some_api_key"}) args = {"min_severity": 0} response = fetch_insights_command(client, args) assert response.outputs_prefix == "Cognni.insights" assert len(response.raw_response) == 1 def test_fetch_insight_with_small_severity(requests_mock): from Cognni import Client, fetch_insights_command mock_response = util_load_json("test_data/fetch_insights_with_small_severity.json") requests_mock.post("https://localhost/intelligence/data/graphql", json=mock_response) client = Client(base_url="https://localhost", verify=False, headers={"Authorization": "Bearer some_api_key"}) min_severity = -1 args = {"min_severity": min_severity} response = fetch_insights_command(client, args) assert response.outputs_prefix == "Cognni.insights" if len(response.raw_response) > 0: for answer in response.raw_response: assert answer["severity"] >= min_severity def test_fetch_insight_with_large_severity(requests_mock): from Cognni import Client, fetch_insights_command mock_response = util_load_json("test_data/fetch_insights_with_large_severity.json") requests_mock.post("https://localhost/intelligence/data/graphql", json=mock_response) client = Client(base_url="https://localhost", verify=False, headers={"Authorization": "Bearer some_api_key"}) min_severity = 10 args = {"min_severity": min_severity} response = fetch_insights_command(client, args) assert response.outputs_prefix == "Cognni.insights" assert len(response.raw_response) == 0 def test_convert_file_event_to_incident(): from Cognni import convert_file_event_to_incident mock_file_event = util_load_json("test_data/file_event.json") result = convert_file_event_to_incident(mock_file_event) assert result["name"] == "event-file-name-1" assert result["details"] == "This is a description" assert result["severity"] == 3 def test_flatten_event_file_items(): from Cognni import flatten_event_file_items mock_event_with_file_items = util_load_json("test_data/event_with_file_items.json") result = flatten_event_file_items(mock_event_with_file_items) assert len(result) == 1 item = result[0] assert item["eventId"] == "event-id-1" assert item["fileId"] == "file-id-1" assert item["severity"] == 3 assert item["sourceApplication"] == "source-app" assert item["eventType"] == "Type1" def test_flatten_event_file_items_with_0_items(): from Cognni import flatten_event_file_items mock_event_with_0_file_items = util_load_json("test_data/event_with_0_file_items.json") result = flatten_event_file_items(mock_event_with_0_file_items) assert len(result) == 0