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"
to-top