Detection rules › Sublime MQL

Sublime MQL rules: file

Brand impersonation: File sharing notification with template artifacts

#
Severity
low
Type
rule
Source
github.com/sublime-security/sublime-rules

Detects messages impersonating file sharing services that contain template artifacts such as placeholder comments, incomplete HTML elements, and development remnants. The message includes 'shared with you' language and exhibits multiple indicators of being generated from a malicious template including HTML comments with development terms, broken anchor tags, and filename elements that closely match the subject line.

Threat classification

Sublime's own taxonomy (not MITRE ATT&CK).

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.html
  • headers
  • headers.auth_summary
  • recipients
  • recipients.to
  • sender.email
  • subject
  • type

Rule body

type.inbound
and strings.icontains(body.current_thread.text, 'shared with you')
// we detect a file sharing logo with high confidence
and any(ml.logo_detect(file.message_screenshot()).brands,
        .name in ('Microsoft', 'Dropbox', 'Google') and .confidence == "high"
)
and 2 of (
  // the subject is very similar to the name of the file-name html class
  any(html.xpath(body.html, '//span[@class="file-name"]').nodes,
      strings.ilevenshtein(.display_text, subject.subject) < 15
  ),
  // we detect a href to a # implying a neglected placeholder
  any(html.xpath(body.html, '//a[@href="#"]').nodes, .raw is not null),
  // we detect "ai-esque" comments
  any(html.xpath(body.html, '//comment()').nodes,
      regex.icontains(.raw, '(optional|section|placeholder|todo|fixme)')
  ),
  // recipients local part is in the body of the message
  any(recipients.to,
      strings.icontains(body.current_thread.text, .email.local_part)
  ),
  strings.icontains(body.html.raw, 'if the button does not work')
)
// and cred theft/bec high confidence
and any(ml.nlu_classifier(body.current_thread.text).intents,
        .name in ("cred_theft", "bec") and .confidence == "high"
)
// not sent from legitimate Microsoft emails as long as auth passes
and not (
  sender.email.email in (
    'no-reply@outlook.mail.microsoft',
    'azuredevops@microsoft.com'
  )
  and headers.auth_summary.dmarc.pass
)

Detection logic

Scope: inbound message.

Detects messages impersonating file sharing services that contain template artifacts such as placeholder comments, incomplete HTML elements, and development remnants. The message includes 'shared with you' language and exhibits multiple indicators of being generated from a malicious template including HTML comments with development terms, broken anchor tags, and filename elements that closely match the subject line.

  1. inbound message
  2. body.current_thread.text contains 'shared with you'
  3. any of ml.logo_detect(file.message_screenshot()).brands where all hold:
    • .name in ('Microsoft', 'Dropbox', 'Google')
    • .confidence is 'high'
  4. at least 2 of:
    • any of html.xpath(body.html, '//span[@class="file-name"]').nodes where:
      • strings.ilevenshtein(.display_text) < 15
    • any of html.xpath(body.html, '//a[@href="#"]').nodes where:
      • .raw is set
    • any of html.xpath(body.html, '//comment()').nodes where:
      • .raw matches '(optional|section|placeholder|todo|fixme)'
    • any of recipients.to where:
      • strings.icontains(body.current_thread.text)
    • body.html.raw contains 'if the button does not work'
  5. any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
    • .name in ('cred_theft', 'bec')
    • .confidence is 'high'
  6. not:
    • all of:
      • sender.email.email in ('no-reply@outlook.mail.microsoft', 'azuredevops@microsoft.com')
      • headers.auth_summary.dmarc.pass

Inspects: body.current_thread.text, body.html, body.html.raw, headers.auth_summary.dmarc.pass, recipients.to, recipients.to[].email.local_part, sender.email.email, subject.subject, type.inbound. Sensors: file.message_screenshot, html.xpath, ml.logo_detect, ml.nlu_classifier, regex.icontains, strings.icontains, strings.ilevenshtein.

Indicators matched (10)

FieldMatchValue
strings.icontainssubstringshared with you
ml.logo_detect(file.message_screenshot()).brands[].namememberMicrosoft
ml.logo_detect(file.message_screenshot()).brands[].namememberDropbox
ml.logo_detect(file.message_screenshot()).brands[].namememberGoogle
ml.logo_detect(file.message_screenshot()).brands[].confidenceequalshigh
regex.icontainsregex(optional|section|placeholder|todo|fixme)
strings.icontainssubstringif the button does not work
ml.nlu_classifier(body.current_thread.text).intents[].namemembercred_theft
ml.nlu_classifier(body.current_thread.text).intents[].namememberbec
ml.nlu_classifier(body.current_thread.text).intents[].confidenceequalshigh

Stages and Predicates

Stage 1: mql_rule

and
  not
    and
      headers.auth_summary.dmarc.pass eq "true"
      sender.email.email in ["azuredevops@microsoft.com", "no-reply@outlook.mail.microsoft"]
  or
    any(html.xpath(body.html, '//a[@href="#"]').nodes)
      html.xpath(body.html, '//a[@href="#"]').nodes.raw is_not_null
    any(html.xpath(body.html, '//comment()').nodes)
      html.xpath(body.html, '//comment()').nodes.raw regex_match "(optional|section|placeholder|todo|fixme)"
    any(recipients.to)
      strings.icontains func_call "strings.icontains(body.current_thread.text)"
    any(html.xpath(body.html, '//span[@class="file-name"]').nodes)
      strings.ilevenshtein func_call "strings.ilevenshtein(html.xpath(body.html, '//span[@class=\"file-name\"]').nodes[].display_text) < 15"
    body.html.raw contains "if the button does not work"
  any(ml.logo_detect(file.message_screenshot()).brands)
    and
      ml.logo_detect(file.message_screenshot()).brands.confidence eq "high"
      ml.logo_detect(file.message_screenshot()).brands.name in ["Dropbox", "Google", "Microsoft"]
  any(ml.nlu_classifier(body.current_thread.text).intents)
    and
      ml.nlu_classifier(body.current_thread.text).intents.confidence eq "high"
      ml.nlu_classifier(body.current_thread.text).intents.name in ["bec", "cred_theft"]
  body.current_thread.text contains "shared with you"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

File sharing link from suspicious sender domain

#
Severity
medium
Type
rule
Source
github.com/sublime-security/sublime-rules

A file sharing link in the body sent from a suspicious sender domain.

Threat classification

Sublime's own taxonomy (not MITRE ATT&CK).

CategoryValues
Attack typesCredential Phishing, Malware/Ransomware
Tactics and techniquesFree file host

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • sender.email
  • type

Rule body

type.inbound
and any(body.links,
        (
          .href_url.domain.domain in $free_file_hosts
          or .href_url.domain.root_domain in $free_file_hosts
        )
        and not .href_url.domain.domain in $tenant_domains
        // remove free_file_hosts used to host images as links
        and not any($file_types_images,
                    strings.iends_with(..href_url.url, strings.concat('.', .))
        )
)
and sender.email.domain.tld in $suspicious_tlds
and not sender.email.domain.root_domain in ("notion.so", "cribl.cloud")
and (
  not profile.by_sender().solicited
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)

Detection logic

Scope: inbound message.

A file sharing link in the body sent from a suspicious sender domain.

  1. inbound message
  2. any of body.links where all hold:
    • any of:
      • .href_url.domain.domain in $free_file_hosts
      • .href_url.domain.root_domain in $free_file_hosts
    • not:
      • .href_url.domain.domain in $tenant_domains
    • not:
      • any of $file_types_images where:
        • strings.iends_with(.href_url.url)
  3. sender.email.domain.tld in $suspicious_tlds
  4. not:
    • sender.email.domain.root_domain in ('notion.so', 'cribl.cloud')
  5. any of:
    • not:
      • profile.by_sender().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign

Inspects: body.links, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.url, sender.email.domain.root_domain, sender.email.domain.tld, type.inbound. Sensors: profile.by_sender, strings.concat, strings.iends_with. Reference lists: $file_types_images, $free_file_hosts, $suspicious_tlds, $tenant_domains.

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      not
        any($file_types_images)
          strings.iends_with func_call "strings.iends_with(body.links[].href_url.url)"
      or
         macro "body.links[].href_url.domain.domain in free_file_hosts"
         macro "body.links[].href_url.domain.root_domain in free_file_hosts"
      not
         macro "body.links[].href_url.domain.domain in tenant_domains"
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    not
      profile.by_sender func_call "profile.by_sender().solicited"
  not
    sender.email.domain.root_domain in ["cribl.cloud", "notion.so"]
  type.inbound eq "true"
   macro "sender.email.domain.tld in suspicious_tlds"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

File sharing link with a suspicious subject

#
Severity
medium
Type
rule
Source
github.com/sublime-security/sublime-rules

A file sharing link in the body with a common BEC subject. This rule could be expanded to include additional BEC subjects.

Threat classification

Sublime's own taxonomy (not MITRE ATT&CK).

CategoryValues
Attack typesBEC/Fraud
Tactics and techniquesFree file host, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.links
  • headers
  • headers.auth_summary
  • sender.email
  • subject
  • type

Rule body

type.inbound
and sender.email.domain.root_domain != 'google.com'
and not (
  sender.email.domain.root_domain == "dropbox.com"
  and headers.auth_summary.dmarc.pass
)
and any(body.links,
        (
          .href_url.domain.domain in $free_file_hosts
          or .href_url.domain.root_domain in $free_file_hosts
        )
        and not (
          // negating Google Forms links
          .href_url.domain.domain == "docs.google.com"
          and strings.istarts_with(.href_url.path, "/forms/")
        )
        and not .href_url.domain.domain in $tenant_domains
)
and regex.icontains(subject.subject, 'immediately', 'urgent')
and any(ml.nlu_classifier(body.current_thread.text).intents, .name != "benign")
and (
  not profile.by_sender().solicited
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)

Detection logic

Scope: inbound message.

A file sharing link in the body with a common BEC subject. This rule could be expanded to include additional BEC subjects.

  1. inbound message
  2. sender.email.domain.root_domain is not 'google.com'
  3. not:
    • all of:
      • sender.email.domain.root_domain is 'dropbox.com'
      • headers.auth_summary.dmarc.pass
  4. any of body.links where all hold:
    • any of:
      • .href_url.domain.domain in $free_file_hosts
      • .href_url.domain.root_domain in $free_file_hosts
    • not:
      • all of:
        • .href_url.domain.domain is 'docs.google.com'
        • .href_url.path starts with '/forms/'
    • not:
      • .href_url.domain.domain in $tenant_domains
  5. subject.subject matches any of 2 patterns
    • immediately
    • urgent
  6. any of ml.nlu_classifier(body.current_thread.text).intents where:
    • .name is not 'benign'
  7. any of:
    • not:
      • profile.by_sender().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign

Inspects: body.current_thread.text, body.links, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.path, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: ml.nlu_classifier, profile.by_sender, regex.icontains, strings.istarts_with. Reference lists: $free_file_hosts, $tenant_domains.

Indicators matched (2)

FieldMatchValue
regex.icontainsregeximmediately
regex.icontainsregexurgent

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      not
        and
          body.links.href_url.domain.domain eq "docs.google.com"
          body.links.href_url.path starts_with "/forms/"
      or
         macro "body.links[].href_url.domain.domain in free_file_hosts"
         macro "body.links[].href_url.domain.root_domain in free_file_hosts"
      not
         macro "body.links[].href_url.domain.domain in tenant_domains"
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    not
      profile.by_sender func_call "profile.by_sender().solicited"
  not
    and
      headers.auth_summary.dmarc.pass eq "true"
      sender.email.domain.root_domain eq "dropbox.com"
  any(ml.nlu_classifier(body.current_thread.text).intents)
    ml.nlu_classifier(body.current_thread.text).intents.name ne "benign"
  or
    subject.subject regex_match "immediately"
    subject.subject regex_match "urgent"
  sender.email.domain.root_domain ne "google.com"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.