EXPLORE
← Back to Explore
sublimehighRule

Brand impersonation: Microsoft Teams invitation

Detects messages impersonating a Microsoft Teams invites by matching known invite text patterns while containing join links that do not resolve to Microsoft domains. Additional verification includes checking for absent phone dial-in options and missing standard Teams help text or HTML meeting components.

MITRE ATT&CK

initial-access

Detection Query

type.inbound
and (
  (
    strings.icontains(body.current_thread.text, 'Microsoft Teams')
    and strings.icontains(body.current_thread.text, 'join the meeting')
    and strings.contains(body.current_thread.text, 'Meeting ID:')
    and strings.contains(body.current_thread.text, 'Passcode:')
  )
  or (
    strings.icontains(body.current_thread.text, "teams")
    // strings that give us confidence it's teams
    and 2 of (
      strings.icontains(body.current_thread.text, "internal"),
      strings.icontains(body.current_thread.text, "message"),
      strings.icontains(body.current_thread.text, "meeting"),
      strings.icontains(body.current_thread.text, "Download Teams")
    )
  )
  // either the subject or sender.display name containt Microsoft Teams and Meeting
  or (
    any([subject.base, sender.display_name],
        strings.icontains(., 'Microsoft Teams')
        and strings.icontains(., 'meeting')
    )
  )
)
// not a reply
and length(headers.references) == 0
and headers.in_reply_to is null
// few links
and length(distinct(body.links, .href_url.url)) < 10
// short body
and length(body.current_thread.text) < 600
// no unsubscribe links
// common in newsletters which link to a webinar style event
and not any(body.links, strings.icontains(.display_text, "unsub"))

// one of the links contains is a CTA that doesn't link to MS
and any(body.current_thread.links,
        (
          .display_text =~ "join the meeting"
          or strings.icontains(.display_text, "join the meeting")
          or strings.icontains(.display_text, "play recording")
        )
        and .href_url.domain.root_domain not in (
          "microsoft.com",
          "microsoft.us",
          "microsoft.cn",
          "live.com"
        )
        and not (
          .href_url.domain.root_domain == "mimecastprotect.com"
          and strings.parse_domain(.href_url.query_params_decoded["domain"][0]).root_domain in (
            "microsoft.com",
            "microsoft.us",
            "microsoft.cn",
            "live.com"
          )
        )
        // rewriters often abstract the link
        and .href_url.domain.root_domain not in $bulk_mailer_url_root_domains
)
// missing the dial by phone element
and not strings.icontains(body.current_thread.text, 'Dial in by phone')

// any of these suspicious elements from the body
and (
  // malicious samples leveraged recipient domain branding here
  not strings.icontains(body.current_thread.text, 'Microsoft Teams Need help?')
  // malicious samples contained unique html elements not present in legit ones
  or strings.icontains(body.html.raw, '<div class="meeting-title">')
  or strings.icontains(body.html.raw, '<div class="meeting-time">')
  or strings.icontains(body.html.raw, '<div class="meeting-location">')
  or strings.icontains(body.html.raw, '<span class="conflict-badge">')
  or strings.icontains(body.html.raw, 'class="join-button"')
)

// 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
)

Data Sources

Email MessagesEmail HeadersEmail Attachments

Platforms

email
Raw Content
name: "Brand impersonation: Microsoft Teams invitation"
description: "Detects messages impersonating a Microsoft Teams invites by matching known invite text patterns while containing join links that do not resolve to Microsoft domains. Additional verification includes checking for absent phone dial-in options and missing standard Teams help text or HTML meeting components."
type: "rule"
severity: "high"
source: |
  type.inbound
  and (
    (
      strings.icontains(body.current_thread.text, 'Microsoft Teams')
      and strings.icontains(body.current_thread.text, 'join the meeting')
      and strings.contains(body.current_thread.text, 'Meeting ID:')
      and strings.contains(body.current_thread.text, 'Passcode:')
    )
    or (
      strings.icontains(body.current_thread.text, "teams")
      // strings that give us confidence it's teams
      and 2 of (
        strings.icontains(body.current_thread.text, "internal"),
        strings.icontains(body.current_thread.text, "message"),
        strings.icontains(body.current_thread.text, "meeting"),
        strings.icontains(body.current_thread.text, "Download Teams")
      )
    )
    // either the subject or sender.display name containt Microsoft Teams and Meeting
    or (
      any([subject.base, sender.display_name],
          strings.icontains(., 'Microsoft Teams')
          and strings.icontains(., 'meeting')
      )
    )
  )
  // not a reply
  and length(headers.references) == 0
  and headers.in_reply_to is null
  // few links
  and length(distinct(body.links, .href_url.url)) < 10
  // short body
  and length(body.current_thread.text) < 600
  // no unsubscribe links
  // common in newsletters which link to a webinar style event
  and not any(body.links, strings.icontains(.display_text, "unsub"))
  
  // one of the links contains is a CTA that doesn't link to MS
  and any(body.current_thread.links,
          (
            .display_text =~ "join the meeting"
            or strings.icontains(.display_text, "join the meeting")
            or strings.icontains(.display_text, "play recording")
          )
          and .href_url.domain.root_domain not in (
            "microsoft.com",
            "microsoft.us",
            "microsoft.cn",
            "live.com"
          )
          and not (
            .href_url.domain.root_domain == "mimecastprotect.com"
            and strings.parse_domain(.href_url.query_params_decoded["domain"][0]).root_domain in (
              "microsoft.com",
              "microsoft.us",
              "microsoft.cn",
              "live.com"
            )
          )
          // rewriters often abstract the link
          and .href_url.domain.root_domain not in $bulk_mailer_url_root_domains
  )
  // missing the dial by phone element
  and not strings.icontains(body.current_thread.text, 'Dial in by phone')
  
  // any of these suspicious elements from the body
  and (
    // malicious samples leveraged recipient domain branding here
    not strings.icontains(body.current_thread.text, 'Microsoft Teams Need help?')
    // malicious samples contained unique html elements not present in legit ones
    or strings.icontains(body.html.raw, '<div class="meeting-title">')
    or strings.icontains(body.html.raw, '<div class="meeting-time">')
    or strings.icontains(body.html.raw, '<div class="meeting-location">')
    or strings.icontains(body.html.raw, '<span class="conflict-badge">')
    or strings.icontains(body.html.raw, 'class="join-button"')
  )
  
  // 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
  )
attack_types:
  - "Credential Phishing"
tactics_and_techniques:
  - "Impersonation: Brand"
  - "Social engineering"
detection_methods:
  - "Content analysis"
  - "Header analysis"
  - "HTML analysis"
  - "URL analysis"
id: "46410ad8-3465-505f-a78e-f77704910a91"