Detection rules › Sublime MQL
Google presentation open redirect phishing
Detects emails containing links to Google Document Presentations that either have a single page with a single external link, have been removed for Terms of Service violations, or have been deleted.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, Open redirect, Social engineering |
Event coverage
Rule body MQL
type.inbound
and not strings.icontains(body.current_thread.text, 'invited you to edit')
and any(body.links,
// body link is to a google doc presentation
.href_url.domain.domain == "docs.google.com"
and strings.istarts_with(.href_url.path, '/presentation/')
// prefilter some to avoid clicking on _every_ google presentation link
and (
(
// make sure the display text is in the current thread and not a previous one.
strings.icontains(body.current_thread.text, .display_text)
// the display_text ends with a word that is 4-10 long
and regex.icontains(.display_text, '[[:punct:]\s][a-z0-9]{5,9}$')
// that word has to include a letter AND a number
and regex.icontains(.display_text,
'[[:punct:]\s](?:[a-z0-9]*[a-z][0-9][a-z0-9]*|[a-z0-9]*[0-9][a-z][a-z0-9]*)$'
)
and strings.iends_with(.href_url.path, '/pub')
)
or
// finally send the link to link analysis that presentation...
(
// contains a single link
length(ml.link_analysis(., mode="aggressive").final_dom.links) == 1
// cannot be edited via link provided
and strings.contains(ml.link_analysis(., mode="aggressive").final_dom.raw,
'canEdit: false'
)
// and a single page
and strings.contains(ml.link_analysis(., mode="aggressive").final_dom.raw,
'slidePageCount: 1.0'
)
// where we have links which have been written via a google open redirect
and any(ml.link_analysis(., mode="aggressive").final_dom.links,
// links are not in thhe org_domains
.href_url.domain.domain not in $org_domains
and (
(
// don't include high rep domains
.href_url.domain.domain not in $tranco_1m
and .href_url.domain.domain not in $umbrella_1m
)
// if it's in Tranco or Umbrella, still include it if it's one of these
or .href_url.domain.domain in $free_file_hosts
or .href_url.domain.root_domain in $free_file_hosts
or .href_url.domain.root_domain in $free_subdomain_hosts
// or it's a url shortner
or .href_url.domain.root_domain in $url_shorteners
or .href_url.domain.root_domain in $social_landing_hosts
)
// which have been "unrolled" by the google_open_redirect rule
and any(.href_url.rewrite.encoders,
. == "google_open_redirect"
)
)
)
// or the presentation has been removed for violation of terms of service
or strings.icontains(ml.link_analysis(., mode="aggressive").final_dom.display_text,
"We're sorry. You can't access this item because it is in violation of our Terms of Service."
)
)
)
// when the sender is not google, the sender should not be a common prevalence
and (
( // the message is not from google actual
sender.email.email not in (
'comments-noreply@docs.google.com',
'drive-shares-dm-noreply@google.com',
'drive-shares-noreply@google.com',
'calendar-notification@google.com'
)
// ensure the sender prevalence is not common
and profile.by_sender().prevalence != "common"
)
// or the message is from google actual
or (
sender.email.email in (
'comments-noreply@docs.google.com',
'drive-shares-dm-noreply@google.com',
'drive-shares-noreply@google.com',
'calendar-notification@google.com'
)
)
)
// not where the sender display name of the message is within org_display_names
and not (
// the message is from google actual
sender.email.email in (
'comments-noreply@docs.google.com',
'drive-shares-dm-noreply@google.com',
'drive-shares-noreply@google.com',
'calendar-notification@google.com'
)
and headers.auth_summary.dmarc.pass
// but the sender display name is within org_display_names
and any($org_display_names,
strings.istarts_with(sender.display_name,
strings.concat(., " (via Google ")
)
or strings.istarts_with(sender.display_name,
strings.concat(., " (Google ")
)
)
)
// negate highly trusted sender domains unless they fail DMARC authentication
// but ignore high_trust if the sender is one of the google actual senders
and (
(
(
sender.email.domain.root_domain in $high_trust_sender_root_domains
and not headers.auth_summary.dmarc.pass
)
or (
sender.email.domain.root_domain in $high_trust_sender_root_domains
and sender.email.email in (
'comments-noreply@docs.google.com',
'drive-shares-dm-noreply@google.com',
'drive-shares-noreply@google.com',
'calendar-notification@google.com'
)
)
or sender.email.domain.root_domain not in $high_trust_sender_root_domains
)
)
Detection logic
Scope: inbound message.
Detects emails containing links to Google Document Presentations that either have a single page with a single external link, have been removed for Terms of Service violations, or have been deleted.
- inbound message
not:
- body.current_thread.text contains 'invited you to edit'
any of
body.linkswhere all hold:- .href_url.domain.domain is 'docs.google.com'
- .href_url.path starts with '/presentation/'
any of:
all of:
- strings.icontains(body.current_thread.text)
- .display_text matches '[[:punct:]\\s][a-z0-9]{5,9}$'
- .display_text matches '[[:punct:]\\s](?:[a-z0-9]*[a-z][0-9][a-z0-9]*|[a-z0-9]*[0-9][a-z][a-z0-9]*)$'
- .href_url.path ends with '/pub'
all of:
- length(ml.link_analysis(., mode='aggressive').final_dom.links) is 1
- ml.link_analysis(., mode='aggressive').final_dom.raw contains 'canEdit: false'
- ml.link_analysis(., mode='aggressive').final_dom.raw contains 'slidePageCount: 1.0'
any of
ml.link_analysis(., mode='aggressive').final_dom.linkswhere all hold:- .href_url.domain.domain not in $org_domains
any of:
all of:
- .href_url.domain.domain not in $tranco_1m
- .href_url.domain.domain not in $umbrella_1m
- .href_url.domain.domain in $free_file_hosts
- .href_url.domain.root_domain in $free_file_hosts
- .href_url.domain.root_domain in $free_subdomain_hosts
- .href_url.domain.root_domain in $url_shorteners
- .href_url.domain.root_domain in $social_landing_hosts
any of
.href_url.rewrite.encoderswhere:- . is 'google_open_redirect'
- ml.link_analysis(., mode='aggressive').final_dom.display_text contains "We're sorry. You can't access this item because it is in violation of our Terms of Service."
any of:
all of:
- sender.email.email not in ('comments-noreply@docs.google.com', 'drive-shares-dm-noreply@google.com', 'drive-shares-noreply@google.com', 'calendar-notification@google.com')
- profile.by_sender().prevalence is not 'common'
- sender.email.email in ('comments-noreply@docs.google.com', 'drive-shares-dm-noreply@google.com', 'drive-shares-noreply@google.com', 'calendar-notification@google.com')
not:
all of:
- sender.email.email in ('comments-noreply@docs.google.com', 'drive-shares-dm-noreply@google.com', 'drive-shares-noreply@google.com', 'calendar-notification@google.com')
- headers.auth_summary.dmarc.pass
any of
$org_display_nameswhere any holds:- strings.istarts_with(sender.display_name)
- strings.istarts_with(sender.display_name)
any of:
all of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
not:
- headers.auth_summary.dmarc.pass
all of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
- sender.email.email in ('comments-noreply@docs.google.com', 'drive-shares-dm-noreply@google.com', 'drive-shares-noreply@google.com', 'calendar-notification@google.com')
- sender.email.domain.root_domain not in $high_trust_sender_root_domains
Inspects: body.current_thread.text, body.links, body.links[].display_text, body.links[].href_url.domain.domain, body.links[].href_url.path, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: ml.link_analysis, profile.by_sender, regex.icontains, strings.concat, strings.contains, strings.icontains, strings.iends_with, strings.istarts_with. Reference lists: $free_file_hosts, $free_subdomain_hosts, $high_trust_sender_root_domains, $org_display_names, $org_domains, $social_landing_hosts, $tranco_1m, $umbrella_1m, $url_shorteners.
Indicators matched (14)
| Field | Match | Value |
|---|---|---|
strings.icontains | substring | invited you to edit |
body.links[].href_url.domain.domain | equals | docs.google.com |
strings.istarts_with | prefix | /presentation/ |
regex.icontains | regex | [[:punct:]\s][a-z0-9]{5,9}$ |
regex.icontains | regex | [[:punct:]\s](?:[a-z0-9]*[a-z][0-9][a-z0-9]*|[a-z0-9]*[0-9][a-z][a-z0-9]*)$ |
strings.iends_with | suffix | /pub |
strings.contains | substring | canEdit: false |
strings.contains | substring | slidePageCount: 1.0 |
ml.link_analysis(body.links[], mode='aggressive').final_dom.links[].href_url.rewrite.encoders[] | equals | google_open_redirect |
strings.icontains | substring | We're sorry. You can't access this item because it is in violation of our Terms of Service. |
sender.email.email | member | comments-noreply@docs.google.com |
sender.email.email | member | drive-shares-dm-noreply@google.com |
2 more
sender.email.email | member | drive-shares-noreply@google.com |
sender.email.email | member | calendar-notification@google.com |