From 285ee67f9d8ebe736886a4f73acf8afcecfab447 Mon Sep 17 00:00:00 2001 From: Tapish Jain Date: Mon, 5 Aug 2024 15:06:42 -0700 Subject: [PATCH 1/5] PAPP-34458: inital work --- zscaler.json | 119 +++++++++++++++++++++++++++++++++++++++++++ zscaler_connector.py | 57 ++++++++++++++++++++- 2 files changed, 175 insertions(+), 1 deletion(-) diff --git a/zscaler.json b/zscaler.json index 5ed9741..cc6ab14 100644 --- a/zscaler.json +++ b/zscaler.json @@ -3000,6 +3000,125 @@ "type": "table" }, "versions": "EQ(*)" + }, + { + "action": "get whitelist", + "identifier": "get_whitelist", + "description": "get urls on the allow list", + "type": "investigate", + "read_only": true, + "parameters": {}, + "output": [ + { + "data_path": "action_result.status", + "data_type": "string", + "example_values": [ + "test success", + "test failed" + ] + }, + { + "data_path": "action_result.data.*.whitelistUrls", + "data_type": "string" + }, + { + "data_path": "action_result.message", + "data_type": "string", + "example_values": [ + "test Total url categories: 97" + ] + }, + { + "data_path": "summary.total_objects", + "data_type": "numeric", + "example_values": [ + 1 + ] + }, + { + "data_path": "summary.total_objects_successful", + "data_type": "numeric", + "example_values": [ + 1 + ] + } + ], + "render": { + "title": "List URL Categories", + "type": "table" + }, + "versions": "EQ(*)" + }, + { + "action": "get blakclist", + "identifier": "get_blacklist", + "description": "get urls on the deny list", + "type": "investigate", + "read_only": true, + "parameters": { + "filter": { + "description": "Filter results be url or ip", + "data_type": "string", + "primary": true, + "contains": [ + "url", + "ip" + ], + "example_values": [ + "127.0.0.1" + ], + "order": 0 + }, + "query": { + "description": "Regular expression to match url or ip against", + "data_type": "string", + "primary": true, + "example_values": [ + "8...8" + ], + "order": 1 + } + }, + "output": [ + { + "data_path": "action_result.status", + "data_type": "string", + "example_values": [ + "test success", + "test failed" + ] + }, + { + "data_path": "action_result.data.*.whitelistUrls", + "data_type": "string" + }, + { + "data_path": "action_result.message", + "data_type": "string", + "example_values": [ + "test Total url categories: 97" + ] + }, + { + "data_path": "summary.total_objects", + "data_type": "numeric", + "example_values": [ + 1 + ] + }, + { + "data_path": "summary.total_objects_successful", + "data_type": "numeric", + "example_values": [ + 1 + ] + } + ], + "render": { + "title": "List URL Categories", + "type": "table" + }, + "versions": "EQ(*)" } ], "pip_dependencies": { diff --git a/zscaler_connector.py b/zscaler_connector.py index dd0686c..d0b15c9 100644 --- a/zscaler_connector.py +++ b/zscaler_connector.py @@ -25,7 +25,7 @@ from bs4 import BeautifulSoup from phantom.action_result import ActionResult from phantom.base_connector import BaseConnector - +import socket from zscaler_consts import * @@ -990,6 +990,55 @@ def _handle_remove_group_user(self, param): return action_result.set_status(phantom.APP_SUCCESS) + def _handle_get_whitelist(self, param): + """ + This action is used to get the default whitelist in zscalar + :return: status phantom.APP_ERROR/phantom.APP_SUCCESS(along with appropriate message) + """ + self.save_progress("In action handler for: {0}".format(self.get_action_identifier())) + action_result = self.add_action_result(ActionResult(dict(param))) + + ret_val, response = self._make_rest_call_helper('/api/v1/settings', action_result) + if phantom.is_fail(ret_val): + return action_result.get_status() + + self.debug_print(response) + + return action_result.set_status(phantom.APP_SUCCESS) + + def _handle_get_blacklist(self, param): + """ + This action is used to get the blacklist in zscalar + :return: status phantom.APP_ERROR/phantom.APP_SUCCESS(along with appropriate message) + """ + self.save_progress("In action handler for: {0}".format(self.get_action_identifier())) + action_result = self.add_action_result(ActionResult(dict(param))) + + ret_val, response = self._make_rest_call_helper('/api/v1/settings/advanced', action_result) + if phantom.is_fail(ret_val): + return action_result.get_status() + + filter = param.get("filter") + query = param.get("query") + + self.debug_print(response) + if not filter and not query: + return action_result.set_status(phantom.APP_SUCCESS) + + parsed_data = [] + + self.debug_print(response) + for entry in response: + self.debug_print(entry) + url = entry.get(url, "") + ip = socket.socket.gethostbyname(url) + if url == filter or ip == filter: + parsed_data.append(entry) + elif query and (re.fullmatch(query, url) or re.fullmatch(query, ip)): + parsed_data.append(entry) + + return action_result.set_status(phantom.APP_SUCCESS) + def handle_action(self, param): ret_val = phantom.APP_SUCCESS @@ -1056,6 +1105,12 @@ def handle_action(self, param): elif action_id == 'remove_group_user': ret_val = self._handle_remove_group_user(param) + elif action_id == 'get_whitelist': + ret_val = self._handle_get_whitelist(param) + + elif action_id == 'get_blacklist': + ret_val = self._handle_get_blacklist(param) + return ret_val def initialize(self): From 1e02979f055d70288882511b1e455c1a00418028 Mon Sep 17 00:00:00 2001 From: splunk-soar-connectors-admin Date: Mon, 5 Aug 2024 22:12:23 +0000 Subject: [PATCH 2/5] Update README.md --- README.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/README.md b/README.md index e954575..3b972d8 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,8 @@ VARIABLE | REQUIRED | TYPE | DESCRIPTION [get groups](#action-get-groups) - Gets a list of groups [add group user](#action-add-group-user) - Add user to group [remove group user](#action-remove-group-user) - Remove user from group +[get whitelist](#action-get-whitelist) - get urls on the allow list +[get blakclist](#action-get-blakclist) - get urls on the deny list ## action: 'test connectivity' Validate the asset configuration for connectivity using supplied configuration @@ -745,4 +747,43 @@ action_result.summary.message | string | | test User removed from group action_result.message | string | | test User removed from group summary.message | string | | summary.total_objects | numeric | | 1 +summary.total_objects_successful | numeric | | 1 + +## action: 'get whitelist' +get urls on the allow list + +Type: **investigate** +Read only: **True** + +#### Action Parameters +No parameters are required for this action + +#### Action Output +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | test success test failed +action_result.data.\*.whitelistUrls | string | | +action_result.message | string | | test Total url categories: 97 +summary.total_objects | numeric | | 1 +summary.total_objects_successful | numeric | | 1 + +## action: 'get blakclist' +get urls on the deny list + +Type: **investigate** +Read only: **True** + +#### Action Parameters +PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS +--------- | -------- | ----------- | ---- | -------- +**filter** | optional | Filter results be url or ip | string | `url` `ip` +**query** | optional | Regular expression to match url or ip against | string | + +#### Action Output +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | test success test failed +action_result.data.\*.whitelistUrls | string | | +action_result.message | string | | test Total url categories: 97 +summary.total_objects | numeric | | 1 summary.total_objects_successful | numeric | | 1 \ No newline at end of file From aae9e0c09aee6d751b5daaef474632a7045a4b5b Mon Sep 17 00:00:00 2001 From: Tapish Jain Date: Tue, 6 Aug 2024 15:48:39 -0700 Subject: [PATCH 3/5] PAPP-34458: get blacklist and get whitelist working --- zscaler.json | 52 ++++++++++++++++++++++++++++++++++--------- zscaler_connector.py | 53 ++++++++++++++++++++++++++------------------ 2 files changed, 73 insertions(+), 32 deletions(-) diff --git a/zscaler.json b/zscaler.json index cc6ab14..8326859 100644 --- a/zscaler.json +++ b/zscaler.json @@ -3018,14 +3018,21 @@ ] }, { - "data_path": "action_result.data.*.whitelistUrls", + "data_path": "action_result.data.*.whitelistUrl", "data_type": "string" }, { - "data_path": "action_result.message", + "data_path": "action_result.summary.total_whitelist_items", + "data_type": "numeric", + "example_values": [ + 10 + ] + }, + { + "data_path": "action_result.summary.message", "data_type": "string", "example_values": [ - "test Total url categories: 97" + "Whitelist retrieved" ] }, { @@ -3050,7 +3057,7 @@ "versions": "EQ(*)" }, { - "action": "get blakclist", + "action": "get blacklist", "identifier": "get_blacklist", "description": "get urls on the deny list", "type": "investigate", @@ -3060,13 +3067,10 @@ "description": "Filter results be url or ip", "data_type": "string", "primary": true, - "contains": [ + "value_list": [ "url", "ip" ], - "example_values": [ - "127.0.0.1" - ], "order": 0 }, "query": { @@ -3089,14 +3093,40 @@ ] }, { - "data_path": "action_result.data.*.whitelistUrls", + "data_path": "action_result.parameter.query", + "data_type": "string", + "column_name": "Query", + "example_values": [ + "8...8" + ], + "column_order": 1 + }, + { + "data_path": "action_result.parameter.filter", + "data_type": "string", + "column_name": "Filter", + "value_list": [ + "url", + "ip" + ], + "column_order": 0 + }, + { + "data_path": "action_result.data.*.blacklistUrl", "data_type": "string" }, { - "data_path": "action_result.message", + "data_path": "action_result.summary.message", "data_type": "string", "example_values": [ - "test Total url categories: 97" + "Blacklist retrieved" + ] + }, + { + "data_path": "action_result.summary.total_blacklist_items", + "data_type": "numeric", + "example_values": [ + 10 ] }, { diff --git a/zscaler_connector.py b/zscaler_connector.py index d0b15c9..269e95c 100644 --- a/zscaler_connector.py +++ b/zscaler_connector.py @@ -18,6 +18,7 @@ import json import re import time +import ipaddress import phantom.app as phantom import phantom.rules as phantom_rules @@ -25,7 +26,6 @@ from bs4 import BeautifulSoup from phantom.action_result import ActionResult from phantom.base_connector import BaseConnector -import socket from zscaler_consts import * @@ -998,14 +998,26 @@ def _handle_get_whitelist(self, param): self.save_progress("In action handler for: {0}".format(self.get_action_identifier())) action_result = self.add_action_result(ActionResult(dict(param))) - ret_val, response = self._make_rest_call_helper('/api/v1/settings', action_result) + ret_val, response = self._get_allowlist(action_result) if phantom.is_fail(ret_val): - return action_result.get_status() + return RetVal(ret_val, None) - self.debug_print(response) + whitelist = response.get('whitelistUrls', []) + for allowed in whitelist: + action_result.add_data(allowed) + summary = action_result.update_summary({}) + summary['total_whitelist_items'] = action_result.get_data_size() + summary['message'] = "Whitelist retrieved" return action_result.set_status(phantom.APP_SUCCESS) + def _is_ip_address(self, address): + try: + ipaddress.ip_address(address) + return True + except ValueError: + return False + def _handle_get_blacklist(self, param): """ This action is used to get the blacklist in zscalar @@ -1014,29 +1026,28 @@ def _handle_get_blacklist(self, param): self.save_progress("In action handler for: {0}".format(self.get_action_identifier())) action_result = self.add_action_result(ActionResult(dict(param))) - ret_val, response = self._make_rest_call_helper('/api/v1/settings/advanced', action_result) + ret_val, response = self._get_blocklist(action_result) if phantom.is_fail(ret_val): - return action_result.get_status() + return RetVal(ret_val, None) filter = param.get("filter") query = param.get("query") - self.debug_print(response) - if not filter and not query: - return action_result.set_status(phantom.APP_SUCCESS) - - parsed_data = [] - - self.debug_print(response) - for entry in response: - self.debug_print(entry) - url = entry.get(url, "") - ip = socket.socket.gethostbyname(url) - if url == filter or ip == filter: - parsed_data.append(entry) - elif query and (re.fullmatch(query, url) or re.fullmatch(query, ip)): - parsed_data.append(entry) + summary = action_result.update_summary({}) + summary['message'] = "Blacklist retrieved" + blocklist = response.get('blacklistUrls', []) + for blocked in blocklist: + is_ip = self._is_ip_address(blocked) + if filter == "ip" and not is_ip: + continue + if filter == "url" and is_ip: + continue + if query and not re.fullmatch(query, blocked): + continue + action_result.add_data(blocked) + + summary['total_blacklist_items'] = action_result.get_data_size() return action_result.set_status(phantom.APP_SUCCESS) def handle_action(self, param): From a09bd24ee3525ae33542ec3b6f992ff46bf45948 Mon Sep 17 00:00:00 2001 From: splunk-soar-connectors-admin Date: Tue, 6 Aug 2024 22:49:25 +0000 Subject: [PATCH 4/5] Update README.md --- README.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 3b972d8..edebb46 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ VARIABLE | REQUIRED | TYPE | DESCRIPTION [add group user](#action-add-group-user) - Add user to group [remove group user](#action-remove-group-user) - Remove user from group [get whitelist](#action-get-whitelist) - get urls on the allow list -[get blakclist](#action-get-blakclist) - get urls on the deny list +[get blacklist](#action-get-blacklist) - get urls on the deny list ## action: 'test connectivity' Validate the asset configuration for connectivity using supplied configuration @@ -762,12 +762,13 @@ No parameters are required for this action DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES --------- | ---- | -------- | -------------- action_result.status | string | | test success test failed -action_result.data.\*.whitelistUrls | string | | -action_result.message | string | | test Total url categories: 97 +action_result.data.\*.whitelistUrl | string | | +action_result.summary.total_whitelist_items | numeric | | 10 +action_result.summary.message | string | | Whitelist retrieved summary.total_objects | numeric | | 1 summary.total_objects_successful | numeric | | 1 -## action: 'get blakclist' +## action: 'get blacklist' get urls on the deny list Type: **investigate** @@ -776,14 +777,17 @@ Read only: **True** #### Action Parameters PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS --------- | -------- | ----------- | ---- | -------- -**filter** | optional | Filter results be url or ip | string | `url` `ip` +**filter** | optional | Filter results be url or ip | string | **query** | optional | Regular expression to match url or ip against | string | #### Action Output DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES --------- | ---- | -------- | -------------- action_result.status | string | | test success test failed -action_result.data.\*.whitelistUrls | string | | -action_result.message | string | | test Total url categories: 97 +action_result.parameter.query | string | | 8...8 +action_result.parameter.filter | string | | +action_result.data.\*.blacklistUrl | string | | +action_result.summary.message | string | | Blacklist retrieved +action_result.summary.total_blacklist_items | numeric | | 10 summary.total_objects | numeric | | 1 summary.total_objects_successful | numeric | | 1 \ No newline at end of file From 8484f703221248f55534e618ee7752061ac9618f Mon Sep 17 00:00:00 2001 From: splunk-soar-connectors-admin Date: Mon, 12 Aug 2024 19:29:14 +0000 Subject: [PATCH 5/5] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4674e26..345fc17 100644 --- a/README.md +++ b/README.md @@ -802,7 +802,7 @@ action_result.data.\*.blacklistUrl | string | | action_result.summary.message | string | | Blacklist retrieved action_result.summary.total_blacklist_items | numeric | | 10 summary.total_objects | numeric | | 1 -summary.total_objects_successful | numeric | | 1 +summary.total_objects_successful | numeric | | 1 ## action: 'update user' Update user with given id