1+ name : " PR# 4702 - Spam: Photo/image lure"
2+ description : ' 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.'
3+ type : " rule"
4+ severity : " low"
5+ source : |
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 (
70+ strings.ilike(body.current_thread.text,
71+ "*picture*",
72+ "*photo*",
73+ "*image*",
74+ "*sad news*",
75+ "*sad announcement*",
76+ "*sad update*",
77+ "*new pics*"
78+ )
79+ or regex.icontains(body.current_thread.text,
80+ '\b(photo|pics?|picture)\b'
81+ )
82+ )
83+ )
84+ )
85+ or (
86+ body.plain.raw is not null
87+ and body.html.display_text is null
88+ and (
89+ length(body.current_thread.text) == 0
90+ or (
91+ length(body.current_thread.text) < 500
92+ // fake forward indicator in the plain text body
93+ and (
94+ regex.contains(body.plain.raw,
95+ 'On (Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday).{0,50} wrote'
96+ )
97+ or strings.icontains(body.plain.raw, 'Original Message')
98+ )
99+ and not regex.contains(body.current_thread.text,
100+ 'On (Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday).{0,50} wrote'
101+ )
102+ and not strings.icontains(body.current_thread.text,
103+ 'Original Message'
104+ )
105+ and not any(headers.hops, any(.fields, .name == "Resent-From"))
106+ )
107+ )
108+ and strings.ilike(body.plain.raw,
109+ "*picture*",
110+ "*photo*",
111+ "*image*",
112+ "*sad news*",
113+ "*sad announcement*",
114+ "*sad update*",
115+ "*pics*"
116+ )
117+ and not strings.istarts_with(body.plain.raw, "[cid:image")
118+ and strings.icontains(subject.subject, sender.display_name)
119+ )
120+ or (
121+ strings.icontains(subject.subject, sender.display_name)
122+ and sender.email.domain.root_domain in $free_email_providers
123+ and length(body.links) == 2
124+ and length(filter(body.links, .display_text == "h")) == 1
125+ and length(filter(body.links, .display_url.scheme == "ttp")) == 1
126+ )
127+ )
128+ and length(body.links) < 5
129+ and any(body.links,
130+ (
131+ (
132+ network.whois(.href_url.domain).days_old < 30
133+ or not network.whois(.href_url.domain).found
134+ or network.whois(.href_url.domain).found is null
135+ )
136+ and .href_url.domain.root_domain != sender.email.domain.root_domain
137+ )
138+ or (
139+ length(.display_text) == 1
140+ and .href_url.domain.root_domain in ("facebook.com", "youtube.com")
141+ )
142+ or (
143+ // random 5-character subdomain
144+ regex.icontains(.href_url.domain.domain,
145+ '^[a-z]{5}\.[a-z]{5,}\.[a-z]+'
146+ )
147+ // subdomain contains 3+ consecutive consonants
148+ and regex.icontains(.href_url.domain.domain,
149+ '^[a-z]*[b-df-hj-np-tv-z]{3,}[a-z]*\.'
150+ )
151+ and network.whois(.href_url.domain).days_old < 365
152+ )
153+ )
154+ )
155+ and (
156+ (
157+ (length(headers.references) > 0 or headers.in_reply_to is null)
158+ and not (
159+ (
160+ strings.istarts_with(subject.subject, "RE:")
161+ or strings.istarts_with(subject.subject, "R:")
162+ or strings.istarts_with(subject.subject, "ODG:")
163+ or strings.istarts_with(subject.subject, "答复:")
164+ or strings.istarts_with(subject.subject, "AW:")
165+ or strings.istarts_with(subject.subject, "TR:")
166+ or strings.istarts_with(subject.subject, "FWD:")
167+ or regex.imatch(subject.subject, '(\[[^\]]+\]\s?){0,3}(re|fwd?)\s?:')
168+ )
169+ )
170+ )
171+ or length(headers.references) == 0
172+ )
173+ // negate highly trusted sender domains unless they fail DMARC authentication
174+ and (
175+ (
176+ sender.email.domain.root_domain in $high_trust_sender_root_domains
177+ and not headers.auth_summary.dmarc.pass
178+ )
179+ or sender.email.domain.root_domain not in $high_trust_sender_root_domains
180+ )
181+ attack_types :
182+ - " Spam"
183+ tactics_and_techniques :
184+ - " Evasion"
185+ - " Social engineering"
186+ detection_methods :
187+ - " Content analysis"
188+ - " Sender analysis"
189+ - " URL analysis"
190+ - " Whois"
191+ id : " 52b43a73-9783-5ae6-a52b-b785a9ed83ad"
192+ tags :
193+ - created_from_open_prs
194+ - rule_status_renamed
195+ - pr_author_cybher0808
196+ references :
197+ - https://github.com/sublime-security/sublime-rules/pull/4702
0 commit comments