Query API
This API requests scheduling a query and returns an object that provides information needed to collect the results.
Note: Orbital will retain the results of all queries for a minimum of 48 hours.
Scheduled queries can have a duration assigned to them specify how long the query will run for. If one or more nodes come online after the query has started running, the results for those new nodes will be created when the nodes connect. A more detailed description of Scheduled Queries can be found at Scheduled Queries.
Live queries, however, behave differently. Live queries run immediately and return information from only those nodes that are connected at the time the query is run. See the Results API for how to retrieve a query’s results. A more detailed description of Live Queries can be found at Live Queries.
Note: Live Queries are also known as probes.
Request Parameters
Orbital accepts the following parameters when creating a query.
-
name
– A descriptive name for the query, used by the UI to help users distinguish queries. -
nodes
– A list of Orbital node identifiers. In order to have a valid query, one or more of the following four prefixes must be used: nodes, os, nodeversion, or netmask. Refer to Specifying Nodes as Subjects of Queries for more details. -
expiry
– The Unix epoch time when the query will expire, after which no nodes will be asked to answer the query. This field is required and must be at least one minute in the future.
interval
– A period in seconds which determines how long until Orbital will want a new result from a node for the query. This field is required and must be set to at least a value of 0. If the value has been set to 0, it causes the query to run on each applicable node only once, for up to a maximum of 24 hours. Using this parameter allows you to define a scheduled query, but have it only run once on each organizational endpoint that matches the query criteria.
The interval is an api
analog of the Run Once function, located on the Scheduled Queries form of the User Interface. Refer to the Scheduled Query popup’s Run Once function section for more information.
os
– A list of operating systems, such as["windows"]
. If present, Orbital will add all hosts with the given operating systems to the list of nodes. Having an explicit node in the list along with its os will not cause queries to run twice on that node.
-
allowos
– Filters the query results so that only results of nodes running the specified operating system are returned, such as["windows"]
. Unlike other prefixes,allowOS
does not select any endpoints. If used, Orbital will run the query as it normally would, using all other parameters, but when returning the results of the query, will only return the results coming from those hosts running the operating system defined by this parameter. This parameter can be thought of as a filter. -
osQuery
– A list of osquery objects. Cannot be combined withstock
. Refer to osquery Objects in Queries for more details. -
stock
– A stock catalog query ID. Cannot be combined withosQuery
. -
stockArgs
– A table of stock parameters, where each value is a list of strings. Used to provide parameters to a stock query. Only useful withstock
. -
context
– A table of strings which will be stored with each result. Used to pass opaque metadata on to webhooks, such as a CTR or Threat Grid URL for more information. -
postbacks
– A list of Postback objects, each describing a remote data store, where results from a scheduled query get sent. See Postback Objects in Queries for more details.
osquery Objects in Queries
Orbital supports sending a list of arbitrary osquery statements to Orbital nodes for evaluation in the osQuery
query parameter. You can give these statements a label, which will be used in the results object to distinguish tables of results. This is a good practice when you combine multiple statements in a single Orbital Query.
[{
"label": "list_applications",
"name": "List Applications",
"sql": "SELECT * FROM applications;"
}]
Postback Objects in Queries
A Postback specifies either an existing Webhook ID or an URL where results for the specified scheduled query will be sent. The remote data store must be able to respond with a 200 to a POST at the time of the query request, in order for the request to get scheduled.
Postback Fields
webhookid
– ID of a saved Webhook.url
– URL of the remote data store, including any supplied query args.token
– Optional. The token value is passed in on the request as a bearer value in the Authorization header.fingerprint
– SHA256 fingerprint of the remote data store certificate. See details on obtaining the fingerprint.format
– Optional. Defaults tocompact
. Result format type. Allowable values: “ctim”, “splunk-compact”, “splunk-expanded”, “s3-compact”, “s3-expanded”, “compact”, and “expanded”. See details on result formats.bucket
– For S3 format, S3 bucket.region
– For S3 format, S3 region.accessKey
– For S3 format, S3 access key.secretKey
– For S3 format, S3 secret key.requirerows
– When set totrue
, only send those results having nonzero rows to the Remote Data Store. This parameter defaults tofalse
, thereby preserving the legacy behavior of sending all results to the RDS.
Specifying Nodes as Subjects of Queries
Orbital supports a number of different methods for specifying the nodes to query. Any or all of the following prefixes may be combined when creating a query and any nodes that match the specified prefix or prefixes will run the query. With the exception of the all
, random
, netmask
, and wildcard
prefixes, any prefixes listed in the table below can be used on the Endpoints page to search for nodes.
A Number of Prefixes are Also Available to Identify Nodes by Specific Properties
- Prefix: Prefix string to identify the value.
- Auto-Detectable: Some prefixes can be automatically detected based on the format of the value, allowing the prefix to be omitted. Note that when a wildcard is used, the prefix can never be auto-detected.
- Allowed Values: Some values have specific allowed values or formats.
- Case Sensitive: The matching for some values is case sensitive.
- Allows Wildcard: Some prefixes allow the use of a wildcard character
%
to pattern match. Note that any time a wildcard is used, the prefix is always required. - Example: An example.
- Description: A description of the prefix.
Prefix | Auto-Detectable | Allowed Values | Case Sensitive | Allows Wildcard | Example | Description |
---|---|---|---|---|---|---|
allowOS | No | windows , linux , darwin |
No | No | "allowOS:darwin" |
Only nodes with one of the specified OSes are allowed from the set of nodes otherwise specified. |
amp | Yes | GUID format | Yes | No | "amp:348301bf-2082-4d83-b340-e6ab2e58579c" |
A Secure Endpoint Computer GUID |
ampuuid | Yes | GUID format | Yes | No | "ampuuid:348301bf-2082-4d83-b340-e6ab2e58579c" |
A Secure Endpoint Computer GUID |
anyconnectudid | No | n/a | Yes | No | "anyconnectudid:163F665789D42AA0EB883A023D67D8CE391DF362" |
The AnyConnect UDID (supported as of node version 1.17 or higher) |
host | No | n/a | No | Yes | "host:DESKTOP-XYZ" |
A host name. |
hostname | No | n/a | No | Yes | "hostname:WOPR" |
A host name. |
hwaddr | Yes | MAC format | No | Yes | "hwaddr:02:42:c8:1f:7d:fa" |
A MAC address |
ip | Yes | IPv4 or IPv6 format | n/a | Yes* | "ip:10.0.0.1" |
A network ipv4 or ipv6 address. When wildcard is used, only matches IPv4. |
ip4 | Yes | IPv4 format | n/a | Yes | "ip4:10.0.0.1" |
A network ipv4 address |
ipv4 | Yes | IPv4 format | n/a | Yes | "ipv4:10.0.0.1" |
A network ipv4 address |
ip6 | Yes | IPv6 format | n/a | Yes | "ip6:fe80::3926:f1ac:d0cf:d1d7" |
A network ipv6 address |
ipv6 | Yes | IPv6 format | n/a | Yes | "ip6:fe80::3926:f1ac:d0cf:d1d7" |
A network ipv6 address |
mac | Yes | MAC format | No | Yes | "mac:02:42:c8:1f:7d:fa" |
A MAC address |
machine | No | n/a | Yes | No | “machine:48469d02bacd44eba481a1a3f0020ea1” | The unique machine identifier (supported as of node version 1.17 or higher). See details below. |
netmask | Yes | CIDR Notation | n/a | No | "netmask:192.168.1.168/24" |
A network ipv4 address with trailing netmask bit count |
nodeversion | No | An existing node version. | n/a | No | "nodeversion:1.12.6" |
An Orbital node version in either {major}.{minor} format or {major}.{minor}.{patch} format. *Using {major}.{minor} will match all patch versions for the given parameters. |
orb | Yes | n/a | Yes | No | "orb:oLPkT67m4nj-QpdGDPNCmQ" |
An Orbital ID |
orbital | Yes | n/a | Yes | No | "orbital:oLPkT67m4nj-QpdGDPNCmQ" |
An Orbital ID |
os | No | windows , linux , darwin |
No | No | "os:windows" |
Every node with the given OS. |
osqueryversion | No | An existing osquery version. | n/a | No | "osqueryversion:4.4.0" |
An Osquery version in either {major}.{minor} format or {major}.{minor}.{patch} format. *Using {major}.{minor} will match all patch versions for the given parameters. |
random | No | Numbers > 0 | n/a | No | "random:5" |
The specified number of random endpoints. |
queryId | No | Any valid Orbital Query ID | Yes | No | "queryId:zfmCLhXjFO6aIvV3frhg_w" |
queryId links the new query to an existing query. Refer to Linked Queries for more information. |
Other wildcard examples:
"ipv4:127.0.0.%"
Match any IPv4 address that begins with 127.0.0."ipv4:%.0.0.1"
Match any IPv4 address that ends with .0.0.1"ipv4:127.0.%.1"
Match any IPv4 address that begins with 127.0., and ends with .1
If you specify the prefix all
in the nodes list, Orbital will query all of the nodes in your organization. This can be very useful in general threat hunting and data collecting queries; however, using the all
prefix may return results for an extremely large number of nodes, depending on the size of your organization. Because of this, you may wish to narrow the results returned by the query by using one of the other prefixes, such as the os
prefix. The os
prefix allows you to specify the operating system the query will run on. For example, if you specify the Linux operating system, your query will only run against those endpoints that are running Linux nodes. For more information on prefixes, refer to the Prefix Table above.
Machine Identifier
The machine prefix returns a unique identifier.
- Linux returns the first one to exist (in this order) of
/etc/machine-id
,/var/lib/dbus/machine-id
, or/var/db/dbus/machine-id
. - Windows returns the
Windows Machine SID
. - macOS returns the
Mac UUID
.
Query API Limits
The following values represent the maximum and minimum limits for six (6) Query API parameters.
- The maximum number of nodes that can be provided to a query or live query is 10,000. However, if you use prefixes, such as
all
oros:linux
in the query or live query, the number of nodes that can be searched across is unlimited. - The maximum number of osquery queries that an Orbital query or live query can initiate is 128.
- The maximum number of postbacks that a query can have is 10.
- The maximum size of osquery results that can be returned to Orbital is 16 Megabytes. All results that osquery returns are compressed.
- The minimum interval that a query can run for before it completes is 5 minutes or 300 seconds.
- The minimum period that a query can run for before it expires is 30 seconds.
The None of the specified nodes were found
Error Message
This error message may cause some confusion if it is displayed. Orbital users are told that they are able to search across nodes that are not currently online, but will be searched when the node or nodes come back online. In spite of this, the error message, None of the specified nodes were found.
may be displayed. The reason for this is straightforward, Orbital has not registered the node yet and is; therefore, unaware that it exists. Also, if you are querying across multiple nodes and none of the nodes being queried are known, the error message will be displayed.
For example, if the node host-1312-win-MB
has been exposed to Orbital in the last 90 days, Orbital will wait for it to come back online and then search across it. However, if a new node named host-1701-thom-MB
has not been exposed to Orbital and is included in the query, Orbital will display the None of the specified nodes were found.
, as Orbital does not yet know about the node.
Note: It is important to understand that this error message will not be displayed if at least one node being queried is known.
Example 1: Getting a List of Processes From the Front Desk
The body of any Orbital API request must be formatted in JSON format and must be accompanied by a bearer authorization header containing an access token. See Orbital API Authentication for more information on authentication.
Scheduled Query Example
http https://$service/v0/query \ "Authorization:Bearer $token" \ osQuery:='[{"sql": "SELECT * FROM processes;"}]' \ nodes:='["host:FRONT-DESK-123"]'
Live Query or Probe Example
http https://$service/v0/probe \ "Authorization:Bearer $token" \ osQuery:='[{"sql": "SELECT * FROM processes;"}]' \ nodes:='["host:FRONT-DESK-123"]'
Example 2: A Non-Stock Query
This example shows the format of all the fields except postback, stock and stockargs, running on a couple explicit nodes plus all Windows nodes.
Scheduled Query Example
http https://$service/v0/query \ "Authorization:Bearer $token" \ name='My Custom Query' \ nodes:='["host:FRONT-DESK-123", "ip:1.2.3.4"]' \ expiry:=1688974114 \ interval:=600 \ os:='["windows"]' \ osQuery:='[{"sql": "SELECT * FROM processes;"}]' \ context:='{"description":"front desk", "value":"anything"}'
Live Query or Probe Example
http https://$service/v0/query \ "Authorization:Bearer $token" \ name='My Custom Query' \ nodes:='["host:FRONT-DESK-123", "ip:1.2.3.4"]' \ expiry:=1688974114 \ os:='["windows"]' \ osQuery:='[{"sql": "SELECT * FROM processes;"}]' \ context:='{"description":"front desk", "value":"anything"}'
Example 3: A Stock Query
This example shows the format of all the fields except postback and osquery, running on a couple explicit nodes plus all Windows nodes. It’s using the stock query with id arp_cache_inspection and query parameters ip_to_mac_count, ip_address, and mac_address.
Scheduled Query Example
http https://$service/v0/query \ "Authorization:Bearer $token" \ name='My Custom Query' \ nodes:='["host:FRONT-DESK-123", "ip:1.2.3.4"]' \ expiry:=1688974114 \ interval:=600 \ os:='["windows"]' \ stock='arp_cache_inspection' \ stockArgs:='{"ip_to_mac_count":["2"], "ip_address":["%"], "mac_address":["%"]}' \ context:='{"description":"front desk", "value":"anything"}'
Live Query or Probe Example
http https://$service/v0/query \ "Authorization:Bearer $token" \ name='My Custom Query' \ nodes:='["host:FRONT-DESK-123", "ip:1.2.3.4"]' \ expiry:=1688974114 \ os:='["windows"]' \ stock='arp_cache_inspection' \ stockArgs:='{"ip_to_mac_count":["2"], "ip_address":["%"], "mac_address":["%"]}' \ context:='{"description":"front desk", "value":"anything"}'
Example 4: A Postback, Using an Existing Webhook
This example shows the format of all the fields except stock and stockargs, running on an explicit node, and using a predefined Webhook object as a remote data store.
Scheduled Query Example
http https://$service/v0/query \ "Authorization:Bearer $token" \ name='My Custom Query' \ nodes:='["host:FRONT-DESK-123"]' \ expiry:=1688974114 \ interval:=600 \ os:='["windows"]' \ osQuery:='[{"sql": "SELECT * FROM processes;"}]' \ context:='{"description":"front desk", "value":"anything"}' \ postback:='{"webhookid":"65CLM4Jnns8uXa9bbBKksA"}'
Live Query or Probe Example
Live queries (probes) do not provide postback, so there is no example that can be provided.
Example 5: A Postback, Using a Live Webhook
This example shows the format of all the fields except stock and stockargs, running on an explicit node, and using a live postback to define the remote data store.
Scheduled Query Example
http https://$service/v0/query \ "Authorization:Bearer $token" \ name='My Custom Query' \ nodes:='["host:FRONT-DESK-123"]' \ expiry:=1688974114 \ interval:=600 \ os:='["windows"]' \ osQuery:='[{"sql": "SELECT * FROM processes;"}]' \ context:='{"description":"front desk", "value":"anything"}' \ postback:='{"url":"https://mywebserver.com","format":"expanded","fingerprint":"C728DF57BE22F0B2391DD3F7C402063F7E3241B50EB758755B96FBADAAA7A361"}'
Live Query or Probe Example
Live queries (probes) do not provide postback, so there is no example that can be provided.