Reconnaissance: Short generic greeting message
Detects potential reconnaissance messages with very short, generic content like 'Hi' or 'Hello' from external senders. These messages are often used to validate email addresses and test deliverability before launching larger attacks.
Sublime rule (View on GitHub)
1name: "Reconnaissance: Short generic greeting message"
2description: |
3 Detects potential reconnaissance messages with very short, generic content like 'Hi' or 'Hello' from external senders. These messages are often used to validate email addresses and test deliverability before launching larger attacks.
4type: "rule"
5severity: "medium"
6source: |
7 type.inbound
8 // detect generic greetings
9 and length(body.current_thread.text) <= 20
10 and length(subject.base) <= 15
11 // exclude messages with previous thread context (forwards/replies)
12 and length(body.previous_threads) == 0
13 and (
14 any(ml.nlu_classifier(body.current_thread.text).entities, .name == "greeting")
15 or strings.ilike(body.current_thread.text, "*hi*", "*hello*", "*hey*")
16 or length(body.current_thread.text) <= 5
17 or regex.match(body.current_thread.text, '\d+')
18 )
19 // external freemail sender
20 and sender.email.domain.root_domain in $free_email_providers
21 and sender.email.domain.root_domain not in (
22 recipients.to[0].email.domain.root_domain
23 )
24 and (
25 length(recipients.cc) == 0
26 or (
27 length(recipients.cc) > 0
28 and all(recipients.cc,
29 .email.domain.root_domain != sender.email.domain.root_domain
30 )
31 )
32 )
33 and (
34 length(recipients.bcc) == 0
35 or (
36 length(recipients.bcc) > 0
37 and all(recipients.bcc,
38 .email.domain.root_domain != sender.email.domain.root_domain
39 )
40 )
41 )
42 // no attachments or links
43 and length(attachments) == 0
44 and length(body.current_thread.links) == 0
45
46 // not where the sender and mailbox display_anames indicate this might be a personal email --> work email
47 // impersonation is covered by other core feed rules
48 and not (
49 sum([length(recipients.to), length(recipients.bcc), length(recipients.cc)]) == 1
50 // use coalesce to deal with either the sender.display_name or the mailbox element being null
51 // if either are null, the function returns false, as it cannot be true if either is null
52 and coalesce(strings.icontains(sender.display_name, mailbox.first_name),
53 false
54 )
55 and coalesce(strings.icontains(sender.display_name, mailbox.last_name), false)
56 )
57 and (
58 // auth failed (or absent) - ignore the profile
59 coalesce(headers.auth_summary.dmarc.pass, false) == false
60 or coalesce(headers.auth_summary.spf.pass, false) == false
61 // auth passed - use the profile
62 or (
63 // no benign messages
64 not profile.by_sender_email().any_messages_benign
65 and (
66 // not soliticed OR common
67 not (
68 profile.by_sender_email().solicited
69 or profile.by_sender_email().prevalence == "common"
70 )
71 // or HAS been spam_malicious
72 or profile.by_sender_email().any_messages_malicious_or_spam
73 )
74 )
75 )
76tags:
77 - "Attack surface reduction"
78attack_types:
79 - "BEC/Fraud"
80 - "Callback Phishing"
81tactics_and_techniques:
82 - "Social engineering"
83 - "Free email provider"
84detection_methods:
85 - "Content analysis"
86 - "Header analysis"
87 - "Natural Language Understanding"
88 - "Sender analysis"
89id: "c67dedab-91f5-5bbe-af81-f9895a02c065"