Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Third Party Software Attributions:

@@@@============================================================================

Library: splunk-sdk - 2.1.0
Library: splunk-sdk - 2.1.1
Homepage: http://github.com/splunk/splunk-sdk-python
License: Apache Software License
License Text:
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,6 @@ VARIABLE | REQUIRED | TYPE | DESCRIPTION
**api_token** | optional | password | API token |
**splunk_owner** | optional | string | The owner context of the namespace |
**splunk_app** | optional | string | The app context of the namespace |
**timezone** | required | timezone | Splunk Server Timezone |
**verify_server_cert** | optional | boolean | Verify Server Certificate |
**on_poll_command** | optional | string | Command for query to use with On Poll |
**on_poll_query** | optional | string | Query to use with On Poll |
Expand Down
1 change: 1 addition & 0 deletions release_notes/unreleased.md
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
**Unreleased**
* remove unused methods and config parameters
36 changes: 15 additions & 21 deletions splunk.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,21 +94,15 @@
"order": 6,
"data_type": "string"
},
"timezone": {
"data_type": "timezone",
"order": 7,
"description": "Splunk Server Timezone",
"required": true
},
"verify_server_cert": {
"data_type": "boolean",
"order": 8,
"order": 7,
"description": "Verify Server Certificate",
"default": false
},
"on_poll_command": {
"data_type": "string",
"order": 9,
"order": 8,
"description": "Command for query to use with On Poll",
"value_list": [
"",
Expand All @@ -122,78 +116,78 @@
},
"on_poll_query": {
"data_type": "string",
"order": 10,
"order": 9,
"description": "Query to use with On Poll"
},
"on_poll_display": {
"data_type": "string",
"order": 11,
"order": 10,
"description": "Fields to save with On Poll"
},
"on_poll_parse_only": {
"data_type": "boolean",
"order": 12,
"order": 11,
"description": "Parse Only",
"default": true
},
"max_container": {
"data_type": "numeric",
"order": 13,
"order": 12,
"description": "Max events to ingest for Scheduled Polling (Default: 100)",
"default": 100
},
"container_update_state": {
"data_type": "numeric",
"order": 14,
"order": 13,
"description": "Container count to update the state file",
"default": 100
},
"container_name_prefix": {
"data_type": "string",
"order": 15,
"order": 14,
"description": "Name to give containers created via ingestion"
},
"container_name_values": {
"data_type": "string",
"order": 16,
"order": 15,
"description": "Values to append to container name"
},
"retry_count": {
"description": "Number of retries",
"data_type": "numeric",
"order": 17,
"order": 16,
"default": 3
},
"remove_empty_cef": {
"description": "Remove CEF fields having empty values from the artifact",
"data_type": "boolean",
"order": 18,
"order": 17,
"default": false
},
"sleeptime_in_requests": {
"description": "The time to wait for next REST call (max 120 seconds)",
"data_type": "numeric",
"order": 19,
"order": 18,
"default": 1
},
"include_cim_fields": {
"description": "Option to keep original Splunk CIM together with SOAR CEF fields",
"data_type": "boolean",
"order": 20,
"order": 19,
"default": false,
"name": "include_cim_fields"
},
"splunk_job_timeout": {
"description": "The duration in seconds to wait before a scheduled Splunk job times out",
"data_type": "numeric",
"order": 21,
"order": 20,
"default": 1200,
"name": "splunk_job_timeout"
},
"use_event_id_sdi": {
"description": "Option to use the event_id field value as the source data identifier instead of the full event hash",
"data_type": "boolean",
"order": 22,
"order": 21,
"default": "False",
"name": "use_event_id_sdi",
"id": 22
Expand Down
79 changes: 1 addition & 78 deletions splunk_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,11 @@
import tempfile
import time
import traceback
from datetime import datetime, timezone
from datetime import timezone
from io import BytesIO
from typing import Optional
from urllib.error import HTTPError as UrllibHTTPError, URLError
from urllib.request import ProxyHandler, Request, build_opener, install_opener, urlopen
from zoneinfo import ZoneInfo

import phantom.app as phantom
import phantom.rules as soar_vault
Expand Down Expand Up @@ -1167,82 +1166,6 @@ def _handle_run_query(self, param):
search_query, action_result, attach_result=attach_result, kwargs_create=kwargs, parse_only=po, add_raw_field=add_raw
)

def _get_tz_str_from_epoch(self, time_format_str, epoch_milli):
# Need to convert from UTC to the device's timezone, get the device's tz from config
config = self.get_config()
device_tz_sting = config[consts.SPLUNK_JSON_TIMEZONE]

to_tz = ZoneInfo(device_tz_sting)

utc_dt = datetime.fromtimestamp(epoch_milli // 1000, tz=timezone.utc)
to_dt = utc_dt.astimezone(to_tz)

# return utc_dt.strftime('%Y-%m-%d %H:%M:%S')
return to_dt.strftime(time_format_str)

def _list_alerts(self, param, action_result=None):
if not action_result:
# Create a action result to represent this action
action_result = self.add_action_result(phantom.ActionResult(dict(param)))

# If end_time is not given, then end_time is 'now'
# If start_time is not given, then start_time is SPLUNK_NUMBER_OF_DAYS_BEFORE_ENDTIME
# days behind end_time
curr_epoch_msecs = int(time.time()) * 1000
start_time_msecs = 0
end_time_msecs = int(phantom.get_value(param, consts.SPLUNK_JSON_END_TIME, curr_epoch_msecs))
start_time_msecs = int(
phantom.get_value(
param,
consts.SPLUNK_JSON_START_TIME,
end_time_msecs - (consts.SPLUNK_MILLISECONDS_IN_A_DAY * consts.SPLUNK_NUMBER_OF_DAYS_BEFORE_ENDTIME),
)
)

if end_time_msecs < start_time_msecs:
return action_result.set_status(phantom.APP_ERROR, consts.SPLUNK_ERR_INVALID_TIME_RANGE)

# From splunk documentation
# To search with an exact date as boundary, such as from November 5 at 8 PM to November 12 at 8 PM,
# use the timeformat: %m/%d/%Y:%H:%M:%S
# TODO, We need not convert the epoch to formatted and then pass the format string also to splunk
# We should be able to work off of just epoch, however not too sure what the input epoch UTC format
# is to splunk and the doc is not that clear.
time_format_str = "%m/%d/%Y:%H:%M:%S"
earliest_time = f"{self._get_tz_str_from_epoch(time_format_str, start_time_msecs)}"
latest_time = f"{self._get_tz_str_from_epoch(time_format_str, end_time_msecs)}"

kwargs_create = {"earliest_time": earliest_time, "latest_time": latest_time, "time_format": time_format_str}
# kwargs_create = {"time_format": "%m/%d/%Y:%H:%M:%S",
# "latest_time": "03/21/2015:14:29:25",
# "earliest_time": "03/21/2015:14:24:25"}

self.save_progress(consts.SPLUNK_PROG_TIME_RANGE, range=json.dumps(kwargs_create))

count = int(phantom.get_value(param, phantom.APP_JSON_CONTAINER_COUNT, consts.SPLUNK_DEFAULT_ALERT_COUNT))

# Work of the saved search name, if given
ss_name = phantom.get_value(self.get_config(), consts.SPLUNK_JSON_ALERT_NAME, None)

# default to blank
ss_query = ""

if ss_name:
# create a list of query's is easier then just replacing the ',' with 'OR ss_name=
# that way we can work on each one of them seperately, like strip them or add quotes
# if not present etc.
ss_names = ['"{}"'.format(x.strip(' "')) for x in ss_name.split(",") if len(x.strip()) > 0]
self.debug_print("ss_names", ss_names)
ss_query = "ss_name = {}".format(" OR ss_name = ".join(ss_names))

query = consts.SPLUNK_SEARCH_AUDIT_INDEX_QUERY.format(ss_query, count)

self.debug_print("query", query)

self._run_query(query, action_result, kwargs_create=kwargs_create)

return action_result.get_status()

def _test_asset_connectivity(self, param):
action_result = self.add_action_result(phantom.ActionResult(dict(param)))

Expand Down
8 changes: 0 additions & 8 deletions splunk_consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@

# Progress messages
SPLUNK_PROG_GOT_JOB_ID = "Got job id '{job_id}'"
SPLUNK_PROG_TIME_RANGE = "Using range '{range}'"
SPLUNK_PROG_CREATED_QUERY = "Created query '{query}'"
SPLUNK_PROG_CREATING_SEARCH_JOB = "Creating search job"
SPLUNK_PROG_WAITING_ON_JOB_ID = "Waiting for job (id:{job_id}) to finish"
Expand All @@ -70,9 +69,7 @@
SPLUNK_JSON_STATUS = "status"
SPLUNK_JSON_URGENCY = "urgency"
SPLUNK_JSON_COMMENT = "comment"
SPLUNK_JSON_ALERT_NAME = "alert"
SPLUNK_JSON_END_TIME = "end_time"
SPLUNK_JSON_TIMEZONE = "timezone"
SPLUNK_JSON_EVENT_IDS = "event_ids"
SPLUNK_JSON_START_TIME = "start_time"
SPLUNK_JSON_SOURCE_TYPE = "source_type"
Expand All @@ -86,13 +83,10 @@

# Default values
SPLUNK_DEFAULT_EVENT_COUNT = 10
SPLUNK_DEFAULT_ALERT_COUNT = 100
SPLUNK_DEFAULT_SOURCE = "Phantom"
SPLUNK_DEFAULT_SOURCE_TYPE = "Automation/Orchestration Platform"

# Numeric constants
SPLUNK_MILLISECONDS_IN_A_DAY = 86400000
SPLUNK_NUMBER_OF_DAYS_BEFORE_ENDTIME = 10

# Dictionaries
SPLUNK_SEVERITY_MAP = {"informational": "low", "low": "low", "medium": "medium", "high": "high", "critical": "high"}
Expand Down Expand Up @@ -163,8 +157,6 @@
SPLUNK_RID_SID_NOTABLE_QUERY += r' | eval search = "( (sid::" . sid . " OR orig_sid::" . sid . ")'
SPLUNK_RID_SID_NOTABLE_QUERY += r' (rid::" . rid . " OR orig_rid::" . rid . ") )"'
SPLUNK_RID_SID_NOTABLE_QUERY += r" | table search] `notable` | table event_id"
SPLUNK_SEARCH_AUDIT_INDEX_QUERY = "search index=_audit action=alert_fired {0} | head {1} | \
fields ss_name sid trigger_time severity"

SPLUNK_DEFAULT_REQUEST_TIMEOUT = 60 # in seconds

Expand Down
Loading