Skip to content

Splunk Enterprise app search

The Search page is the standard Splunk Search Processing Language (SPL) interface. In the DomainTools App, you use it to run the custom search commands that call DomainTools APIs and to query the threat feed indexes you enable in advanced configuration.

DomainTools custom search commands extend SPL with enrichment, investigation, passive DNS, WHOIS history, and RDAP lookups. Each command is a generating or transforming command that you pipe into a search. The commands below run against the DomainTools APIs and return results into your search pipeline.

Several commands also power dedicated UI pages: the DNSDB commands back Farsight DNSDB, dtwhoishistory backs WHOIS history, and dtparseddomainrdap backs Domain RDAP. The utility commands dtaccountinfo and dtidnadecode support the app’s internal pages. The threat feed commands and Iris Detect commands are grouped in their own sections below.

Extracts a domain from a URL field using tldextract, so DomainTools APIs receive a valid domain as input.

  • Syntax: | dtdomainextract field_in=string field_out=string include_subdomains=bool debug=bool feature=string
  • Parameters:
    • field_in (required)
    • field_out (required)
    • include_subdomains (optional)
    • debug (optional)
    • feature (optional)
  • Example: ... | dtdomainextract field_in=url field_out=domain

Queries Iris Enrich for up to 100 comma-separated domains. Set inline_results=true to keep the event data inline with your results.

  • Syntax: | dtirisenrich domain=string inline_results=string feature=string
  • Parameters:
    • domain (required)
    • inline_results (optional)
    • feature (optional)
  • Example: | makeresults | eval domain="domaintools.com" | dtirisenrich domain=domain inline_results=true

Queries Iris Investigate for up to 100 comma-separated domains supplied through domain, pivots on a domain attribute, or runs an IrisQL query. An IrisQL query returns up to 500 matching domains as Splunk events. The command doesn’t support pagination, so refine queries that match more than 500 domains.

You must provide irisql, domain, or both pivot_type and pivot_value. If you provide more than one input mode, the command uses irisql first, then domain. Review Query with IrisQL for formatting instructions.

  • Syntax: | dtirisinvestigate irisql=string domain=string pivot_type=string pivot_value=string feature=string no_cache=bool
  • Parameters:
    • irisql (optional) — a raw IrisQL query string. Must begin with the version header # IrisQL-1.0 followed by \n and the query body. Always queries live and skips the cache, independent of no_cache.
    • domain (optional)
    • pivot_type (required unless using irisql or domain)
    • pivot_value (required unless using irisql or domain)
    • feature (optional)
    • no_cache (optional)
  • Domain example: | dtirisinvestigate domain="domaintools.com"
  • Pivot example: | dtirisinvestigate pivot_type="ip" pivot_value="x.x.x.x"
  • IrisQL example: | dtirisinvestigate irisql="# IrisQL-1.0\nDOMAIN CONTAINS \"phishing\""

Formats the JSON returned by Iris Investigate into a row with named components.

  • Syntax: | dtformatinvestigate output=string feature=string
  • Parameters:
    • output (required)
    • feature (optional)
  • Example: | dtirisinvestigate domain="domaintools.com" | dtformatinvestigate output=risk

Returns Parsed Domain RDAP API results for a domain. This command supports only the domain parameter. The Parsed Domain RDAP API is a lookup service, separate from the Parsed Domain RDAP Feed. Enable it under Enable the Parsed Domain RDAP API, and view results in the Domain RDAP page.

  • Syntax: | dtparseddomainrdap domain=string
  • Parameters:
    • domain (required)

Queries Farsight DNSDB for passive DNS information on an IP, domain, hostname, or subnet.

  • Syntax: | dtdnsdb target=ip/hostname type=rdata/rrset/raw rrtype=a/aaa/cname/etc time_first_before=time time_first_after=time time_last_before=time time_last_after=time target_type=auto/ip/name bailiwick=bailiwick
  • Parameters:
    • target (required)
    • type (required)
    • rrtype (required)
    • bailiwick (optional)
    • time_first_before (optional)
    • time_first_after (optional)
    • time_last_before (optional)
    • time_last_after (optional)
    • target_type (optional)
  • Example: | dtdnsdb target=domaintools.com target_type=domain type=rdata rrtype=CNAME

Performs a Farsight DNSDB passive DNS flexible search.

  • Syntax: | dtdnsdbflex query_type=<rdata|rrnames> match_type=<glob|regex> query=<pattern> rrtype=A/mx/cname/etc bailiwick=bailiwick time_first_before=time time_first_after=time time_last_before=time time_last_after=time
  • Parameters:
    • query_type (required)
    • match_type (required)
    • query (required)
    • rrtype (required)
    • bailiwick (optional)
    • time_first_before (optional)
    • time_first_after (optional)
    • time_last_before (optional)
    • time_last_after (optional)
  • Example: | dtdnsdbflex query_type=rdata match_type=regex query="[0-9]{5,6}-ledger\.com\.$"

Returns the DNSDB API query limit, queries remaining, and reset time.

  • Syntax: | dtdnsdblimit
  • Parameters: none
  • Example: | dtdnsdblimit

Enriches Splunk events from a query with passive DNS information from Farsight DNSDB.

  • Syntax: | dtdnsdbenrich field_in=string field_type=domain/ip/raw lookup_type=rrset/rrdata max_count=int time_first_before=time time_first_after=time time_last_before=time time_last_after=time rrtype=any/A/ns/... bailiwick=string include_subdomains=bool
  • Parameters:
    • field_in (required)
    • field_type (required)
    • lookup_type (required)
    • max_count (optional)
    • rrtype (optional)
    • bailiwick (optional)
    • time_first_before (optional)
    • time_first_after (optional)
    • time_last_before (optional)
    • time_last_after (optional)
    • include_subdomains (optional)
    • feature (optional)
  • Example: | dtdnsdbenrich field_in=domain field_type=domain lookup_type=rrset rrtype=A include_subdomains=true time_first_after=1593070040

Performs a WHOIS history search on a domain using the WHOIS History API endpoint. This command backs the WHOIS history page.

  • Syntax: | dtwhoishistory domain=string mode=string
  • Parameters:
    • domain (required)
    • mode (optional) — controls what the search returns:
      • list (default) returns the matching WHOIS history records.
      • check_existence returns only the boolean has_history_entries.
      • count returns the number of history entries.
  • Example: ... | dtwhoishistory domain=domain
  • Example: ... | dtwhoishistory domain=domain mode="check_existence"

Returns the provisioned DomainTools APIs and account status for your configured credentials. Each result row carries an id field (for example, iris-enrich, iris-investigate, iris-detect-monitors), so you can filter for a specific API. The app uses this command internally to drive the API Usage and Diagnostic Panel pages.

  • Syntax: | dtaccountinfo params=string feature=string
  • Parameters:
    • params (optional)
    • feature (optional)
  • Example: | dtaccountinfo | search id="iris-enrich" | stats count

Decodes internationalized domain names (IDNs) from Punycode into their Unicode form. Use it to add a decoded field to events before display or further processing.

  • Syntax: | dtidnadecode field_in=string field_out=string feature=string
  • Parameters:
    • field_in (required)
    • field_out (required)
    • feature (optional)
  • Example: | `dt_basesearch` | dtidnadecode field_in=domain field_out=decoded

Formats the output returned by the Iris Enrich API into named components, the enrichment-side counterpart to dtformatinvestigate.

  • Syntax: | dtformatenrich
  • Parameters: none
  • Example: ... | dtirisenrich domain=domain | dtformatenrich

Removes expired rows from a DomainTools KV Store cache collection. Use it to clear entries older than a set number of days from a named collection.

  • Syntax: | dtexpirecache collection=string time_field=string num_days_back=int feature=string
  • Parameters:
    • collection (required)
    • time_field (required)
    • num_days_back (optional)
    • feature (optional)
  • Example: | dtexpirecache collection="dt_iris_enrich_queue" time_field="queued" num_days_back=1

IrisQL is a text-based query language for the Iris Investigate API. Use the irisql parameter on dtirisinvestigate to run IrisQL queries directly from Splunk SPL, without needing to build a pivot query.

| dtirisinvestigate irisql="# IrisQL-1.0\nDOMAIN CONTAINS \"phishing\""

This returns up to 500 domains in Iris Investigate that contain the word phishing. Each result row includes the domain name and the full raw JSON response from the API. The command doesn’t expose the API page_size or position parameters, so refine the query if more than 500 domains match.

Pipe the results into dtformatinvestigate for a formatted table:

| dtirisinvestigate irisql="# IrisQL-1.0\nDOMAIN CONTAINS \"phishing\"" | dtformatinvestigate output=risk

An IrisQL query string has two parts, separated by a newline:

# IrisQL-1.0
DOMAIN CONTAINS "x"
  • The # IrisQL-1.0 version header is required. A missing or malformed header returns an IrisQL header is invalid error.
  • Use \n to separate the header from the query body. The app converts \n to a real newline before sending the query to the API.

Combine conditions with AND on its own \n-separated line:

| dtirisinvestigate irisql="# IrisQL-1.0\nRISK_SCORE GREATER_THAN 70\nAND\nCREATE_DATE WITHIN \"The last 30 days\""

For the full field and operator reference — supported fields, string/numeric/date operators, AND/OR logic, and the parsed_domain_rdap:/parsed_whois: data source prefixes — see IrisQL: Iris Query Language for API. Field names and operators are identical between the API and the Splunk command.

Find high-risk domains registered in the last 30 days:

| dtirisinvestigate irisql="# IrisQL-1.0\nRISK_SCORE GREATER_THAN 70\nAND\nCREATE_DATE WITHIN \"The last 30 days\""

Find domains sharing a registrant email — useful when investigating a known actor’s infrastructure:

| dtirisinvestigate irisql="# IrisQL-1.0\nREGISTRANT_CONTACT_EMAIL MATCHES \"badactor@example.com\""

Find domains sharing an SSL certificate hash with a known malicious domain:

| dtirisinvestigate irisql="# IrisQL-1.0\nSSL_HASH MATCHES \"<sha1_hash>\""

Save high-risk results to a lookup for alerting:

| dtirisinvestigate irisql="# IrisQL-1.0\nRISK_SCORE GREATER_THAN 90\nAND\nCREATE_DATE WITHIN \"The last 1 day\"" | table domain _raw | outputlookup append=true dt_high_risk_domains.csv

Combine registration identity, hosting subnet, and certificate fingerprint in a single query to correlate infrastructure. A domain matching all three conditions is very likely part of the same actor’s infrastructure:

| dtirisinvestigate irisql="# IrisQL-1.0\nREGISTRANT_CONTACT_EMAIL MATCHES \"badactor@example.com\"\nAND\nIP CONTAINS \"192.168.\"\nAND\nSSL_HASH MATCHES \"<sha1_hash>\""

The threat feed commands are generating commands that pull indicators directly from the DomainTools Threat Feeds API. Retrieve data with a time window, or use a session to continue from the position saved by a previous request.

For enabling and searching the ingested feed indexes instead, see Threat Feeds.

Provide at least one of after, before, or sessionID:

  • after — start of the query window. Use a negative integer from -1 through -432000 for seconds before the current time, or an ISO 8601 UTC timestamp. For example, after=-60 retrieves data from the last 60 seconds.
  • before — end of the query window. It accepts the same relative-seconds and ISO 8601 formats as after.
  • sessionID — a case-sensitive identifier containing 1–64 letters, numbers, or hyphens. A new session starts with the most recent hour of data unless you also provide a time window or fromBeginning=true. Reuse the identifier to retrieve data added since the previous request.
  • fromBeginning — set to true on the first request for a new sessionID to start at the beginning of retained feed data. Don’t reuse it with an existing session. The IP feed commands reject searches that combine fromBeginning=true with after.
  • top — limits the response to an integer from 1 through 1000000000.
  • feature — optional app context passed with the request.

The domain feed commands also accept domain to filter results for one domain. The IP feed commands instead provide filters for hosting activity, threat percentages, and IP ownership.

dtfeediphotlist and dtfeediprisk support the same filters. When you provide more than one filter, the feed applies each filter.

ParameterAccepted valueFilters for
pdns_resolutions_minPositive integerAt least this many passive DNS resolutions
bad_pdns_resolutions_minPositive integerAt least this many passive DNS resolutions for threatening domains
total_domains_maxPositive integerNo more than this many hosted domains
third_party_threats_minPositive integerAt least this many domains identified by third-party threat intelligence
all_threats_combined_percent_minInteger from 0 through 100Minimum percentage of confirmed or predicted threatening domains
combined_phishing_percent_minInteger from 0 through 100Minimum percentage of confirmed or predicted phishing domains
combined_malware_percent_minInteger from 0 through 100Minimum percentage of confirmed or predicted malware domains
combined_spam_percent_minInteger from 0 through 100Minimum percentage of confirmed or predicted spam domains
all_threats_percent_minInteger from 0 through 100Minimum percentage of confirmed threatening domains
percent_phishing_minInteger from 0 through 100Minimum percentage of confirmed phishing domains
percent_malware_minInteger from 0 through 100Minimum percentage of confirmed malware domains
percent_spam_minInteger from 0 through 100Minimum percentage of confirmed spam domains
asnInteger without an AS prefixExact autonomous system number
organizationStringExact organization name; wildcards aren’t supported
country_codeTwo-letter ISO country codeIP geolocation country

See the IP Hotlist API and IP Risk API for the complete response schemas and field definitions.

New domains as they are discovered in domain registration information, observed by the DomainTools global sensor network, or reported by trusted third parties.

  • Syntax: | dtfeeddomaindiscovery after=string before=string sessionID=string fromBeginning=true domain=string top=int feature=string
  • Example: | dtfeeddomaindiscovery after=-60

High-risk, apex-level domains that the DomainTools global sensor network observes to be active within 24 hours.

  • Syntax: | dtfeeddomainhotlist after=string before=string sessionID=string fromBeginning=true domain=string top=int feature=string
  • Example: | dtfeeddomainhotlist after=-60 | table timestamp domain phishing_risk malware_risk spam_risk proximity_risk overall_risk expires

Changes to global domain registration information, populated by the Registration Data Access Protocol (RDAP). Complements the 5-Minute WHOIS Feed as registries and registrars move from WHOIS to RDAP.

  • Syntax: | dtfeeddomainrdap after=string before=string sessionID=string fromBeginning=true domain=string top=int feature=string
  • Example: | dtfeeddomainrdap after=-60

Real-time domain risk information for apex-level domains, regardless of observed traffic.

  • Syntax: | dtfeeddomainrisk after=string before=string sessionID=string fromBeginning=true domain=string top=int feature=string
  • Example: | dtfeeddomainrisk after=-60 | table timestamp domain phishing_risk malware_risk spam_risk proximity_risk overall_risk

Retrieves high-risk hosting IP addresses where more than half of hosted domains meet the IP Hotlist risk and recent-activity criteria.

  • Syntax: | dtfeediphotlist after=string before=string sessionID=string fromBeginning=true top=int feature=string [filter=value ...]
  • Example:
| dtfeediphotlist after=-60 top=5
| table timestamp ip asn organization country total_domains all_threats_combined_count all_threats_combined_percent

Retrieves hosting IP addresses with domain activity, risk, ownership, geolocation, and threat-percentage context for investigation and filtering.

  • Syntax: | dtfeediprisk after=string before=string sessionID=string fromBeginning=true top=int feature=string [filter=value ...]
  • Example:
| dtfeediprisk after=-3600 all_threats_combined_percent_min=50 total_domains_max=1000 top=100
| table timestamp ip asn organization country total_domains all_threats_combined_percent combined_phishing_percent combined_malware_percent combined_spam_percent

Apex-level domains (for example, example.com but not www.example.com) that DomainTools has newly observed to be active in its DNS sensor network.

  • Syntax: | dtfeednad after=string before=string sessionID=string fromBeginning=true domain=string top=int feature=string
  • Example: | dtfeednad after=-60 | table timestamp domain

Apex-level domains observed for the first time by the DomainTools sensor network, and which aren’t present in the DNSDB historical database.

  • Syntax: | dtfeednod after=string before=string sessionID=string fromBeginning=true domain=string top=int feature=string
  • Example: | dtfeednod after=-60 | table timestamp domain

Hostname resolutions observed for the first time by the DomainTools global DNS sensor network.

  • Syntax: | dtfeednoh after=string before=string sessionID=string fromBeginning=true domain=string top=int feature=string
  • Example: | dtfeednoh after=-60 | table timestamp domain

These commands back the app’s Iris Detect import and sync features. They run automatically as part of the app’s saved searches, but you can also run them directly.

Imports the Iris Detect monitors configured on your DomainTools account.

  • Syntax: | dtimportirisdetectmonitors feature=string
  • Parameters:
    • feature (optional)
  • Example: | dtimportirisdetectmonitors

Imports the current day’s Iris Detect results for a given list of monitor IDs. Pipe in the monitor IDs from the dt_iris_detect_monitors lookup.

  • Syntax: | dtimportirisdetectresults feature=string
  • Parameters:
    • feature (optional)
  • Example: | from inputlookup:dt_iris_detect_monitors | dtimportirisdetectresults

Syncs the dt_iris_detect_results entries with the state watched into the dt_monitoring_list, keeping the Iris Detect watchlist aligned with your monitored domains.

  • Syntax: | dtsyncirisdetectwatchlist
  • Parameters: none
  • Example: | dtsyncirisdetectwatchlist

Set up a recurring search with an Iris Investigate search hash

Section titled “Set up a recurring search with an Iris Investigate search hash”

This example uses dtirisinvestigate to look up domains matching a search hash, parse the first-seen value into a table, and collect the results into a summary index. Save it as a report to run on a schedule.

| dtirisinvestigate pivot_type=search_hash pivot_value=YOUR_SEARCH_HASH no_cache=true
| eval json = replace(_raw, "^[^\{]+", "")
| spath input=json path=first_seen.value
| rename first_seen.value as first_seen
| table first_seen domain
| collect index=summary_index_icloud

For how to schedule a report, see the Splunk Reporting Manual.

Section titled “Set up a recurring search with a DNSDB flexible search”

This example uses dtdnsdbflex to look up domains matching a regular expression, last observed in DomainTools’ DNS sensor network over the past 30 days. Storing a relative Unix timestamp in a variable creates a relative time fence, so the window shifts with the schedule when you save this as a report.

| eval thirty_days_ago=relative_time(now(), "-30d@d")
| eval thirty_days_ago_unix=thirty_days_ago
| dtdnsdbflex query_type=rrnames match_type=regex query="-icloud\.(net|com)\.$" rrtype=A time_last_after=thirty_days_ago_unix

For how to write regular expressions for the DNSDB flexible search, see the regular expression user guide.

Save an IP feed search as a Splunk report to write new feed results to an event index on a schedule. Create the destination index before you enable the report. Use a persistent sessionID. Each scheduled search continues from its prior request.

| dtfeediprisk sessionID="ip-risk-ingestion"
| collect index=YOUR_IP_RISK_INDEX

Save this search as a report and schedule it for the interval you need. The first request for a session starts with the most recent hour of feed data. To retrieve retained history, create a separate one-time search with fromBeginning=true, then reuse the same sessionID in the scheduled report without fromBeginning.

Use dtfeediphotlist instead of dtfeediprisk to get IP Hotlist data. Replace YOUR_IP_RISK_INDEX with the event index you created.

Each feed saved search you enable in Enable Threat Feeds writes its results into a dedicated Splunk index that you create. Query that index directly from the Search page. The index names are fixed by the app:

FeedIndex
Domain Discoverydt_feed_domain_discovery
Domain Hotlistdt_feed_domain_hotlist
Domain Riskdt_feed_domainrisk
Newly Active Domains (NAD)dt_feed_nad
Newly Observed Domains (NOD)dt_feed_nod
Newly Observed Hostnames (NOH)dt_feed_noh
Parsed Domain RDAPdt_feed_rdap

Every feed event carries a domain and a timestamp. The Domain Risk and Domain Hotlist feeds also carry the per-category risk scores (phishing_risk, malware_risk, spam_risk, proximity_risk, overall_risk), and Domain Hotlist adds expires.

View the 100 most recent domains from a feed:

index=dt_feed_nod
| sort - _time
| head 100
| table _time, domain

Check whether a specific domain appeared in a feed:

index=dt_feed_nod domain="example.com"

Find domains containing a keyword — useful for hunting a brand or term:

index=dt_feed_nod domain="*microsoft*"

Review the highest-risk domains from the Domain Risk feed:

index=dt_feed_domainrisk
| sort - overall_risk
| table _time, domain, overall_risk, phishing_risk, malware_risk, spam_risk, proximity_risk

For threat feed parameter details, see Threat feed parameters.