• Sublime Core Feed
Medium Severity

Callback Phishing solicitation in message body

Labels

Callback Phishing
Free email provider
Impersonation: Brand
Out of band pivot
Social engineering
File analysis
Sender analysis

Description

A fraudulent invoice/receipt found in the body of the message. Callback Phishing is an attempt by an attacker to solicit the victim (recipient) to call a phone number. The resulting interaction could lead to a multitude of attacks ranging from Financial theft, Remote Access Trojan (RAT) Installation or Ransomware Deployment.

References

No references.

Sublime Security
Created Aug 17th, 2023 • Last updated Feb 26th, 2025
Feed Source
Sublime Core Feed
Source
GitHub
type.inbound
and length(attachments) == 0
and (
  not profile.by_sender().solicited
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_false_positives
  )
)
and (
  sender.email.domain.root_domain in $free_email_providers
  or sender.email.domain.tld in $suspicious_tlds
  or network.whois(sender.email.domain).found == false
  or headers.mailer in~ ("Microsoft CDO for Windows 2000")
  or (
    length(recipients.to) == 1
    and all(recipients.to, .email.domain.domain not in $org_domains)
  )
)
and (
  // this section is synced with attachment_callback_phish_with_pdf.yml and attachment_callback_phish_with_img.yml
  regex.icontains(body.current_thread.text,
                  '(p.{0,3}a.{0,3}y.{0,3}p.{0,3}a.{0,3}l|ma?c.?fee|n[o0]rt[o0]n|geek.{0,5}squad|ebay|symantec|best buy|lifel[o0]c|secure anywhere|starz|utilities premium|pc security|at&t)'
  )
  or any(ml.logo_detect(beta.message_screenshot()).brands,
         .name in ("PayPal", "Norton", "GeekSquad", "Ebay", "McAfee", "AT&T")
  )
)
and length(body.current_thread.text) < 1750
and (
  (
    // this seciton is synced with attachment_callback_phish_with_img.yml and attachment_callback_phish_with_pdf.yml
    // however, the 3 of logic and requiring a phone number is specific to this rule in order to reduce FPs
    // caused by messages which mention cancelling or otherwise managing a subscription
    // it is also synced and below for message_screenshot OCR output
    3 of (
      strings.icontains(body.current_thread.text, 'purchase'),
      strings.icontains(body.current_thread.text, 'payment'),
      strings.icontains(body.current_thread.text, 'transaction'),
      strings.icontains(body.current_thread.text, 'subscription'),
      strings.icontains(body.current_thread.text, 'antivirus'),
      strings.icontains(body.current_thread.text, 'order'),
      strings.icontains(body.current_thread.text, 'support'),
      strings.icontains(body.current_thread.text, 'help line'),
      strings.icontains(body.current_thread.text, 'receipt'),
      strings.icontains(body.current_thread.text, 'invoice'),
      strings.icontains(body.current_thread.text, 'call'),
      strings.icontains(body.current_thread.text, 'cancel'),
      strings.icontains(body.current_thread.text, 'renew'),
      strings.icontains(body.current_thread.text, 'refund'),
      regex.icontains(body.current_thread.text, "(?:reach|contact) us at"),
      strings.icontains(body.current_thread.text, "+1"),
      strings.icontains(body.current_thread.text, "amount"),
      strings.icontains(body.current_thread.text, "charged"),
      strings.icontains(body.current_thread.text, "crypto"),
      strings.icontains(body.current_thread.text, "wallet address"),
      regex.icontains(body.current_thread.text, '\$\d{3}\.\d{2}\b'),
    )
    // phone number regex
    and 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 (
    any(file.explode(beta.message_screenshot()),
        // this seciton is synced with attachment_callback_phish_with_img.yml and attachment_callback_phish_with_pdf.yml
        // and above for current_thread.text
        3 of (
          strings.icontains(.scan.ocr.raw, 'purchase'),
          strings.icontains(.scan.ocr.raw, 'payment'),
          strings.icontains(.scan.ocr.raw, 'transaction'),
          strings.icontains(.scan.ocr.raw, 'subscription'),
          strings.icontains(.scan.ocr.raw, 'antivirus'),
          strings.icontains(.scan.ocr.raw, 'order'),
          strings.icontains(.scan.ocr.raw, 'support'),
          strings.icontains(.scan.ocr.raw, 'help line'),
          strings.icontains(.scan.ocr.raw, 'receipt'),
          strings.icontains(.scan.ocr.raw, 'invoice'),
          strings.icontains(.scan.ocr.raw, 'call'),
          strings.icontains(.scan.ocr.raw, 'helpdesk'),
          strings.icontains(.scan.ocr.raw, 'cancel'),
          strings.icontains(.scan.ocr.raw, 'renew'),
          strings.icontains(.scan.ocr.raw, 'refund'),
          regex.icontains(.scan.ocr.raw, "(?:reach|contact) us at"),
          strings.icontains(.scan.ocr.raw, '+1'),
          strings.icontains(.scan.ocr.raw, 'amount'),
          strings.icontains(.scan.ocr.raw, 'charged'),
          strings.icontains(.scan.ocr.raw, 'crypto'),
          strings.icontains(.scan.ocr.raw, 'wallet address'),
          regex.icontains(.scan.ocr.raw, '\$\d{3}\.\d{2}\b'),
        )
        // phone number regex
        and regex.icontains(.scan.ocr.raw,
                            '\+?([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}'
        )

        // negate messages with previous threads.  While callback phishing with thread hijacking or with current_thread 
        // padded with whitespace and previous threads in the message has been observed, the intetion of using OCR is for image embedded callbacks
        and not regex.icount(.scan.ocr.raw, '(?:from|to|sent|date|cc|subject):') > 3
        // this notation of previous threads often only occurs once
        and not regex.icontains(.scan.ocr.raw, 'wrote:[\r\n]')
    )
  )
)
// not high trust sender domains
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
)
and not strings.ends_with(headers.message_id, "@shopify.com>")
MQL Rule Console
DocsLearning Labs

Playground

Test against your own EMLs or sample data.

Share

Post about this on your socials.

Get Started. Today.

Managed or self-managed. No MX changes.

Get Started