Detection rules › Sublime MQL

Attachment: Microsoft OAuth credential harvesting via EML with embedded malicious links

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

Detects inbound messages containing EML attachments with embedded links targeting Microsoft OAuth authentication flows. The rule identifies suspicious Microsoft login URLs with specific query parameters indicating credential harvesting attempts, including offline access permissions, read/write scopes, and reprocessing endpoints. Links are detected within EML body content, embedded PDF/HTML attachments, and ICS calendar files.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Evasion, PDF

Event coverage

Rule body MQL

type.inbound
and any(attachments,
        (.content_type == "message/rfc822" or .file_extension in ("eml"))
        and (
          // links in attached EML body
          any(file.parse_eml(.).body.links,
              .href_url.domain.domain == 'login.microsoftonline.com'
              and (
                strings.ilike(.href_url.query_params,
                              '*offline_access*',
                              '*.readwrite*',
                              '*.read*',
                              '*ctx=*',
                              '*prompt=none*'
                )
                or (
                  strings.icontains(.href_url.path, '/common/reprocess')
                  and strings.icontains(.href_url.query_params, 'ctx=')
                  and strings.icontains(.href_url.query_params, 'sessionId=')
                )
              )
          )
          // links in PDF and HTML attachments inside the EML
          or any(filter(file.parse_eml(.).attachments,
                        .file_type in ("pdf", "html")
                 ),
                 any(file.explode(.),
                     any(.scan.url.urls,
                         .domain.domain == 'login.microsoftonline.com'
                         and (
                           strings.ilike(.query_params,
                                         '*offline_access*',
                                         '*.readwrite*',
                                         '*.read*',
                                         '*ctx=*',
                                         '*prompt=none*'
                           )
                           or (
                             strings.icontains(.path, '/common/reprocess')
                             and strings.icontains(.query_params, 'ctx=')
                             and strings.icontains(.query_params, 'sessionId=')
                           )
                         )
                     )
                 )
          )
          // links in ICS attachments inside the EML
          or any(filter(file.parse_eml(.).attachments,
                        .file_type == "ics"
                        or .file_extension == "ics"
                        or .content_type in ("application/ics", "text/calendar")
                 ),
                 //
                 // 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
                 //
                 any(beta.file.parse_ics(.).events,
                     any(.links,
                         .href_url.domain.domain == 'login.microsoftonline.com'
                         and (
                           strings.ilike(.href_url.query_params,
                                         '*offline_access*',
                                         '*.readwrite*',
                                         '*.read*',
                                         '*ctx=*',
                                         '*prompt=none*'
                           )
                           or (
                             strings.icontains(.href_url.path,
                                               '/common/reprocess'
                             )
                             and strings.icontains(.href_url.query_params,
                                                   'ctx='
                             )
                             and strings.icontains(.href_url.query_params,
                                                   'sessionId='
                             )
                           )
                         )
                     )
                 )
          )
        )
) 

Detection logic

Scope: inbound message.

Detects inbound messages containing EML attachments with embedded links targeting Microsoft OAuth authentication flows. The rule identifies suspicious Microsoft login URLs with specific query parameters indicating credential harvesting attempts, including offline access permissions, read/write scopes, and reprocessing endpoints. Links are detected within EML body content, embedded PDF/HTML attachments, and ICS calendar files.

  1. inbound message
  2. any of attachments where all hold:
    • any of:
      • .content_type is 'message/rfc822'
      • .file_extension in ('eml')
    • any of:
      • any of file.parse_eml(.).body.links where all hold:
        • .href_url.domain.domain is 'login.microsoftonline.com'
        • any of:
          • .href_url.query_params matches any of 5 patterns
            • *offline_access*
            • *.readwrite*
            • *.read*
            • *ctx=*
            • *prompt=none*
          • all of:
            • .href_url.path contains '/common/reprocess'
            • .href_url.query_params contains 'ctx='
            • .href_url.query_params contains 'sessionId='
      • any of filter(...) where:
        • any of file.explode(.) where:
          • any of .scan.url.urls where all hold:
            • .domain.domain is 'login.microsoftonline.com'
            • any of:
              • .query_params matches any of 5 patterns
                • *offline_access*
                • *.readwrite*
                • *.read*
                • *ctx=*
                • *prompt=none*
              • all of:
                • .path contains '/common/reprocess'
                • .query_params contains 'ctx='
                • .query_params contains 'sessionId='
      • any of filter(...) where:
        • any of beta.file.parse_ics(.).events where:
          • any of .links where all hold:
            • .href_url.domain.domain is 'login.microsoftonline.com'
            • any of:
              • .href_url.query_params matches any of 5 patterns
                • *offline_access*
                • *.readwrite*
                • *.read*
                • *ctx=*
                • *prompt=none*
              • all of:
                • .href_url.path contains '/common/reprocess'
                • .href_url.query_params contains 'ctx='
                • .href_url.query_params contains 'sessionId='

Inspects: attachments[].content_type, attachments[].file_extension, type.inbound. Sensors: beta.file.parse_ics, file.explode, file.parse_eml, strings.icontains, strings.ilike.

Indicators matched (19)

FieldMatchValue
attachments[].content_typeequalsmessage/rfc822
attachments[].file_extensionmembereml
file.parse_eml(attachments[]).body.links[].href_url.domain.domainequalslogin.microsoftonline.com
strings.ilikesubstring*offline_access*
strings.ilikesubstring*.readwrite*
strings.ilikesubstring*.read*
strings.ilikesubstring*ctx=*
strings.ilikesubstring*prompt=none*
strings.icontainssubstring/common/reprocess
strings.icontainssubstringctx=
strings.icontainssubstringsessionId=
file.parse_eml(attachments[]).attachments[].file_typememberpdf
7 more
file.parse_eml(attachments[]).attachments[].file_typememberhtml
file.explode(filter(...)[])[].scan.url.urls[].domain.domainequalslogin.microsoftonline.com
file.parse_eml(attachments[]).attachments[].file_typeequalsics
file.parse_eml(attachments[]).attachments[].file_extensionequalsics
file.parse_eml(attachments[]).attachments[].content_typememberapplication/ics
file.parse_eml(attachments[]).attachments[].content_typemembertext/calendar
beta.file.parse_ics(filter(...)[]).events[].links[].href_url.domain.domainequalslogin.microsoftonline.com