Skip to content

Commit

Permalink
CrowdStrikeFalcon: ioc count in case of rate limit (demisto#36602)
Browse files Browse the repository at this point in the history
* return rate limit messgae

* update RN

* get count according documentation

* fix RN

* update test

* update RN

* fix pre commit

* revert RN

* RN

* RN after merge master
  • Loading branch information
ilappe authored Nov 6, 2024
1 parent f9cab1b commit cce807f
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3990,8 +3990,31 @@ def get_ioc_device_count_command(ioc_type: str, value: str):
ioc_id = f"{ioc_type}:{value}"
if not device_count_res:
return create_entry_object(raw_res, hr=f"Could not find any devices the IOC **{ioc_id}** was detected in.")

device_count = device_count_res[0].get("device_count")
if argToBoolean(device_count_res[0].get('limit_exceeded', False)):
demisto.debug(f'limit exceeded for {ioc_id}, trying to count by run_indicator_device_id_request')
# rate limit exceeded, so we will get the count by running the run_indicator_device_id_request function
# see https://falcon.crowdstrike.com/documentation/page/ed1b4a95/detection-and-prevention-policy-apis

device_count = 0
params = assign_params(
type=ioc_type,
value=value
)

while True:
device_ids_raw = run_indicator_device_id_request(params)
device_count += len(device_ids_raw.get('resources', []))
offset = demisto.get(device_ids_raw, 'meta.pagination.offset')
if not offset:
break
params['offset'] = offset

device_count_res[0]['device_count'] = device_count

context = [get_trasnformed_dict(device_count, IOC_DEVICE_COUNT_MAP) for device_count in device_count_res]
hr = f'Indicator of Compromise **{ioc_id}** device count: **{device_count_res[0].get("device_count")}**'
hr = f'Indicator of Compromise **{ioc_id}** device count: **{device_count}**'
return create_entry_object(contents=raw_res, ec={'CrowdStrike.IOC(val.ID === obj.ID)': context}, hr=hr)


Expand Down Expand Up @@ -4935,6 +4958,10 @@ def validate_response(raw_res):
return 'resources' in raw_res


def run_indicator_device_id_request(params):
return http_request('GET', '/indicators/queries/devices/v1', params=params, status_code=404)


def get_indicator_device_id():
args = demisto.args()
ioc_type = args.get('type')
Expand All @@ -4943,7 +4970,7 @@ def get_indicator_device_id():
type=ioc_type,
value=ioc_value
)
raw_res = http_request('GET', '/indicators/queries/devices/v1', params=params, status_code=404)
raw_res = run_indicator_device_id_request(params=params)
errors = raw_res.get('errors', [])
for error in errors:
if error.get('code') == 404:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5054,7 +5054,7 @@ script:
- contextPath: CrowdStrike.IOARules.version_ids
description: The IOA rule's version ID.
type: String
dockerimage: demisto/py3-tools:1.0.0.112434
dockerimage: demisto/py3-tools:1.0.0.112922
isfetch: true
ismappable: true
isremotesyncin: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3343,6 +3343,43 @@ def test_get_ioc_device_count_command_exists(requests_mock):
assert result['EntryContext']['CrowdStrike.IOC(val.ID === obj.ID)'][0]['ID'] == 'md5:testmd5'


def test_get_ioc_device_count_command_rate_limit_exceeded(requests_mock):
"""
Test cs-falcon-device-count-ioc with rate limit exceeded
Given
- There is a rate limit in CS side
When
- The user is running cs-falcon-device-count-ioc with md5:testmd5
Then
- ensure the correct count is returned by the offset mechanism
"""
from CrowdStrikeFalcon import get_ioc_device_count_command
response = {'resources': [{'id': 'md5:testmd5', 'type': 'md5',
'value': 'testmd5', 'limit_exceeded': 'true', 'device_count': 1}]}
indicators_queries_res = {'resources': ["res_1", "res_2", "res_3"]}
indicators_queries_res_with_offset = indicators_queries_res | {'meta': {'pagination': {'offset': 1}}}
requests_mock.get(
f'{SERVER_URL}/indicators/aggregates/devices-count/v1',
json=response,
status_code=200,
)
requests_mock.get(
f'{SERVER_URL}/indicators/queries/devices/v1',
json=indicators_queries_res_with_offset,
status_code=200,
)
requests_mock.get(
f'{SERVER_URL}/indicators/queries/devices/v1?type=md5&value=testmd5&offset=1',
json=indicators_queries_res,
status_code=200,
)

res = get_ioc_device_count_command(ioc_type='md5', value='testmd5')

assert 'device count: **6**' in res['HumanReadable']


def test_get_process_details_command_not_exists(requests_mock, mocker):
"""
Test cs-falcon-process-details with an unsuccessful query (doesn't exist)
Expand Down
7 changes: 7 additions & 0 deletions Packs/CrowdStrikeFalcon/ReleaseNotes/2_0_24.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

#### Integrations

##### CrowdStrike Falcon

- Fixed an issue where the command ***cs-falcon-device-count-ioc*** not returned the correct value in case a rate limit occurred.
- Updated the Docker image to: *demisto/py3-tools:1.0.0.112922*.
2 changes: 1 addition & 1 deletion Packs/CrowdStrikeFalcon/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "CrowdStrike Falcon",
"description": "The CrowdStrike Falcon OAuth 2 API (formerly the Falcon Firehose API), enables fetching and resolving detections, searching devices, getting behaviors by ID, containing hosts, and lifting host containment.",
"support": "xsoar",
"currentVersion": "2.0.23",
"currentVersion": "2.0.24",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down

0 comments on commit cce807f

Please sign in to comment.