Detection rules › Sublime MQL

Sublime MQL rules: self

Headers: Self-sender using Microsoft CompAuth bypass with credential theft content

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

Detects messages sent to self or invalid domains containing credential theft content that bypass Microsoft's CompAuth while failing both SPF and DMARC authentication checks.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSpoofing, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • headers.hops
  • recipients
  • recipients.to[0]
  • sender.email
  • type

Rule body

type.inbound
// self sender
and length(recipients.to) == 1
and length(recipients.cc) == 0
and length(recipients.bcc) == 0
and (
  sender.email.email == recipients.to[0].email.email
  or recipients.to[0].email.domain.valid == false
)
// cred theft
and any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == "cred_theft" and .confidence != "low"
)
// microsoft compauth pass, but spf and dmarc fail
and any(headers.hops, any(.fields, strings.icontains(.value, 'compauth=pass')))
and not coalesce(headers.auth_summary.dmarc.pass, false)
and not coalesce(headers.auth_summary.spf.pass, false)

Detection logic

Scope: inbound message.

Detects messages sent to self or invalid domains containing credential theft content that bypass Microsoft's CompAuth while failing both SPF and DMARC authentication checks.

  1. inbound message
  2. length(recipients.to) is 1
  3. length(recipients.cc) is 0
  4. length(recipients.bcc) is 0
  5. any of:
    • sender.email.email is recipients.to[0].email.email
    • recipients.to[0].email.domain.valid is False
  6. any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
    • .name is 'cred_theft'
    • .confidence is not 'low'
  7. any of headers.hops where:
    • any of .fields where:
      • .value contains 'compauth=pass'
  8. not:
    • coalesce(headers.auth_summary.dmarc.pass)
  9. not:
    • coalesce(headers.auth_summary.spf.pass)

Inspects: body.current_thread.text, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, headers.hops, headers.hops[].fields, headers.hops[].fields[].value, recipients.bcc, recipients.cc, recipients.to, recipients.to[0].email.domain.valid, recipients.to[0].email.email, sender.email.email, type.inbound. Sensors: ml.nlu_classifier, strings.icontains.

Indicators matched (2)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
strings.icontainssubstringcompauth=pass

Stages and Predicates

Stage 1: mql_rule

and
  any(headers.hops)
    any(headers.hops.fields)
      headers.hops.fields.value contains "compauth=pass"
  any(ml.nlu_classifier(body.current_thread.text).intents)
    and
      ml.nlu_classifier(body.current_thread.text).intents.confidence ne "low"
      ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
  not
    coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
  not
    coalesce func_call "coalesce(headers.auth_summary.spf.pass)"
  or
    recipients.to[0].email.domain.valid eq "false"
    sender.email.email cross_field_compare "recipients.to[0].email.email"
  recipients.bcc length_compare "0"
  recipients.cc length_compare "0"
  recipients.to length_compare "1"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: Single character path with credential theft body and self sender behavior or invalid recipient

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

Message where the sender and recipient are the same or the recipient domain is invalid, contains a link with a single character path and no query parameters or fragments, and includes credential theft language.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • recipients
  • recipients.to[0]
  • sender.email
  • type

Rule body

type.inbound
// self sender or invaild recipent domain
and length(recipients.to) == 1
and (
  sender.email.email == recipients.to[0].email.email
  or recipients.to[0].email.domain.valid == false
)
// path contains 1 character
and any(body.current_thread.links,
        regex.imatch(.href_url.path, '\/[A-Za-z0-9]')
        and .href_url.query_params is null
        and .href_url.fragment is null
        and .display_url.url is null
)
and any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == "cred_theft" and .confidence != "low"
)

Detection logic

Scope: inbound message.

Message where the sender and recipient are the same or the recipient domain is invalid, contains a link with a single character path and no query parameters or fragments, and includes credential theft language.

  1. inbound message
  2. length(recipients.to) is 1
  3. any of:
    • sender.email.email is recipients.to[0].email.email
    • recipients.to[0].email.domain.valid is False
  4. any of body.current_thread.links where all hold:
    • .href_url.path matches '\\/[A-Za-z0-9]'
    • .href_url.query_params is missing
    • .href_url.fragment is missing
    • .display_url.url is missing
  5. any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
    • .name is 'cred_theft'
    • .confidence is not 'low'

Inspects: body.current_thread.links, body.current_thread.links[].display_url.url, body.current_thread.links[].href_url.fragment, body.current_thread.links[].href_url.path, body.current_thread.links[].href_url.query_params, body.current_thread.text, recipients.to, recipients.to[0].email.domain.valid, recipients.to[0].email.email, sender.email.email, type.inbound. Sensors: ml.nlu_classifier, regex.imatch.

Indicators matched (2)

FieldMatchValue
regex.imatchregex\/[A-Za-z0-9]
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    and
      body.current_thread.links.display_url.url is_null
      body.current_thread.links.href_url.fragment is_null
      body.current_thread.links.href_url.path regex_match "\\/[A-Za-z0-9]"
      body.current_thread.links.href_url.query_params is_null
  any(ml.nlu_classifier(body.current_thread.text).intents)
    and
      ml.nlu_classifier(body.current_thread.text).intents.confidence ne "low"
      ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
  or
    recipients.to[0].email.domain.valid eq "false"
    sender.email.email cross_field_compare "recipients.to[0].email.email"
  recipients.to length_compare "1"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Self-sender with copy/paste instructions and suspicious domains (French/Français)

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

Detects messages where the sender emails themselves with French text containing 'copier' (copy) and 'coller' (paste) instructions, along with suspicious domains like pages.dev or web.app. The subject line contains both the sender's email and display name, which are different values.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Free subdomain host, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • recipients
  • recipients.to
  • sender.email
  • subject
  • type

Rule body

type.inbound
// self sender
and (
  length(recipients.to) == 1
  and length(recipients.cc) == 0
  and sender.email.email in map(recipients.to, .email.email)
)
and strings.icontains(subject.subject, sender.email.email)
and strings.icontains(subject.subject, sender.display_name)
and sender.email.email != sender.display_name
// copy
and strings.icontains(body.current_thread.text, 'copier')
// paste
and strings.icontains(body.current_thread.text, 'coller')
and (
  strings.contains(body.current_thread.text, '.pages.dev')
  or strings.contains(body.current_thread.text, '.web.app')
)

Detection logic

Scope: inbound message.

Detects messages where the sender emails themselves with French text containing 'copier' (copy) and 'coller' (paste) instructions, along with suspicious domains like pages.dev or web.app. The subject line contains both the sender's email and display name, which are different values.

  1. inbound message
  2. all of:
    • length(recipients.to) is 1
    • length(recipients.cc) is 0
    • sender.email.email in map(recipients.to, .email.email)
  3. strings.icontains(subject.subject)
  4. strings.icontains(subject.subject)
  5. sender.email.email is not sender.display_name
  6. body.current_thread.text contains 'copier'
  7. body.current_thread.text contains 'coller'
  8. any of:
    • body.current_thread.text contains '.pages.dev'
    • body.current_thread.text contains '.web.app'

Inspects: body.current_thread.text, recipients.cc, recipients.to, recipients.to[].email.email, sender.display_name, sender.email.email, subject.subject, type.inbound. Sensors: strings.contains, strings.icontains.

Indicators matched (4)

FieldMatchValue
strings.icontainssubstringcopier
strings.icontainssubstringcoller
strings.containssubstring.pages.dev
strings.containssubstring.web.app

Stages and Predicates

Stage 1: mql_rule

and
  or
    body.current_thread.text contains ".pages.dev"
    body.current_thread.text contains ".web.app"
  body.current_thread.text contains "coller"
  body.current_thread.text contains "copier"
  recipients.cc length_compare "0"
  recipients.to length_compare "1"
  sender.email.email cross_field_compare "sender.display_name"
  strings.icontains func_call "strings.icontains(subject.subject)"
  type.inbound eq "true"
   macro "sender.email.email in map(recipients.to, .email.email)"

Indicators

These rows show field, operator, and value matches.