VIP Impersonation: VIP handoff with fake forwarded invoice thread
Flags inbound messages that fabricate a forwarded thread to impersonate a VIP and redirect payment on a fake past-due invoice. The oldest thread segment shows a forward addressed to the VIP, immediately preceded by a message purportedly from that same VIP containing a mailto link pointing to an attacker-controlled address. The live message routes to that mailto address instead of the VIP's legitimate address, which has been dropped from the recipient list, while only a single organizational recipient remains. This pattern is consistent with invoice or overdue-account lures that exploit a hijacked thread to trick a target into paying a fraudulent account.
Sublime rule (View on GitHub)
1name: "VIP Impersonation: VIP handoff with fake forwarded invoice thread"
2description: "Flags inbound messages that fabricate a forwarded thread to impersonate a VIP and redirect payment on a fake past-due invoice. The oldest thread segment shows a forward addressed to the VIP, immediately preceded by a message purportedly from that same VIP containing a mailto link pointing to an attacker-controlled address. The live message routes to that mailto address instead of the VIP's legitimate address, which has been dropped from the recipient list, while only a single organizational recipient remains. This pattern is consistent with invoice or overdue-account lures that exploit a hijacked thread to trick a target into paying a fraudulent account."
3type: "rule"
4severity: "high"
5source: |
6 type.inbound
7 and length(body.previous_threads) > 1
8
9 // the oldest segment is a forward and has a single recipient which is the VIP
10 and length(body.previous_threads[length(body.previous_threads) - 1].recipients.to
11 ) == 1
12 // the segment is a forward
13 // handle where there is no subject
14 and coalesce(body.previous_threads[length(body.previous_threads) - 1].subject.is_forward,
15 false
16 )
17 and any($org_vips,
18 // oldest thread (len-1) forward is TO the VIP
19 body.previous_threads[length(body.previous_threads) - 1].recipients.to[0].display_name =~ .display_name
20 // next oldest thread (len-2) is FROM the same VIP;
21 and body.previous_threads[length(body.previous_threads) - 2].sender.display_name =~ .display_name
22 )
23 // the rcpt email format of the oldest thread matches the sender email format of the next oldest thread
24 and body.previous_threads[length(body.previous_threads) - 1].recipients.to[0].email.email =~ body.previous_threads[length(body.previous_threads
25 ) - 2].sender.email.email
26
27 // the message authored by the "VIP" links to an email (parsed mailto:) that the live message now routes to
28 // this is the "VIP handoff" step, the fake VIP mentions the email address, which becomes the "victim", the actor sends it to that address and includes the faked emails emails in the chain.
29 and any(body.previous_threads[length(body.previous_threads) - 2].links,
30 .href_url.url != ""
31 and .href_url.scheme == "mailto"
32 and any(flatten([recipients.to, recipients.cc, recipients.bcc]),
33 strings.icontains(.email.email, ..href_url.url)
34 )
35 )
36
37 // the VIP's authoritative list-email is NOT among the live recipients (dropped)
38 and not any(flatten([recipients.to, recipients.cc, recipients.bcc]),
39 any($org_vips,
40 .email != ""
41 and strings.icontains(..email.email, .email)
42 and body.previous_threads[length(body.previous_threads) - 2].sender.display_name =~ .display_name
43 )
44 )
45 // we only have a single org_domain recipient
46 and length(filter(flatten([recipients.to, recipients.cc, recipients.bcc]),
47 .email.domain.root_domain in $org_domains
48 )
49 ) == 1
50 // this message is not from the org itself
51 and not (
52 sender.email.domain.root_domain in $org_domains
53 and coalesce(headers.auth_summary.dmarc.pass, false)
54 )
55attack_types:
56 - "BEC/Fraud"
57tactics_and_techniques:
58 - "Impersonation: VIP"
59 - "Social engineering"
60 - "Spoofing"
61 - "Out of band pivot"
62detection_methods:
63 - "Header analysis"
64 - "Content analysis"
65 - "URL analysis"
66 - "Sender analysis"
67id: "f8f7881e-04d6-5016-811c-20c565f43e4a"