Detection rules › Sublime MQL

Suspicious Office 365 app authorization (OAuth) link

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

Message contains a suspicious Office 365 app authorization (OAuth) link. The app may be compromised or was stood up for malicious purposes. Once the app has been authorized, the attacker will have read or write permissions to the user's Office 365 account.

Threat classification

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

CategoryValues
Attack typesCredential Phishing

Event coverage

Rule body MQL

type.inbound
and (
  // links in email body
  any([body.links, body.current_thread.links],
      any(.,
          .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, HTML, DOCX and PPTX attachments
  or any(filter(attachments, .file_type in ("pdf", "html", "docx", "pptx")),
         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=')
                   )
                 )
             )
         )
  )
  or any(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
         //
         and 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.

Message contains a suspicious Office 365 app authorization (OAuth) link. The app may be compromised or was stood up for malicious purposes. Once the app has been authorized, the attacker will have read or write permissions to the user's Office 365 account.

  1. inbound message
  2. any of:
    • any of [body.links, body.current_thread.links] where:
      • any of . 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(attachments) 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 attachments where all hold:
      • any of:
        • .file_type is 'ics'
        • .file_extension is 'ics'
        • .content_type in ('application/ics', 'text/calendar')
      • 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, attachments[].file_type, body.current_thread.links, body.links, type.inbound. Sensors: beta.file.parse_ics, file.explode, strings.icontains, strings.ilike.

Indicators matched (19)

FieldMatchValue
[body.links, body.current_thread.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=
attachments[].file_typememberpdf
attachments[].file_typememberhtml
attachments[].file_typememberdocx
7 more
attachments[].file_typememberpptx
file.explode(filter(attachments)[])[].scan.url.urls[].domain.domainequalslogin.microsoftonline.com
attachments[].file_typeequalsics
attachments[].file_extensionequalsics
attachments[].content_typememberapplication/ics
attachments[].content_typemembertext/calendar
beta.file.parse_ics(attachments[]).events[].links[].href_url.domain.domainequalslogin.microsoftonline.com