Callback phishing via e-signature service

Detects messages containing e-signature topics combined with tech support keywords and phone numbers. Message includes brand impersonation (PayPal, Norton, McAfee, etc.) and transaction-related language, with no attachments and reply-to addresses from free email providers.

Sublime rule (View on GitHub)

  1name: "Callback phishing via e-signature service"
  2description: "Detects messages containing e-signature topics combined with tech support keywords and phone numbers. Message includes brand impersonation (PayPal, Norton, McAfee, etc.) and transaction-related language, with no attachments and reply-to addresses from free email providers."
  3type: "rule"
  4severity: "high"
  5source: |
  6  type.inbound
  7  and length(attachments) == 0
  8  and any(headers.reply_to, .email.domain.root_domain in $free_email_providers)
  9  and any(beta.ml_topic(body.current_thread.text).topics, .name == "E-Signature")
 10  and (headers.auth_summary.spf.pass or headers.auth_summary.dmarc.pass)
 11  and (
 12    // this section is synced with attachment_callback_phish_with_pdf.yml and attachment_callback_phish_with_img.yml
 13    regex.icontains(strings.replace_confusables(body.current_thread.text),
 14                    '(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)'
 15    )
 16    or any(ml.logo_detect(file.message_screenshot()).brands,
 17           .name in (
 18             "PayPal",
 19             "Norton",
 20             "GeekSquad",
 21             "Ebay",
 22             "McAfee",
 23             "AT&T",
 24             "Microsoft"
 25           )
 26    )
 27  )
 28  and (
 29    (
 30      // this seciton is synced with attachment_callback_phish_with_img.yml and attachment_callback_phish_with_pdf.yml
 31      // however, the 3 of logic and requiring a phone number is specific to this rule in order to reduce FPs
 32      // caused by messages which mention cancelling or otherwise managing a subscription
 33      // it is also synced and below for message_screenshot OCR output
 34      3 of (
 35        strings.icontains(body.current_thread.text, 'purchase'),
 36        strings.icontains(body.current_thread.text, 'payment'),
 37        strings.icontains(body.current_thread.text, 'transaction'),
 38        strings.icontains(body.current_thread.text, 'subscription'),
 39        strings.icontains(body.current_thread.text, 'antivirus'),
 40        strings.icontains(body.current_thread.text, 'order'),
 41        strings.icontains(body.current_thread.text, 'support'),
 42        strings.icontains(body.current_thread.text, 'help line'),
 43        strings.icontains(body.current_thread.text, 'receipt'),
 44        strings.icontains(body.current_thread.text, 'invoice'),
 45        strings.icontains(body.current_thread.text, 'call'),
 46        strings.icontains(body.current_thread.text, 'cancel'),
 47        strings.icontains(body.current_thread.text, 'renew'),
 48        strings.icontains(body.current_thread.text, 'refund'),
 49        regex.icontains(body.current_thread.text, "(?:reach|contact) us at"),
 50        strings.icontains(body.current_thread.text, "+1"),
 51        strings.icontains(body.current_thread.text, "amount"),
 52        strings.icontains(body.current_thread.text, "charged"),
 53        strings.icontains(body.current_thread.text, "crypto"),
 54        strings.icontains(body.current_thread.text, "wallet address"),
 55        regex.icontains(body.current_thread.text, '\$\d{3}\.\d{2}\b'),
 56      )
 57      // phone number regex
 58      and regex.icontains(body.current_thread.text,
 59                          '\+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}',
 60                          '\+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4}'
 61      )
 62    )
 63    or (
 64      // this seciton is synced with attachment_callback_phish_with_img.yml and attachment_callback_phish_with_pdf.yml
 65      // and above for current_thread.text
 66      //
 67      // This rule makes use of a beta feature and is subject to change without notice
 68      // using the beta feature in custom rules is not suggested until it has been formally released
 69      //
 70      3 of (
 71        strings.icontains(beta.ocr(file.message_screenshot()).text, 'purchase'),
 72        strings.icontains(beta.ocr(file.message_screenshot()).text, 'payment'),
 73        strings.icontains(beta.ocr(file.message_screenshot()).text, 'transaction'),
 74        strings.icontains(beta.ocr(file.message_screenshot()).text,
 75                          'subscription'
 76        ),
 77        strings.icontains(beta.ocr(file.message_screenshot()).text, 'antivirus'),
 78        strings.icontains(beta.ocr(file.message_screenshot()).text, 'order'),
 79        strings.icontains(beta.ocr(file.message_screenshot()).text, 'support'),
 80        strings.icontains(beta.ocr(file.message_screenshot()).text, 'help line'),
 81        strings.icontains(beta.ocr(file.message_screenshot()).text, 'receipt'),
 82        strings.icontains(beta.ocr(file.message_screenshot()).text, 'invoice'),
 83        strings.icontains(beta.ocr(file.message_screenshot()).text, 'call'),
 84        strings.icontains(beta.ocr(file.message_screenshot()).text, 'helpdesk'),
 85        strings.icontains(beta.ocr(file.message_screenshot()).text, 'cancel'),
 86        strings.icontains(beta.ocr(file.message_screenshot()).text, 'renew'),
 87        strings.icontains(beta.ocr(file.message_screenshot()).text, 'refund'),
 88        regex.icontains(beta.ocr(file.message_screenshot()).text,
 89                        "(?:reach|contact) us at"
 90        ),
 91        strings.icontains(beta.ocr(file.message_screenshot()).text, '+1'),
 92        strings.icontains(beta.ocr(file.message_screenshot()).text, 'amount'),
 93        strings.icontains(beta.ocr(file.message_screenshot()).text, 'charged'),
 94        strings.icontains(beta.ocr(file.message_screenshot()).text, 'crypto'),
 95        strings.icontains(beta.ocr(file.message_screenshot()).text,
 96                          'wallet address'
 97        ),
 98        regex.icontains(beta.ocr(file.message_screenshot()).text,
 99                        '\$\d{3}\.\d{2}\b'
100        ),
101      )
102      // phone number regex
103      and regex.icontains(beta.ocr(file.message_screenshot()).text,
104                          '\+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}',
105                          '\+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4}'
106      )
107  
108      // negate messages with previous threads.  While callback phishing with thread hijacking or with current_thread 
109      // padded with whitespace and previous threads in the message has been observed, the intetion of using OCR is for image embedded callbacks
110      and not regex.icount(beta.ocr(file.message_screenshot()).text,
111                           '(?:from|to|sent|date|cc|subject):'
112      ) > 3
113      // this notation of previous threads often only occurs once
114      and not regex.icontains(beta.ocr(file.message_screenshot()).text,
115                              'wrote:[\r\n]'
116      )
117    )
118  )  
119attack_types:
120  - "Callback Phishing"
121tactics_and_techniques:
122  - "Free email provider"
123  - "Impersonation: Brand"
124  - "Social engineering"
125detection_methods:
126  - "Content analysis"
127  - "Computer Vision"
128  - "Header analysis"
129  - "Optical Character Recognition"
130id: "ed37b4fd-22bb-5f55-92fa-215e42f5fe5a"
to-top