EXPLORE
← Back to Explore
sublimemediumRule

Business Email Compromise (BEC) with request for mobile number

This rule detects unsolicited messages with a small plain text body, that is attempting to solicit a mobile number.

MITRE ATT&CK

initial-access

Detection Query

type.inbound
and (
  length(body.current_thread.text) < 500
  or any(map(filter(ml.nlu_classifier(body.current_thread.text).entities,
                    .name == "disclaimer"
             ),
             .text
         ),
         (length(body.current_thread.text) - length(.)) < 500
  )
)
and length(attachments) == 0
and regex.icontains(body.current_thread.text,
                    '(?:mobile|contact|current|reliable).{0,10}(?:phone|number|#|\bno)|whatsapp|\bcell|personalcell|(?:share|what).{0,25}number.{0,15}(?:connect|reach|text|message|contact|call)|(?:\bdrop|which|send.{0,5}your|best).{0,25}(?:number|\bnum\b|#).{0,15}(?:(?:connect|reach|contact|call).{0,5}you|text|message|works?\b|stay connected)|forward.{0,25}(?:\bnum\b|#)|get (?:your.{0,25}(?:number|\bnum\b|#)|in touch.{0,15}(?:via|by|through).{0,10}(?:text|phone|cell|sms|whatsapp))|(?:provide|confirm|reply.{0,15}with).{0,25}(?:direct|preferred).{0,15}(?:text.?enabled.{0,15})?(?:phone.{0,5})?(?:number|\bnum\b|#|line)|(?:share|send).{0,25}(?:direct|preferred).{0,15}(?:text.?enabled.{0,15})?(?:phone.{0,5})(?:number|\bnum\b|#|line)|(?:share|send).{0,25}preferred.{0,15}(?:text.?enabled.{0,15})?(?:number|\bnum\b|#|line)|(?:direct|preferred).{0,15}line.{0,15}(?:for|to|via).{0,10}(?:text|call|reach|contact|sms)'
)
and (
  any(ml.nlu_classifier(body.current_thread.text).intents,
      .name in ("bec", "advance_fee") and .confidence != "low"
  )
  or (
    // confidence can be low on very short bodies
    length(body.current_thread.text) < 550
    and (
      any(ml.nlu_classifier(body.current_thread.text).intents, .name == "bec")
      or any(ml.nlu_classifier(sender.display_name).intents, .name == "bec")
      or any(ml.nlu_classifier(body.current_thread.text).entities,
             strings.icontains(.text, "kindly")
      )
    )
  )
)
and (
  (
    (
      length(headers.references) > 0
      or not any(headers.hops,
                 any(.fields, strings.ilike(.name, "In-Reply-To"))
      )
    )
    and not (
      (
        strings.istarts_with(subject.subject, "RE:")
        or strings.istarts_with(subject.subject, "RES:")
        or strings.istarts_with(subject.subject, "R:")
        or strings.istarts_with(subject.subject, "ODG:")
        or strings.istarts_with(subject.subject, "答复:")
        or strings.istarts_with(subject.subject, "AW:")
        or strings.istarts_with(subject.subject, "TR:")
        or strings.istarts_with(subject.subject, "FWD:")
        or regex.imatch(subject.subject,
                        '(\[[^\]]+\]\s?){0,3}(re|fwd?|automat.*)\s?:.*'
        )
      )
    )
  )
  or length(headers.references) == 0
)
and (
  not profile.by_sender().solicited
  or profile.by_sender().any_messages_malicious_or_spam
)
and not profile.by_sender().any_messages_benign

Data Sources

Email MessagesEmail HeadersEmail Attachments

Platforms

email
Raw Content
name: "Business Email Compromise (BEC) with request for mobile number"
description: "This rule detects unsolicited messages with a small plain text body, that is attempting to solicit a mobile number."
type: "rule"
severity: "medium"
source: |
  type.inbound
  and (
    length(body.current_thread.text) < 500
    or any(map(filter(ml.nlu_classifier(body.current_thread.text).entities,
                      .name == "disclaimer"
               ),
               .text
           ),
           (length(body.current_thread.text) - length(.)) < 500
    )
  )
  and length(attachments) == 0
  and regex.icontains(body.current_thread.text,
                      '(?:mobile|contact|current|reliable).{0,10}(?:phone|number|#|\bno)|whatsapp|\bcell|personalcell|(?:share|what).{0,25}number.{0,15}(?:connect|reach|text|message|contact|call)|(?:\bdrop|which|send.{0,5}your|best).{0,25}(?:number|\bnum\b|#).{0,15}(?:(?:connect|reach|contact|call).{0,5}you|text|message|works?\b|stay connected)|forward.{0,25}(?:\bnum\b|#)|get (?:your.{0,25}(?:number|\bnum\b|#)|in touch.{0,15}(?:via|by|through).{0,10}(?:text|phone|cell|sms|whatsapp))|(?:provide|confirm|reply.{0,15}with).{0,25}(?:direct|preferred).{0,15}(?:text.?enabled.{0,15})?(?:phone.{0,5})?(?:number|\bnum\b|#|line)|(?:share|send).{0,25}(?:direct|preferred).{0,15}(?:text.?enabled.{0,15})?(?:phone.{0,5})(?:number|\bnum\b|#|line)|(?:share|send).{0,25}preferred.{0,15}(?:text.?enabled.{0,15})?(?:number|\bnum\b|#|line)|(?:direct|preferred).{0,15}line.{0,15}(?:for|to|via).{0,10}(?:text|call|reach|contact|sms)'
  )
  and (
    any(ml.nlu_classifier(body.current_thread.text).intents,
        .name in ("bec", "advance_fee") and .confidence != "low"
    )
    or (
      // confidence can be low on very short bodies
      length(body.current_thread.text) < 550
      and (
        any(ml.nlu_classifier(body.current_thread.text).intents, .name == "bec")
        or any(ml.nlu_classifier(sender.display_name).intents, .name == "bec")
        or any(ml.nlu_classifier(body.current_thread.text).entities,
               strings.icontains(.text, "kindly")
        )
      )
    )
  )
  and (
    (
      (
        length(headers.references) > 0
        or not any(headers.hops,
                   any(.fields, strings.ilike(.name, "In-Reply-To"))
        )
      )
      and not (
        (
          strings.istarts_with(subject.subject, "RE:")
          or strings.istarts_with(subject.subject, "RES:")
          or strings.istarts_with(subject.subject, "R:")
          or strings.istarts_with(subject.subject, "ODG:")
          or strings.istarts_with(subject.subject, "答复:")
          or strings.istarts_with(subject.subject, "AW:")
          or strings.istarts_with(subject.subject, "TR:")
          or strings.istarts_with(subject.subject, "FWD:")
          or regex.imatch(subject.subject,
                          '(\[[^\]]+\]\s?){0,3}(re|fwd?|automat.*)\s?:.*'
          )
        )
      )
    )
    or length(headers.references) == 0
  )
  and (
    not profile.by_sender().solicited
    or profile.by_sender().any_messages_malicious_or_spam
  )
  and not profile.by_sender().any_messages_benign

attack_types:
  - "BEC/Fraud"
tactics_and_techniques:
  - "Social engineering"
detection_methods:
  - "Content analysis"
  - "Natural Language Understanding"
  - "Sender analysis"
id: "514ffd68-a663-5b83-8a25-e380f0a7f1a7"