Skip to content

Commit da4576a

Browse files
[Shared Samples] [PR #4380] added rule: PR# 4380 - Spam: Website errors solicitation
1 parent 6e9763d commit da4576a

1 file changed

Lines changed: 135 additions & 0 deletions

File tree

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
name: "PR# 4380 - Spam: Website errors solicitation"
2+
description: "This rule detects messages claiming to have identified errors on a website. The messages typically offer to send pricing or information upon request."
3+
type: "rule"
4+
severity: "low"
5+
source: |
6+
type.inbound
7+
and not profile.by_sender().solicited
8+
// no attachments
9+
and length(attachments) == 0
10+
// subject must contain SEO or web dev spam keywords or be short
11+
and (
12+
(
13+
// SEO or web development service keywords
14+
regex.icontains(strings.replace_confusables(subject.subject),
15+
'(?:proposal|cost|estimate|error|bug|audit|screenshot|strategy|rankings|issues|fix|website|design|review|price)'
16+
)
17+
or regex.icontains(subject.base,
18+
'[^\x{2600}-\x{27BF}\x{1F300}-\x{1F9FF}][\x{2600}-\x{27BF}\x{1F300}-\x{1F9FF}]\x{FE0F}?$'
19+
)
20+
// report and follow up keywords
21+
or (
22+
strings.icontains(strings.replace_confusables(subject.subject), "report")
23+
and regex.icontains(strings.replace_confusables(body.current_thread.text),
24+
"(?:free|send you|can i send|may i send|let me know|interested|get back to me|reply back|just reply)"
25+
)
26+
)
27+
// short subject
28+
or length(subject.base) < 5
29+
)
30+
// or a reply or forward in a thread that mentions website or screenshots
31+
or (
32+
(length(subject.base) < 5 or subject.is_reply or subject.is_forward)
33+
and any(body.previous_threads,
34+
regex.icontains(strings.replace_confusables(.text),
35+
"(?:screenshot|website)"
36+
)
37+
)
38+
)
39+
)
40+
// body structure and content patterns
41+
and (
42+
// Single thread with no links
43+
(
44+
length(body.links) == 0
45+
and length(body.previous_threads) == 0
46+
// short message between 20 and 500 chars
47+
and 20 < length(body.current_thread.text) < 500
48+
// service offering keywords
49+
and regex.icontains(strings.replace_confusables(body.current_thread.text),
50+
"(?:available|screenshot|error list|plan|quote|rank|professional|price|mistake|visibility|improvement|review|emailed.{0,10}more details)"
51+
)
52+
// generic greeting
53+
and regex.icontains(strings.replace_confusables(body.current_thread.text),
54+
'h(?:i|ello|ey)\b'
55+
)
56+
// problem or urgency keywords
57+
and regex.icontains(strings.replace_confusables(body.current_thread.text),
58+
'(?:error|report|issues|website|repair|redesign|upgrade|Google\s+.{0,15}find it|glitch)'
59+
)
60+
// website or page mention
61+
and regex.icontains(strings.replace_confusables(body.current_thread.text),
62+
"(?:site|website|page)"
63+
)
64+
and regex.icontains(strings.replace_confusables(body.current_thread.text),
65+
'(mail\.|mx|\.u)?\.?@?(aol|yahoo|hotmail|google|gmail|googlemail)\.com'
66+
)
67+
)
68+
or any(body.links, regex.icontains(.display_text, '\.?@?(hotmail)\.com'))
69+
// Single thread with unsubscribe link or $org_domains link
70+
or (
71+
length(body.links) <= 3
72+
and (
73+
// unsubscribe mailto link
74+
regex.icontains(body.html.raw, "mailto:*[++unsubscribe@]")
75+
// or link to found in org_domains
76+
or any(body.links, .href_url.domain.root_domain in~ $org_domains)
77+
)
78+
and length(body.previous_threads) == 0
79+
// short message between 20 and 500 chars
80+
and 20 < length(body.current_thread.text) < 500
81+
// service offering keywords
82+
and regex.icontains(strings.replace_confusables(body.current_thread.text),
83+
"(?:screenshot|error list|plan|quote|rank|professional|price|mistake)"
84+
)
85+
// generic greeting
86+
and regex.icontains(strings.replace_confusables(body.current_thread.text),
87+
'(?:h(?:i|ello|ey)|morning)\b'
88+
)
89+
// problem or urgency keywords
90+
and regex.icontains(strings.replace_confusables(body.current_thread.text),
91+
'(?:error|report|issues|website|repair|redesign|upgrade|Google\s+.{0,15}find it)'
92+
)
93+
// website or page mention
94+
and regex.icontains(strings.replace_confusables(body.current_thread.text),
95+
"(?:site|website|page)"
96+
)
97+
)
98+
// Multiple thread messages
99+
or (
100+
length(body.links) == 0
101+
// small thread with less than 5 messages
102+
and length(body.previous_threads) < 5
103+
// check previous messages for spam characteristics
104+
and any(body.previous_threads,
105+
// short previous messages less than 400 chars
106+
length(.text) < 400
107+
and (
108+
// generic greeting
109+
regex.icontains(strings.replace_confusables(.text),
110+
'(?:h(?:i|ello|ey)|morning)\b'
111+
)
112+
// service offering keywords
113+
and regex.icontains(strings.replace_confusables(.text),
114+
'(?:\berror(?:\s+list)?\b|screenshot|report|plan)'
115+
)
116+
// previous threads written in English
117+
and ml.nlu_classifier(.text).language == "english"
118+
)
119+
)
120+
)
121+
)
122+
tags:
123+
- "Attack surface reduction"
124+
- pr_author_cybher0808
125+
- created_from_open_prs
126+
- rule_status_renamed
127+
attack_types:
128+
- "Spam"
129+
detection_methods:
130+
- "Content analysis"
131+
- "Sender analysis"
132+
- "Natural Language Understanding"
133+
id: "5c1bac1a-407f-5ac9-81ed-800b666a7447"
134+
references:
135+
- https://github.com/sublime-security/sublime-rules/pull/4380

0 commit comments

Comments
 (0)