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