Detection rules › Sublime MQL
Sublime MQL rules: govdelivery
| Rule | Severity |
|---|---|
| Vendor compromise: GovDelivery message with suspicious link | high |
Vendor compromise: GovDelivery message with suspicious link
#Detects messages from GovDelivery that contain links to non-government domains, URL shorteners, newly registered domains, or domains with suspicious redirects. GovDelivery is a digital communications system that lets government agencies send updates via email, text, and social media. We have observed compromised American municipal and county GovDelivery delivering phishing emails.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Free subdomain host, IPFS, Social engineering, Evasion, Impersonation: Brand |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and (
sender.email.domain.domain == "public.govdelivery.com"
or any(headers.domains, .root_domain == "govdelivery.com")
)
and (headers.auth_summary.spf.pass or headers.auth_summary.dmarc.pass)
and length(body.links) < 10
and any(body.links,
any(filter(regex.extract(.href_url.path, '/CL0/(?P<url>.*?)/1/'),
strings.parse_url(.named_groups["url"]).domain.root_domain not in (
"google.com",
"govdelivery.com",
"granicus.com",
"legistar1.com" // domain owned by granicus
)
and strings.parse_url(.named_groups["url"]).domain.tld not in (
"gov"
)
),
// this is inside the filtered results to avoid flagging this condition on known link domains, as listed above
strings.parse_url(.named_groups["url"]).domain.domain in $url_shorteners
or strings.parse_url(.named_groups["url"]).domain.domain in $social_landing_hosts
or strings.parse_url(.named_groups["url"]).domain.root_domain in $url_shorteners
or strings.parse_url(.named_groups["url"]).domain.root_domain in $social_landing_hosts
or strings.parse_url(.named_groups["url"]).domain.domain in $free_subdomain_hosts
or strings.parse_url(.named_groups["url"]).domain.root_domain in $free_subdomain_hosts
or network.whois(strings.parse_url(.named_groups["url"]).domain).days_old < 30
or any(ml.link_analysis(strings.parse_url(.named_groups["url"])).redirect_history,
network.whois(.domain).days_old < 30
or strings.icontains(.domain.domain, "ipfs")
or regex.icontains(.query_params, '[\.-/]ipfs[\.-/]')
)
// page redirects to common website, observed when evasion happens
or (
length(ml.link_analysis(strings.parse_url(.named_groups["url"])).redirect_history
) > 1
and ml.link_analysis(strings.parse_url(.named_groups["url"])).effective_url.domain.root_domain in $tranco_10k
)
)
)
Detection logic
Scope: inbound message.
Detects messages from GovDelivery that contain links to non-government domains, URL shorteners, newly registered domains, or domains with suspicious redirects. GovDelivery is a digital communications system that lets government agencies send updates via email, text, and social media. We have observed compromised American municipal and county GovDelivery delivering phishing emails.
- inbound message
any of:
- sender.email.domain.domain is 'public.govdelivery.com'
any of
headers.domainswhere:- .root_domain is 'govdelivery.com'
any of:
- headers.auth_summary.spf.pass
- headers.auth_summary.dmarc.pass
- length(body.links) < 10
any of
body.linkswhere:any of
filter(...)where any holds:- strings.parse_url(.named_groups['url']).domain.domain in $url_shorteners
- strings.parse_url(.named_groups['url']).domain.domain in $social_landing_hosts
- strings.parse_url(.named_groups['url']).domain.root_domain in $url_shorteners
- strings.parse_url(.named_groups['url']).domain.root_domain in $social_landing_hosts
- strings.parse_url(.named_groups['url']).domain.domain in $free_subdomain_hosts
- strings.parse_url(.named_groups['url']).domain.root_domain in $free_subdomain_hosts
- network.whois(strings.parse_url(.named_groups['url']).domain).days_old < 30
any of
ml.link_analysis(strings.parse_url(.named_groups['url'])).redirect_historywhere any holds:- network.whois(.domain).days_old < 30
- .domain.domain contains 'ipfs'
- .query_params matches '[\\.-/]ipfs[\\.-/]'
all of:
- length(ml.link_analysis(strings.parse_url(.named_groups['url'])).redirect_history) > 1
- ml.link_analysis(strings.parse_url(.named_groups['url'])).effective_url.domain.root_domain in $tranco_10k
Inspects: body.links, body.links[].href_url.path, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, headers.domains, headers.domains[].root_domain, sender.email.domain.domain, type.inbound. Sensors: ml.link_analysis, network.whois, regex.extract, regex.icontains, strings.icontains, strings.parse_url. Reference lists: $free_subdomain_hosts, $social_landing_hosts, $tranco_10k, $url_shorteners.
Indicators matched (5)
| Field | Match | Value |
|---|---|---|
sender.email.domain.domain | equals | public.govdelivery.com |
headers.domains[].root_domain | equals | govdelivery.com |
regex.extract | regex | /CL0/(?P<url>.*?)/1/ |
strings.icontains | substring | ipfs |
regex.icontains | regex | [\.-/]ipfs[\.-/] |
Stages and Predicates
Stage 1: mql_rule
and
any(body.links)
any(filter(...))
or
any(ml.link_analysis(strings.parse_url(filter(...).named_groups['url'])).redirect_history)
or
ml.link_analysis(strings.parse_url(filter(...)[].named_groups['url'])).redirect_history[].domain.domain contains "ipfs"
ml.link_analysis(strings.parse_url(filter(...)[].named_groups['url'])).redirect_history[].query_params regex_match "[\\.-/]ipfs[\\.-/]"
network.whois func_call "network.whois(ml.link_analysis(strings.parse_url(filter(...)[].named_groups['url'])).redirect_history[].domain).days_old < 30"
and
ml.link_analysis func_call "ml.link_analysis(strings.parse_url(filter(...)[].named_groups['url'])).effective_url.domain.root_domain in tranco_10k"
ml.link_analysis(strings.parse_url(filter(...)[].named_groups['url'])).redirect_history length_compare "1"
network.whois func_call "network.whois(strings.parse_url(filter(...)[].named_groups['url']).domain).days_old < 30"
strings.parse_url func_call "strings.parse_url(filter(...)[].named_groups['url']).domain.domain in free_subdomain_hosts"
strings.parse_url func_call "strings.parse_url(filter(...)[].named_groups['url']).domain.domain in social_landing_hosts"
strings.parse_url func_call "strings.parse_url(filter(...)[].named_groups['url']).domain.domain in url_shorteners"
strings.parse_url func_call "strings.parse_url(filter(...)[].named_groups['url']).domain.root_domain in free_subdomain_hosts"
strings.parse_url func_call "strings.parse_url(filter(...)[].named_groups['url']).domain.root_domain in social_landing_hosts"
strings.parse_url func_call "strings.parse_url(filter(...)[].named_groups['url']).domain.root_domain in url_shorteners"
or
any(headers.domains)
headers.domains.root_domain eq "govdelivery.com"
sender.email.domain.domain eq "public.govdelivery.com"
or
headers.auth_summary.dmarc.pass eq "true"
headers.auth_summary.spf.pass eq "true"
body.links length_compare "10"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.