Reconnaissance: Large unknown recipient list

Recon messages, a form of deliverability testing, are used to validate whether a recipient address is valid or not, potentially preceding an attack.

There's a large number of recipients that are unknown to the organization, no links or attachments, and a short body and subject from an unknown sender.

Sublime rule (View on GitHub)

 1name: "Reconnaissance: Large unknown recipient list"
 2description: |
 3  Recon messages, a form of deliverability testing, are used to validate whether a recipient address is valid or not, potentially preceding an attack.
 4
 5  There's a large number of recipients that are unknown to the organization, no links or attachments, and a short body and subject from an unknown sender.  
 6type: "rule"
 7severity: "low"
 8source: |
 9  type.inbound
10  and (
11    length(recipients.to) > 10
12    and length(filter(recipients.to,
13                      .email.domain.domain not in $org_domains
14                      and .email.email not in $recipient_emails
15                      and (
16                        .email.domain.valid
17                        or strings.icontains(.display_name, "undisclosed")
18                      )
19               )
20    ) >= 10
21  )
22  and (
23    length(subject.subject) <= 10 
24    or subject.subject == body.current_thread.text
25    or (subject.is_reply and length(body.previous_threads) == 0)
26  )
27  and (
28    length(body.links) == 0
29    or length(filter(body.links,
30                     (
31                       .display_text is null
32                       and .display_url.url == sender.email.domain.root_domain
33                     )
34                     or .href_url.domain.domain == "aka.ms"
35                     or network.whois(.display_url.domain).days_old < 30
36              )
37    ) == length(body.links)
38  )
39  and (
40    length(attachments) == 0
41    or (
42      length(attachments) == 1
43      and any(attachments,
44              .file_type in ("pdf", "png", "jpg", "tif", "heif", "doc", "docx")
45              and any(file.explode(.),
46                      length(.scan.ocr.raw) < 20
47                      or length(.scan.strings.strings) == 1
48              )
49      )
50    )
51  )
52  and (
53    body.current_thread.text is null
54    or length(body.current_thread.text) < 50
55    // body length without disclaimer is shorter than 50 characters
56    or (
57      any(map(filter(ml.nlu_classifier(body.current_thread.text).entities,
58                     .name == "disclaimer"
59              ),
60              .text
61          ),
62          (length(body.current_thread.text) - length(.)) < 50
63      )
64    )
65  )
66  and profile.by_sender().prevalence != "common"
67  and not profile.by_sender().solicited
68  and not profile.by_sender().any_messages_benign
69  
70  // negate highly trusted sender domains unless they fail DMARC authentication
71  and (
72    (
73      sender.email.domain.root_domain in $high_trust_sender_root_domains
74      and not headers.auth_summary.dmarc.pass
75    )
76    or sender.email.domain.root_domain not in $high_trust_sender_root_domains
77  )  
78tags:
79  - "Attack surface reduction"
80  - "Deliverability testing"
81attack_types:
82  - "Reconnaissance"
83detection_methods:
84  - "Content analysis"
85  - "Header analysis"
86  - "Sender analysis"
87id: "24783a28-b6e2-5cca-9f6d-19c2cdfa6a9a"

Related rules

to-top