CyrenThreatInDepthRandomHunt
This script will take a random Cyren Threat InDepth feed indicator and its relationships and create a threat hunting incident for you. The main query parameters for the resulting, internal indicator query are: 1. Seen for the first time by the feed source within the last 7 days. 2. No investigation on it yet. 3. Must have relationships to other indicators.
Details
| ID | CyrenThreatInDepthRandomHunt |
|---|---|
| Language | python |
| From Version | 6.0.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Tags | incidents iocs cyren hunt |
README
This script will take a random Cyren Threat InDepth feed indicator and its relationships
and create a threat hunting incident for you.
The main query parameters for the resulting, internal indicator query are:
- Seen for the first time by the feed source within the last 7 days.
- No investigation on it yet.
- Must have relationships to other indicators.
Script Data
| Name | Description |
|---|---|
| Script Type | python3 |
| Tags | incidents, ioc, cyren, hunt |
| XSOAR Version | 6.0.0 |
Inputs
| Argument Name | Description |
|---|---|
| indicator_type | Optional: One of ip_reputation, malware_files, malware_urls, phishing_urls, will determine the Cyren Threat InDepth feed the indicator is taken from (if not provided a random indicator type is chosen) |
| incident_type | Optional: If not provided, an incident of type “Hunt” is created |
Outputs
There are no outputs for this script.
Human Readable Output
Successfully created incident Cyren Threat InDepth Threat Hunt.
Click here to investigate: 1234.
import demistomock as demisto import pytest from CommonServerPython import DemistoException, entryTypes FIND_INDICATORS_NORMAL = [ { "Type": entryTypes["note"], "Contents": [ { "value": "http://google.de", "indicator_type": "URL", } ], } ] ERROR = [{"Type": entryTypes["error"], "Contents": [{}]}] FIND_INDICATORS_EMPTY = [{"Type": entryTypes["note"], "Contents": []}] def executeCommand( find_indicators_result=FIND_INDICATORS_NORMAL, find_indicators_error=False, get_users_error=False, create_new_incident_error=False, investigate_error=False, ): def inner(command, args=None): if command == "findIndicators": if find_indicators_error: return ERROR return find_indicators_result elif command == "getUsers": if get_users_error: return ERROR return [ { "Type": entryTypes["note"], "Contents": [ { "id": "admin", } ], } ] elif command == "createNewIncident": if create_new_incident_error: return ERROR return [ { "Type": entryTypes["note"], "Contents": [{}], "EntryContext": { "CreatedIncidentID": "1234", }, } ] elif command == "investigate": if investigate_error: return ERROR return [ { "Type": entryTypes["note"], "Contents": [{}], } ] return None return inner @pytest.mark.parametrize( "args, expected_incident", [ ( {}, { "name": "Cyren Threat InDepth Threat Hunt", "type": "Hunt", "details": "indicator_type: URL\nvalue: http://google.de\n", "owner": "admin", }, ), ( {"assignee": "other.user"}, { "name": "Cyren Threat InDepth Threat Hunt", "type": "Hunt", "details": "indicator_type: URL\nvalue: http://google.de\n", "owner": "other.user", }, ), ( {"assignee": "other.user", "incident_type": "My Type"}, { "name": "Cyren Threat InDepth Threat Hunt", "type": "My Type", "details": "indicator_type: URL\nvalue: http://google.de\n", "owner": "other.user", }, ), ( {"indicator_type": "ip_reputation"}, { "name": "Cyren Threat InDepth Threat Hunt", "type": "Hunt", "details": "indicator_type: URL\nvalue: http://google.de\n", "owner": "admin", }, ), ( {"incident_type": "My Type"}, { "name": "Cyren Threat InDepth Threat Hunt", "type": "My Type", "details": "indicator_type: URL\nvalue: http://google.de\n", "owner": "admin", }, ), ( {"indicator_type": "ip_reputation", "incident_type": "My Type"}, { "name": "Cyren Threat InDepth Threat Hunt", "type": "My Type", "details": "indicator_type: URL\nvalue: http://google.de\n", "owner": "admin", }, ), ], ) def test_create_random_hunt_incident(mocker, args, expected_incident): """ Given: Different arg input When: Running create_random_hunt_incident command. Then: An incident has been created and a link is posted """ from CyrenThreatInDepthRandomHunt import create_random_hunt_incident mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand()) result = create_random_hunt_incident(args) demisto.executeCommand.assert_any_call("createNewIncident", expected_incident) assert result.readable_output == ( "Successfully created incident Cyren Threat InDepth Threat Hunt.\nClick here to investigate: [1234](#/incident/1234)." ) def test_create_random_hunt_incident_find_indicators_error(mocker): """ Given: Errors in findIndicators When: Running create_random_hunt_incident command. Then: An exception is thrown """ from CyrenThreatInDepthRandomHunt import create_random_hunt_incident mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand(find_indicators_error=True)) with pytest.raises(DemistoException): create_random_hunt_incident({}) def test_create_random_hunt_incident_find_indicators_empty(mocker): """ Given: No indicators according to query When: Running create_random_hunt_incident command. Then: An error message is printed """ from CyrenThreatInDepthRandomHunt import create_random_hunt_incident mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand(find_indicators_result=FIND_INDICATORS_EMPTY)) result = create_random_hunt_incident({}) assert "Could not find any indicators for " in result.readable_output def test_create_random_hunt_incident_get_current_user_error(mocker): """ Given: Getting current user produces an error When: Running create_random_hunt_incident command. Then: Incident is still created """ from CyrenThreatInDepthRandomHunt import create_random_hunt_incident mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand(get_users_error=True)) result = create_random_hunt_incident({}) assert result.readable_output == ( "Successfully created incident Cyren Threat InDepth Threat Hunt.\nClick here to investigate: [1234](#/incident/1234)." ) def test_create_random_hunt_incident_create_new_incident_error(mocker): """ Given: Creating the incident will produce an error When: Running create_random_hunt_incident command. Then: An exception is thrown """ from CyrenThreatInDepthRandomHunt import create_random_hunt_incident mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand(create_new_incident_error=True)) with pytest.raises(DemistoException): create_random_hunt_incident({}) def test_create_random_hunt_incident_investigate_error(mocker): """ Given: Getting current user produces an error When: Running create_random_hunt_incident command. Then: Incident is still created """ from CyrenThreatInDepthRandomHunt import create_random_hunt_incident mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand(investigate_error=True)) result = create_random_hunt_incident({}) assert result.readable_output == ( "Successfully created incident Cyren Threat InDepth Threat Hunt.\n" "Click here to investigate: [1234](#/incident/1234).\n" "(An investigation has not been started.)" )