Detection rules › Sublime MQL

Sublime MQL rules: headers

AnonymousFox indicators

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

Detects email messages that contain (anonymous|smtp)fox in the sender email address, X-Authenticated-Sender or X-Sender fields. This is indicative of messages sourced from an AnonymousFox compromised website.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Credential Phishing, Malware/Ransomware

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • headers.hops
  • sender.email
  • type

Rule body

type.inbound
and (
  any(headers.hops,
      any(.fields,
          strings.istarts_with(.name, "X-Authenticated-Sender", "X-Sender")
          and regex.icontains(.value, "(anonymous|smtp)fox-")
      )
  )
  or regex.icontains(sender.email.email, "(anonymous|smtp)fox-")
)

Detection logic

Scope: inbound message.

Detects email messages that contain (anonymous|smtp)fox in the sender email address, X-Authenticated-Sender or X-Sender fields. This is indicative of messages sourced from an AnonymousFox compromised website.

  1. inbound message
  2. any of:
    • any of headers.hops where:
      • any of .fields where all hold:
        • .name starts with any of 2 patterns
          • X-Authenticated-Sender
          • X-Sender
        • .value matches '(anonymous|smtp)fox-'
    • sender.email.email matches '(anonymous|smtp)fox-'

Inspects: headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.hops[].fields[].value, sender.email.email, type.inbound. Sensors: regex.icontains, strings.istarts_with.

Indicators matched (3)

FieldMatchValue
strings.istarts_withprefixX-Authenticated-Sender
strings.istarts_withprefixX-Sender
regex.icontainsregex(anonymous|smtp)fox-

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(headers.hops)
      any(headers.hops.fields)
        and
          or
            headers.hops.fields[].name starts_with "X-Authenticated-Sender"
            headers.hops.fields[].name starts_with "X-Sender"
          headers.hops.fields[].value regex_match "(anonymous|smtp)fox-"
    sender.email.email regex_match "(anonymous|smtp)fox-"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

BEC with unusual reply-to or return-path mismatch

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

Detects an unusual header mismatch where the sender is not a freemail address, but the reply-to or return-path are. NLU also detects a BEC intent with medium or high confidence.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud
Tactics and techniquesEvasion, Free email provider, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • headers.hops
  • headers.reply_to
  • headers.return_path
  • sender.email
  • type

Rule body

type.inbound
and any(ml.nlu_classifier(body.current_thread.text).intents,
        .name in ("bec", "advance_fee") and .confidence == "high"
)
and (
  headers.return_path.domain.root_domain in $free_email_providers
  or (
    length(headers.reply_to) > 0
    and all(headers.reply_to,
            .email.domain.root_domain in $free_email_providers
    )
  )
)
and (
  (
    sender.email.domain.root_domain == "paypal.com"
    and (
      not headers.auth_summary.dmarc.pass
      or headers.auth_summary.dmarc.pass is null
    )
  )
  or sender.email.domain.root_domain is null
  or sender.email.domain.root_domain != "paypal.com"
)
and sender.email.domain.root_domain not in $free_email_providers

// negate gmail autoforwards and null return paths
and (
  headers.return_path.email is null
  or not strings.ilike(headers.return_path.local_part, "*+caf_=*")
)

// negate listservs
and not (
  any(headers.hops, any(.fields, .name == "List-Unsubscribe"))
  and strings.contains(sender.display_name, "via")
)

// negate legit replies
and not (length(headers.references) > 0 or headers.in_reply_to is not null)

// legitimate quickbooks from known sender
and not (
  sender.email.email == "quickbooks@notification.intuit.com"
  and headers.auth_summary.spf.pass
  and beta.profile.by_reply_to().prevalence in (
    "outlier",
    "uncommon",
    "rare",
    "common"
  )
)

Detection logic

Scope: inbound message.

Detects an unusual header mismatch where the sender is not a freemail address, but the reply-to or return-path are. NLU also detects a BEC intent with medium or high confidence.

  1. inbound message
  2. any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
    • .name in ('bec', 'advance_fee')
    • .confidence is 'high'
  3. any of:
    • headers.return_path.domain.root_domain in $free_email_providers
    • all of:
      • length(headers.reply_to) > 0
      • all of headers.reply_to where:
        • .email.domain.root_domain in $free_email_providers
  4. any of:
    • all of:
      • sender.email.domain.root_domain is 'paypal.com'
      • any of:
        • not:
          • headers.auth_summary.dmarc.pass
        • headers.auth_summary.dmarc.pass is missing
    • sender.email.domain.root_domain is missing
    • sender.email.domain.root_domain is not 'paypal.com'
  5. sender.email.domain.root_domain not in $free_email_providers
  6. any of:
    • headers.return_path.email is missing
    • not:
      • headers.return_path.local_part matches '*+caf_=*'
  7. not:
    • all of:
      • any of headers.hops where:
        • any of .fields where:
          • .name is 'List-Unsubscribe'
      • sender.display_name contains 'via'
  8. none of:
    • length(headers.references) > 0
    • headers.in_reply_to is set
  9. not:
    • all of:
      • sender.email.email is 'quickbooks@notification.intuit.com'
      • headers.auth_summary.spf.pass
      • beta.profile.by_reply_to().prevalence in ('outlier', 'uncommon', 'rare', 'common')

Inspects: body.current_thread.text, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.in_reply_to, headers.references, headers.reply_to, headers.reply_to[].email.domain.root_domain, headers.return_path.domain.root_domain, headers.return_path.email, headers.return_path.local_part, sender.display_name, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: beta.profile.by_reply_to, ml.nlu_classifier, strings.contains, strings.ilike. Reference lists: $free_email_providers.

Indicators matched (4)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text).intents[].namememberbec
ml.nlu_classifier(body.current_thread.text).intents[].namememberadvance_fee
ml.nlu_classifier(body.current_thread.text).intents[].confidenceequalshigh
sender.email.domain.root_domainequalspaypal.com

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      or
        not
          headers.auth_summary.dmarc.pass eq "true"
        headers.auth_summary.dmarc.pass is_null
      sender.email.domain.root_domain eq "paypal.com"
    sender.email.domain.root_domain is_null
    sender.email.domain.root_domain ne "paypal.com"
  not
    and
      any(headers.hops)
        any(headers.hops.fields)
          headers.hops.fields.name eq "List-Unsubscribe"
      sender.display_name contains "via"
  not
    and
      beta.profile.by_reply_to func_call "beta.profile.by_reply_to().prevalence in (outlier, uncommon, rare, common)"
      headers.auth_summary.spf.pass eq "true"
      sender.email.email eq "quickbooks@notification.intuit.com"
  not
    or
      headers.in_reply_to is_not_null
      headers.references length_compare "0"
  or
    and
      headers.reply_to length_compare "0"
       macro "all(headers.reply_to)"
     macro "headers.return_path.domain.root_domain in free_email_providers"
  or
    not
      headers.return_path.local_part match "+caf_="
    headers.return_path.email is_null
  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 ["advance_fee", "bec"]
  type.inbound eq "true"
   macro "sender.email.domain.root_domain not in free_email_providers"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.hopsarray_any(no value, null check)excludes:headers.hops
sender.display_namecontainsviaexcludes:sender.display_name field:"sender.display_name" value:"via"
headers.auth_summary.spf.passeqtrueexcludes:headers.auth_summary.spf.pass field:"headers.auth_summary.spf.pass" value:"true"
sender.email.emaileqquickbooks@notification.intuit.comexcludes:sender.email.email field:"sender.email.email" value:"quickbooks@notification.intuit.com"
headers.in_reply_tois_not_null(no value, null check)excludes:headers.in_reply_to
headers.referenceslength_compare0excludes:headers.references field:"headers.references" value:"0"

Indicators

These rows show field, operator, and value matches.

Business Email Compromise (BEC) attempt with masked recipients and reply-to mismatch (unsolicited)

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

This rule detects unsolicited messages where the recipient matches the sender address and no other recipients are identified. The reply-to address does not match the sender, and is a freemail with no links in the body. This a common combination of techniques used by low level BEC threats.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud
Tactics and techniquesEvasion, Free email provider

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • headers
  • headers.reply_to
  • recipients
  • recipients.to
  • sender.email
  • type

Rule body

type.inbound
and any(recipients.to, .email.email == sender.email.email)
and length(recipients.cc) == 0
and length(recipients.bcc) == 0
and length(body.links) == 0
and any(headers.reply_to,
        .email.domain.domain in $free_email_providers
        and not .email.domain.domain == sender.email.domain.domain
)
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.

This rule detects unsolicited messages where the recipient matches the sender address and no other recipients are identified. The reply-to address does not match the sender, and is a freemail with no links in the body. This a common combination of techniques used by low level BEC threats.

  1. inbound message
  2. any of recipients.to where:
    • .email.email is sender.email.email
  3. length(recipients.cc) is 0
  4. length(recipients.bcc) is 0
  5. length(body.links) is 0
  6. any of headers.reply_to where all hold:
    • .email.domain.domain in $free_email_providers
    • not:
      • .email.domain.domain is sender.email.domain.domain
  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.links, headers.reply_to, headers.reply_to[].email.domain.domain, recipients.bcc, recipients.cc, recipients.to, recipients.to[].email.email, sender.email.domain.domain, sender.email.email, type.inbound. Sensors: profile.by_sender. Reference lists: $free_email_providers.

Stages and Predicates

Stage 1: mql_rule

and
  any(headers.reply_to)
    and
      not
        headers.reply_to.email.domain.domain cross_field_compare "sender.email.domain.domain"
       macro "headers.reply_to[].email.domain.domain in free_email_providers"
  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"
  any(recipients.to)
    recipients.to.email.email cross_field_compare "sender.email.email"
  body.links length_compare "0"
  recipients.bcc length_compare "0"
  recipients.cc length_compare "0"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

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

Headers: Fake in-reply-to with wildcard sender and missing thread context

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

Detects messages claiming to be replies with In-Reply-To headers but lacking previous thread context, sent from addresses containing multiple wildcard characters in the local part.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Credential Phishing
Tactics and techniquesEvasion, Social engineering, Spoofing

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • headers
  • sender.email
  • subject
  • type

Rule body

type.inbound
and headers.in_reply_to is not null
and not (subject.is_forward or subject.is_reply)
and length(body.previous_threads) == 0
and strings.count(sender.email.local_part, "*") >= 2

Detection logic

Scope: inbound message.

Detects messages claiming to be replies with In-Reply-To headers but lacking previous thread context, sent from addresses containing multiple wildcard characters in the local part.

  1. inbound message
  2. headers.in_reply_to is set
  3. none of:
    • subject.is_forward
    • subject.is_reply
  4. length(body.previous_threads) is 0
  5. strings.count(sender.email.local_part, '*') ≥ 2

Inspects: body.previous_threads, headers.in_reply_to, sender.email.local_part, subject.is_forward, subject.is_reply, type.inbound. Sensors: strings.count.

Stages and Predicates

Stage 1: mql_rule

and
  not
    or
      subject.is_forward eq "true"
      subject.is_reply eq "true"
  body.previous_threads length_compare "0"
  headers.in_reply_to is_not_null
  strings.count func_call "strings.count(sender.email.local_part, \"*\") >= 2"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
headers.in_reply_tois_not_null
  • (no value, null check)
field:"headers.in_reply_to" kind:is_not_null
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Headers: Invalid recipient domain with mismatched reply-to from new sender

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

Message sent to an invalid recipient domain with a reply-to address that differs from the sender address, originating from a new sender.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Credential Phishing, Spam
Tactics and techniquesEvasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • headers.reply_to[0]
  • recipients
  • recipients.to
  • sender.email
  • type

Rule body

type.inbound
and length(recipients.to) <= 1
and all(recipients.to, .email.domain.valid == false)
and length(headers.reply_to) == 1
and headers.reply_to[0].email.domain.root_domain != sender.email.domain.root_domain
and profile.by_sender_email().prevalence == "new"

Detection logic

Scope: inbound message.

Message sent to an invalid recipient domain with a reply-to address that differs from the sender address, originating from a new sender.

  1. inbound message
  2. length(recipients.to) ≤ 1
  3. all of recipients.to where:
    • .email.domain.valid is False
  4. length(headers.reply_to) is 1
  5. headers.reply_to[0].email.domain.root_domain is not sender.email.domain.root_domain
  6. profile.by_sender_email().prevalence is 'new'

Inspects: headers.reply_to, headers.reply_to[0].email.domain.root_domain, recipients.to, recipients.to[].email.domain.valid, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender_email.

Stages and Predicates

Stage 1: mql_rule

and
  headers.reply_to length_compare "1"
  headers.reply_to[0].email.domain.root_domain cross_field_compare "sender.email.domain.root_domain"
  profile.by_sender_email func_call "profile.by_sender_email().prevalence == new"
  recipients.to length_compare "1"
  type.inbound eq "true"
   macro "all(recipients.to)"

Indicators

These rows show field, operator, and value matches.

Headers: iOS/iPadOS mailer with invalid build number

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

Detects emails claiming to be sent from an iOS or iPadOS device that contain an invalid build number.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Credential Phishing, Malware/Ransomware
Tactics and techniquesEvasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • type

Rule body

type.inbound
and regex.contains(headers.mailer, '(iPad|iPhone) Mail')
and not regex.contains(headers.mailer, '(iPad|iPhone) Mail \([0-9]{2}')

Detection logic

Scope: inbound message.

Detects emails claiming to be sent from an iOS or iPadOS device that contain an invalid build number.

  1. inbound message
  2. headers.mailer matches '(iPad|iPhone) Mail'
  3. not:
    • headers.mailer matches '(iPad|iPhone) Mail \\([0-9]{2}'

Inspects: headers.mailer, type.inbound. Sensors: regex.contains.

Indicators matched (1)

FieldMatchValue
regex.containsregex(iPad|iPhone) Mail

Stages and Predicates

Stage 1: mql_rule

and
  not
    headers.mailer regex_match "(iPad|iPhone) Mail \\([0-9]{2}"
  headers.mailer regex_match "(iPad|iPhone) Mail"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.mailerregex_match(iPad|iPhone) Mail ([0-9]{2}excludes:headers.mailer field:"headers.mailer" value:"(iPad|iPhone) Mail ([0-9]{2}"

Indicators

These rows show field, operator, and value matches.

Headers: Outlook Express mailer

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

Detects emails claiming to be sent from Outlook Express, which is a legacy email client that is no longer supported or commonly used.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Credential Phishing, Malware/Ransomware
Tactics and techniquesEvasion, Spoofing

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • type

Rule body

type.inbound
and strings.icontains(headers.mailer, 'Outlook Express')
and not profile.by_sender_email().any_messages_benign

Detection logic

Scope: inbound message.

Detects emails claiming to be sent from Outlook Express, which is a legacy email client that is no longer supported or commonly used.

  1. inbound message
  2. headers.mailer contains 'Outlook Express'
  3. not:
    • profile.by_sender_email().any_messages_benign

Inspects: headers.mailer, type.inbound. Sensors: profile.by_sender_email, strings.icontains.

Indicators matched (1)

FieldMatchValue
strings.icontainssubstringOutlook Express

Stages and Predicates

Stage 1: mql_rule

and
  not
    profile.by_sender_email func_call "profile.by_sender_email().any_messages_benign"
  headers.mailer contains "Outlook Express"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Headers: risky-recover-production message ID

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

Detects messages containing 'risky-recover-production' in the message ID header, which may indicate suspicious or malicious activity.

Threat classification

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

CategoryValues
Attack typesSpam
Tactics and techniquesEvasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • type

Rule body

type.inbound
and strings.icontains(headers.message_id, 'risky-recover-production')

Detection logic

Scope: inbound message.

Detects messages containing 'risky-recover-production' in the message ID header, which may indicate suspicious or malicious activity.

  1. inbound message
  2. headers.message_id contains 'risky-recover-production'

Inspects: headers.message_id, type.inbound. Sensors: strings.icontains.

Indicators matched (1)

FieldMatchValue
strings.icontainssubstringrisky-recover-production

Stages and Predicates

Stage 1: mql_rule

and
  headers.message_id contains "risky-recover-production"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Headers: System account impersonation with empty sender address

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

Detects messages with an empty sender email address and a display name impersonating system accounts like mailer-daemon, postmaster, or administrator, but lacking legitimate bounce back content as determined by natural language processing.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Credential Phishing
Tactics and techniquesImpersonation: Employee, Social engineering, Spoofing

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
and sender.email.email == ""
and (
  strings.icontains(sender.display_name, "mailer-daemon")
  or strings.icontains(sender.display_name, "postmaster")
)
and not (
  (
    any(ml.nlu_classifier(body.current_thread.text).topics,
        .name == "Bounce Back and Delivery Failure Notifications"
        and .confidence == "high"
    )
    or regex.icontains(subject.subject, 'Undeliver(?:ed|able)')
    or regex.icontains(subject.subject,
                       'Mensagem não entregue'
    ) // portuguese bounce back variant 
    or regex.icontains(subject.subject,
                       '系统退信'
    ) // chinese bounce back variant 
  )
)

Detection logic

Scope: inbound message.

Detects messages with an empty sender email address and a display name impersonating system accounts like mailer-daemon, postmaster, or administrator, but lacking legitimate bounce back content as determined by natural language processing.

  1. inbound message
  2. sender.email.email is ''
  3. any of:
    • sender.display_name contains 'mailer-daemon'
    • sender.display_name contains 'postmaster'
  4. none of:
    • any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
      • .name is 'Bounce Back and Delivery Failure Notifications'
      • .confidence is 'high'
    • subject.subject matches 'Undeliver(?:ed|able)'
    • subject.subject matches 'Mensagem não entregue'
    • subject.subject matches '系统退信'

Inspects: body.current_thread.text, sender.display_name, sender.email.email, subject.subject, type.inbound. Sensors: ml.nlu_classifier, regex.icontains, strings.icontains.

Indicators matched (3)

FieldMatchValue
sender.email.emailequals
strings.icontainssubstringmailer-daemon
strings.icontainssubstringpostmaster

Stages and Predicates

Stage 1: mql_rule

and
  not
    or
      any(ml.nlu_classifier(body.current_thread.text).topics)
        and
          ml.nlu_classifier(body.current_thread.text).topics.confidence eq "high"
          ml.nlu_classifier(body.current_thread.text).topics.name eq "Bounce Back and Delivery Failure Notifications"
      subject.subject regex_match "Mensagem não entregue"
      subject.subject regex_match "Undeliver(?:ed|able)"
      subject.subject regex_match "系统退信"
  or
    sender.display_name contains "mailer-daemon"
    sender.display_name contains "postmaster"
  sender.email.email eq ""
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
ml.nlu_classifier(body.current_thread.text).topicsarray_any(no value, null check)excludes:ml.nlu_classifier(body.current_thread.text).topics
subject.subjectregex_matchMensagem não entregueexcludes:subject.subject field:"subject.subject" value:"Mensagem não entregue"
subject.subjectregex_matchUndeliver(?:ed|able)excludes:subject.subject field:"subject.subject" value:"Undeliver(?:ed|able)"
subject.subjectregex_match系统退信excludes:subject.subject field:"subject.subject" value:"系统退信"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
sender.display_namecontains
  • mailer-daemon
  • postmaster
field:"sender.display_name" kind:contains
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Headers: X-Source-Auth mismatch with mismatched reply-to domain

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

Detects messages where the X-Source-Auth header value doesn't match the sender's email address and the reply-to domain differs from the sender's domain, indicating potential sender spoofing or impersonation.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud
Tactics and techniquesSocial engineering, Spoofing

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.hops
  • headers.reply_to
  • sender.email
  • type

Rule body

type.inbound
// X-Source-Auth doesn't match sender
and any(headers.hops,
        any(.fields,
            .name == 'X-Source-Auth'
            and .value != sender.email.email
            and strings.parse_email(.value).email is not null
        )
)
// mismatched sender (from) and Reply-to
and length(headers.reply_to) > 0
and all(headers.reply_to,
        .email.domain.root_domain != sender.email.domain.root_domain
)
and length(ml.nlu_classifier(body.current_thread.text).intents) > 0
and not any(ml.nlu_classifier(body.current_thread.text).intents,
            .name == 'benign' and .confidence != 'low'
)

Detection logic

Scope: inbound message.

Detects messages where the X-Source-Auth header value doesn't match the sender's email address and the reply-to domain differs from the sender's domain, indicating potential sender spoofing or impersonation.

  1. inbound message
  2. any of headers.hops where:
    • any of .fields where all hold:
      • .name is 'X-Source-Auth'
      • .value is not sender.email.email
      • strings.parse_email(.value).email is set
  3. length(headers.reply_to) > 0
  4. all of headers.reply_to where:
    • .email.domain.root_domain is not sender.email.domain.root_domain
  5. length(ml.nlu_classifier(body.current_thread.text).intents) > 0
  6. not:
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name is 'benign'
      • .confidence is not 'low'

Inspects: body.current_thread.text, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.hops[].fields[].value, headers.reply_to, headers.reply_to[].email.domain.root_domain, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: ml.nlu_classifier, strings.parse_email.

Indicators matched (1)

FieldMatchValue
headers.hops[].fields[].nameequalsX-Source-Auth

Stages and Predicates

Stage 1: mql_rule

and
  any(headers.hops)
    any(headers.hops.fields)
      and
        headers.hops.fields[].name eq "X-Source-Auth"
        headers.hops.fields[].value cross_field_compare "sender.email.email"
        strings.parse_email(headers.hops[].fields[].value).email is_not_null
  not
    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 "benign"
  headers.reply_to length_compare "0"
  ml.nlu_classifier(body.current_thread.text).intents length_compare "0"
  type.inbound eq "true"
   macro "all(headers.reply_to)"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
ml.nlu_classifier(body.current_thread.text).intentsarray_any(no value, null check)excludes:ml.nlu_classifier(body.current_thread.text).intents

Indicators

These rows show field, operator, and value matches.

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

Headers: Zimbra mailer from a non-supported OS version

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

Detects Zimbra originated emails sent from non-supported Windows versions. Observed in widespread HTML credential phishing campaigns.

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • type

Rule body

type.inbound
and strings.starts_with(headers.mailer, "Zimbra")
and regex.icontains(headers.mailer, '\b(5\.1|6\.1)\.\d{4}\b')

Detection logic

Scope: inbound message.

Detects Zimbra originated emails sent from non-supported Windows versions. Observed in widespread HTML credential phishing campaigns.

  1. inbound message
  2. headers.mailer starts with 'Zimbra'
  3. headers.mailer matches '\\b(5\\.1|6\\.1)\\.\\d{4}\\b'

Inspects: headers.mailer, type.inbound. Sensors: regex.icontains, strings.starts_with.

Indicators matched (2)

FieldMatchValue
strings.starts_withprefixZimbra
regex.icontainsregex\b(5\.1|6\.1)\.\d{4}\b

Stages and Predicates

Stage 1: mql_rule

and
  headers.mailer regex_match "\\b(5\\.1|6\\.1)\\.\\d{4}\\b"
  headers.mailer starts_with "Zimbra"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Inbound message from popular service via newly observed distribution list

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

Detects when a message comes through a distribution list by matching on return paths containing Sender Rewrite Scheme (SRS) from a previously unknown domain sender to a single recipient who has never interacted with the organization. This method has been observed being abused by threat actors to deliver callback phishing.

Threat classification

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

CategoryValues
Attack typesCallback Phishing
Tactics and techniquesEvasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • headers.auth_summary
  • headers.hops
  • headers.reply_to
  • headers.return_path
  • mailbox
  • recipients
  • recipients.to
  • sender.email
  • type

Rule body

type.inbound
and length(recipients.to) == 1
and length(recipients.bcc) == 0
// abuse involves a popular service
and sender.email.domain.root_domain in $tranco_50k

// message is not from a free mail provider, we have only observed sevice providers abused
and sender.email.domain.root_domain not in $free_email_providers
and sender.email.domain.domain not in $free_email_providers
and not any(recipients.to, .email.email =~ sender.email.email)

// uses Sender Rewrite Scheme indicating the message traversed a distribtion list or other automatic relay
and (
  strings.icontains(headers.return_path.local_part, "+SRS=")
  // when the receipient is a group controlled by the final recipient
  // the return_path header can be overwritten
  // check the SPF designator for evidence of SRS 
  or strings.icontains(headers.auth_summary.spf.details.designator, "+SRS=")
  or any(headers.hops,
         strings.icontains(.authentication_results.spf_details.designator,
                           '+SRS='
         )
  )
)
// the sender and recipient is not in $org_domains
and sender.email.domain.domain not in $org_domains
// the recipient has never sent an email to the org
and all(recipients.to,
        .email.domain.domain not in $org_domains
        // ensure the recipient domain has never send/received an email to/from the org
        and (
          (
            // use the domain only if the sender domain is not within free_email_providers
            .email.domain.domain not in $free_email_providers
            and .email.domain.root_domain not in $free_email_providers
            and .email.domain.domain not in $sender_domains
            and .email.domain.root_domain not in $sender_domains
            and .email.domain.domain not in $recipient_domains
            and .email.domain.root_domain not in $recipient_domains
          )
          or (
            // use the email address the sender domain is within free_email_providers
            (
              .email.domain.domain in $free_email_providers
              or .email.domain.root_domain in $free_email_providers
            )
            and .email.email not in $sender_emails
            and .email.email not in $recipient_emails
          )
          or (
            .email.domain.root_domain in ("onmicrosoft.com")
            // negate onmicrosoft domains within org_domains
            and not .email.domain.domain in $org_domains
          )
        )
)
// if there are reply-to addresses, ensure they are also not assoicated with the org
and all(headers.reply_to,
        .email.domain.domain not in $org_domains
        and .display_name not in $org_display_names
)

// check the return path to ensure it's not related to our sender or the mailbox at all
and not strings.iends_with(headers.return_path.local_part,
                           strings.concat('@', sender.email.domain.domain)
)
and not strings.icontains(headers.return_path.local_part,
                          mailbox.email.local_part
)

// not an inbox rule or automatic forward from a Microsoft Account
and not any(headers.hops,
            any(.fields,
                .name in~ (
                  'X-MS-Exchange-ForwardingLoop',
                  'X-MS-Exchange-Inbox-Rules-Loop'
                )
            )
)

Detection logic

Scope: inbound message.

Detects when a message comes through a distribution list by matching on return paths containing Sender Rewrite Scheme (SRS) from a previously unknown domain sender to a single recipient who has never interacted with the organization. This method has been observed being abused by threat actors to deliver callback phishing.

  1. inbound message
  2. length(recipients.to) is 1
  3. length(recipients.bcc) is 0
  4. sender.email.domain.root_domain in $tranco_50k
  5. sender.email.domain.root_domain not in $free_email_providers
  6. sender.email.domain.domain not in $free_email_providers
  7. not:
    • any of recipients.to where:
      • .email.email is sender.email.email
  8. any of:
    • headers.return_path.local_part contains '+SRS='
    • headers.auth_summary.spf.details.designator contains '+SRS='
    • any of headers.hops where:
      • .authentication_results.spf_details.designator contains '+SRS='
  9. sender.email.domain.domain not in $org_domains
  10. all of recipients.to where all hold:
    • .email.domain.domain not in $org_domains
    • any of:
      • all of:
        • .email.domain.domain not in $free_email_providers
        • .email.domain.root_domain not in $free_email_providers
        • .email.domain.domain not in $sender_domains
        • .email.domain.root_domain not in $sender_domains
        • .email.domain.domain not in $recipient_domains
        • .email.domain.root_domain not in $recipient_domains
      • all of:
        • any of:
          • .email.domain.domain in $free_email_providers
          • .email.domain.root_domain in $free_email_providers
        • .email.email not in $sender_emails
        • .email.email not in $recipient_emails
      • all of:
        • .email.domain.root_domain in ('onmicrosoft.com')
        • not:
          • .email.domain.domain in $org_domains
  11. all of headers.reply_to where all hold:
    • .email.domain.domain not in $org_domains
    • .display_name not in $org_display_names
  12. not:
    • strings.iends_with(headers.return_path.local_part)
  13. not:
    • strings.icontains(headers.return_path.local_part)
  14. not:
    • any of headers.hops where:
      • any of .fields where:
        • .name in ('X-MS-Exchange-ForwardingLoop', 'X-MS-Exchange-Inbox-Rules-Loop')

Inspects: headers.auth_summary.spf.details.designator, headers.hops, headers.hops[].authentication_results.spf_details.designator, headers.hops[].fields, headers.hops[].fields[].name, headers.reply_to, headers.reply_to[].display_name, headers.reply_to[].email.domain.domain, headers.return_path.local_part, mailbox.email.local_part, recipients.bcc, recipients.to, recipients.to[].email.domain.domain, recipients.to[].email.domain.root_domain, recipients.to[].email.email, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: strings.concat, strings.icontains, strings.iends_with. Reference lists: $free_email_providers, $org_display_names, $org_domains, $recipient_domains, $recipient_emails, $sender_domains, $sender_emails, $tranco_50k.

Indicators matched (2)

FieldMatchValue
strings.icontainssubstring+SRS=
recipients.to[].email.domain.root_domainmemberonmicrosoft.com

Stages and Predicates

Stage 1: mql_rule

and
  not
    any(headers.hops)
      any(headers.hops.fields)
        headers.hops.fields.name in ["X-MS-Exchange-ForwardingLoop", "X-MS-Exchange-Inbox-Rules-Loop"]
  or
    any(headers.hops)
      headers.hops.authentication_results.spf_details.designator contains "+SRS="
    headers.auth_summary.spf.details.designator contains "+SRS="
    headers.return_path.local_part contains "+SRS="
  not
    any(recipients.to)
      recipients.to.email.email cross_field_compare "sender.email.email"
  not
    strings.icontains func_call "strings.icontains(headers.return_path.local_part)"
  not
    strings.iends_with func_call "strings.iends_with(headers.return_path.local_part)"
  recipients.bcc length_compare "0"
  recipients.to length_compare "1"
  type.inbound eq "true"
   macro "all(headers.reply_to)"
   macro "all(recipients.to)"
   macro "sender.email.domain.domain not in free_email_providers"
   macro "sender.email.domain.domain not in org_domains"
   macro "sender.email.domain.root_domain in tranco_50k"
   macro "sender.email.domain.root_domain not in free_email_providers"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.hopsarray_any(no value, null check)excludes:headers.hops
recipients.toarray_any(no value, null check)excludes:recipients.to

Indicators

These rows show field, operator, and value matches.

PHP Mailer with common phishing attachments

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

Mail coming from a PHP Mailer user agent that includes attachments with commonly used names in phishing campaigns

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImage as content

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • headers
  • type

Rule body

type.inbound
and strings.ilike(headers.mailer, '*phpmailer*')
and any(attachments, .file_name in~ ('image.png', 'name.png', 'use.png'))

Detection logic

Scope: inbound message.

Mail coming from a PHP Mailer user agent that includes attachments with commonly used names in phishing campaigns

  1. inbound message
  2. headers.mailer matches '*phpmailer*'
  3. any of attachments where:
    • .file_name in ('image.png', 'name.png', 'use.png')

Inspects: attachments[].file_name, headers.mailer, type.inbound. Sensors: strings.ilike.

Indicators matched (4)

FieldMatchValue
strings.ilikesubstring*phpmailer*
attachments[].file_namememberimage.png
attachments[].file_namemembername.png
attachments[].file_namememberuse.png

Stages and Predicates

Stage 1: mql_rule

and
  any(attachments)
    attachments.file_name in ["image.png", "name.png", "use.png"]
  headers.mailer match "phpmailer"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Russia return-path TLD (untrusted sender)

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

The return-path header is a .ru TLD from an untrusted sender.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Credential Phishing, Malware/Ransomware

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • headers.return_path
  • sender.email
  • type

Rule body

type.inbound
and headers.return_path.domain.tld == "ru"
and sender.email.domain.domain != "corp.mail.ru"
and sender.email.domain.domain != "calendar.yandex.ru"
and (
  (
    profile.by_sender().prevalence in ("new", "outlier")
    and not profile.by_sender().solicited
  )
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)
and not profile.by_sender().any_messages_benign

Detection logic

Scope: inbound message.

The return-path header is a .ru TLD from an untrusted sender.

  1. inbound message
  2. headers.return_path.domain.tld is 'ru'
  3. sender.email.domain.domain is not 'corp.mail.ru'
  4. sender.email.domain.domain is not 'calendar.yandex.ru'
  5. any of:
    • all of:
      • profile.by_sender().prevalence in ('new', 'outlier')
      • not:
        • profile.by_sender().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  6. not:
    • profile.by_sender().any_messages_benign

Inspects: headers.return_path.domain.tld, sender.email.domain.domain, type.inbound. Sensors: profile.by_sender.

Indicators matched (1)

FieldMatchValue
headers.return_path.domain.tldequalsru

Stages and Predicates

Stage 1: mql_rule

and
  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"
    and
      not
        profile.by_sender func_call "profile.by_sender().solicited"
      profile.by_sender func_call "profile.by_sender().prevalence in (new, outlier)"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  headers.return_path.domain.tld eq "ru"
  sender.email.domain.domain ne "calendar.yandex.ru"
  sender.email.domain.domain ne "corp.mail.ru"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Sendgrid onmicrosoft.com domain phishing

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

The message originates from an onmicrosoft.com email address being sent via Sendgrid.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • headers.return_path
  • sender.email
  • type

Rule body

type.inbound
and headers.return_path.domain.domain == "sendgrid.net"
and sender.email.domain.root_domain == "onmicrosoft.com"
and not strings.like(sender.email.local_part,
                     "*postmaster*",
                     "*mailer-daemon*",
                     "*administrator*"
)

Detection logic

Scope: inbound message.

The message originates from an onmicrosoft.com email address being sent via Sendgrid.

  1. inbound message
  2. headers.return_path.domain.domain is 'sendgrid.net'
  3. sender.email.domain.root_domain is 'onmicrosoft.com'
  4. not:
    • sender.email.local_part matches any of 3 patterns
      • *postmaster*
      • *mailer-daemon*
      • *administrator*

Inspects: headers.return_path.domain.domain, sender.email.domain.root_domain, sender.email.local_part, type.inbound. Sensors: strings.like.

Indicators matched (2)

FieldMatchValue
headers.return_path.domain.domainequalssendgrid.net
sender.email.domain.root_domainequalsonmicrosoft.com

Stages and Predicates

Stage 1: mql_rule

and
  not
    or
      sender.email.local_part match "administrator"
      sender.email.local_part match "mailer-daemon"
      sender.email.local_part match "postmaster"
  headers.return_path.domain.domain eq "sendgrid.net"
  sender.email.domain.root_domain eq "onmicrosoft.com"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

Sendgrid voicemail phish

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

The message may contain a fake voicemail notification being sent via Sendgrid.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.return_path
  • subject
  • type

Rule body

type.inbound
and headers.return_path.domain.domain == 'sendgrid.net'
and (
  regex.icontains(strings.replace_confusables(subject.subject),
                  'v[o0][il1]cema[il1][li1]',
                  'v[o0][il1]ce message'
  )
  or any(ml.nlu_classifier(body.current_thread.text).topics,
         .name == "Voicemail Call and Missed Call Notifications"
         and .confidence == "high"
  )
)
and any(ml.nlu_classifier(body.current_thread.text).intents,
        .name not in ("benign")
)

Detection logic

Scope: inbound message.

The message may contain a fake voicemail notification being sent via Sendgrid.

  1. inbound message
  2. headers.return_path.domain.domain is 'sendgrid.net'
  3. any of:
    • strings.replace_confusables(subject.subject) matches any of 2 patterns
      • v[o0][il1]cema[il1][li1]
      • v[o0][il1]ce message
    • any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
      • .name is 'Voicemail Call and Missed Call Notifications'
      • .confidence is 'high'
  4. any of ml.nlu_classifier(body.current_thread.text).intents where:
    • .name not in ('benign')

Inspects: body.current_thread.text, headers.return_path.domain.domain, subject.subject, type.inbound. Sensors: ml.nlu_classifier, regex.icontains, strings.replace_confusables.

Indicators matched (5)

FieldMatchValue
headers.return_path.domain.domainequalssendgrid.net
regex.icontainsregexv[o0][il1]cema[il1][li1]
regex.icontainsregexv[o0][il1]ce message
ml.nlu_classifier(body.current_thread.text).topics[].nameequalsVoicemail Call and Missed Call Notifications
ml.nlu_classifier(body.current_thread.text).topics[].confidenceequalshigh

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(ml.nlu_classifier(body.current_thread.text).topics)
      and
        ml.nlu_classifier(body.current_thread.text).topics.confidence eq "high"
        ml.nlu_classifier(body.current_thread.text).topics.name eq "Voicemail Call and Missed Call Notifications"
    strings.replace_confusables(subject.subject) regex_match "v[o0][il1]ce message"
    strings.replace_confusables(subject.subject) regex_match "v[o0][il1]cema[il1][li1]"
  any(ml.nlu_classifier(body.current_thread.text).intents)
    not
      ml.nlu_classifier(body.current_thread.text).intents.name eq "benign"
  headers.return_path.domain.domain eq "sendgrid.net"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

SPF temp error

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

Attackers can spoof domains that have no MX/SPF records, resulting in a DNS timeout. In O365 this fails closed (goes to spam), but in Gmail this fails open (lands in the inbox) and shows a red padlock Reproduce on Ubuntu 18.04: echo "test" | mail -s "Test" user@gmail.com -a"From: Support support@nomxdomain.com" Example headers: Received-SPF: temperror (google.com: error in processing during lookup of support@ltbit.com: DNS error) client-ip=<>; Authentication-Results: mx.google.com; spf=temperror (google.com: error in processing during lookup of support@nomxdomain.com: DNS error) smtp.mailfrom=support@nomxdomain.com

Threat classification

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

CategoryValues
Tactics and techniquesSpoofing

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • headers.hops
  • type

Rule body

type.inbound
and any(headers.hops,
        any(.fields,
            strings.ilike(.name, "Received-SPF")
            and strings.ilike(.value, "*spf=temperror*")
        )
)

Detection logic

Scope: inbound message.

Attackers can spoof domains that have no MX/SPF records, resulting in a DNS timeout. In O365 this fails closed (goes to spam), but in Gmail this fails open (lands in the inbox) and shows a red padlock Reproduce on Ubuntu 18.04: echo "test" | mail -s "Test" user@gmail.com -a"From: Support support@nomxdomain.com" Example headers: Received-SPF: temperror (google.com: error in processing during lookup of support@ltbit.com: DNS error) client-ip=<>; Authentication-Results: mx.google.com; spf=temperror (google.com: error in processing during lookup of support@nomxdomain.com: DNS error) smtp.mailfrom=support@nomxdomain.com

  1. inbound message
  2. any of headers.hops where:
    • any of .fields where all hold:
      • .name matches 'Received-SPF'
      • .value matches '*spf=temperror*'

Inspects: headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.hops[].fields[].value, type.inbound. Sensors: strings.ilike.

Indicators matched (2)

FieldMatchValue
strings.ilikesubstringReceived-SPF
strings.ilikesubstring*spf=temperror*

Stages and Predicates

Stage 1: mql_rule

and
  any(headers.hops)
    any(headers.hops.fields)
      and
        headers.hops.fields[].name eq "Received-SPF"
        headers.hops.fields[].value match "spf=temperror"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

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

Suspicious newly registered reply-to domain with engaging financial or urgent language

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

Detects messages from a mismatched newly registered Reply-to domain that contain a financial or urgent request, or a request and an NLU tag with medium to high confidence, from an untrusted sender. This technique is typically observed in Vendor impersonation.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud
Tactics and techniquesSocial engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • headers.reply_to
  • sender.email
  • type

Rule body

type.inbound
and length(body.current_thread.text) < 5000
and (
  any(headers.reply_to,
      // mismatched reply-to and sender domain
      .email.domain.root_domain != sender.email.domain.root_domain
      // newly registered reply-to domain
      and network.whois(.email.domain).days_old <= 30
  )
  or (
    network.whois(sender.email.domain).days_old < 30
    and sender.email.domain.tld in $suspicious_tlds
  )
)
// request is being made
and any(ml.nlu_classifier(body.current_thread.text).entities,
        .name == "request"
)
// there's financial/urgency OR a tag of medium/high confidence
and (
  any(ml.nlu_classifier(body.current_thread.text).entities,
      .name in ("financial", "urgency")
  )
  or any(ml.nlu_classifier(body.current_thread.text).tags,
         .name is not null and .confidence in ("medium", "high")
  )
)
and (
  not profile.by_sender().solicited

  // 
  // This rule makes use of a beta feature and is subject to change without notice
  // using the beta feature in custom rules is not suggested until it has been formally released
  // 
  or not beta.profile.by_reply_to().solicited
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)
// 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
)

Detection logic

Scope: inbound message.

Detects messages from a mismatched newly registered Reply-to domain that contain a financial or urgent request, or a request and an NLU tag with medium to high confidence, from an untrusted sender. This technique is typically observed in Vendor impersonation.

  1. inbound message
  2. length(body.current_thread.text) < 5000
  3. any of:
    • any of headers.reply_to where all hold:
      • .email.domain.root_domain is not sender.email.domain.root_domain
      • network.whois(.email.domain).days_old ≤ 30
    • all of:
      • network.whois(sender.email.domain).days_old < 30
      • sender.email.domain.tld in $suspicious_tlds
  4. any of ml.nlu_classifier(body.current_thread.text).entities where:
    • .name is 'request'
  5. any of:
    • any of ml.nlu_classifier(body.current_thread.text).entities where:
      • .name in ('financial', 'urgency')
    • any of ml.nlu_classifier(body.current_thread.text).tags where all hold:
      • .name is set
      • .confidence in ('medium', 'high')
  6. any of:
    • not:
      • profile.by_sender().solicited
    • not:
      • beta.profile.by_reply_to().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  7. 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

Inspects: body.current_thread.text, headers.auth_summary.dmarc.pass, headers.reply_to, headers.reply_to[].email.domain, headers.reply_to[].email.domain.root_domain, sender.email.domain, sender.email.domain.root_domain, sender.email.domain.tld, type.inbound. Sensors: beta.profile.by_reply_to, ml.nlu_classifier, network.whois, profile.by_sender. Reference lists: $high_trust_sender_root_domains, $suspicious_tlds.

Indicators matched (5)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsrequest
ml.nlu_classifier(body.current_thread.text).entities[].namememberfinancial
ml.nlu_classifier(body.current_thread.text).entities[].namememberurgency
ml.nlu_classifier(body.current_thread.text).tags[].confidencemembermedium
ml.nlu_classifier(body.current_thread.text).tags[].confidencememberhigh

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    any(headers.reply_to)
      and
        headers.reply_to.email.domain.root_domain cross_field_compare "sender.email.domain.root_domain"
        network.whois func_call "network.whois(headers.reply_to[].email.domain).days_old <= 30"
    and
      network.whois func_call "network.whois(sender.email.domain).days_old < 30"
       macro "sender.email.domain.tld in suspicious_tlds"
  or
    any(ml.nlu_classifier(body.current_thread.text).tags)
      and
        ml.nlu_classifier(body.current_thread.text).tags.confidence in ["high", "medium"]
        ml.nlu_classifier(body.current_thread.text).tags.name is_not_null
    any(ml.nlu_classifier(body.current_thread.text).entities)
      ml.nlu_classifier(body.current_thread.text).entities.name in ["financial", "urgency"]
  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
      beta.profile.by_reply_to func_call "beta.profile.by_reply_to().solicited"
    not
      profile.by_sender func_call "profile.by_sender().solicited"
  any(ml.nlu_classifier(body.current_thread.text).entities)
    ml.nlu_classifier(body.current_thread.text).entities.name eq "request"
  body.current_thread.text length_compare "5000"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

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