Detection rules › Sublime MQL
Credential phishing: Generic document sharing
Detects credential phishing attempts using generic document sharing language where the sender claims to have sent a document for review, but the link doesn't point to legitimate file sharing services.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, BEC/Fraud |
| Tactics and techniques | Social engineering, Evasion, Impersonation: Employee |
Event coverage
Rule body MQL
type.inbound
// exclude if it's a reply to an existing conversation
and (
not length(body.previous_threads) > 0
// still match if self-sender BCC pattern
or (
length(recipients.to) == 1
and length(recipients.cc) == 0
and sender.email.email == recipients.to[0].email.email
)
)
and (
// subject contains document sharing language
regex.icontains(subject.base,
'\b(has\s+sent\s+you|sent\s+you|shared\s+with\s+you|document\s+to\s+review|document\s*(number|num|#)|file\s+to\s+review|proposal\s+document|new\s+document|document\s+.{0,20}(assigned|available)|(complete|review|shared?).{0,20}agreement.{0,20}|document\s+(?:transfer|shared))\b'
)
or strings.icontains(subject.subject, 'document to review')
or strings.icontains(subject.subject, 'file to review')
or strings.icontains(subject.subject, 'sent you')
or strings.icontains(subject.subject, 'eDocuments Notification')
// or recipient's SLD is the subject
or (
subject.base == sender.email.domain.sld
// account for near-matches
or (
length(subject.base) < length(sender.email.domain.sld)
and any([subject.base], strings.icontains(sender.email.domain.sld, .))
)
)
// blank subject with recipient SLD in message body
or (
(length(subject.base) == 0 or subject.base is null)
and any(recipients.to,
strings.istarts_with(body.current_thread.text, .email.domain.sld)
)
)
)
and (
// body contains document sharing language
regex.icontains(body.current_thread.text,
'\b(?:document\s+I\s+sent|proposal\s+document|(?:proposal|documents?)\s+for\s+your\s+(?:approval|consideration|review|signature)|see\s+the\s+below|document.*(?:review|posted)|file.*review|let\s+me\s+know\s+what\s+you\s+think|shared.{0,50}document|(?:review\s+and\s+)?sign\s+your\s+document|electronic\s+signature\s+required)\b'
)
or strings.icontains(body.current_thread.text, 'document I sent')
or strings.icontains(body.current_thread.text, 'proposal document')
or strings.icontains(body.current_thread.text, 'let me know what you think')
// account for image-as-content
or (
length(body.current_thread.text) < 10
and (
regex.icontains(beta.ocr(file.message_screenshot()).text,
'\b(document\s+I\s+sent|proposal\s+document|see\s+the\s+below|document.*review|file.*review|let\s+me\s+know\s+what\s+you\s+think|shared.{0,50}document)\b'
)
or strings.icontains(beta.ocr(file.message_screenshot()).text,
'document I sent'
)
or strings.icontains(beta.ocr(file.message_screenshot()).text,
'proposal document'
)
or strings.icontains(beta.ocr(file.message_screenshot()).text,
'let me know what you think'
)
)
)
)
// has links that look like file attachments but aren't
and any(filter(body.links,
// display text looks like a file
(
regex.icontains(.display_text,
'\.(pdf|doc|docx|goto|xls|xlsx|ppt|pptx)'
)
or regex.icontains(.display_text, '\d+kb|\d+mb')
or strings.icontains(.display_text, 'document')
or strings.icontains(.display_text, 'proposal')
or strings.icontains(.display_text, 'review')
// account for image-as-content
or (
length(body.current_thread.text) < 10
and length(body.links) == 1
)
)
// but the URL doesn't point to legitimate file sharing
and .href_url.domain.root_domain not in (
"sharepoint.com",
"google.com",
"dropbox.com",
"box.com",
"onedrive.com",
"1drv.ms",
"aka.ms",
"microsoft.com",
"office.com",
"docusign.com",
"adobesign.com",
"hellosign.com",
"signable.app"
)
and .href_url.domain.domain not in ("drive.google.com")
),
// and points to suspicious domains
.href_url.domain.tld in $suspicious_tlds
or .href_url.domain.root_domain in $url_shorteners
or .href_url.domain.domain in $url_shorteners
or .href_url.domain.root_domain in $free_file_hosts
or .href_url.domain.domain in $free_file_hosts
// or it's a forms/survey platform being abused in self_service_creation_platform_domains
or .href_url.domain.root_domain in $self_service_creation_platform_domains
or .href_url.domain.domain in $self_service_creation_platform_domains
// bulk mailer abuse has been observed
or (
(
.href_url.domain.root_domain in $bulk_mailer_url_root_domains
or (
.href_url.rewrite.original is not null
and 'mandrill' in .href_url.rewrite.encoders
)
)
and .href_url.domain.sld not in $org_slds
)
// or the page redirects to common website, observed when evasion happens
or (
length(ml.link_analysis(., mode="aggressive").redirect_history) > 0
and ml.link_analysis(., mode="aggressive").effective_url.domain.root_domain in $tranco_10k
)
// or common email marketing/tracking patterns
or regex.match(.href_url.url, 'url\d+\..*\.com/ls/click')
or regex.match(.href_url.path, '/ls/click|/click|/c/')
)
// negate highly trusted sender domains unless they fail DMARC authentication
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 not in $high_trust_sender_root_domains
)
and (
profile.by_sender().solicited == false
or profile.by_sender_email().prevalence == "new"
or profile.by_sender_email().days_since.last_contact > 30
or (
profile.by_sender().any_messages_malicious_or_spam
and not profile.by_sender().any_messages_benign
)
// or it's a spoof of the org_domain
or (
sender.email.domain.domain in $org_domains
and not (
headers.auth_summary.spf.pass
or coalesce(headers.auth_summary.dmarc.pass, false)
)
)
)
and not profile.by_sender().any_messages_benign
Detection logic
Scope: inbound message.
Detects credential phishing attempts using generic document sharing language where the sender claims to have sent a document for review, but the link doesn't point to legitimate file sharing services.
- inbound message
any of:
not:
- length(body.previous_threads) > 0
all of:
- length(recipients.to) is 1
- length(recipients.cc) is 0
- sender.email.email is recipients.to[0].email.email
any of:
- subject.base matches '\\b(has\\s+sent\\s+you|sent\\s+you|shared\\s+with\\s+you|document\\s+to\\s+review|document\\s*(number|num|#)|file\\s+to\\s+review|proposal\\s+document|new\\s+document|document\\s+.{0,20}(assigned|available)|(complete|review|shared?).{0,20}agreement.{0,20}|document\\s+(?:transfer|shared))\\b'
- subject.subject contains 'document to review'
- subject.subject contains 'file to review'
- subject.subject contains 'sent you'
- subject.subject contains 'eDocuments Notification'
any of:
- subject.base is sender.email.domain.sld
all of:
- length(subject.base) < length(sender.email.domain.sld)
any of
[subject.base]where:- strings.icontains(sender.email.domain.sld)
all of:
any of:
- length(subject.base) is 0
- subject.base is missing
any of
recipients.towhere:- strings.istarts_with(body.current_thread.text)
any of:
- body.current_thread.text matches '\\b(?:document\\s+I\\s+sent|proposal\\s+document|(?:proposal|documents?)\\s+for\\s+your\\s+(?:approval|consideration|review|signature)|see\\s+the\\s+below|document.*(?:review|posted)|file.*review|let\\s+me\\s+know\\s+what\\s+you\\s+think|shared.{0,50}document|(?:review\\s+and\\s+)?sign\\s+your\\s+document|electronic\\s+signature\\s+required)\\b'
- body.current_thread.text contains 'document I sent'
- body.current_thread.text contains 'proposal document'
- body.current_thread.text contains 'let me know what you think'
all of:
- length(body.current_thread.text) < 10
any of:
- beta.ocr(file.message_screenshot()).text matches '\\b(document\\s+I\\s+sent|proposal\\s+document|see\\s+the\\s+below|document.*review|file.*review|let\\s+me\\s+know\\s+what\\s+you\\s+think|shared.{0,50}document)\\b'
- beta.ocr(file.message_screenshot()).text contains 'document I sent'
- beta.ocr(file.message_screenshot()).text contains 'proposal document'
- beta.ocr(file.message_screenshot()).text contains 'let me know what you think'
any of
filter(body.links)where any holds:- .href_url.domain.tld in $suspicious_tlds
- .href_url.domain.root_domain in $url_shorteners
- .href_url.domain.domain in $url_shorteners
- .href_url.domain.root_domain in $free_file_hosts
- .href_url.domain.domain in $free_file_hosts
- .href_url.domain.root_domain in $self_service_creation_platform_domains
- .href_url.domain.domain in $self_service_creation_platform_domains
all of:
any of:
- .href_url.domain.root_domain in $bulk_mailer_url_root_domains
all of:
- .href_url.rewrite.original is set
- .href_url.rewrite.encoders contains 'mandrill'
- .href_url.domain.sld not in $org_slds
all of:
- length(ml.link_analysis(., mode='aggressive').redirect_history) > 0
- ml.link_analysis(.).effective_url.domain.root_domain in $tranco_10k
- .href_url.url matches 'url\\d+\\..*\\.com/ls/click'
- .href_url.path matches '/ls/click|/click|/c/'
any of:
all of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
not:
- headers.auth_summary.dmarc.pass
- sender.email.domain.root_domain not in $high_trust_sender_root_domains
any of:
- profile.by_sender().solicited is False
- profile.by_sender_email().prevalence is 'new'
- profile.by_sender_email().days_since.last_contact > 30
all of:
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
all of:
- sender.email.domain.domain in $org_domains
none of:
- headers.auth_summary.spf.pass
- coalesce(headers.auth_summary.dmarc.pass)
not:
- profile.by_sender().any_messages_benign
Inspects: body.current_thread.text, body.links, body.links[].display_text, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.previous_threads, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, recipients.cc, recipients.to, recipients.to[0].email.email, recipients.to[].email.domain.sld, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.domain.sld, sender.email.email, subject.base, subject.subject, type.inbound. Sensors: beta.ocr, file.message_screenshot, ml.link_analysis, profile.by_sender, profile.by_sender_email, regex.icontains, regex.match, strings.icontains, strings.istarts_with. Reference lists: $bulk_mailer_url_root_domains, $free_file_hosts, $high_trust_sender_root_domains, $org_domains, $org_slds, $self_service_creation_platform_domains, $suspicious_tlds, $tranco_10k, $url_shorteners.
Indicators matched (32)
| Field | Match | Value |
|---|---|---|
regex.icontains | regex | \b(has\s+sent\s+you|sent\s+you|shared\s+with\s+you|document\s+to\s+review|document\s*(number|num|#)|file\s+to\s+review|proposal\s+document|new\s+document|document\s+.{0,20}(assigned|available)|(complete|review|shared?).{0,20}agreement.{0,20}|document\s+(?:transfer|shared))\b |
strings.icontains | substring | document to review |
strings.icontains | substring | file to review |
strings.icontains | substring | sent you |
strings.icontains | substring | eDocuments Notification |
regex.icontains | regex | \b(?:document\s+I\s+sent|proposal\s+document|(?:proposal|documents?)\s+for\s+your\s+(?:approval|consideration|review|signature)|see\s+the\s+below|document.*(?:review|posted)|file.*review|let\s+me\s+know\s+what\s+you\s+think|shared.{0,50}document|(?:review\s+and\s+)?sign\s+your\s+document|electronic\s+signature\s+required)\b |
strings.icontains | substring | document I sent |
strings.icontains | substring | proposal document |
strings.icontains | substring | let me know what you think |
regex.icontains | regex | \b(document\s+I\s+sent|proposal\s+document|see\s+the\s+below|document.*review|file.*review|let\s+me\s+know\s+what\s+you\s+think|shared.{0,50}document)\b |
regex.icontains | regex | \.(pdf|doc|docx|goto|xls|xlsx|ppt|pptx) |
regex.icontains | regex | \d+kb|\d+mb |
20 more
strings.icontains | substring | document |
strings.icontains | substring | proposal |
strings.icontains | substring | review |
body.links[].href_url.domain.root_domain | member | sharepoint.com |
body.links[].href_url.domain.root_domain | member | google.com |
body.links[].href_url.domain.root_domain | member | dropbox.com |
body.links[].href_url.domain.root_domain | member | box.com |
body.links[].href_url.domain.root_domain | member | onedrive.com |
body.links[].href_url.domain.root_domain | member | 1drv.ms |
body.links[].href_url.domain.root_domain | member | aka.ms |
body.links[].href_url.domain.root_domain | member | microsoft.com |
body.links[].href_url.domain.root_domain | member | office.com |
body.links[].href_url.domain.root_domain | member | docusign.com |
body.links[].href_url.domain.root_domain | member | adobesign.com |
body.links[].href_url.domain.root_domain | member | hellosign.com |
body.links[].href_url.domain.root_domain | member | signable.app |
body.links[].href_url.domain.domain | member | drive.google.com |
filter(body.links)[].href_url.rewrite.encoders | contains | mandrill |
regex.match | regex | url\d+\..*\.com/ls/click |
regex.match | regex | /ls/click|/click|/c/ |