Detection rules › Sublime MQL

Callback phishing in body or attachment (untrusted sender)

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

Detects callback scams by analyzing text within images of receipts or invoices from untrusted senders.

Threat classification

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

CategoryValues
Attack typesCallback Phishing
Tactics and techniquesOut of band pivot, Social engineering

Event coverage

Rule body MQL

type.inbound
and length(attachments) < 5
and (
  any(attachments,
      (.file_type in $file_types_images or .file_type in ("pdf", "xlsx"))
      and (
        any(ml.nlu_classifier(beta.ocr(.).text).intents,
            .name == "callback_scam" and .confidence in ("medium", "high")
        )
        or any(file.explode(.),

               // exclude images taken with mobile cameras and screenshots from android
               not any(.scan.exiftool.fields,
                       .key == "Model"
                       or (
                         .key == "Software"
                         and strings.starts_with(.value, "Android")
                       )
                       or (.key == "UserComment" and .value == "Screenshot")
               )
               and any(ml.nlu_classifier(.scan.ocr.raw).intents,
                       .name == "callback_scam"
                       and .confidence in ("medium", "high")
               )
        )
      )
      and (
        // negate noreply unless a logo is found in the attachment
        (
          sender.email.local_part in ("no_reply", "noreply")
          and any(ml.logo_detect(.).brands,
                  .name in ("PayPal", "Norton", "GeekSquad", "Ebay", "McAfee")
          )
        )
        or sender.email.local_part not in ("no_reply", "noreply")
      )
  )
  or (
    any(ml.nlu_classifier(body.current_thread.text).intents,
        .name in ("callback_scam") and .confidence in ("medium", "high")
    )
    and (
      (
        270 < length(body.current_thread.text) < 1750
        or (
          75 < length(body.current_thread.text) < 1750
          and (
            strings.ilike(body.current_thread.text,
                          "*PayPal*",
                          "*Norton*",
                          "*GeekSquad*",
                          "*Ebay*",
                          "*McAfee*",
                          "*=1"
            )
            // phone number regex
            or regex.icontains(body.current_thread.text,
                               '\+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}',
                               '\+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4}'
            )
            or 1 of (
              strings.icontains(beta.ocr(file.message_screenshot()).text,
                                "geek squad"
              ),
              strings.icontains(beta.ocr(file.message_screenshot()).text,
                                "lifelock"
              ),
              strings.icontains(beta.ocr(file.message_screenshot()).text,
                                "best buy"
              ),
              strings.icontains(beta.ocr(file.message_screenshot()).text,
                                "mcafee"
              ),
              strings.icontains(beta.ocr(file.message_screenshot()).text,
                                "norton"
              ),
              strings.icontains(beta.ocr(file.message_screenshot()).text,
                                "ebay"
              ),
              strings.icontains(beta.ocr(file.message_screenshot()).text,
                                "paypal"
              ),
              strings.icontains(beta.ocr(file.message_screenshot()).text,
                                "virus"
              ),
            )
          )
        )
      )
    )
  )
)
and not (
  any(headers.domains, .domain == "smtp-out.gcp.bigcommerce.net")
  and strings.icontains(body.html.raw, "bigcommerce.com")
)
and (
  not profile.by_sender_email().solicited
  or (
    profile.by_sender_email().any_messages_malicious_or_spam
    and not profile.by_sender_email().any_messages_benign
  )
)

// 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
)
// negate opsgenie email notifications
and not sender.email.email == 'opsgenie@opsgenie.net'

Detection logic

Scope: inbound message.

Detects callback scams by analyzing text within images of receipts or invoices from untrusted senders.

  1. inbound message
  2. length(attachments) < 5
  3. any of:
    • any of attachments where all hold:
      • any of:
        • .file_type in $file_types_images
        • .file_type in ('pdf', 'xlsx')
      • any of:
        • any of ml.nlu_classifier(beta.ocr(.).text).intents where all hold:
          • .name is 'callback_scam'
          • .confidence in ('medium', 'high')
        • any of file.explode(.) where all hold:
          • not:
            • any of .scan.exiftool.fields where any holds:
              • .key is 'Model'
              • all of:
                • .key is 'Software'
                • .value starts with 'Android'
              • all of:
                • .key is 'UserComment'
                • .value is 'Screenshot'
          • any of ml.nlu_classifier(.scan.ocr.raw).intents where all hold:
            • .name is 'callback_scam'
            • .confidence in ('medium', 'high')
      • any of:
        • all of:
          • sender.email.local_part in ('no_reply', 'noreply')
          • any of ml.logo_detect(.).brands where:
            • .name in ('PayPal', 'Norton', 'GeekSquad', 'Ebay', 'McAfee')
        • sender.email.local_part not in ('no_reply', 'noreply')
    • all of:
      • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
        • .name in ('callback_scam')
        • .confidence in ('medium', 'high')
      • any of:
        • all of:
          • length(body.current_thread.text) > 270
          • length(body.current_thread.text) < 1750
        • all of:
          • all of:
            • length(body.current_thread.text) > 75
            • length(body.current_thread.text) < 1750
          • any of:
            • body.current_thread.text matches any of 6 patterns
              • *PayPal*
              • *Norton*
              • *GeekSquad*
              • *Ebay*
              • *McAfee*
              • *=1
            • body.current_thread.text matches any of 2 patterns
              • \+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}
              • \+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4}
            • at least 1 of 8: beta.ocr(file.message_screenshot()).text contains any of 8 patterns
              • geek squad
              • lifelock
              • best buy
              • mcafee
              • norton
              • ebay
              • paypal
              • virus
  4. not:
    • all of:
      • any of headers.domains where:
        • .domain is 'smtp-out.gcp.bigcommerce.net'
      • body.html.raw contains 'bigcommerce.com'
  5. any of:
    • not:
      • profile.by_sender_email().solicited
    • all of:
      • profile.by_sender_email().any_messages_malicious_or_spam
      • not:
        • profile.by_sender_email().any_messages_benign
  6. any of:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • not:
        • headers.auth_summary.dmarc.pass
    • sender.email.domain.root_domain not in $high_trust_sender_root_domains
  7. not:
    • sender.email.email is 'opsgenie@opsgenie.net'

Inspects: attachments[].file_type, body.current_thread.text, body.html.raw, headers.auth_summary.dmarc.pass, headers.domains, headers.domains[].domain, sender.email.domain.root_domain, sender.email.email, sender.email.local_part, type.inbound. Sensors: beta.ocr, file.explode, file.message_screenshot, ml.logo_detect, ml.nlu_classifier, profile.by_sender_email, regex.icontains, strings.icontains, strings.ilike, strings.starts_with. Reference lists: $file_types_images, $high_trust_sender_root_domains.

Indicators matched (42)

FieldMatchValue
attachments[].file_typememberpdf
attachments[].file_typememberxlsx
ml.nlu_classifier(beta.ocr(attachments[]).text).intents[].nameequalscallback_scam
ml.nlu_classifier(beta.ocr(attachments[]).text).intents[].confidencemembermedium
ml.nlu_classifier(beta.ocr(attachments[]).text).intents[].confidencememberhigh
file.explode(attachments[])[].scan.exiftool.fields[].keyequalsModel
file.explode(attachments[])[].scan.exiftool.fields[].keyequalsSoftware
strings.starts_withprefixAndroid
file.explode(attachments[])[].scan.exiftool.fields[].keyequalsUserComment
file.explode(attachments[])[].scan.exiftool.fields[].valueequalsScreenshot
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].nameequalscallback_scam
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidencemembermedium
30 more
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidencememberhigh
sender.email.local_partmemberno_reply
sender.email.local_partmembernoreply
ml.logo_detect(attachments[]).brands[].namememberPayPal
ml.logo_detect(attachments[]).brands[].namememberNorton
ml.logo_detect(attachments[]).brands[].namememberGeekSquad
ml.logo_detect(attachments[]).brands[].namememberEbay
ml.logo_detect(attachments[]).brands[].namememberMcAfee
ml.nlu_classifier(body.current_thread.text).intents[].namemembercallback_scam
ml.nlu_classifier(body.current_thread.text).intents[].confidencemembermedium
ml.nlu_classifier(body.current_thread.text).intents[].confidencememberhigh
strings.ilikesubstring*PayPal*
strings.ilikesubstring*Norton*
strings.ilikesubstring*GeekSquad*
strings.ilikesubstring*Ebay*
strings.ilikesubstring*McAfee*
strings.ilikesubstring*=1
regex.icontainsregex\+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}
regex.icontainsregex\+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4}
strings.icontainssubstringgeek squad
strings.icontainssubstringlifelock
strings.icontainssubstringbest buy
strings.icontainssubstringmcafee
strings.icontainssubstringnorton
strings.icontainssubstringebay
strings.icontainssubstringpaypal
strings.icontainssubstringvirus
headers.domains[].domainequalssmtp-out.gcp.bigcommerce.net
strings.icontainssubstringbigcommerce.com
sender.email.emailequalsopsgenie@opsgenie.net