diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 73febfe..12991e1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/phantomcyber/dev-cicd-tools - rev: v1.16 + rev: v1.17 hooks: - id: org-hook - id: package-app-dependencies diff --git a/LICENSE b/LICENSE index bc44b00..b7b3c69 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright (c) 2016-2023 Splunk Inc. + Copyright (c) 2016-2024 Splunk Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/NOTICE b/NOTICE index fc4fbb4..14ba140 100644 --- a/NOTICE +++ b/NOTICE @@ -1,5 +1,5 @@ Splunk SOAR Splunk -Copyright (c) 2016-2023 Splunk Inc. +Copyright (c) 2016-2024 Splunk Inc. Third-party Software Attributions: @@ -29,11 +29,6 @@ License: Zope Copyright 1987-2006 implementation only works for dates between Copyright 2003-2019 Stuart Bishop -Library: requests -Version: 2.25.0 -License: Apache 2.0 -Kenneth Reitz - Library: simplejson Version: 3.17.2 License: Academic 2.1 diff --git a/README.md b/README.md index 094a86a..f6f6e8b 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # Splunk Publisher: Splunk -Connector Version: 2.15.1 +Connector Version: 2.16.0 Product Vendor: Splunk Inc. Product Name: Splunk Enterprise Product Version Supported (regex): ".\*" @@ -11,7 +11,7 @@ Minimum Product Version: 6.1.1 This app integrates with Splunk to update data on the device, in addition to investigate and ingestion actions [comment]: # " File: README.md" -[comment]: # " Copyright (c) 2016-2023 Splunk Inc." +[comment]: # " Copyright (c) 2016-2024 Splunk Inc." [comment]: # "" [comment]: # "Licensed under the Apache License, Version 2.0 (the 'License');" [comment]: # "you may not use this file except in compliance with the License." @@ -39,7 +39,7 @@ This app integrates with Splunk to update data on the device, in addition to inv ## Splunk-SDK This app uses the Splunk-SDK module, which is licensed under the Apache Software License, Copyright -(c) 2011-2019 Splunk, Inc. +(c) 2011-2024 Splunk, Inc. ## State File Permissions @@ -54,9 +54,21 @@ Please check the permissions for the state file as mentioned below. #### State File Permissions -- File Rights: rw-rw-r-- (664) (The phantom user should have read and write access for the state +- File Rights: rw-rw-r-- (664) (The Splunk SOAR user should have read and write access for the state file) -- File Owner: appropriate phantom user +- File Owner: appropriate Splunk SOAR user + +## Required Permissions for Post Data Action +The endpoint used by the post data action is not supported on Splunk Cloud Platform. Hence, the following steps are not applicable for Splunk Cloud Platform. + +For sending events to Splunk Platform, the User configured in the asset would require **edit_tcp** capability. Follow the below steps to configure + +- Login to the Splunk Platform +- Go to **Setting > Roles** +- Click on role of the user configured in the asset(example: user) and go to **Capabilities** +- Search for '**edit_tcp**' in the capabilities enable it for the particular role +- To check if the capability is given to your user, go to **Settings > Users** and in the **Edit dropdown** and select **View Capabilities** +- Search for '**edit_tcp**' and if a tick besides it appears then the permission has been enabled for the user ## Asset Configuration Parameters @@ -464,51 +476,51 @@ action_result.parameter.start_time | string | | -2d 2022-03-18T16:12:07.130+ action_result.data.\*._bkt | string | | action_result.data.\*._cd | string | | action_result.data.\*._indextime | string | | -action_result.data.\*._key | string | | 1659398400|_audit -action_result.data.\*._kv | string | | +action_result.data.\*._key | string | | user +action_result.data.\*._kv | string | | 1 action_result.data.\*._origtime | string | | 1659398400 action_result.data.\*._raw | string | | action_result.data.\*._serial | string | | action_result.data.\*._si | string | | action_result.data.\*._sourcetype | string | | -action_result.data.\*._subsecond | string | | +action_result.data.\*._subsecond | string | | .427 action_result.data.\*._time | string | | action_result.data.\*._value | string | | 184 -action_result.data.\*.a | string | | +action_result.data.\*.a | string | | abc action_result.data.\*.content.app | string | | search -action_result.data.\*.content.host | string | | -action_result.data.\*.content.info | string | | -action_result.data.\*.content.search | string | | -action_result.data.\*.content.search_type | string | | -action_result.data.\*.content.sid | string | | -action_result.data.\*.content.source | string | | -action_result.data.\*.content.sourcetype | string | | +action_result.data.\*.content.host | string | | test +action_result.data.\*.content.info | string | | granted +action_result.data.\*.content.search | string | | index = main +action_result.data.\*.content.search_type | string | | adhoc +action_result.data.\*.content.sid | string | | 1621953839.25275 +action_result.data.\*.content.source | string | | source +action_result.data.\*.content.sourcetype | string | | source action_result.data.\*.content.uri | string | | /en-US/app/search/search?q=search%20index%3Dmain%20%7C%20head%2010&sid=1651356328.532450&display.page.search.mode=smart&dispatch.sample_ratio=1&workload_pool=&earliest=-24h%40h&latest=now action_result.data.\*.content.view | string | | search -action_result.data.\*.count | string | | -action_result.data.\*.count(host) | string | | +action_result.data.\*.count | string | | 3058733 +action_result.data.\*.count(host) | string | | 28 action_result.data.\*.event | string | | {"data": {"count": 3, "size": 112, "transform": "access_app_tracker"}, "version": "1.0"} action_result.data.\*.host | string | `host name` | 10.1.67.187:8088 action_result.data.\*.index | string | | -action_result.data.\*.is_Acceleration_Jobs | string | | -action_result.data.\*.is_Adhoc_Jobs | string | | -action_result.data.\*.is_Failed_Jobs | string | | -action_result.data.\*.is_Realtime_Jobs | string | | -action_result.data.\*.is_Scheduled_Jobs | string | | -action_result.data.\*.is_Subsearch_Jobs | string | | -action_result.data.\*.is_not_Acceleration_Jobs | string | | -action_result.data.\*.is_not_Adhoc_Jobs | string | | -action_result.data.\*.is_not_Failed_Jobs | string | | -action_result.data.\*.is_not_Realtime_Jobs | string | | -action_result.data.\*.is_not_Scheduled_Jobs | string | | -action_result.data.\*.is_not_Subsearch_Jobs | string | | +action_result.data.\*.is_Acceleration_Jobs | string | | 0 +action_result.data.\*.is_Adhoc_Jobs | string | | 1 +action_result.data.\*.is_Failed_Jobs | string | | 0 +action_result.data.\*.is_Realtime_Jobs | string | | 0 +action_result.data.\*.is_Scheduled_Jobs | string | | 0 +action_result.data.\*.is_Subsearch_Jobs | string | | 0 +action_result.data.\*.is_not_Acceleration_Jobs | string | | 1 +action_result.data.\*.is_not_Adhoc_Jobs | string | | 0 +action_result.data.\*.is_not_Failed_Jobs | string | | 1 +action_result.data.\*.is_not_Realtime_Jobs | string | | 1 +action_result.data.\*.is_not_Scheduled_Jobs | string | | 1 +action_result.data.\*.is_not_Subsearch_Jobs | string | | 1 action_result.data.\*.linecount | string | | action_result.data.\*.source | string | | action_result.data.\*.sourcetype | string | | action_result.data.\*.spent | string | | 223 action_result.data.\*.splunk_server | string | `host name` | -action_result.data.\*.user | string | | -action_result.data.\*.values(source) | string | | +action_result.data.\*.user | string | | admin +action_result.data.\*.values(source) | string | | /opt/splunk/var/log/splunk/scheduler.log action_result.summary.sid | string | | 1612177958.977510 action_result.summary.total_events | numeric | | 2 action_result.message | string | | Sid: 1612177958.977510, Total events: 2 @@ -561,7 +573,7 @@ Post data to Splunk Type: **generic** Read only: **False** -This action creates an event on Splunk with the data included in the data parameter. If not specified the parameters will default to the following: +This action creates an event on Splunk with the data included in the data parameter. If not specified the parameters will default to the following: #### Action Parameters PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS diff --git a/__init__.py b/__init__.py index bc35686..d7d82bb 100644 --- a/__init__.py +++ b/__init__.py @@ -1,6 +1,6 @@ # File: __init__.py # -# Copyright (c) 2016-2023 Splunk Inc. +# Copyright (c) 2016-2024 Splunk Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/manual_readme_content.md b/manual_readme_content.md index 0a18d61..419dde5 100644 --- a/manual_readme_content.md +++ b/manual_readme_content.md @@ -1,5 +1,5 @@ [comment]: # " File: README.md" -[comment]: # " Copyright (c) 2016-2023 Splunk Inc." +[comment]: # " Copyright (c) 2016-2024 Splunk Inc." [comment]: # "" [comment]: # "Licensed under the Apache License, Version 2.0 (the 'License');" [comment]: # "you may not use this file except in compliance with the License." @@ -27,7 +27,7 @@ ## Splunk-SDK This app uses the Splunk-SDK module, which is licensed under the Apache Software License, Copyright -(c) 2011-2019 Splunk, Inc. +(c) 2011-2024 Splunk, Inc. ## State File Permissions @@ -42,9 +42,21 @@ Please check the permissions for the state file as mentioned below. #### State File Permissions -- File Rights: rw-rw-r-- (664) (The phantom user should have read and write access for the state +- File Rights: rw-rw-r-- (664) (The Splunk SOAR user should have read and write access for the state file) -- File Owner: appropriate phantom user +- File Owner: appropriate Splunk SOAR user + +## Required Permissions for Post Data Action +The endpoint used by the post data action is not supported on Splunk Cloud Platform. Hence, the following steps are not applicable for Splunk Cloud Platform. + +For sending events to Splunk Platform, the User configured in the asset would require **edit_tcp** capability. Follow the below steps to configure + +- Login to the Splunk Platform +- Go to **Setting > Roles** +- Click on role of the user configured in the asset(example: user) and go to **Capabilities** +- Search for '**edit_tcp**' in the capabilities enable it for the particular role +- To check if the capability is given to your user, go to **Settings > Users** and in the **Edit dropdown** and select **View Capabilities** +- Search for '**edit_tcp**' and if a tick besides it appears then the permission has been enabled for the user ## Asset Configuration Parameters diff --git a/release_notes/2.16.0.md b/release_notes/2.16.0.md new file mode 100644 index 0000000..5da072a --- /dev/null +++ b/release_notes/2.16.0.md @@ -0,0 +1,3 @@ +* Documentation update for steps to allow edit_tcp capability for a user [PAPP-31540] +* Bug fix for 'on poll' cef field names [PAPP-30430] +* Bug fix for accessing vault temp directory path [PAPP-32416] \ No newline at end of file diff --git a/splunk.json b/splunk.json index c3f78cf..f4f19ed 100644 --- a/splunk.json +++ b/splunk.json @@ -31,8 +31,8 @@ ], "type": "siem", "main_module": "splunk_connector.py", - "app_version": "2.15.1", - "utctime_updated": "2023-12-05T22:26:49.000000Z", + "app_version": "2.16.0", + "utctime_updated": "2022-09-08T08:47:45.000000Z", "package_name": "phantom_splunk", "product_name": "Splunk Enterprise", "product_vendor": "Splunk Inc.", @@ -41,12 +41,12 @@ "fips_compliant": true, "python_version": "3", "latest_tested_versions": [ - "On-premise, Splunk Enterprise Security v9.0.0, Dec 5, 2023", - "Cloud, Splunk Cloud Platform v8.2.2112, Dec 5, 2023" + "On-premise, Splunk Enterprise Security v9.0.0, Jan 8 2024", + "Cloud, Splunk Cloud Platform v9.0.2303.202, Jan 8 2024" ], "logo": "logo_splunk.svg", "logo_dark": "logo_splunk_dark.svg", - "license": "Copyright (c) 2016-2023 Splunk Inc.", + "license": "Copyright (c) 2016-2024 Splunk Inc.", "pip_dependencies": { "wheel": [ { @@ -592,13 +592,15 @@ "data_path": "action_result.data.*._key", "data_type": "string", "example_values": [ - "1659398400|_audit" + "user" ] }, { "data_path": "action_result.data.*._kv", "data_type": "string", - "example_value": "1" + "example_values": [ + "1" + ] }, { "data_path": "action_result.data.*._origtime", @@ -628,7 +630,9 @@ { "data_path": "action_result.data.*._subsecond", "data_type": "string", - "example_value": ".427" + "example_values": [ + ".427" + ] }, { "data_path": "action_result.data.*._time", @@ -646,7 +650,9 @@ { "data_path": "action_result.data.*.a", "data_type": "string", - "example_value": "abc" + "example_values": [ + "abc" + ] }, { "data_path": "action_result.data.*.content.app", @@ -658,37 +664,51 @@ { "data_path": "action_result.data.*.content.host", "data_type": "string", - "example_value": "test" + "example_values": [ + "test" + ] }, { "data_path": "action_result.data.*.content.info", "data_type": "string", - "example_value": "granted" + "example_values": [ + "granted" + ] }, { "data_path": "action_result.data.*.content.search", "data_type": "string", - "example_value": "search [| makeresults | eval myfield = \"test\" | table search] `notable` | table event_id" + "example_values": [ + "index = main" + ] }, { "data_path": "action_result.data.*.content.search_type", "data_type": "string", - "example_value": "adhoc" + "example_values": [ + "adhoc" + ] }, { "data_path": "action_result.data.*.content.sid", "data_type": "string", - "example_value": "1621953839.25275" + "example_values": [ + "1621953839.25275" + ] }, { "data_path": "action_result.data.*.content.source", "data_type": "string", - "example_value": "source" + "example_values": [ + "source" + ] }, { "data_path": "action_result.data.*.content.sourcetype", "data_type": "string", - "example_value": "source" + "example_values": [ + "source" + ] }, { "data_path": "action_result.data.*.content.uri", @@ -707,12 +727,16 @@ { "data_path": "action_result.data.*.count", "data_type": "string", - "example_value": "3058733" + "example_values": [ + "3058733" + ] }, { "data_path": "action_result.data.*.count(host)", "data_type": "string", - "example_value": "28" + "example_values": [ + "28" + ] }, { "data_path": "action_result.data.*.event", @@ -740,62 +764,86 @@ { "data_path": "action_result.data.*.is_Acceleration_Jobs", "data_type": "string", - "example_value": "0" + "example_values": [ + "0" + ] }, { "data_path": "action_result.data.*.is_Adhoc_Jobs", "data_type": "string", - "example_value": "1" + "example_values": [ + "1" + ] }, { "data_path": "action_result.data.*.is_Failed_Jobs", "data_type": "string", - "example_value": "0" + "example_values": [ + "0" + ] }, { "data_path": "action_result.data.*.is_Realtime_Jobs", "data_type": "string", - "example_value": "0" + "example_values": [ + "0" + ] }, { "data_path": "action_result.data.*.is_Scheduled_Jobs", "data_type": "string", - "example_value": "0" + "example_values": [ + "0" + ] }, { "data_path": "action_result.data.*.is_Subsearch_Jobs", "data_type": "string", - "example_value": "0" + "example_values": [ + "0" + ] }, { "data_path": "action_result.data.*.is_not_Acceleration_Jobs", "data_type": "string", - "example_value": "1" + "example_values": [ + "1" + ] }, { "data_path": "action_result.data.*.is_not_Adhoc_Jobs", "data_type": "string", - "example_value": "0" + "example_values": [ + "0" + ] }, { "data_path": "action_result.data.*.is_not_Failed_Jobs", "data_type": "string", - "example_value": "1" + "example_values": [ + "1" + ] }, { "data_path": "action_result.data.*.is_not_Realtime_Jobs", "data_type": "string", - "example_value": "1" + "example_values": [ + "1" + ] }, { "data_path": "action_result.data.*.is_not_Scheduled_Jobs", "data_type": "string", - "example_value": "1" + "example_values": [ + "1" + ] }, { "data_path": "action_result.data.*.is_not_Subsearch_Jobs", "data_type": "string", - "example_value": "1" + "example_values": [ + "1" + ] }, { "data_path": "action_result.data.*.linecount", @@ -826,12 +874,16 @@ { "data_path": "action_result.data.*.user", "data_type": "string", - "example_value": "admin" + "example_values": [ + "admin" + ] }, { "data_path": "action_result.data.*.values(source)", "data_type": "string", - "example_value": "/opt/splunk/var/log/splunk/scheduler.log" + "example_values": [ + "/opt/splunk/var/log/splunk/scheduler.log" + ] }, { "data_path": "action_result.summary.sid", @@ -1080,7 +1132,7 @@ { "action": "post data", "description": "Post data to Splunk", - "verbose": "This action creates an event on Splunk with the data included in the data parameter. If not specified the parameters will default to the following:", + "verbose": "This action creates an event on Splunk with the data included in the data parameter. If not specified the parameters will default to the following:", "type": "generic", "identifier": "post_data", "read_only": false, @@ -1246,4 +1298,4 @@ } ] } -} \ No newline at end of file +} diff --git a/splunk_connector.py b/splunk_connector.py index 97c61f9..bd0bc0e 100644 --- a/splunk_connector.py +++ b/splunk_connector.py @@ -1,6 +1,6 @@ # File: splunk_connector.py # -# Copyright (c) 2016-2023 Splunk Inc. +# Copyright (c) 2016-2024 Splunk Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -62,7 +62,7 @@ def __new__(cls, val1, val2=None): return tuple.__new__(RetVal, (val1, val2)) -class SplunkConnector(phantom.BaseConnector): +class SplunkConnector(BaseConnector): ACTION_ID_POST_DATA = "post_data" ACTION_ID_RUN_QUERY = "run_query" @@ -138,7 +138,7 @@ def initialize(self): self._state = self.load_state() if self._state is None: self.debug_print("Please check the owner, owner group, and the permissions of the state file") - self.debug_print("The phantom user should have correct access rights and ownership for the \ + self.debug_print("The Splunk SOAR user should have correct access rights and ownership for the \ corresponding state file (refer readme file for more information)") return phantom.APP_ERROR @@ -390,7 +390,7 @@ def _process_response(self, r, action_result): return self._process_json_response(r, action_result) # Process an HTML response, Do this no matter what the api talks. - # There is a high chance of a PROXY in between phantom and the rest of + # There is a high chance of a PROXY in between Splunk SOAR and the rest of # world, in case of errors, PROXY's return HTML, this function parses # the error and adds it to the action_result. if 'html' in r.headers.get('Content-Type', ''): @@ -915,7 +915,12 @@ def _on_poll(self, param): # noqa: C901 ret_val = self._run_query(search_query, action_result, kwargs_create=search_params, parse_only=po) if phantom.is_fail(ret_val): - self.save_progress(action_result.get_message()) + if "Invalid index_earliest" in action_result.get_message(): + self.debug_print("The value of 'start_time' parameter {} is not a valid epoch time. Re-invoking api without start_time".format( + search_params.get("index_earliest"))) + del self._state['start_time'] + else: + self.save_progress(action_result.get_message()) return action_result.set_status(phantom.APP_ERROR) display = config.get('on_poll_display') @@ -944,6 +949,7 @@ def _on_poll(self, param): # noqa: C901 name_mappings[k.lower()] = k for h in header_set: cef_name = consts.CIM_CEF_MAP.get(h, h) + cef_name = name_mappings.get(cef_name, cef_name) cef_key_value = name_mappings.get(h, h) cef[cef_name] = item.get(cef_key_value) # Add original CIM fields if option is checked @@ -1017,7 +1023,7 @@ def _get_event_start(self, start_time): return None try: - # convert to Phantom timestamp format + # convert to Splunk SOAR timestamp format # '%Y-%m-%dT%H:%M:%S.%fZ datetime_obj = dateutil_parse(start_time) return datetime_obj.astimezone(pytz.utc).strftime('%Y-%m-%dT%H:%M:%S.%fZ') @@ -1340,17 +1346,14 @@ def _run_query(self, search_query, action_result, attach_result=False, kwargs_cr def add_json_result(self, action_result, data): - if hasattr(Vault, 'get_vault_tmp_dir'): - tmp = tempfile.NamedTemporaryFile(dir=Vault.get_vault_tmp_dir(), delete=False) - else: - tmp = tempfile.NamedTemporaryFile(dir='/opt/phantom/vault/tmp/', delete=False) + fd, path = tempfile.mkstemp(dir=Vault.get_vault_tmp_dir(), text=True) vault_attach_dict = {} vault_attach_dict[phantom.APP_JSON_ACTION_NAME] = self.get_action_name() vault_attach_dict[phantom.APP_JSON_APP_RUN_ID] = self.get_app_run_id() try: - with open(tmp.name, 'w') as f: + with open(path, 'w') as f: json.dump(data, f) except Exception as e: @@ -1363,7 +1366,7 @@ def add_json_result(self, action_result, data): container_id = self.get_container_id() try: - success, message, _ = soar_vault.vault_add(container_id, tmp.name, 'splunk_run_query_result.json', vault_attach_dict) + success, message, _ = soar_vault.vault_add(container_id, path, 'splunk_run_query_result.json', vault_attach_dict) except Exception as e: self._dump_error_log(e) diff --git a/splunk_consts.py b/splunk_consts.py index 0e88b02..6c5b31f 100644 --- a/splunk_consts.py +++ b/splunk_consts.py @@ -1,6 +1,6 @@ # File: splunk_consts.py # -# Copyright (c) 2016-2023 Splunk Inc. +# Copyright (c) 2016-2024 Splunk Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/splunk_run_query.html b/splunk_run_query.html index 63e6d90..6229bbb 100644 --- a/splunk_run_query.html +++ b/splunk_run_query.html @@ -10,7 +10,7 @@ {% block widget_content %}