Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ASM] - EXPANDR - 1578 #24639

Merged
merged 1 commit into from
Feb 16, 2023
Merged
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
5 changes: 4 additions & 1 deletion Packs/CortexAttackSurfaceManagement/.pack-ignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,7 @@ ignore=PB114
ASM
CMDB
subplaybooks
GCP
Xpanse
GCP
StripChars
multiSelect
1 change: 1 addition & 0 deletions Packs/CortexAttackSurfaceManagement/.secrets-ignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
inferredCveMatchType
1.1.1.1
2.2.2.2.
[email protected]
[email protected]
https://xsiam.com
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
"locked": false,
"name": "ASM - Asset ID",
"neverSetAsRequired": false,
"openEnded": false,
"openEnded": true,
"ownerOnly": false,
"required": false,
"sla": 0,
"system": false,
"threshold": 72,
"type": "shortText",
"type": "multiSelect",
"unmapped": false,
"unsearchable": true,
"useAsKpi": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
"locked": false,
"name": "ASM - Attack Surface Rule ID",
"neverSetAsRequired": false,
"openEnded": false,
"openEnded": true,
"ownerOnly": false,
"required": false,
"sla": 0,
"system": false,
"threshold": 72,
"type": "shortText",
"type": "multiSelect",
"unmapped": false,
"unsearchable": true,
"useAsKpi": false,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
{
"associatedToAll": true,
"caseInsensitive": true,
"cliName": "asmremediationpathrule",
"closeForm": false,
"columns": [
{
"displayName": "Name",
"fieldCalcScript": "",
"isDefault": true,
"isReadOnly": false,
"key": "name",
"orgType": "shortText",
"required": false,
"script": "",
"selectValues": null,
"type": "shortText",
"width": 150
},
{
"displayName": "Description",
"fieldCalcScript": "",
"isDefault": true,
"isReadOnly": false,
"key": "description",
"orgType": "shortText",
"required": false,
"script": "",
"selectValues": null,
"type": "shortText",
"width": 150
},
{
"displayName": "Action",
"fieldCalcScript": "",
"isDefault": true,
"isReadOnly": false,
"key": "action",
"orgType": "shortText",
"required": false,
"script": "",
"selectValues": null,
"type": "shortText",
"width": 150
},
{
"displayName": "Created_by",
"fieldCalcScript": "",
"isDefault": true,
"isReadOnly": false,
"key": "created_by",
"orgType": "shortText",
"required": false,
"script": "",
"selectValues": null,
"type": "shortText",
"width": 150
},
{
"displayName": "Criteria",
"fieldCalcScript": "",
"isDefault": true,
"isReadOnly": false,
"key": "criteria",
"orgType": "shortText",
"required": false,
"script": "",
"selectValues": null,
"type": "shortText",
"width": 150
}
],
"content": true,
"defaultRows": [
{}
],
"description": "Shows information on matching remediation path rule",
"editForm": true,
"group": 0,
"hidden": true,
"id": "incident_asmremediationpathrule",
"isReadOnly": false,
"locked": false,
"name": "ASM - Remediation Path Rule",
"neverSetAsRequired": false,
"openEnded": false,
"ownerOnly": false,
"required": false,
"sla": 0,
"system": false,
"threshold": 72,
"type": "grid",
"unmapped": false,
"unsearchable": true,
"useAsKpi": false,
"version": -1,
"fromVersion": "6.5.0"
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
"locked": false,
"name": "ASM - Service ID",
"neverSetAsRequired": false,
"openEnded": false,
"openEnded": true,
"ownerOnly": false,
"required": false,
"sla": 0,
"system": false,
"threshold": 72,
"type": "shortText",
"type": "multiSelect",
"unmapped": false,
"unsearchable": true,
"useAsKpi": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,25 @@ class Client(BaseClient):
Client class to interact with the service API.
"""

def __init__(self, base_url, verify, proxy, headers, auth):
def __init__(self, base_url, verify, proxy, headers):
"""
Class initialization.
"""
super().__init__(base_url, verify=verify, proxy=proxy, headers=headers, auth=auth)
super().__init__(base_url, verify=verify, proxy=proxy, headers=headers)

def list_remediation_rule_request(self, request_data: Dict) -> Dict[str, Any]:
"""Get a list of all your remediation rules using the 'xpanse_remediation_rules/rules/' endpoint.

Args:
request_data (dict): dict of parameters for API call.

Returns:
dict: dict containing list of external services.
"""

response = self._http_request('POST', '/xpanse_remediation_rules/rules/', json_data=request_data)

return response

def list_external_service_request(self, search_params: List[Dict]) -> Dict[str, Any]:
"""Get a list of all your external services using the '/assets/get_external_services/' endpoint.
Expand All @@ -30,10 +44,8 @@ def list_external_service_request(self, search_params: List[Dict]) -> Dict[str,
dict: dict containing list of external services.
"""
data = {"request_data": {"filters": search_params, "search_to": DEFAULT_SEARCH_LIMIT}}
headers = self._headers

response = self._http_request('POST', '/assets/get_external_services/',
json_data=data, headers=headers)
response = self._http_request('POST', '/assets/get_external_services/', json_data=data)

return response

Expand All @@ -47,10 +59,8 @@ def get_external_service_request(self, service_id_list: List[str]) -> Dict[str,
dict: dict containing information on single external service.
"""
data = {"request_data": {"service_id_list": service_id_list}}
headers = self._headers

response = self._http_request('POST', '/assets/get_external_service',
json_data=data, headers=headers)
response = self._http_request('POST', '/assets/get_external_service', json_data=data)

return response

Expand All @@ -61,10 +71,8 @@ def list_external_ip_address_range_request(self) -> Dict[str, Any]:
dict: dict containing list of external ip address ranges.
"""
data = {"request_data": {"search_to": DEFAULT_SEARCH_LIMIT}}
headers = self._headers

response = self._http_request('POST', '/assets/get_external_ip_address_ranges/',
json_data=data, headers=headers)
response = self._http_request('POST', '/assets/get_external_ip_address_ranges/', json_data=data)

return response

Expand All @@ -78,10 +86,8 @@ def get_external_ip_address_range_request(self, range_id_list: List[str]) -> Dic
dict: dict containing information on external ip address range.
"""
data = {"request_data": {"range_id_list": range_id_list}}
headers = self._headers

response = self._http_request('POST', '/assets/get_external_ip_address_range/',
json_data=data, headers=headers)
response = self._http_request('POST', '/assets/get_external_ip_address_range/', json_data=data)

return response

Expand All @@ -95,10 +101,8 @@ def list_asset_internet_exposure_request(self, search_params: List[dict]) -> Dic
dict: dict containing list of internet exposure assets.
"""
data = {"request_data": {"filters": search_params, "search_to": DEFAULT_SEARCH_LIMIT}}
headers = self._headers

response = self._http_request('POST', '/assets/get_assets_internet_exposure/',
json_data=data, headers=headers)
response = self._http_request('POST', '/assets/get_assets_internet_exposure/', json_data=data)

return response

Expand All @@ -112,10 +116,8 @@ def get_asset_internet_exposure_request(self, asm_id_list: List[str]) -> Dict[st
dict: dict containing information on an internet exposure asset.
"""
data = {"request_data": {"asm_id_list": asm_id_list}}
headers = self._headers

response = self._http_request('POST', '/assets/get_asset_internet_exposure/',
json_data=data, headers=headers)
response = self._http_request('POST', '/assets/get_asset_internet_exposure/', json_data=data)

return response

Expand Down Expand Up @@ -145,6 +147,49 @@ def format_asm_id(formatted_response: List[dict]) -> List[dict]:
''' COMMAND FUNCTIONS '''


def list_remediation_rule_command(client: Client, args: Dict[str, Any]) -> CommandResults:
"""
asm-list-remediation-rule command: Returns list of remediation path rules.

Args:
client (Client): CortexAttackSurfaceManagment client to use.
args (dict): all command arguments, usually passed from ``demisto.args()``.
``args['asm_rule_id']`` A string representing the ASM Rule ID you want to get association
remediation path rules for.
``args['sort_by_creation_time']`` optional - enum (asc,desc).

Returns:
CommandResults: A ``CommandResults`` object that is then passed to ``return_results``,
that contains list of remediation path rules.
"""
asm_rule_id = str(args.get('asm_rule_id'))
sort_by_creation_time = args.get('sort_by_creation_time')

# create list of search parameters or pass empty list.
search_params = []
if asm_rule_id:
search_params.append({"field": "attack_surface_rule_id", "operator": "eq", "value": asm_rule_id})
if sort_by_creation_time:
request_data = {"request_data": {"filters": search_params, 'search_from': 0,
'search_to': DEFAULT_SEARCH_LIMIT, "sort": {"field": "created_at", "keyword": sort_by_creation_time}}}
else:
request_data = {"request_data": {"filters": search_params, 'search_from': 0,
'search_to': DEFAULT_SEARCH_LIMIT}}

response = client.list_remediation_rule_request(request_data)
parsed = response.get('reply', {}).get('remediation_rules')
markdown = tableToMarkdown('Remediation Rules', parsed, removeNull=True, headerTransform=string_to_table_header)
command_results = CommandResults(
outputs_prefix='ASM.RemediationRule',
outputs_key_field='rule_id',
outputs=parsed,
raw_response=response,
readable_output=markdown
)

return command_results


def list_external_service_command(client: Client, args: Dict[str, Any]) -> CommandResults:
"""
asm-list-external-service command: Returns list of external services.
Expand Down Expand Up @@ -423,16 +468,16 @@ def main() -> None:
base_url=base_url,
verify=verify_certificate,
headers=headers,
proxy=proxy,
auth=None)
proxy=proxy)

commands = {
'asm-list-external-service': list_external_service_command,
'asm-get-external-service': get_external_service_command,
'asm-list-external-ip-address-range': list_external_ip_address_range_command,
'asm-get-external-ip-address-range': get_external_ip_address_range_command,
'asm-list-asset-internet-exposure': list_asset_internet_exposure_command,
'asm-get-asset-internet-exposure': get_asset_internet_exposure_command
'asm-get-asset-internet-exposure': get_asset_internet_exposure_command,
'asm-list-remediation-rule': list_remediation_rule_command
}

if command == 'test-module':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,14 +327,54 @@ script:
- contextPath: ASM.AssetInternetExposure.externally_inferred_vulnerability_score
description: Asset vulnerability score.
type: Unknown
dockerimage: demisto/python3:3.10.8.37753
- arguments:
- description: A string representing the ASM rule ID you want to get the associated remediation path rules for.
name: asm_rule_id
required: true
- auto: PREDEFINED
description: Sorts returned incidents by the date/time that the incident was created ("asc" - ascending, "desc" - descending).
name: sort_by_creation_time
predefined:
- asc
- desc
description: Returns list of remediation path rules.
name: asm-list-remediation-rule
outputs:
- contextPath: ASM.RemediationRule.rule_id
description: Remediation path rule UUID.
type: String
- contextPath: ASM.RemediationRule.rule_name
description: Remediation path rule name.
type: String
- contextPath: ASM.RemediationRule.description
description: Remediation path rule description.
type: String
- contextPath: ASM.RemediationRule.attack_surface_rule_id
description: Association ASM rule ID for the remediation path rules.
type: String
- contextPath: ASM.RemediationRule.criteria
description: Array of remediation path rule criteria.
type: Unknown
- contextPath: ASM.RemediationRule.criteria_conjunction
description: Whether criteria is processed with AND or OR.
type: String
- contextPath: ASM.RemediationRule.action
description: Action to take on rule match.
type: String
- contextPath: ASM.RemediationRule.created_by
description: Email of who created the rule.
type: String
- contextPath: ASM.RemediationRule.created_by_pretty
description: Readable name of who created the rule.
type: String
- contextPath: ASM.RemediationRule.created_at
description: Date the rule was created.
type: Date
dockerimage: demisto/python3:3.10.10.47713
runonce: false
script: ''
subtype: python3
type: python
fromversion: 6.5.0
marketplaces:
- marketplacev2
- xpanse
tests:
- CortexAttackSurfaceManagement_Test
Loading