Fake thread with suspicious indicators
Fake thread contains suspicious indicators, which can lead to BEC, credential phishing, and other undesirable outcomes.
Sublime rule (View on GitHub)
1name: "Fake thread with suspicious indicators"
2description: "Fake thread contains suspicious indicators, which can lead to BEC, credential phishing, and other undesirable outcomes."
3type: "rule"
4severity: "medium"
5source: |
6 type.inbound
7 // fake thread check
8 and (
9 (
10 (
11 strings.istarts_with(subject.subject, "RE:")
12 or strings.istarts_with(subject.subject, "FW:")
13 or strings.istarts_with(subject.subject, "FWD:")
14 or regex.imatch(subject.subject,
15 '(\[[^\]]+\]\s?){0,3}(re|fwd?|automat.*)\s?:.*'
16 )
17 )
18 )
19 // fake thread, but no indication in the subject line
20 // current_thread pulls the recent thread, but the full body contains the fake "original" email
21 or (
22 not (
23 (
24 strings.istarts_with(subject.subject, "RE:")
25 or strings.istarts_with(subject.subject, "R:")
26 or strings.istarts_with(subject.subject, "ODG:")
27 or strings.istarts_with(subject.subject, "答复:")
28 or strings.istarts_with(subject.subject, "AW:")
29 or strings.istarts_with(subject.subject, "TR:")
30 or strings.istarts_with(subject.subject, "FWD:")
31 )
32 )
33 and 3 of (
34 strings.icontains(body.html.display_text, "from:"),
35 strings.icontains(body.html.display_text, "to:"),
36 strings.icontains(body.html.display_text, "sent:"),
37 strings.icontains(body.html.display_text, "subject:")
38 )
39 and (
40 length(body.current_thread.text) + 100 < length(body.html.display_text)
41 )
42 // negating bouncebacks
43 and not any(attachments,
44 .content_type in ("message/delivery-status", "message/rfc822")
45 )
46 )
47 )
48
49 and (
50 (length(headers.references) == 0 and headers.in_reply_to is null)
51 or not any(headers.hops, any(.fields, strings.ilike(.name, "In-Reply-To")))
52 )
53
54 // and not solicited
55 and not profile.by_sender().solicited
56 and 4 of (
57 // language attempting to engage
58 (
59 any(ml.nlu_classifier(body.current_thread.text).entities,
60 .name == "request"
61 )
62 and any(ml.nlu_classifier(body.current_thread.text).entities,
63 .name == "financial"
64 )
65 ),
66
67 // invoicing language
68 (
69 any(ml.nlu_classifier(body.current_thread.text).tags, .name == "invoice")
70 or any(ml.nlu_classifier(body.current_thread.text).entities,
71 .text == "invoice"
72 )
73 ),
74
75 // urgency request
76 any(ml.nlu_classifier(body.current_thread.text).entities, .name == "urgency"),
77
78 // cred_theft detection
79 any(ml.nlu_classifier(body.current_thread.text).intents,
80 .name == "cred_theft" and .confidence in~ ("medium", "high")
81 ),
82
83 // commonly abused sender TLD
84 strings.ilike(sender.email.domain.tld, "*.jp"),
85
86 // headers traverse abused TLD
87 any(headers.domains, strings.ilike(.tld, "*.jp")),
88
89 // known suspicious pattern in the URL path
90 any(body.links, regex.match(.href_url.path, '\/[a-z]{3}\d[a-z]')),
91
92 // link display text is in all caps
93 any(body.links, regex.match(.display_text, '[A-Z ]+')),
94
95 // display name contains an email
96 regex.contains(sender.display_name, '[a-z0-9]+@[a-z]+'),
97
98 // Sender domain is empty
99 sender.email.domain.domain == "",
100
101 // sender domain matches no body domains
102 all(body.links,
103 .href_url.domain.root_domain != sender.email.domain.root_domain
104 ),
105
106 // body contains name of VIP
107 (
108 any($org_vips, strings.icontains(body.html.inner_text, .display_name))
109 or any($org_vips, strings.icontains(body.plain.raw, .display_name))
110 ),
111
112 // new body domain
113 any(body.links, network.whois(.href_url.domain).days_old < 30),
114
115 // new sender domain
116 network.whois(sender.email.domain).days_old < 30,
117
118 // new sender
119 profile.by_sender().days_known < 7,
120
121 // excessive whitespace
122 (
123 regex.icontains(body.html.raw, '((<br\s*/?>\s*){20,}|\n{20,})')
124 or regex.icontains(body.html.raw, '(<p[^>]*>\s*<br\s*/?>\s*</p>\s*){30,}')
125 or regex.icontains(body.html.raw,
126 '(<p class=".*?"><span style=".*?"><o:p> </o:p></span></p>\s*){30,}'
127 )
128 or regex.icontains(body.html.raw, '(<p> </p>\s*){7,}')
129 or regex.icontains(body.html.raw, '(<p[^>]*>\s* <br>\s*</p>\s*){5,}')
130 or regex.icontains(body.html.raw, '(<p[^>]*> </p>\s*){7,}')
131 ),
132
133 // body contains recipient SLD
134 any(recipients.to,
135 strings.icontains(body.current_thread.text, .email.domain.sld)
136 )
137 )
138
139 // negate highly trusted sender domains unless they fail DMARC authentication
140 and (
141 (
142 sender.email.domain.root_domain in $high_trust_sender_root_domains
143 and not headers.auth_summary.dmarc.pass
144 )
145 or sender.email.domain.root_domain not in $high_trust_sender_root_domains
146 )
147 and not profile.by_sender().any_false_positives
148
149tags:
150 - "Attack surface reduction"
151attack_types:
152 - "BEC/Fraud"
153 - "Credential Phishing"
154 - "Spam"
155tactics_and_techniques:
156 - "Evasion"
157 - "Social engineering"
158detection_methods:
159 - "Content analysis"
160 - "Header analysis"
161 - "Natural Language Understanding"
162 - "Sender analysis"
163id: "c2e18a57-1f52-544f-bb6d-a578e286cf89"