Detection rules › Sublime MQL

Sublime MQL rules: header

Message traversed multiple onmicrosoft.com tenants

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

This detection rule identifies messages that have traversed multiple distinct onmicrosoft.com tenants. This technique has been observed as an evasion tactic to distribute a single message across a list of targeted recipients.

Threat Classification

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

CategoryValues
Attack typesCallback Phishing
Tactics and techniquesEvasion, Free email provider, Free subdomain host

Telemetry Coverage

PlatformRecord / event type
SublimeInbound email message

Message Attributes

  • headers
  • headers.hops
  • headers.return_path
  • recipients
  • recipients.to
  • type

Rule Body

type.inbound
and length(recipients.to) == 1
and all(recipients.to,
        .email.domain.root_domain == "onmicrosoft.com"
        and not .email.domain.domain in $org_domains
)
// the message has traversed two or more different "onmicrosoft.com" subdomains
and length(distinct(map(filter(headers.hops,
                               strings.icontains(.authentication_results.spf_details.designator,
                                                 '.onmicrosoft.com'
                               )
                               and not strings.contains(.authentication_results.spf_details.designator,
                                                        "@"
                               )
                        ),
                        .authentication_results.spf_details.designator
                    ),
                    .
           )
) > 1
and all(recipients.to,
        .email.domain.domain != headers.return_path.domain.domain
)

Detection Logic

Scope: inbound message.

This detection rule identifies messages that have traversed multiple distinct onmicrosoft.com tenants. This technique has been observed as an evasion tactic to distribute a single message across a list of targeted recipients.

  1. inbound message
  2. length(recipients.to) == 1
  3. all of recipients.to where all hold:
    • .email.domain.root_domain is 'onmicrosoft.com'
    • not:
      • .email.domain.domain in $org_domains
  4. length(distinct(map(filter(headers.hops, strings.icontains(.authentication_results.spf_details.designator, '.onmicrosoft.com' ) and not strings.contains(.authentication_results.spf_details.designator, "@" ) ), .authentication_results.spf_details.designator ), . ) ) > 1
  5. all of recipients.to where:
    • .email.domain.domain is not headers.return_path.domain.domain

Inspects: headers.hops, headers.hops[].authentication_results.spf_details.designator, headers.return_path.domain.domain, recipients.to, recipients.to[].email.domain.domain, recipients.to[].email.domain.root_domain, type.inbound. Sensors: strings.contains, strings.icontains. Reference lists: $org_domains.

Indicators Matched (2)

FieldMatchValue
recipients.to[].email.domain.root_domainequalsonmicrosoft.com
strings.icontainssubstring.onmicrosoft.com

Stages and Predicates

Stage 1: mql_rule

and
  length func_call "length(distinct(map(filter(headers.hops,\n                               strings.icontains(.authentication_results.spf_details.designator,\n                                                 '.onmicrosoft.com'\n                               )\n                               and not strings.contains(.authentication_results.spf_details.designator,\n                                                        \"@\"\n                               )\n                        ),\n                        .authentication_results.spf_details.designator\n                    ),\n                    .\n           )\n) > 1"
  recipients.to length_compare "1"
  type.inbound eq "true"
   macro "all(recipients.to,\n        .email.domain.domain != headers.return_path.domain.domain\n)"
   macro "all(recipients.to,\n        .email.domain.root_domain == \"onmicrosoft.com\"\n        and not .email.domain.domain in $org_domains\n)"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
type.inboundeq
  • true transforms: boolean corpus 1212 (mql 1212)
field:"type.inbound" kind:eq value:"true"

Targeting: Specific AOL address

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

Message targeting a specific AOL address (me@aol.com) with a single recipient.

Threat Classification

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

CategoryValues
Attack typesSpam
Tactics and techniquesSocial engineering

Telemetry Coverage

PlatformRecord / event type
SublimeInbound email message

Message Attributes

  • recipients
  • recipients.to[0]
  • type

Rule Body

type.inbound
and length(recipients.to) == 1
and recipients.to[0].email.email == "me@aol.com"

Detection Logic

Scope: inbound message.

Message targeting a specific AOL address (me@aol.com) with a single recipient.

  1. inbound message
  2. length(recipients.to) == 1
  3. recipients.to[0].email.email is 'me@aol.com'

Inspects: recipients.to, recipients.to[0].email.email, type.inbound.

Indicators Matched (1)

FieldMatchValue
recipients.to[0].email.emailequalsme@aol.com

Stages and Predicates

Stage 1: mql_rule

and
  recipients.to length_compare "1"
  recipients.to[0].email.email eq "me@aol.com"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Back to all Sublime MQL rules