-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Build search indicator query from arguments. #40648
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
Merged
omerKarkKatz
merged 27 commits into
master
from
fixed_argument_search_indicators_agentix
Jul 23, 2025
+279
−2
Merged
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
c94f4b6
search indicators agentix
omerKarkKatz 9bde5b0
commit
omerKarkKatz f49c39a
rebase
omerKarkKatz f20a08c
commit
omerKarkKatz 25b98bb
pre commit fixes
omerKarkKatz cc73499
revert poetry changes
omerKarkKatz bd9ef6a
RN
omerKarkKatz 36dd086
merge with master
omerKarkKatz ea1000e
commit
omerKarkKatz a228934
Merged master into current branch.
61eed2a
Bump pack from version CommonScripts to 1.19.90.
de1db91
review and add qoutes over the query
omerKarkKatz c84dbd6
Update Packs/CommonScripts/Scripts/SearchIndicatorAgentix/README.md
omerKarkKatz 81c1ad3
fix tags issue (#40669)
jbabazadeh c0749e1
Update Microsoft Defender for Endpoint (ATP) integration docs (#40630)
kamalq97 93c868f
Fixed invalid escape character (#40667)
MosheEichler 0a06224
Auto Updated Docker PR from 2025-07-22 GitLab Pipeline ID 4250850 (#4…
content-bot 1aab125
TIM - Fix the domain regex to avoid match backtick at the end (#40660)
MosheEichler e96a241
[GetEndpointData] Refactor endpoint args and output structure (#40383)
mmhw 6e27c9c
Excessive User Account Lockouts + silent-Suspicious local user accoun…
idovandijk e774e31
PAN-OS - Security Advisories Vulnerability Check (#40414)
aneeshamore 6f47eaf
pre commit
omerKarkKatz 9b59727
merge with master
omerKarkKatz 99f95b2
bumped base
omerKarkKatz 3c10872
desc
omerKarkKatz 7e9fc22
pre-commit
omerKarkKatz 2d4966c
merge with master
omerKarkKatz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
## Base | ||
|
||
Documentation and Metadata improvements. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
|
||
#### Scripts | ||
|
||
##### New: SearchIndicatorAgentix | ||
|
||
- New: Added a new script- SearchIndicatorAgentix that Searches Cortex XSOAR Indicators. |
38 changes: 38 additions & 0 deletions
38
Packs/CommonScripts/Scripts/SearchIndicatorAgentix/README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
This script searches indicators by specified fields. | ||
|
||
## Script Data | ||
|
||
--- | ||
|
||
| **Name** | **Description** | | ||
| --- | --- | | ||
| Script Type | python3 | | ||
| Tags | Utility | | ||
| Cortex XSOAR Version | 6.5.0 | | ||
|
||
## Inputs | ||
|
||
--- | ||
|
||
| **Argument Name** | **Description** | | ||
| --- | --- | | ||
| value | A single value or comma separated list of values to search. | | ||
| expirationStatus | The expiration status of the indicator. | | ||
| type | The type of the indicator to search can be a single value or a comma separated list of values. | | ||
| IssuesIDs | The issues that is linked to the indicator can be a single value or a comma separated list of values. | | ||
| size | The number of indicators to return, defaults to a max of 25. | | ||
|
||
## Outputs | ||
|
||
--- | ||
|
||
| **Path** | **Description** | **Type** | | ||
| --- | --- | --- | | ||
| foundIndicators.id | The id of the indicator in the XSOAR database. | Unknown | | ||
| foundIndicators.indicator_type | The type of Indicator \(i.e. IP, Domain, URL, etc\) | Unknown | | ||
| foundIndicators.value | The value of the Indicator | Unknown | | ||
| foundIndicators.score | The numeric score of the indicator \(0 = Unknown, 1 = Good, 2 = Suspicious, 3 = Malicious\) | Unknown | | ||
| foundIndicators.verdict | The human readable score/verdict of the Indicator. | Unknown | | ||
| foundIndicators.investigationIDs | The investigations related to the indicator. | Unknown | | ||
| foundIndicators.expiration | The expiration status of the indicator. | Unknown | | ||
| foundIndicators.lastSeen | The timestamp of the last time the indicator was sensitive. | Unknown | |
78 changes: 78 additions & 0 deletions
78
Packs/CommonScripts/Scripts/SearchIndicatorAgentix/SearchIndicatorAgentix.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import demistomock as demisto # noqa: F401 | ||
from CommonServerPython import * # noqa: F401 | ||
|
||
KEYS_TO_EXCLUDE_FROM_QUERY = ["size"] | ||
|
||
|
||
def prepare_query(args: dict) -> str: | ||
""" | ||
Prepares a query for list-based searches with safe handling | ||
|
||
Args: | ||
key (str): Field/attribute to search | ||
value (str/list): Value or list of values to match | ||
|
||
Returns: | ||
str: Formatted query string | ||
""" | ||
query_sections = [] | ||
for key, values in args.items(): | ||
query = "" | ||
if key in KEYS_TO_EXCLUDE_FROM_QUERY: | ||
continue | ||
|
||
if not values: | ||
continue | ||
|
||
if key == "IssuesIDs": | ||
key = "investigationIDs" | ||
|
||
values_as_list = argToList(values) | ||
if len(values_as_list) > 1: | ||
query = " OR ".join(f'{key}:"{str(v).strip()}"' for v in values_as_list) | ||
else: | ||
query = f'{key}:"{str(values_as_list[0]).strip()}"' | ||
|
||
query_sections.append(query) | ||
|
||
return " AND ".join(f"({qs})" for qs in query_sections) if query_sections else "" | ||
|
||
|
||
def search_indicators(args): | ||
# search for indicators | ||
query = prepare_query(args) | ||
indicators = demisto.executeCommand("findIndicators", {"query": query, "size": args.get("size")})[0]["Contents"] | ||
|
||
# return specific information for found indicators | ||
filtered_indicators = [] | ||
fields = ["id", "indicator_type", "value", "score", "expirationStatus", "investigationIDs", "lastSeen"] | ||
for indicator in indicators: | ||
style_indicator = {} | ||
for field in fields: | ||
style_indicator[field] = indicator.get(field, indicator.get("CustomFields", {}).get(field, "n/a")) | ||
style_indicator["verdict"] = scoreToReputation(style_indicator["score"]) | ||
filtered_indicators.append(style_indicator) | ||
|
||
headers = fields + ["verdict"] | ||
markdown = tableToMarkdown(f"Indicators Found: {query=}", filtered_indicators, headers) | ||
return markdown, filtered_indicators | ||
|
||
|
||
def main(): | ||
args = demisto.args() | ||
try: | ||
readable_output, outputs = search_indicators(args) | ||
results = CommandResults( | ||
outputs_prefix="foundIndicators", | ||
outputs_key_field="id", | ||
readable_output=readable_output, | ||
outputs=outputs, | ||
ignore_auto_extract=True, | ||
) | ||
return_results(results) | ||
except DemistoException as error: | ||
return_error(str(error), error) | ||
|
||
|
||
if __name__ in ("__main__", "__builtin__", "builtins"): | ||
main() |
65 changes: 65 additions & 0 deletions
65
Packs/CommonScripts/Scripts/SearchIndicatorAgentix/SearchIndicatorAgentix.yml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
args: | ||
- description: 'A comma-separated list of indicator values to filter the search results (e.g., "1.1.1.1,8.8.8.8").' | ||
name: value | ||
required: false | ||
isArray: true | ||
- description: 'The expiration status of the indicator.' | ||
name: expirationStatus | ||
required: false | ||
predefined: | ||
- expired | ||
- active | ||
- description: 'The type of the indicator to search can be a single value or a comma separated list of values.' | ||
name: type | ||
required: false | ||
isArray: true | ||
- description: 'The IssuesIDs that are linked to the indicator can be a single value or a comma separated list of values.' | ||
name: IssuesIDs | ||
required: false | ||
isArray: true | ||
- defaultValue: "25" | ||
description: The number of indicators to return, defaults to a max of 25. | ||
name: size | ||
comment: |- | ||
This script searches indicators by specified fields. | ||
commonfields: | ||
id: SearchIndicatorAgentix | ||
version: -1 | ||
contentitemexportablefields: | ||
contentitemfields: | ||
fromServerVersion: "" | ||
dockerimage: demisto/python3:3.12.8.3296088 | ||
enabled: true | ||
name: SearchIndicatorAgentix | ||
outputs: | ||
- contextPath: foundIndicators.id | ||
description: The id of the indicator in the XSOAR database. | ||
- contextPath: foundIndicators.indicator_type | ||
description: The type of Indicator (i.e. IP, Domain, URL, etc). | ||
- contextPath: foundIndicators.value | ||
description: The value of the Indicator. | ||
- contextPath: foundIndicators.score | ||
description: The numeric score of the indicator (0 = Unknown, 1 = Good, 2 = Suspicious, 3 = Malicious). | ||
- contextPath: foundIndicators.verdict | ||
description: The human readable score/verdict of the Indicator. | ||
- contextPath: foundIndicators.investigationIDs | ||
description: The investigations related to the indicator. | ||
- contextPath: foundIndicators.expirationStatus | ||
description: The expiration status of the indicator. | ||
- contextPath: foundIndicators.lastSeen | ||
description: The timestamp of the last time the indicator was sensitive. | ||
|
||
runas: DBotWeakRole | ||
script: '' | ||
scripttarget: 0 | ||
subtype: python3 | ||
tags: | ||
- Utility | ||
type: python | ||
fromversion: 6.5.0 | ||
tests: | ||
- No tests (auto formatted) | ||
marketplaces: | ||
- platform | ||
supportedModules: | ||
- agentix |
87 changes: 87 additions & 0 deletions
87
Packs/CommonScripts/Scripts/SearchIndicatorAgentix/SearchIndicatorAgentix_test.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
from Packs.CommonScripts.Scripts.SearchIndicatorAgentix.SearchIndicatorAgentix import prepare_query, search_indicators | ||
import demistomock as demisto | ||
|
||
|
||
def test_prepare_list_query(): | ||
""" | ||
Given: Arguments with multiple values for each field including value, expirationStatus, verdict, and type | ||
When: prepare_query is called with these arguments | ||
Then: Returns a properly formatted query string with OR conditions for multiple values and AND conditions between fields | ||
""" | ||
args = { | ||
"value": ["example.com", "example.org"], # List of values to search | ||
"expirationStatus": ["active"], # Possible expiration statuses | ||
"verdict": ["Benign", "Malicious"], # Possible verdicts | ||
"type": ["Domain", "IP", "URL"], # Indicator | ||
} | ||
res = """(value:"example.com" OR value:"example.org") AND (expirationStatus:"active") AND\ | ||
(verdict:"Benign" OR verdict:"Malicious") AND (type:"Domain" OR type:"IP" OR type:"URL")""" | ||
generated_query = prepare_query(args) | ||
assert res == generated_query | ||
|
||
|
||
def test_prepare_query_with_empty_values(): | ||
""" | ||
Given: Arguments with mixed empty lists and populated lists, including custom fields | ||
When: prepare_query is called with these arguments | ||
Then: Returns a query string that excludes empty fields and includes only populated fields | ||
""" | ||
args = { | ||
"value": ["example.com"], # Single value | ||
"expirationStatus": [], # Empty list | ||
"verdict": ["Benign"], # Single verdict | ||
"type": [], # Empty list | ||
"score": ["5", "10"], # Additional field with multiple values | ||
} | ||
res = '(value:"example.com") AND (verdict:"Benign") AND (score:"5" OR score:"10")' | ||
generated_query = prepare_query(args) | ||
assert res == generated_query | ||
|
||
|
||
def test_prepare_query_edge_cases(): | ||
""" | ||
Given: Arguments with special characters, spaces, email formats, empty strings, and mixed data types | ||
When: prepare_query is called with these edge case arguments | ||
Then: Returns a properly formatted query string that handles special characters and excludes empty values | ||
""" | ||
args = { | ||
"value": ["test with spaces", "[email protected]", "192.168.1.1"], # Special characters and formats | ||
"expirationStatus": ["expired"], # Single status | ||
"verdict": [], # Empty verdict list | ||
"type": ["Email", "IP"], # Mixed types | ||
"anotherField": ["value1"], # Single custom field | ||
} | ||
res = """(value:"test with spaces" OR value:"[email protected]" OR value:"192.168.1.1") AND \ | ||
(expirationStatus:"expired") AND (type:"Email" OR type:"IP") AND (anotherField:"value1")""" | ||
generated_query = prepare_query(args) | ||
assert res == generated_query | ||
|
||
|
||
def test_search_indicators_basic_functionality(mocker): | ||
""" | ||
Given: Basic arguments with value, type, and size for searching indicators | ||
When: search_indicators is called with these arguments | ||
Then: Returns markdown output and filtered indicators with proper verdict mapping | ||
""" | ||
args = {"value": "example.com", "type": "Domain", "size": 50} | ||
|
||
mock_indicators = [ | ||
{ | ||
"id": "1", | ||
"indicator_type": "Domain", | ||
"value": "example.com", | ||
"score": 2, | ||
"expirationStatus": "active", | ||
"investigationIDs": ["inv1"], | ||
"expiration": "2024-12-31", | ||
"lastSeen": "2024-01-01", | ||
} | ||
] | ||
|
||
mocker.patch.object(demisto, "executeCommand", return_value=[{"Contents": mock_indicators}]) | ||
markdown, filtered_indicators = search_indicators(args) | ||
|
||
assert "Indicators Found" in markdown | ||
assert len(filtered_indicators) == 1 | ||
assert filtered_indicators[0]["id"] == "1" | ||
assert filtered_indicators[0]["verdict"] == "Suspicious" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.