BEC: Tax document request
Detects messages requesting W-2 tax documents or related tax information that exhibit authentication failures such as DMARC or SPF failures, or mismatched reply-to addresses. The rule identifies senders using common administrative local parts and filters for messages containing W-2 language combined with request entities detected through natural language processing.
Sublime rule (View on GitHub)
1name: "BEC: Tax document request"
2description: "Detects messages requesting W-2 tax documents or related tax information that exhibit authentication failures such as DMARC or SPF failures, or mismatched reply-to addresses. The rule identifies senders using common administrative local parts and filters for messages containing W-2 language combined with request entities detected through natural language processing."
3type: "rule"
4severity: "medium"
5source: |
6 type.inbound
7 // searching for common sender emails
8 and sender.email.local_part in~ (
9 "contact",
10 "no-reply",
11 "noreply",
12 "info",
13 "admin"
14 )
15 // sender emails unmatched
16 and (
17 length(headers.reply_to) > 0
18 and all(headers.reply_to,
19 .email.domain.root_domain != sender.email.domain.root_domain
20 )
21 )
22 // subject lines with words correlating to tax information
23 and (
24 strings.icontains(subject.base, 'wage')
25 or strings.icontains(strings.replace_confusables(subject.base), 'Ŵ-2')
26 or regex.icontains(subject.base, 'tax (?:form|state?ment|year)')
27 or regex.icontains(subject.base, '\bw-?2?\b')
28 or regex.icontains(strings.replace_confusables(subject.base), '\birs\b')
29 )
30 // body text containing variations of "w2" or "wage statements"
31 and (
32 (
33 strings.icontains(strings.replace_confusables(body.current_thread.text),
34 'Ẇ-2'
35 )
36 or strings.icontains(body.current_thread.text, "wage statements")
37 or regex.icontains(body.current_thread.text, 'w-?2[a-z]?\b')
38 )
39 )
40 // ml classifying for requests
41 and any(ml.nlu_classifier(body.current_thread.text).entities,
42 .name == "request"
43 )
44 // exclude legitimate senders or domains
45 and not any(ml.nlu_classifier(body.current_thread.text).intents,
46 .name == "benign" and .confidence == "high"
47 )
48 and not (
49 sender.email.domain.domain in $org_domains
50 and coalesce(headers.auth_summary.dmarc.pass, false)
51 )
52 and not (
53 sender.email.domain.root_domain in (
54 "excel.com",
55 "sharepoint.com",
56 "sharepointonline.com",
57 "powerpoint.com",
58 "onenote.com",
59 "microsoft.com",
60 "jotform.com",
61 "wetrasnfer.com"
62 )
63 and coalesce(headers.auth_summary.dmarc.pass, false)
64 )
65 // negate highly trusted sender domains unless they fail DMARC authentication
66 and not (
67 sender.email.domain.root_domain in $high_trust_sender_root_domains
68 and coalesce(headers.auth_summary.dmarc.pass, false)
69 )
70
71attack_types:
72 - "BEC/Fraud"
73tactics_and_techniques:
74 - "Social engineering"
75 - "Spoofing"
76detection_methods:
77 - "Content analysis"
78 - "Header analysis"
79 - "Natural Language Understanding"
80 - "Sender analysis"
81id: "4834a45e-6d70-5ad9-9043-024eea995e95"