🌙
 

Subscribe to the Taegis™ XDR Documentation RSS Feed at .

Learn more about RSS readers or RSS browser extensions.

Advanced Search Query Language

search queries advanced search query language

Query Language is a powerful new interface that enables you to craft searches for alerts and events available in your tenant. Learn the basic syntax, schemas, and operators of Secureworks® Taegis™ XDR’s query language to craft search queries from scratch.

Access Query Language by navigating to Advanced Search from the left navigation bar.

Note

The advanced search interface you most recently chose is saved as your default search preference. Use the button at the top right of either Advanced Search option to toggle between them. For example, if you most recently used the Advanced Search Builder, you may need to select Use Query Language from the top right.

Query Language

Query Language

Tip

Search Help

Select Search Help to open the inline help that includes:

  • Build with Me section that helps you craft successful queries
  • Basic syntax
  • Available data types (schemas) and field names (context-aware as you type)
  • Operators
  • Examples

Collapse and expand the inline help using the Search Help link, or by selecting the arrow icon at the bottom.

Select Schema Library to view all the searchable schemas and fields in XDR.

Query Language Help

Query Language Help

Basic Syntax

Quick Start

To get started, you can run this simple example search for process events from the last 24 hours:

FROM process earliest =-24h

Next, you could substitute process with any of the other event types (see the Build With Me section below). You can even query multiple event types, as in this example:

FROM process, auth earliest =-12h

Query Language Fundamentals

To specify strings in the query language, use single quotes (and note that the WHERE is always optional):

FROM process WHERE image_path CONTAINS 'powershell.exe'

To search for string values that themselves include single quotes, escape with an e before the first single quote and with a backslash before any single quote(s) in the string:

from process where commandline contains e'echo \'mimikatz\''

Operators and any values specified are case-insensitive. In the examples, we've capitalized the operators only for emphasis.

A search cannot query alerts and events simultaneously and two independent queries must be run.

When running a multi-event search using field names independent to individual event types, individual queries are run and the results returned are a union of those queries.

To see more complex query options and examples, including boolean logic, regex matching, and more, see the Operators section.

Querying Common Fields and Logical Types

It is also possible to make queries without specifying any schema(s) and query all relevant schemas automatically.

Common Fields exist in the schemas for multiple event types. For example, sensor_type = 'ENDPOINT_REDCLOAK' would return all events that come from the Red Cloak™ Endpoint Agent, for all relevant schemas.

Logical Types can be used if you don’t know which schema(s) or specific field(s) to query. Logical types are preceded by the @ symbol. These automatically query the relevant schemas. For example, you could query:

@ip='8.8.8.8'
@user CONTAINS 'system'

For more information and examples on logical types, see the Logical Types section.

Querying Alerts

Alerts can be queried by fields that are specific to the alert schema as well as fields from the event schemas. Querying by event schemas provides greater flexibility to search, using a much larger set of fields instead of being constrained to the more limited fields within the alert. It also allows for querying fields that have a certain relationship which have been generalized within the alert. An example of this use case is, searching for the fields process.image_path and process.parent_image_path, both of which are normalized as the fileName entity within the alert schema.

To query for alerts, the ’alert’ data type must be specified by using the from alert clause at the beginning of the query. Specifiying just event fields without explicitly asking for the alert data type will run an events search. When running an alert search using event fields, the event type must be prepended to the field name. E.g. To search alerts using the process image path, you must specify the fields as process.image_path.

Alert queries can also use logical types as outlined above.

Query for an alert using the title field within the alert schema:

from alert where title contains 'Powershell'

Query for an alert using the commandline field within the event schema:

from alert where process.commandline contains 'powershell.exe'

Query for an alert using logical field types:

from alert where @ip = 10.1.1.10

Operators

The query language supports the operators listed below. All string values must be enclosed in single quotes and are interpreted as literals. All searches are case insensitive (contains, CONTAINS, and ConTAinS are equivalent).

Operator Description
= <literal> case-insensitive exact match
!= <literal> boolean NOT of equality
> <number> numeric greater than
>= <number> numeric greater or equal
< <number> numeric less than
<= <number> numeric less than or equal
contains <string> case-insensitive substring match of string literal in field
<fieldname> !contains <string exclusion> negation of case insensitive substring match of string literal in field
matches <string> case sensitive wildcard match of glob style string pattern in field
<fieldname> !matches <string exclusion> negation of case insensitive wildcard match of glob style string pattern in field
matches_regex <string> case insensitive regex match of string pattern in field
!matches_regex <string> negation of case insensitive regex match of string pattern in field
in <value list> boolean expression evaluates true if field value is contained in value list
!in <value list> boolean expression evaluates true if field value is not contained in value list
is not null tests for the existence of field and that it is not null
is null returns true if specified field does not exist or is null

contains

The contains operator tests for a substring match of a quoted string or literal string value and no wildcard expansion/matching occurs. Instead, when you use the contains operator and specify an asterisk *, the * symbol is treated as a literal character.

Example: Query process events where the commandline contains ’netsvc.exe’

from process commandline contains 'netsvc.exe'

matches

The matches operator must be specified with a supported glob pattern in the value string to execute as a wildcard search. The supported glob characters are the * and ? characters. Without the asterisk or question mark symbols, the query runs as a literal equality search. An asterisk matches zero or more characters, including an empty character. A question mark matches any single character.

Example: Query dnsquery events for a domain name ending with the suffix ’.google.com’

from dnsquery @domain matches '*.google.com'

matches_regex

The matches_regex operator supports regular expressions in the query string. The regex value will need to escape any characters, such as dots, which have a special meaning within regular expression syntax. Events and alerts use different backends and depending on the query being run the regex engine and notation will differ.

For events, the regex engine is Java compatible; please see the Java regex documentation for notation help.

For alerts, the regex engine is Lucene based; please see the Elastic regex documentation for notation help.

Example: Query process events where commandline field matches a string that is comprised of lower case characters and numbers followed by a file extension of .exe

from process commandline matches_regex '[a-z0-9]*\.exe'

Reserved Words

The following identifiers are reserved words that must be accompanied by single quotes if used in search terms as literal values.

from process where commandline contains 'search'

Note: All operators/reserved words are case insensitive (e.g. AND, and, aNd are equivalent).

AGG, AGGREGATE, AND, AS, ASC,
AVG, BY, CONTAINS, COUNT,
CARDINALITY, DESC, DESCENDANT,
EARLIEST, FALSE, FIELDS, FROM,
HEAD, IN, IS, INDEX,
LATEST, MATCHES, MATCHES_REGEX,
MAX, MIN, NOT, NOW, NULL, OF,
OR, SEARCH, SORT, SUM,
TAIL, TOP, TRUE, WHERE

Logical Types

Common Fields

If you query a field that exists for multiple event types, you will get results from all event types that match your query on this field. The sensor_type field exists for all event types and can be used to find all events from a particular data source. For example: sensor_type = 'ENDPOINT_REDCLOAK' would return all events from the Red Cloak Endpoint Agent, for all relevant schemas.

Other fields in common to many but not all events include: sensor_id, host_id

Resource ID

Each event in XDR has a unique resource_id, but this is not a normal common field. If you search for a valid resource_id=<value>, the one matching event will automatically be returned, regardless of the event type.

CIDR Notation

The query language supports CIDR notation for IP address fields when using the = (literal), matches or IN operators. Negation of these operators is supported with CIDR notation as well (e.g. !=, !matches and !IN).

At this time, CIDR notation is only supported for event queries. Alert queries do not support CIDR notation and a valid IP address must be used.

Example: Query netflow events where the source address is within the IP range ’192.168.2.0/24’:

from netflow where source_address = '192.168.2.0/24'

Note:

The following matches query will act as textual wildcard match and not a CIDR query:

from netflow where @ip matches '192.168.2*'

The following matches query will act as CIDR query:

from netflow where @ip matches '192.168.2.*.*'

Logical Types

Logical types are special fields that map to field names under the appropriate data schemas for that particular field category. The logical types are designed to alleviate the need to remember and specify each individual field name for each pertinent schema. Logical types are denoted with the @ prefix. A logical type, specified with @<logical type name>, will automatically query all the relevant event fields.

Notes: When a negation operator is used with a logical type, the search engine makes sure none of the fields mapped to the logical type in the query match the value provided.

When using the @raw logical type any backslashes will have to be escaped due to the backend used when searching for raw data. Please see examples at the end of this Logical Types section.

When your query has only a logical type in the search, then you will see results for alerts and events in a tabbed view.

Example: Query all alerts and events that have a username field for the value ’system’:

@user contains 'system'

Logical Type Mappings

Find the latest logical type mappings within the Search Help of Advanced Search in XDR.

Logical Type Query Examples

@raw contains '192.168.0.1'

returns all events, across all types, where the original_data text (the raw message) contains ’192.168.0.1’.

from netflow @ip = '10.0.0.1'

is recognized as a query for an IP address matching ’10.0.0.1’ and would be expanded to:

from netflow (source_address='10.0.0.1' OR destination_address='10.0.0.1' OR source_nat_address='10.0.0.1' OR destination_nat_address='10.0.0.1')

Logical type names can be used anywhere that a schema field name would be used:

from auth @user='bob'

This performs a query over all fields tagged as logical type ’user’ for the value ’bob’ and expands to:

from auth (source_user_name='bob' OR extra_subject_domain_user_id='bob' OR extra_target_domain_user_id='bob' OR target_user_name='bob' OR extra_targetoutboundusername='bob' OR extra_userprincipalname='bob' OR extra_virtualaccount='bob')

The query below performs a search for all ’commandline’ fields under the process event type with the value specified:

from process where @command contains 'add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run'

If we were to use the @raw logical type of the query above, we'd have to escape the backslahes due to the backend differences:

from process where @raw contains 'add HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run'

Search by Hostname

Query Language supports searches for events and alerts by hostname. The hostname field is a special use case where the hostname is first translated to a host_id from the endpoint databases within XDR, and the search is then run with the obtained host_id. Hostname searches do not work with network or cloud events.

The translation is completed using a backend API that only allows lookup for an exact match; therefore, the hostname field only supports literal match operators:

The hostname translation is also case sensitive and the value you provide should match against the hostname stored in the endpoint database.

Hostname Search Examples

Searching for Process Events using Hostname

Searching for Process Events using Hostname

Example: Query for all authentication events reported by an endpoint agent installed on ’Demo-PC01’

from auth where hostname = 'Demo-PC01'

Example: Query for all alerts fired for the host ’Demo-PC01’

from alert where hostname = 'Demo-PC01'

Note

The hostname field is a different use case than the logical type field @host. The @host logical type is mapped to various event fields. These event fields are populated when there is an asset name collected as part of the event original data. The @host logical type does not map to the actual endpoint hostname. Please review the Logical Types section for the mapping of the @host type.

Arrays

Queries over array fields are essentially flattened such that you can search for matches across any of the array elements using standard field.subfield notation:

from http http_response_headers.record.key='Authorization' and http_response_headers.record.value='Bearer 1234'

Note: The above query finds records that have an ’Authorization’ header and have a header with value ’Bearer 1234’, but this does not guarantee that these belong to the same header record. The ability to match on specific array indices is not supported.

String Literals

Single Quotes Usage

Example: Query process events for the directory path 'Windows\system32':

from process where image_path contains 'Windows\system32'

Escape Interpreting Modifier Usage

Example: Query process events that have a new line in the commandline field:

from process where @command contains e'dir\nmkdir test'

Example: Query process events where the value has singles quote and need to be escaped

from process where commandline contains e'echo \'mimikatz\''

Time Ranges

Constrain a query to a limited time range using the following:

where delta is an integer and unit is one of the following:

The optional [@unit] causes the resulting time value to be truncated to the specified second, minute, hour, day, week, month, or year rather than using the raw time value.

When only the latest time constraint is specified in the query, a default of the preceding 24 hours is applied for the earliest time constraint.

An absolute time range can also be specified as a formatted date string:

earliest='2019-06-1T00:00:00' AND latest='2019-06-30T00:00:00'

Note: Dates should be in the ISO 8601 standard, e.g., (2019-07-01, 2019-06-01T00:00:00)

Functions

Searches can be further qualified by “piping“ results into additional functions.

search | functions

When the query searches across multiple data types, the function operates across each data field independently.

Example: Query up to 5 results for the process and the auth data types each. In total, this example returns up to 10 results:

from process, auth where @user contains 'admin' | head 5

sort

sort sorts results by specified fields/ordering. When only one event type is queried, sorting by any field is supported, but when multiple event types are queried, only sorting by event_time_usec and ingest_time_usec fields are supported. Sorting for alerts is not currently supported.

search | sort field [ASC|DESC] (, field [ASC|DESC)?

from dnsquery query_name MATCHES '*.secureworks.com' earliest=-30d | sort query_name desc

from netflow source_address='10.0.0.1' earliest=-1d@d | sort source_address asc

from auth, process earliest=-1d | sort event_time_usec asc

head returns the first N number of results from each event type in search order.

search | head N

from dnsquery @domain MATCHES '*.secureworks.com' earliest=-30d | head 10

tail

tail returns the last N number of results from each event type, starting at the end of the result set. Tail reverses the order of the results before returning the last N results.

search | tail N

from dnsquery @domain MATCHES '*.secureworks.com' earliest=-30d | tail 10

fields

Note: The field operator is available only via the API and is not available in the XDR application.

fields restricts the query to include/exclude field sets when the data is being returned. By default, all fields — with exception of original_data — are returned in the results. Queries run more efficiently if only the required fields are selected. The fields function acts like a column selector.

search | fields field (, field)?

from dnsquery @domain MATCHES '*.secureworks.com' earliest=-30d | fields query_name

Aggregations

aggregate allows users to group the results of their query and performs the listed operations on the results of their query:

Operator Description
sum Calculate the sum of a field for every row returned by the query.
min Find the smallest value of a field.
max Find the largest value of a field.
avg Find the average value of a field for every row returned by the query.
count Count the number of rows which have a field. If no field is specified all rows are counted.
cardinality Count the number of rows which have a distinct, non-null value for a field.
(aggregate) by Group or aggregate the results by the values of the field specified and display a count for each value.

An aggregate query takes the following form:

search | aggregate [sum|min|max|avg|count|cardinality](field)

by

The by clause can either specify an optional field list or a time duration where the results will be grouped by the specified field or time unit:

search | aggregate _aggregation (, _aggregation)? by field
search | aggregate _aggregation (, _aggregation)? by int unit

where unit is

Examples: Get a list of usernames and their count from process events that had powershell in their commandline:

from process where commandline contains 'powershell' | aggregate count(username) by username

Get the earliest and latest authentication event for the username ’bob’ in the last 3 days:

from auth where source_user_name = 'bob' and earliest=-3d | aggregate min(event_time_usec), max(event_time_usec)

Get the sum of transfer bytes and the average of transfer bytes for the netflows from the Cisco ASA for the last 24 hours:

from netflow where sensor_type='CISCO_FIREWALL_ASA' | aggregate sum(tx_byte_count) as sum_tx, avg(tx_byte_count)

Query the count of domains matching *.net over the last day:

from dnsquery where query_name MATCHES '*.net' latest=-1d | aggregate count by query_name

Query the count of dnsquery events for each hour of the last 24 hours:

from dnsquery earliest=-1d | aggregate count by 1h

Note

Aggregation is only supported for event queries at this time. When running an aggregation with multiple event type queries aggregation will be performed per event type. Aggregation queries do not currently support aggregating on a logical type. Report creation from an aggregation query is also not supported at this time.

Examples

Query for all generic events from Zeek in the last 2 hours

from generic where sensor_type = 'zeek' earliest = -2h

Query for all generic events within the last 2 hours with the substring ’secureworks’

from generic where original_data contains 'secureworks' earliest = -2h

or, using the logical type @raw as an alias for original_data:

from generic where @raw contains 'secureworks' earliest = -2h

Query for all alerts that have a severity of high or critical:

from alert where severity >= 0.6

Query for all alerts that have a severity of low:

from alert where severity >= 0.2 and severity < 0.4

Query for all alerts where ’Powershell’ appears in the alert title:

from alert where title contains 'Powershell'

Query for all alerts where ’mimikatz’ appears in the commandline event fields:

from alert where @command contains 'mimikatz'

Query for all alerts where the username ’admin’ is the user associated with the event that generated the alert:

from alert where @user contains 'admin'

Query for all alerts that have the detector name of ’TDR Watchlist’:

from alert where metadata.creator.detector.detector_name = 'TDR Watchlist'

Query for all alerts generated by the detector ID ’event-filter’:

from alert where metadata.creator.detector.detector_id contains 'event-filter'

Query for alerts where the process parent image path contains ’cmd.exe’:

from alert where process.parent_image_path contains 'cmd.exe'

Query across all event types that have an IP address field for the IP ’10.0.0.1’:

@ip='10.0.0.1'

Query across all event types that have a domain name field for the name ’redcloak.secureworks.com’:

@domain='redcloak.secureworks.com'

Query only netflow events for the IP address ’10.0.0.1’:

from netflow @ip='10.0.0.1'

Query netflow and auth event types for the IP ’10.0.0.1’:

from netflow, auth @ip='10.0.0.1'

Query only netflow events for IP addresses in the range ’192.168.2.0/24’:

from netflow where @ip='192.168.2.0/24'

Query netflow and auth event types for IP addresses in the range ’192.168.2.0/24’:

from netflow, auth where @ip matches '192.168.2.0/24'

Query only netflow events for IP addresses in the range ’192.168.2.0/24’:

from netflow, auth where @ip matches '192.168.2.*'

Query only netflow events for IP addresses in the range ’192.168.0.0/16’:

from netflow, auth where @ip matches '192.168.*'

Query only netflow events for IP addresses in the range ’192.168.0.0/16’:

from netflow, auth where @ip in ('192.168.0.0/16')

Query auth for the user ’bob’:

from auth where @user='bob'

Query dnsquery events for the last 30 days:

from dnsquery earliest=-30d

Query dnsquery events starting from 30 days in the past till 10 days in the past:

from dnsquery earliest=-30d latest=-10d

Query dnsquery events for the last 2 days starting from the beginning of the day (in this example, 00:00:00 of yesterday):

from dnsquery earliest=-2d@d

Query dnsquery events starting from the specified date/time until current time:

from dnsquery earliest='2021-04-01T00:00:00'

Query process events where commandline field contains the phrase ’exe’:

from process commandline contains 'exe'

Query process events where commandline field does not contain the phrase ’exe’:

from process commandline !contains 'exe'

Query process events where the sensor type field is not equal to ’ENDPOINT_CROWD_STRIKE’:

from process sensor_type != 'ENDPOINT_CROWD_STRIKE'

Query process events where commandline field matches a string that is comprised of lowercase characters and numbers followed by a file extension of ’.exe’:

from process commandline matches_regex '[a-z0-9]*\.exe'

Query process events where the sensor type is one of ’ENDPOINT_REDCLOAK’, ’ENDPOINT_CROWD_STRIKE’:

from process sensor_type IN ('ENDPOINT_REDCLOAK','ENDPOINT_CROWD_STRIKE')

Query dnsquery events for domain name ending with ’.google.com’. It is mandatory to mention field name when using wildcard for equality:

from dnsquery @domain matches '*.google.com'

Query process events where sensor type equals ’ENDPOINT_CROWD_STRIKE’ and process ID equals ’5201’. The fields are AND-ed by default if no operator is specified:

from process where sensor_type='ENDPOINT_CROWD_STRIKE' process_id='5201'

Query process events where sensor_type equals ’ENDPOINT_REDCLOAK’ OR process ID equals ’5201’:

from process sensor_type='ENDPOINT_REDCLOAK' OR process_id='5201'

Query process events for the directory path ’Windows\system32’:

from process where image_path contains 'Windows\system32'

Query process events where the value has single quotes that need to be escaped:

from process where commandline contains e'echo \'mimikatz\''

Query auth events for user accounts being unlocked (Windows Event ID 4767):

from auth where win_event_id='4767'

Query 10 process events in the last 1 day (24 hours from current time) where sensor_type equals ’ENDPOINT_CROWD_STRIKE’, sorted by timestamp descending:

from process sensor_type='ENDPOINT_CROWD_STRIKE' earliest=-1d | head 10

Query 10 process events in the last 1 day (24 hours from current time) where sensor_type equals ’ENDPOINT_REDCLOAK’, sorted by timestamp ascending:

from process sensor_type='ENDPOINT_REDCLOAK' earliest=-1d | tail 10

Query auth events where the target_user_name field is null:

from auth target_user_name is null

Query auth events where the target_user_name field is not null:

from auth target_user_name is not null

Query process events that have a newline in the commandline:

from process where @command contains e'dir\nmkdir test'

Search for Generic Events

General search for generic events:

from generic

Generic Query

Generic Query

General search for generic events from a specified sensor:

from generic where sensor_type = 'zeek'

Generic Zeek Query

Generic Zeek Query

Searching Raw Data of Generic Events

This query searches generic events for specified data in a 2 hour window:

from generic where original_data contains 'secureworks' EARLIEST = -2h

Searching Raw Data of Generic Events

Searching Raw Data of Generic Events

Note

XDR only stores data that is not normalized as generic events. All normalized events still contain the original unaltered message in the original_data field. For more information, see FAQ: Generic Events and Normalized Data.

Running Your Search Query

When you are ready to try your query:

Tip

See Sort, Arrange, and Filter Search Results for tips on adjusting the table of query results.

Saving Your Search Query

To save your Query Language search, select Save from above the input field, enter a name for the search, and then select Save.

Save Query Language Search

Save Query Language Search

Sharing Searches

To share a search, select Copy Link above the table of search results, or select the Share Link icon Copy Share Link icon to copy the URL to your clipboard.

Copy the Share Links

Copy the Share Links

Viewing Saved Searches

To view Query Language searches that you and other members of your organization saved, select Saved Searches from below the input field. The Saved Searches in Query Language function as they do in the Advanced Search builder. See Saved Searches for more information.

Query Language Saved Searches

Query Language Saved Searches

Filter and Rearrange Search Results

The Query Language table of search results includes the following controls to filter and rearrange data:

Column Menu

Open the menu for available columns in the table by selecting the menu icon to the right of the column name.

Advanced Search Column Menu

Advanced Search Column Menu

Column Filter

Open a column menu and select the filter icon. The table updates results as you enter text in the column filter. Alternatively, use the checkmarks to filter by grouped field values, where available.

Filter a Search Column

Filter a Search Column

Pin a Column

You can pin a column to the left or right of the table. To do so, open the menu for the column you would like to pin by selecting the hamburger icon, select Pin Column, and then choose which side you would like to pin the column to.

Pin a Column

Pin a Column

Autosize Columns

Clean up the table appearance using the autosize column features. This helps show obscured information when a column is too narrow.

Autosize Search Columns

Autosize Search Columns

Choose Columns to Display

Choose which columns you want to appear in the table by opening a column menu, selecting the columns icon, and checking or unchecking the desired columns.

Use the text box to quickly filter for column names.

Or, open the Columns drawer from the right of the search results table.

Select Displayed Columns

Select Displayed Columns

Arrange Columns

Drag and drop columns by the header to rearrange them.

Rearrange Search Columns

Rearrange Search Columns

Reset Columns

To reset the columns of a table to their default size and ordering, select Reset Columns from a column menu.

Reset Columns

Reset Columns

Export Search Results

You can export data from search results in XDR as a CSV file.

Export Selected

  1. Use the checkboxes to select the results you wish to download.
  2. From the Actions menu on the upper right-hand of the results table, select Export Selected as CSV. The download request is sent and is processed.
  3. Navigate to Data Exports to check the status of the request and download any available files.

Export All

  1. From the Actions menu on the upper right-hand of the results table, select Export All as CSV. The download request is sent and is processed.
  2. Navigate to Data Exports to check the status of the request and download any available files.

Note

Downloadable files have an expiration date, which is listed in the Downloads table File Expiration column.

Tip

Files available for download are limited to 100,000 rows. If a data set larger than 100,000 rows in size is needed, you must refine the data table through date picker or search parameters and/or submit multiple requests spanning the full desired dataset.

 

On this page: