Skip to content
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
83 changes: 83 additions & 0 deletions detection-rules/tax_w2_impersonation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: "BEC: Tax document request"
description: "Detects messages requesting W-2 tax documents or related tax information that exhibit authentication failures such as DMARC or SPF failures, or mismatched reply-to addresses. The rule identifies senders using common administrative local parts and filters for messages containing W-2 language combined with request entities detected through natural language processing."
type: "rule"
severity: "medium"
source: |
type.inbound
and sender.email.local_part in~ (
"contact",
"no-reply",
"noreply",
"info",
"admin"
)
and not (
sender.email.domain.domain in $org_domains
and coalesce(headers.auth_summary.dmarc.pass, false)
)

// mismatched From and Reply-to
and (
length(headers.reply_to) > 0
and all(headers.reply_to,
.email.domain.root_domain != sender.email.domain.root_domain
)
)

// W-2 Language with a request
and (
strings.contains(subject.base, 'W-2')
or strings.icontains(subject.base, 'wage')
or strings.icontains(subject.base, 'tax form')
or strings.icontains(subject.base, 'irs')
or regex.icontains(subject.base, 'w2\b')
)
// body text containing variations of "W2"
and (
(
strings.icontains(body.current_thread.text, "w2")
or regex.icontains(body.current_thread.text, 'w-2\b')
or strings.icontains(body.current_thread.text, "Ẇ-2")
or regex.icontains(body.current_thread.text, 'w-2[a-z]?\b')
or strings.icontains(body.current_thread.text, "wage statements")
)
or (
length(headers.reply_to) > 0
and all(headers.reply_to, network.whois(.email.domain).days_old <= 60)
and strings.icontains(body.current_thread.text, "w-2")
)
)
and any(ml.nlu_classifier(body.current_thread.text).entities,
.name == "request"
)
and sender.email.domain.root_domain not in (
"excel.com",
"sharepoint.com",
"sharepointonline.com",
"powerpoint.com",
"onenote.com",
"microsoft.com"
)
and not any(ml.nlu_classifier(body.current_thread.text).intents,
.name == "benign" and .confidence == "high"
)

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



attack_types:
- "BEC/Fraud"
tactics_and_techniques:
- "Social engineering"
- "Spoofing"
detection_methods:
- "Content analysis"
- "Header analysis"
- "Natural Language Understanding"
- "Sender analysis"
id: "4834a45e-6d70-5ad9-9043-024eea995e95"
Loading