Credential phishing: Fake storage alerts (unsolicited)

This rule targets credential phishing attempts disguised as storage space alerts, activating for inbound emails with specific storage-related keywords and evaluating sender trustworthiness and history.

Sublime rule (View on GitHub)

  1name: "Credential phishing: Fake storage alerts (unsolicited)"
  2description: "This rule targets credential phishing attempts disguised as storage space alerts, activating for inbound emails with specific storage-related keywords and evaluating sender trustworthiness and history."
  3type: "rule"
  4severity: "medium"
  5source: |
  6  type.inbound
  7  and (
  8    (
  9      0 < length(body.links) < 8
 10      and any([subject.subject, sender.display_name],
 11              regex.icontains(., "(?:storage|mailbox)")
 12      )
 13    )
 14    or (
 15      //
 16      // This rule makes use of a beta feature and is subject to change without notice
 17      // using the beta feature in custom rules is not suggested until it has been formally released
 18      //
 19      any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents,
 20          .name == "cred_theft" and .confidence == "high"
 21      )
 22      and regex.icontains(beta.ocr(file.message_screenshot()).text,
 23                          "storage.{0,50}full",
 24                          "free.{0,50}upgrade",
 25                          "storage.{0,50}details",
 26                          "storage.{0,50}quot",
 27                          "email.{0,50}storage",
 28                          "total.{0,50}storage",
 29                          "storage.{0,50}limit",
 30                          "cloud.{0,50}update payment",
 31      )
 32      and not strings.ilike(beta.ocr(file.message_screenshot()).text,
 33                            "*free plan*"
 34      )
 35    )
 36    or (
 37      any(body.links,
 38          // fingerprints of a hyperlinked image
 39          .display_text is null
 40          and .display_url.url is null
 41          and (
 42            .href_url.domain.root_domain in $free_file_hosts
 43            or .href_url.domain.root_domain == "beehiiv.com"
 44          )
 45      )
 46      and length(attachments) == 1
 47      and all(attachments,
 48              .file_type in $file_types_images
 49              and .size > 2000
 50              and any(file.explode(.),
 51                      regex.icontains(.scan.ocr.raw,
 52                                      "storage.{0,50}full",
 53                                      "free.{0,50}upgrade",
 54                                      "storage.{0,50}details",
 55                                      "storage.{0,50}quot",
 56                                      "email.{0,50}storage",
 57                                      "total.{0,50}storage"
 58                      )
 59              )
 60      )
 61    )
 62  )
 63  and (
 64    strings.icontains(subject.subject,
 65                      "exceeded",
 66                      "out of",
 67                      "mailbox",
 68                      "icloud",
 69                      "all storage used",
 70                      "compliance",
 71                      "critical",
 72                      "problem",
 73                      "max storage",
 74                      "be deleted",
 75                      "action required",
 76                      "undelivered messages",
 77                      "review storage",
 78                      "subscription terminated",
 79                      "final notice",
 80                      "data retention",
 81                      "file deletion",
 82                      "suspend"
 83    )
 84    or regex.icontains(subject.subject,
 85                       '\bfull\b',
 86                       '\blimit(?:ed|\b)',
 87                       "storage (?:space|capacity warning|is used|danger|plan)",
 88                       '(?:upgrade|\bact\b) (?:today|now)',
 89                       'at (?:100|9[0-9](?:\.\d+)?|one[\s-]?hundred) ?(?:percent|%)',
 90                       'back(?:ing|ed)? up'
 91    )
 92  )
 93  
 94  // negate customer service requests about storage
 95  and not any(ml.nlu_classifier(body.current_thread.text).topics,
 96              .name in ("Customer Service and Support", "B2B Cold Outreach")
 97              and .confidence == "high"
 98  )
 99  
100  // negate links to loopnet.com - a popular commerical property listing service
101  and not (any(body.links, .href_url.domain.root_domain == "loopnet.com"))
102  
103  // negate legitimate sharepoint storage alerts
104  and (
105    (
106      sender.email.email == "no-reply@sharepointonline.com"
107      and not headers.auth_summary.dmarc.pass
108      and (
109        not all(body.links,
110                .href_url.domain.root_domain in~ (
111                  "sharepoint.com",
112                  "microsoft.com",
113                  "aka.ms"
114                )
115        )
116      )
117    )
118    or sender.email.email != "no-reply@sharepointonline.com"
119  )
120  
121  // negate legitimate iCloud China storage alerts
122  and (
123    (
124      sender.email.email == "noreply@icloud.com.cn"
125      and not headers.auth_summary.dmarc.pass
126      and (
127        not all(body.links,
128                .href_url.domain.root_domain in~ ("icloud.com", "aka.ms")
129        )
130      )
131    )
132    or sender.email.email != "noreply@icloud.com.cn"
133  )
134  
135  // negate bouncebacks and undeliverables
136  and not any(attachments,
137              .content_type in (
138                "message/global-delivery-status",
139                "message/delivery-status",
140              )
141              or (
142                .content_type == "message/rfc822"
143                and any(file.parse_eml(.).attachments,
144                        .content_type in (
145                          "message/global-delivery-status",
146                          "message/delivery-status",
147                        )
148                )
149              )
150  )
151  
152  // negate highly trusted sender domains unless they fail DMARC authentication
153  and not (
154    sender.email.domain.root_domain in $high_trust_sender_root_domains
155    and coalesce(headers.auth_summary.dmarc.pass, false)
156  )
157  and (
158    not profile.by_sender().solicited
159    or profile.by_sender().any_messages_malicious_or_spam
160  )
161  // negate instances where proofpoint sends a review of a reported message via analyzer
162  and not (
163    sender.email.email == "analyzer@analyzer.securityeducation.com"
164    and any(headers.domains, .root_domain == "pphosted.com")
165    and headers.auth_summary.spf.pass
166    and headers.auth_summary.dmarc.pass
167  )  
168attack_types:
169  - "Credential Phishing"
170tactics_and_techniques:
171  - "Social engineering"
172detection_methods:
173  - "Content analysis"
174  - "Sender analysis"
175
176id: "750f04d6-f68a-564c-9e41-c1e5a58df28f"
to-top