Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create Impersonation_vip_fake_thread_not_recip.yml #1936

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 181 additions & 0 deletions detection-rules/Impersonation_vip_fake_thread_not_recip.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
name: "VIP Impersonation: Fake Thread with VIP Author not in Recipients from a New Sender"
description: "This rule is intended to detect fake threads that are impersonating a VIP. It looks for a previous thread matching $org_vips display name and email address and checks the VIP authoring the previous thread is not a current recipient and this message is from a suspicous sender"
type: "rule"
severity: "medium"
source: |
type.inbound
and any([body.current_thread.text, body.html.display_text, body.plain.raw],
// find threaded messages with a _few_ previous messages, but not too many
3 <= sum([
strings.icount(., "from:"),
strings.icount(., "to:"),
strings.icount(., "sent:"),
strings.icount(., "date:"),
strings.icount(., "cc:"),
strings.icount(., "subject:")
]
) < 60
)
// There is a previous thread which has been authored by a VIP
and any($org_vips,
(
// without quotes around display_name
strings.icontains(coalesce(body.html.display_text, body.plain.raw),
strings.concat("From: ",
.display_name,
" <",
.email,
">"
)
)
// with single quotes around display_name
or strings.icontains(coalesce(body.html.display_text, body.plain.raw),
strings.concat("From: \'",
.display_name,
"\' <",
.email,
">"
)
)
// with quotes around display_name
or strings.icontains(coalesce(body.html.display_text, body.plain.raw),
strings.concat("From: \"",
.display_name,
"\" <",
.email,
">"
)
)
// with quotes, with mailto
or strings.icontains(coalesce(body.html.display_text, body.plain.raw),
strings.concat("From: \"",
.display_name,
"\" [mailto:",
.email,
"]"
)
)
// without quotes, with mailto
or strings.icontains(coalesce(body.html.display_text, body.plain.raw),
strings.concat("From: ",
.display_name,
" [mailto:",
.email,
"]"
)
)
// without quotes only email address
or strings.icontains(coalesce(body.html.display_text, body.plain.raw),
strings.concat("From: ", .email)
)
// with quotes only email address
or strings.icontains(coalesce(body.html.display_text, body.plain.raw),
strings.concat("From: \"", .email)
)
)
)
// and none of the recipients that authored a previous thread are in $org_vips
and not any([recipients.to, recipients.cc, recipients.bcc],
any(., // the recipient shows up as a previous sender in the thread
(
// without quotes around display_name
strings.icontains(coalesce(body.html.display_text, body.plain.raw),
strings.concat("From: ",
.display_name,
" <",
.email.email,
">"
)
)
// with single quotes around display_name
or strings.icontains(coalesce(body.html.display_text, body.plain.raw),
strings.concat("From: \'",
.display_name,
"\' <",
.email.email,
">"
)
)
// with quotes around display_name
or strings.icontains(coalesce(body.html.display_text, body.plain.raw),
strings.concat("From: \"",
.display_name,
"\" <",
.email.email,
">"
)
)
// with quotes, with mailto
or strings.icontains(coalesce(body.html.display_text, body.plain.raw),
strings.concat("From: \"",
.display_name,
"\" [mailto:",
.email.email,
"]"
)
)
// without quotes, with mailto
or strings.icontains(coalesce(body.html.display_text, body.plain.raw),
strings.concat("From: ",
.display_name,
" [mailto:",
.email.email,
"]"
)
)
// without quotes only email address
or strings.icontains(coalesce(body.html.display_text, body.plain.raw),
strings.concat("From: ", .email.email)
)
// with quotes only email address
or strings.icontains(coalesce(body.html.display_text, body.plain.raw),
strings.concat("From: \"", .email.email)
)
// without quotes only display_name
or strings.icontains(coalesce(body.html.display_text, body.plain.raw),
strings.concat("From: ", .display_name)
)
// with quotes only display_namea
or strings.icontains(coalesce(body.html.display_text, body.plain.raw),
strings.concat("From: \"", .display_name)
)
)
// and that recipeint is in the $org_vips
and any($org_vips, ..email.email == .email)
)
)
and (
profile.by_sender().prevalence in ("new", "rare")
or not profile.by_sender().solicited
or profile.by_sender().days_known < 10
)
// negate org domains unless they fail DMARC authentication
and (
(
sender.email.domain.root_domain in $org_domains
and not headers.auth_summary.dmarc.pass
)
or sender.email.domain.root_domain not in $org_domains
)

// negate highly trusted sender domains unless they fail DMARC authentication
and (
(
sender.email.domain.root_domain in $high_trust_sender_root_domains
and not headers.auth_summary.dmarc.pass
)
or sender.email.domain.root_domain not in $high_trust_sender_root_domains
)

and not profile.by_sender().any_false_positives
attack_types:
- "BEC/Fraud"
tactics_and_techniques:
- "Evasion"
- "Impersonation: VIP"
- "Social engineering"
- "Spoofing"
detection_methods:
- "Content analysis"
- "Sender analysis"
id: "36af5488-d10e-5b76-adaf-e0d0a0955aaa"
Loading