Callback phishing in body or attachment (untrusted sender)

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

Sublime rule (View on GitHub)

  1name: "Callback phishing in body or attachment (untrusted sender)"
  2description: |
  3    Detects callback scams by analyzing text within images of receipts or invoices from untrusted senders.
  4type: "rule"
  5severity: "medium"
  6source: |
  7  type.inbound
  8  and length(attachments) < 5
  9  and (
 10    any(attachments,
 11        (.file_type in $file_types_images or .file_type in ("pdf", "xlsx"))
 12        and (
 13          any(ml.nlu_classifier(beta.ocr(.).text).intents,
 14              .name == "callback_scam" and .confidence in ("medium", "high")
 15          )
 16          or any(file.explode(.),
 17  
 18                 // exclude images taken with mobile cameras and screenshots from android
 19                 not any(.scan.exiftool.fields,
 20                         .key == "Model"
 21                         or (
 22                           .key == "Software"
 23                           and strings.starts_with(.value, "Android")
 24                         )
 25                         or (.key == "UserComment" and .value == "Screenshot")
 26                 )
 27                 and any(ml.nlu_classifier(.scan.ocr.raw).intents,
 28                         .name == "callback_scam"
 29                         and .confidence in ("medium", "high")
 30                 )
 31          )
 32        )
 33        and (
 34          // negate noreply unless a logo is found in the attachment
 35          (
 36            sender.email.local_part in ("no_reply", "noreply")
 37            and any(ml.logo_detect(.).brands,
 38                    .name in ("PayPal", "Norton", "GeekSquad", "Ebay", "McAfee")
 39            )
 40          )
 41          or sender.email.local_part not in ("no_reply", "noreply")
 42        )
 43    )
 44    or (
 45      any(ml.nlu_classifier(body.current_thread.text).intents,
 46          .name in ("callback_scam") and .confidence in ("medium", "high")
 47      )
 48      and (
 49        (
 50          270 < length(body.current_thread.text) < 1750
 51          or (
 52            75 < length(body.current_thread.text) < 1750
 53            and (
 54              strings.ilike(body.current_thread.text,
 55                            "*PayPal*",
 56                            "*Norton*",
 57                            "*GeekSquad*",
 58                            "*Ebay*",
 59                            "*McAfee*",
 60                            "*=1"
 61              )
 62              // phone number regex
 63              or regex.icontains(body.current_thread.text,
 64                               '\+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}',
 65                               '\+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4}'
 66              )
 67              or 1 of (
 68                strings.icontains(beta.ocr(file.message_screenshot()).text,
 69                                  "geek squad"
 70                ),
 71                strings.icontains(beta.ocr(file.message_screenshot()).text,
 72                                  "lifelock"
 73                ),
 74                strings.icontains(beta.ocr(file.message_screenshot()).text,
 75                                  "best buy"
 76                ),
 77                strings.icontains(beta.ocr(file.message_screenshot()).text,
 78                                  "mcafee"
 79                ),
 80                strings.icontains(beta.ocr(file.message_screenshot()).text,
 81                                  "norton"
 82                ),
 83                strings.icontains(beta.ocr(file.message_screenshot()).text,
 84                                  "ebay"
 85                ),
 86                strings.icontains(beta.ocr(file.message_screenshot()).text,
 87                                  "paypal"
 88                ),
 89                strings.icontains(beta.ocr(file.message_screenshot()).text,
 90                                  "virus"
 91                ),
 92              )
 93            )
 94          )
 95        )
 96      )
 97    )
 98  )
 99  and not (
100    any(headers.domains, .domain == "smtp-out.gcp.bigcommerce.net")
101    and strings.icontains(body.html.raw, "bigcommerce.com")
102  )
103  and (
104    not profile.by_sender().solicited
105    or (
106      profile.by_sender().any_messages_malicious_or_spam
107      and not profile.by_sender().any_messages_benign
108    )
109  )
110  
111  // negate highly trusted sender domains unless they fail DMARC authentication
112  and (
113    (
114      sender.email.domain.root_domain in $high_trust_sender_root_domains
115      and not headers.auth_summary.dmarc.pass
116    )
117    or sender.email.domain.root_domain not in $high_trust_sender_root_domains
118  )  
119
120attack_types:
121  - "Callback Phishing"
122tactics_and_techniques:
123  - "Out of band pivot"
124  - "Social engineering"
125detection_methods:
126  - "Content analysis"
127  - "File analysis"
128  - "Optical Character Recognition"
129  - "Natural Language Understanding"
130  - "Sender analysis"
131id: "b93c6f94-c9a3-587a-8eb5-6856754f8222"
to-top