VIP impersonation: Fake thread with name-in-brackets header artifact
Detects inbound messages containing a fabricated prior thread in which a known VIP appears as the author, but the quoted header lists the VIP's name inside angle brackets where an email address belongs (e.g., "Jane Doe
Sublime rule (View on GitHub)
1name: "VIP impersonation: Fake thread with name-in-brackets header artifact"
2description: "Detects inbound messages containing a fabricated prior thread in which a known VIP appears as the author, but the quoted header lists the VIP's name inside angle brackets where an email address belongs (e.g., \"Jane Doe<Jane Doe>\" or \"Jane Doe < Jane Doe >\"), or the organization's brand name in place of an address. Legitimate mail clients write a real address between the brackets. The rule also requires that the VIP's real address is absent from the live message, which is consistent with an actor who fabricated the thread and dropped the executive before sending the fraudulent request."
3type: "rule"
4severity: "high"
5source: |
6 type.inbound
7 and any(map(filter(body.previous_threads,
8 .sender.display_name != ""
9 and any($org_vips,
10 strings.icontains(..sender.display_name,
11 .display_name
12 )
13 )
14 // a To:/From: line whose <...> repeats the display name ("Jane Doe<Jane Doe>")
15 and any(regex.extract(.preamble,
16 '(?i)(?:to|from)\s*:\s*(?P<dn>[^<\n]*[a-z][^<\n]*?)\s*<\s*(?P<inner>[^@<>\n/]*[a-z][^@<>\n/]*?)\s*>'
17 ),
18 strings.icontains(.named_groups["dn"],
19 .named_groups["inner"]
20 )
21 or strings.icontains(.named_groups["inner"],
22 .named_groups["dn"]
23 )
24 // or the brackets hold the org's brand instead of an address ("Jane Doe <Acme>");
25 // exact match, since substring would let short brands hit any word
26 or .named_groups["inner"] in~ $org_brand_names
27 )
28 ),
29 .sender.display_name
30 ),
31 // that VIP's real address is absent from the live recipients and sender
32 not any(flatten([recipients.to, recipients.cc, recipients.bcc]),
33 any($org_vips,
34 strings.icontains(..., .display_name)
35 and .email != ""
36 and strings.icontains(..email.email, .email)
37 )
38 )
39 and not any($org_vips,
40 strings.icontains(.., .display_name)
41 and .email != ""
42 and strings.icontains(sender.email.email, .email)
43 )
44 )
45 and not (
46 sender.email.domain.root_domain in $org_domains
47 and coalesce(headers.auth_summary.dmarc.pass, false)
48 )
49attack_types:
50 - "BEC/Fraud"
51tactics_and_techniques:
52 - "Impersonation: VIP"
53 - "Social engineering"
54 - "Spoofing"
55detection_methods:
56 - "Content analysis"
57 - "Header analysis"
58 - "Sender analysis"
59id: "815a49c5-173f-5b0d-868d-37a9a258f645"