Spam: Fake photo share
Message contains pretexting language about sharing photos ("found these photos and thought you'd like them", "remember these photos?") and a link with a newly registered domain. Fake threads and plain text bodies have been seen in the wild, indicating active evasion techniques.
Sublime rule (View on GitHub)
1name: "Spam: Fake photo share"
2description: 'Message contains pretexting language about sharing photos ("found these photos and thought you''d like them", "remember these photos?") and a link with a newly registered domain. Fake threads and plain text bodies have been seen in the wild, indicating active evasion techniques.'
3type: "rule"
4severity: "low"
5source: |
6 type.inbound
7 and length(attachments) == 0
8 and (
9 (
10 (
11 (
12 (length(body.plain.raw) < 500 and length(body.current_thread.text) == 0)
13 or (
14 length(body.html.display_text) < 500
15 and length(body.current_thread.text) == 0
16 )
17 or length(body.current_thread.text) < 500
18 or any(map(filter(ml.nlu_classifier(body.current_thread.text).entities,
19 .name == "disclaimer"
20 ),
21 .text
22 ),
23 (length(body.current_thread.text) - length(.)) < 500
24 )
25 )
26 and strings.ilike(subject.subject,
27 "*picture*",
28 "*photo*",
29 "*image*",
30 "*sad news*",
31 "*sad announcement*",
32 "*sad update*",
33 "*new pics*",
34 "*Reunion*",
35 "*planing*"
36 )
37 )
38 or (
39 (
40 (
41 length(body.html.display_text) < 500
42 and length(body.current_thread.text) == 0
43 )
44 and strings.ilike(body.html.display_text,
45 "*picture*",
46 "*photo*",
47 "*image*",
48 "*sad news*",
49 "*sad announcement*",
50 "*sad update*",
51 "*new pics*"
52 )
53 )
54 or (
55 (length(body.plain.raw) < 500 and length(body.current_thread.text) == 0)
56 and strings.ilike(body.plain.raw,
57 "*picture*",
58 "*photo*",
59 "*image*",
60 "*sad news*",
61 "*sad announcement*",
62 "*sad update*",
63 "*new pics*"
64 )
65 and not strings.icontains(body.plain.raw, "[cid:image")
66 )
67 or (
68 length(body.current_thread.text) < 500
69 and strings.ilike(body.current_thread.text,
70 "*picture*",
71 "*photo*",
72 "*image*",
73 "*sad news*",
74 "*sad announcement*",
75 "*sad update*",
76 "*new pics*"
77 )
78 )
79 )
80 or (
81 body.plain.raw is not null
82 and body.html.display_text is null
83 and (
84 length(body.current_thread.text) == 0
85 or (
86 length(body.current_thread.text) < 500
87 // fake forward indicator in the plain text body
88 and (
89 regex.contains(body.plain.raw,
90 'On (Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday).{0,50} wrote'
91 )
92 or strings.icontains(body.plain.raw, 'Original Message')
93 )
94 and not regex.contains(body.current_thread.text,
95 'On (Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday).{0,50} wrote'
96 )
97 and not strings.icontains(body.current_thread.text,
98 'Original Message'
99 )
100 and not any(headers.hops, any(.fields, .name == "Resent-From"))
101 )
102 )
103 and strings.ilike(body.plain.raw,
104 "*picture*",
105 "*photo*",
106 "*image*",
107 "*sad news*",
108 "*sad announcement*",
109 "*sad update*",
110 "*pics*"
111 )
112 and not strings.istarts_with(body.plain.raw, "[cid:image")
113 and strings.icontains(subject.subject, sender.display_name)
114 )
115 or (
116 strings.icontains(subject.subject, sender.display_name)
117 and sender.email.domain.root_domain in $free_email_providers
118 and length(body.links) == 2
119 and length(filter(body.links, .display_text == "h")) == 1
120 and length(filter(body.links, .display_url.scheme == "ttp")) == 1
121 )
122 )
123 and length(body.links) < 5
124 and any(body.links,
125 (
126 (
127 network.whois(.href_url.domain).days_old < 30
128 or not network.whois(.href_url.domain).found
129 or network.whois(.href_url.domain).found is null
130 )
131 and .href_url.domain.root_domain != sender.email.domain.root_domain
132 )
133 or (
134 length(.display_text) == 1
135 and .href_url.domain.root_domain in ("facebook.com", "youtube.com")
136 )
137 or (
138 // random 5-character subdomain
139 regex.icontains(.href_url.domain.domain,
140 '^[a-z]{5}\.[a-z]{5,}\.[a-z]+'
141 )
142 // subdomain contains 3+ consecutive consonants
143 and regex.icontains(.href_url.domain.domain,
144 '^[a-z]*[b-df-hj-np-tv-z]{3,}[a-z]*\.'
145 )
146 and network.whois(.href_url.domain).days_old < 365
147 )
148 )
149 )
150 and (
151 (
152 (length(headers.references) > 0 or headers.in_reply_to is null)
153 and not (
154 (
155 strings.istarts_with(subject.subject, "RE:")
156 or strings.istarts_with(subject.subject, "R:")
157 or strings.istarts_with(subject.subject, "ODG:")
158 or strings.istarts_with(subject.subject, "答复:")
159 or strings.istarts_with(subject.subject, "AW:")
160 or strings.istarts_with(subject.subject, "TR:")
161 or strings.istarts_with(subject.subject, "FWD:")
162 or regex.imatch(subject.subject, '(\[[^\]]+\]\s?){0,3}(re|fwd?)\s?:')
163 )
164 )
165 )
166 or length(headers.references) == 0
167 )
168 // negate highly trusted sender domains unless they fail DMARC authentication
169 and (
170 (
171 sender.email.domain.root_domain in $high_trust_sender_root_domains
172 and not headers.auth_summary.dmarc.pass
173 )
174 or sender.email.domain.root_domain not in $high_trust_sender_root_domains
175 )
176attack_types:
177 - "Spam"
178tactics_and_techniques:
179 - "Evasion"
180 - "Social engineering"
181detection_methods:
182 - "Content analysis"
183 - "Sender analysis"
184 - "URL analysis"
185 - "Whois"
186id: "eb086f7d-3ad7-52cd-8e16-3ce08726b9ea"