Confirm that your administrator has installed the Query app in Splunk.
Go to the Splunk Dashboard or Search box and start your search with a pipe '|' in front of the queryai command, like this:
Piping your search to queryai
Tailor your search with parameters and operators as described below. Run | queryai help=allfor sub-options to understand search syntax, available connectors, attribute namings, etc.
Search Command Syntax
The queryai command accepts from one to three parameters.
Syntax:
| queryai search=”<search conditions>” events="<list of events>" connectors="<list of connectors>"
A mandatory parameter that carries your search conditions and boolean logic.
connectors
An optional comma-separated parameter identifying the connector aliases that you want to include in your search (e.g., MS Defender, S3, etc.). Without this parameter, all connectors will be queried.
Note: Your connectors are unique to your configured data sources and you can get that list that using | queryai help=connectors. Query platform administrators can configure additional connectors from the 'Connections' page in Query's Console at https://go.query.ai/.
exclude_connectors
An optional comma-separated parameter identifying the connector aliases that you want to exclude in your search (e.g., MS Defender, S3, etc.).
events
An optional comma-separated parameter identifying the event types that you want to include in your search (e.g.: file_activity, detection_finding.). Without this parameter, all events will be queried.
An optional comma-separated parameter identifying the event types that you want to exclude in your search (e.g.: file_activity, detection_finding).
help
An optional parameter that, when used, must be set to what you are seeking help on. Start with | queryai help=all and it will list what other things you can ask for further help on. For example, help=events will list all event names. help=network_activity will list the attributes of network_activity. help=connectors will list configured connectors.
Help, Examples, and Attribute and Connector Namings
Here are common help options available from within Splunk search:
Understand all the help sub-options: | queryai help=all
Help on search syntax, along with examples: | queryai help=search
Get names of connectors configured in your environment: | queryai help=connectors
Get searchable list of Entities and Events: | queryai help=[entities|events]
Get schema details of a given Event: | queryai help=<event name>
Operators
You can tailor your queryai searches using the following operators.
Operator
Symbol
Equals
=
Not Equals
!=
Contains
value
Starts With
value*
Ends With
*value
NOT (Boolean)
NOT
Logical AND
AND
Logical OR
OR
IN
IN(a,b,c)
ALL
Search Types
Searches can be considered to be one of two types:
Entity searches are very simple and allow you to retrieve a wealth of data related to a single Entity. Entity searches may include connectors and events parameters, and/or a single condition (i.e., Equals, Contains, Starts With, or Ends With), to limit your results.
Event searches are searches with specific Event-based conditions to return precisely the events you’re looking for. When performing Event searches, you should refer to the Query Data Model(QDM) for maximum effectiveness.
We’ll explain both of these types of searches below, starting with a basic Entity search.
Entity Search
Query makes it extremely simple to search across diverse, distributed sets of data to find common resources such as hostnames, IP addresses, file hashes, and more. These common resource types are called Entities.
Adding a condition (for example "=") to your Entity search retrieves matching results only.
You don’t need to learn anything about data models to perform highly-effective Entity searches like these:
account_id
account_name
command_line
country
credential_id
cve_id
cwe_id
email
file_hash
file_name
group_id
group_name
hostname
ip
mac_address
port
process_id
process_name
resource_id
subnet
url
user_agent
user_id
username
If you would like to understand Entities in more detail, you can read our guide explaining normalization of QDM Entities here.
Event Searches
To search for Events, all of the same syntax and conditions apply as for Entity searches. However, you should also familiarize yourself with relevant sections of the Query Data Model (QDM) so that you can specify event-attribute based conditions on the Event type you are looking for.
Events always have attributes, which could be simple data types like a string, or a complex type, i.e., an Object, which further have their own attributes. The attribute hierarchy can be examined further by clicking on them.
When you perform a search for the specific Event or a containing Object's attributes that you are interested in, use a dot to separate hierarchically-related attributes, for example:
You could also do a wildcard search (with no attributes) to get a list of all results for that Event, as shown below:
| queryai search="scan_activity = *"
Above star searches are not supported on Entities. They are only supported on scalar attributes of Events (or their underlying Objects' scalar attributes).
In your search syntax, don't use display caption name, use the actual lowercased name with spaces replaced with underscores, i.e. snakecased names. So, for example, use"datastore_activity.activity_id" rather than "Datastore Activity.Activity ID" (the latter is meant for display readability). Same goes for the underlying Object and other attributes' naming.
Event Search
QDM Events are cybersecurity events (or activities) of interest, such as Authentication Events.
| queryai search="user_inventory.user.name=ana OR [email protected]"
In
| queryai search="user_inventory.user.name IN (ana, ava, 'abc xyz', 'abc pqr')"
IN conditions are not supported with values containing wildcards. Break out into OR conditions instead, in that scenario.
Negating condition(s) using NOT
| queryai search="NOT (user_inventory.user.name=ana OR [email protected])"
| queryai search="NOT user_inventory.user.name IN (ana, ava, 'abc xyz', 'abc pqr')"
Noteworthy Search Scenarios: Tips for Success
Left associativity
In the absence of parentheses, the default order of evaluation is left to right. So this search:
| queryai search="user_inventory.user.type=System OR [email protected] AND user_inventory.user.name=ava"
would be executed as:
| queryai search="(user_inventory.user.type=System OR [email protected]) AND user_inventory.user.name=ava"
Using parentheses to prioritize associativity
| queryai search="user_inventory.user.type=System OR ([email protected] AND user_inventory.user.name=ava)"
Nesting of parentheses is not supported. However, you can use multiple parentheses to associate separate condition sections.
Case Sensitivity
Field names are case-sensitive. Use the lowercase snake_case name vs. display caption name.
Values are generally case-insensitive. (An exception is enum attribute values that are all uppercase. See the "Conditions on enum attributes" section below.)
Checking for null or not-null values
You can search for an attribute that has a non-empty value. For example, you can search the User Inventory events for users with a valid value for email_addr like this:
You can also search for an attribute that does not have a value, i.e., checking for nulls. Here is an example search for users for whom email_addr is not set:
Enum attributes hold a value from a specific set. For example, incident_finding.impact_id can only have one of these values: LOW, MEDIUM, HIGH, or CRITICAL. (Refer to the QDM documentation to see all enum attributes and their allowed values.)
Here are some scenarios to be aware of with enum attributes:
You can only use equality or inequality conditions, i.e., you cannot use ‘starts with,’ ‘contains,’ or ‘ends with’ style conditions.
Use uppercase for enum attribute value letters: Rather than ‘Informational,’ use ‘INFORMATIONAL.’
Although the QDM documentation shows both values and an internal numeric code for enum values, only use the uppercase style values, not the internal codes. For example, rather than a scan_activity.severity_id value of "1," use "INFORMATIONAL."
Handling spaces, special characters, or reserved keywords
Values containing reserved keywords (like AND, OR, NOT, IN), whitespaces should be enclosed inside single quotes. For example:
However, 'Starts With,' 'Ends With,' and 'Contains' operators do not support quoted values.
Conditions on certain attribute types
Operators like 'Starts With,' 'Ends With,' and 'Contains' are only supported with attributes that hold strings. So, for example, the following Entities don't support those operations:
ip
mac_address
file_hash
Connection-specific condition limitations
Depending upon the connection, certain conditions may not be supported. For example, threat intelligence platforms like VirusTotal don't support 'Starts With,' 'Ends With,' and 'Contains' operators on url.
Don't put search conditions across different entity types, or across entity and event together
By design, Entity Searches are simple. Each Entity Search supports one condition on a single entity type - but not across multiple entity types or across events. Also, you can't do an unconstrained entity=* search.
For example, you cannot do:
ip=*
ip=1.1.1.1 OR ip=1.2.3.4
ip=1.1.1.1 AND network_activity.action_id=DENIED
Instead, you can search for multiple values within the same entity type through the use of IN / Starts With / Ends With. You could also use an ORed Event search.
Examples:
ip IN (1.1.1.1, 1.2.3.4)
hostname="DATACENTER1*"
network_activity.device.ip=1.1.1.1 OR network_activity.device.ip=1.2.3.4
network_activity.device.ip=1.1.1.1 AND network_activity.action_id=DENIED
No AND-ing across multiple event types
When AND-ing multiple conditions, you must use the same Event types between the conditions. For example, this is valid, because the conditions are on the same Event: "user_inventory":
| queryai search="user_inventory.user.name = abc AND user_inventory.user.type!=System"
But the below example is not valid, because the AND conditions are on different Event types: "user_inventory" and "network_activity":
| queryai search="user_inventory.user.name = abc AND network_activity.device.ip=1.1.1.1"
It is valid to do OR-ing across multiple event types. For example, this is valid if you want to see these two unrelated events together:
| queryai search="user_inventory.user.name = abc OR network_activitydevice.ip=1.1.1.1"
Connection-specific Error Handling With Partial Results
Searches performed from the Query platform initiate multiple distributed parallel queries run via relevant connectors into your data sources. There could be connection-specific errors or warnings that cause a subset of data connections to provide only partial results. In that scenario, the app will still show you the available results, and will also show you the specific warnings and errors from the connections that didn't provide results.
Extracting data from stringified JSON hierarchy
Leveraging the JSON viewer:
OCSF is a hierarchical schema, i.e. it contains sub-objects further containing sub-fields (which could be objects too having their own sub-fields). The _raw field contains the native platform's raw data (mapped from OCSF's raw_data) and Splunk only shows its JSON viewer for data in _raw field. To apply the JSON viewer to another field, you can assign its value into the _raw field:
... | eval _raw=xyzfield
If you want to preserve the original _raw, then you can do:
... | rename _raw AS original_raw | eval _raw=xyzfield
Extracting Interesting Fields
By default, Splunk extracts Interesting Fields only from the top-level fields in the JSON hierarchy. Splunk stringifies to flatten the hierarchical data, and that could make it hard for the analyst to visually scan sub-fields. However, all it takes is using the spath command to extract the relevant sub-field(s) of interest:
... | spath input=xyzfield
If you need to extract from another stringified field or from another subfield of xyzfield, you can continue chaining spath to extract further from multiple fields. For example:
... | spath input=xyzfield | spath input=pqrfield
Extracting only specific sub-paths
Instead of extracting all sub-fields, if you care only about a certain field, you can extract using:
... | spath input=xyz path=pqr output=xyz_pqr
Note that In above example, we also specified an output field name prefix to be added to the subfields, so that we can easily distinguish.
Keeping only desired fields in the output
You can chain further on top of the above examples and do... | fields a, b, c, d to only keep fields you desire to keep - a, b, c, d in our example. You can also alternatively remove undesired field(s) by adding a dash in front: ... | fields -xyz, -pqr
Updated 4 days ago
What’s Next
From here, you might also be interested in one of these topics: