The Shadowspotter query language
Shadowspotter uses a domain-specific query language called ShadowLang.
The syntax is intentionally close to VirusTotal's query language and to Kibana's KQL,
so if you are familiar with either you should feel at home. The same syntax is used in
the search bar and when defining a detection.
Anatomy of a query
A query is a sequence of field:value conditions, optionally scoped to an entity:
entity:whois registrar:*NameCheap* creation_date:2024-01-01+
You can omit entity: entirely — Shadowspotter infers the entity from the fields you use:
registrar:*NameCheap* creation_date:2024-01-01+
Syntax rules
Entities
Every query targets one of these entities. If you do not write entity: explicitly, Shadowspotter picks one based on the fields used.
| Entity | What it contains |
domain | Aggregated view of every domain seen across the data sources, with first/last seen timestamps. |
whois | Domain registration records: registrar, registrant, dates, contacts, name servers. |
dns | DNS records of all common types (A, AAAA, MX, NS, CNAME, TXT, CAA, SOA, DNAME) and their TTLs. |
cert | TLS certificates from Certificate Transparency logs and active scanning. |
http | HTTP responses including headers, meta tags, title, JARM fingerprint and content hashes. |
Fields by entity
Domain
| Field | Notes |
domain | The domain name. Wildcards supported. |
fuzzy_domain | Find domains similar to the value (n-gram + Jaro-Winkler). Paid plans only. |
tag | Match a tag attached to the domain. Paid plans only. |
WHOIS
| Field | Notes |
domain | Domain name. |
creation_date, updated_date, expired_date | Registration dates. Use +/- for ranges. |
statuses | EPP statuses (e.g. clientHold). |
name_server, dnssec | Name server hostnames and DNSSEC flag. |
registrar, registrar_country, registrar_iana_id, registrar_url, registrar_whois_server, registrar_abuse_contact_email, registrar_abuse_contact_phone | Registrar details. |
registrant_name, registrant_org, registrant_street, registrant_city, registrant_state, registrant_postal, registrant_country, registrant_phone, registrant_email | Registrant contact (often redacted). |
tech_* / admin_* | Same set of fields for technical and administrative contacts. |
fuzzy_domain | Similar-domain search. |
contains_hyphen, contains_nr, starts_with_nr, ends_with_nr, domain_length | Lexical features (numeric / boolean). Paid plans only. |
DNS
| Field | Notes |
domain | Domain name. |
a_record, aaaa_record, mx_record, ns_record, cname_record, dname_record, caa_record, txt_record, soa_record | Record values. These are array fields — a single match is enough. |
a_record_ttl, aaaa_record_ttl, … txt_record_ttl | TTL of the corresponding record type. |
asn | ASN of any A/AAAA record on the domain. |
ip_country | Country of any A/AAAA record. |
mail_server_provider | Inferred provider (Google, Microsoft, …) from MX records. |
fuzzy_domain, tag | Similar-domain and tag matching. |
Certificate
| Field | Notes |
domain, l1d, l2d | Domain and 1st/2nd-level domain extracted from the certificate. |
cert_index | CT log index (numeric). |
fingerprint, serial_number, signature_algorithm | Certificate identifiers. |
issuer, issuer_email_address, issuerAltName | Issuer fields. |
subject, subject_email_address, subjectAltName | Subject fields. |
not_before, not_after, seen | Validity dates and the time the certificate was first seen. |
basicConstraints, keyUsage, extendedKeyUsage, certificatePolicies, authorityInfoAccess, authorityKeyIdentifier, crlDistributionPoints, extra | X.509 extensions. |
source_name, source_url | The CT log or scan source. |
fuzzy_domain, tag | Similar-domain and tag matching. |
HTTP
| Field | Notes |
domain, l2d | Domain and 2nd-level domain. |
ip, port | Endpoint addresses. |
title | HTML <title>. |
header, header_value | HTTP response headers. header matches header names, header_value matches header values. |
meta, meta_value | HTML <meta> tag names and values. |
jarm | JARM TLS fingerprint. |
hash, favicon_hash, favicon_dhash | Body hash, favicon MMH3 hash, favicon difference hash. |
timeslot, first_seen, last_seen | When the response was observed. |
Examples
Subdomains of a known apex domain
entity:domain domain:*.google.com
Newly registered domains via a specific registrar on Cloudflare
entity:whois registrar:*WEBCC* name_server:*.cloudflare.com creation_date:2024-07-01+
Recent ZeroSSL certs, excluding the www subdomain
entity:cert issuer:*ZeroSSL* seen:2024-08-01+ NOT domain:www.*
Domains pointing to a specific A record
entity:dns a_record:142.250.203.* domain:*.ch
Pages whose title mentions a brand on a domain that isn't theirs
entity:http title:'*Swisscom*' NOT domain:*.swisscom.ch NOT domain:swisscom.ch
Look-alike domains registered recently
entity:whois fuzzy_domain:amazon.com creation_date:2024-09-01+
Multi-entity: WHOIS + DNS together
(entity:whois registrar:'NameCheap, Inc.' domain:shadow*) AND (entity:dns ns_record:*.dreamhost.com.)
Subscription gating. Some fields and features are restricted to paid plans:
fuzzy_domain, the lexical features
(
starts_with_nr,
ends_with_nr,
contains_nr,
contains_hyphen,
domain_length),
the
tag field, the
http entity, and multi-entity queries.
The exact data history window also depends on your plan. See the
pricing page for details.