Email Spoofing
This detection identifies email spoofing attempts where adversaries manipulate email headers — particularly the FROM, Reply-To, and Display Name fields — to impersonate legitimate senders. The detection focuses on emails that fail SPF, DKIM, or DMARC authentication checks, mismatches between the envelope sender (Return-Path/MailFrom) and the header From address, and abuse of Microsoft 365 Direct Send to bypass authentication. Spoofed emails are frequently used to enable phishing, business email compromise (BEC), and impersonation attacks against high-value targets such as executives, finance teams, and third-party vendors.
What is T1672 Email Spoofing?
Email Spoofing (T1672) maps to the Defense Evasion tactic — the adversary is trying to avoid being detected in MITRE ATT&CK.
This page provides production-ready detection logic for Email Spoofing, covering the data sources and telemetry it touches: Microsoft Defender for Office 365, Microsoft Sentinel. The queries below are rated high severity at medium confidence, and ship for 7 SIEM platforms — KQL, SPL, Elastic, QRadar, Sumo, YARA-L, LogScale.
MITRE ATT&CK
- Tactic
- Defense Evasion
- Technique
- T1672 Email Spoofing
- Canonical reference
- https://attack.mitre.org/techniques/T1672/
EmailEvents
| where Timestamp > ago(1h)
| where EmailDirection in ("Inbound", "IntraOrg")
| extend AuthDetails = tostring(AuthenticationDetails)
| extend SPFResult = extract(@"spf=([a-z]+)", 1, AuthDetails)
| extend DKIMResult = extract(@"dkim=([a-z]+)", 1, AuthDetails)
| extend DMARCResult = extract(@"dmarc=([a-z]+)", 1, AuthDetails)
| where (SPFResult in ("fail", "softfail", "none") and DKIMResult in ("fail", "none") and DMARCResult in ("fail", "none", "bestguesspass"))
or (SenderFromDomain != SenderMailFromDomain and isnotempty(SenderFromDomain) and isnotempty(SenderMailFromDomain))
| extend HeaderFromDomain = tolower(SenderFromDomain)
| extend EnvelopeFromDomain = tolower(SenderMailFromDomain)
| extend DomainMismatch = iff(HeaderFromDomain != EnvelopeFromDomain, true, false)
| extend AuthFailCount = (iff(SPFResult in ("fail", "softfail"), 1, 0) + iff(DKIMResult == "fail", 1, 0) + iff(DMARCResult == "fail", 1, 0))
| where DeliveryAction != "Blocked"
| project
Timestamp,
NetworkMessageId,
SenderFromAddress,
SenderMailFromAddress,
SenderFromDomain,
SenderMailFromDomain,
RecipientEmailAddress,
Subject,
SPFResult,
DKIMResult,
DMARCResult,
DomainMismatch,
AuthFailCount,
DeliveryAction,
DeliveryLocation,
ThreatTypes,
ConfidenceLevel
| order by Timestamp desc Detects inbound and intra-org emails that fail SPF, DKIM, and DMARC authentication checks and/or exhibit a mismatch between the header From domain and the envelope sender (MailFrom/Return-Path) domain — the two primary indicators of email spoofing. Results are filtered to emails that were not blocked at the gateway, meaning they reached or could reach recipient inboxes.
Data Sources
Required Tables
False Positives
- Legitimate bulk email services (Mailchimp, SendGrid, Constant Contact) that send on behalf of a domain without proper DKIM/SPF alignment — review if SenderMailFromDomain is a known ESP subdomain
- Internal applications or multifunction printers using Microsoft 365 Direct Send with a functional mailbox From address but no DKIM signing configured
- Third-party HR, legal, or CRM platforms authorized to send on behalf of the organization that have not completed DMARC alignment setup
- Partner or vendor organizations with legitimately weak email authentication posture — correlate with known vendor domains in an allowlist
- Email forwarding chains (e.g., alumni addresses forwarding to personal email) that can cause SPF failures due to the forwarding server's IP not being in the original SPF record
Sigma rule & cross-platform mapping
The detection logic for Email Spoofing (T1672) above is provided in a vendor-neutral
form so you can deploy it on any SIEM. The same logic is shipped here as native
KQL (Microsoft Sentinel / Defender), SPL (Splunk), Elastic (Elastic Security (EQL)), QRadar (IBM QRadar (AQL)), Sumo (Sumo Logic CSE), YARA-L (Google Chronicle / SecOps), LogScale (CrowdStrike LogScale (CQL)) queries. In Sigma terms, this detection targets the
following logsource:
logsource:
product: azure Browse the community-maintained Sigma rules for this technique:
Platform-specific guides for T1672
Testing Methodology
Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1Send Spoofed Email via Python SMTP to External Relay (No Auth)
Expected signal: Email delivery logs showing From header '[email protected]' with envelope sender '[email protected]' — triggering SenderFromDomain != SenderMailFromDomain mismatch. SPF will fail since [email protected] is not authorized to send for contoso.com.
- Test 2Validate DMARC Policy Weakness on Target Domain
Expected signal: DNS query logs (if captured via Sysmon Event 22 on Windows or auditd/bind logs on Linux) showing TXT record lookups for _dmarc and _domainkey subdomains. No email telemetry generated by this test step.
- Test 3Spoofed Email via SendGrid API with Mismatched From Header (Authorized Test)
Expected signal: Email delivery to test mailbox with From header showing [email protected] but Authentication-Results showing dkim=pass (SendGrid DKIM) and spf=pass (SendGrid IP) — but DMARC will fail due to domain alignment mismatch between contoso.com (From header domain) and sendgrid.net (DKIM/SPF domain). The SenderFromDomain vs SenderMailFromDomain mismatch will be logged in EmailEvents.
Response Playbook
Triage
- Step 1: Retrieve the full email headers from the EmailEvents record using the NetworkMessageId — confirm the header From, Return-Path (MailFrom), Reply-To, and X-Originating-IP fields. Discrepancies between header From and Return-Path/Reply-To are definitive spoofing indicators.
- Step 2: Check the SPF, DKIM, and DMARC result fields. A DMARC result of 'fail' combined with SPF 'fail' and DKIM 'fail' indicates no authentication mechanism validated the sender. Note whether the DMARC policy is p=none (no enforcement) vs p=quarantine or p=reject — p=none allows spoofed mail through even with DMARC configured.
- Step 3: Determine if the spoofed domain belongs to your organization, a trusted partner, or an unrelated external entity. Internal domain spoofing (e.g., someone spoofing [email protected]) is significantly higher risk than external brand impersonation.
- Step 4: Identify the recipient(s) and their role. Executives, finance/accounts payable, HR, and IT administrators are high-value BEC targets. Check if the subject line contains urgency cues: 'wire transfer', 'invoice', 'urgent', 'password reset', 'payroll update'.
- Step 5: Search EmailEvents and EmailUrlInfo for the NetworkMessageId to determine if the email contained malicious links or attachments. Cross-reference with ThreatIntelligenceIndicator for the sending IP address.
- Step 6: Query OfficeActivity for any actions taken by the recipient after email delivery — check for email reads, forwarding rules created, or file downloads within 30 minutes of delivery.
- Step 7: Verify whether the spoofed sender domain has published SPF, DKIM, and DMARC records. Use external DNS lookup (dig/nslookup) to check TXT records. A missing or p=none DMARC policy confirms the attacker exploited a configuration weakness.
Containment
- If the email was delivered to a recipient inbox, use the Microsoft 365 Security & Compliance Center (or Purview) Content Search / Threat Explorer to perform a targeted purge of the spoofed email from all recipient mailboxes using the NetworkMessageId.
- If the recipient has already interacted with the email (clicked a link, opened an attachment), immediately trigger account security review: revoke active sessions via Entra ID (Azure AD) > Users > Revoke Sessions, reset credentials, and require MFA re-enrollment.
- Block the sending IP address and spoofed sender domain in Exchange Online Protection (EOP) tenant allow/block lists to prevent follow-up spoofed messages from the same infrastructure.
- If the spoofed domain is your own organization's domain and the attack exploited a Direct Send abuse path (printer/application relay), identify and disable the responsible internal relay configuration in the Exchange Admin Center > Mail Flow > Connectors.
- Notify the spoofed individual or brand owner if it is an external party (e.g., a vendor, government agency, or financial institution) so they can issue an internal alert to their own staff.
- Create an EOP transport rule to quarantine future inbound messages where the From header domain matches your internal domains but originates from external IPs not in your authorized send infrastructure.
Evidence Collection
- Export the full email (including raw headers) as an .eml file from the Microsoft 365 Defender portal (Threat Explorer > select message > Download email). Preserve as forensic evidence before any purge actions.
- Run the following KQL in Sentinel to collect all emails from the same sending IP within the prior 7 days: EmailEvents | where SenderIPv4 == '<observed_IP>' | project Timestamp, SenderFromAddress, RecipientEmailAddress, Subject, DeliveryAction | order by Timestamp
- Collect OfficeActivity logs for the impacted recipient covering the 1-hour window post-delivery: OfficeActivity | where UserId == '<recipient_UPN>' | where TimeGenerated between (datetime('<delivery_time>') .. datetime('<delivery_time+1h>')) | project TimeGenerated, Operation, ClientIP, ResultStatus
- Check EmailPostDeliveryEvents in Sentinel for any post-delivery actions (ZAP moves, user-reported phish): EmailPostDeliveryEvents | where NetworkMessageId == '<NetworkMessageId>' | project Timestamp, Action, ActionType, ActionResult
- Preserve DNS resolution evidence: document the SPF record (TXT lookup on sender domain), DKIM selector record (TXT lookup on _domainkey), and DMARC record (TXT lookup on _dmarc) at time of investigation — these records may change.
- Document the sending IP's PTR record, ASN, and geolocation. Check against threat intelligence sources (VirusTotal, AbuseIPDB, Talos) for reputation data.
Escalation Criteria
- ! Escalate immediately if the spoofed email impersonates a C-suite executive (CEO, CFO, CISO) and the recipient is in a financial approval role — this matches BEC Wire Transfer fraud TTPs.
- ! Escalate if the recipient clicked a link in the spoofed email and subsequent telemetry shows credential submission (AADSignInLogs showing unusual login location within 15 minutes of email delivery).
- ! Escalate if multiple recipients across different departments received the same spoofed email in a coordinated campaign — indicates organized spear-phishing rather than opportunistic spam.
- ! Escalate if the spoofed sender is a known government, law enforcement, or regulatory body — DPRK-attributed groups (TA427/Kimsuky) are documented to spoof journalists, academics, and policy institutions.
- ! Escalate if post-delivery OfficeActivity logs show the recipient created an auto-forward rule to an external address — this is a primary indicator of a compromised account following a successful spear-phish.
- ! Escalate to CISO and legal if PII, financial data, or sensitive IP may have been disclosed in a reply to the spoofed sender.
Investigation Guide
Forensic Artifacts
- >
Raw email headers (Internet Message Headers) — X-Originating-IP, Received chain, Return-Path, Reply-To, DKIM-Signature, Authentication-Results - >
Microsoft 365 Message Trace logs (Exchange Admin Center > Mail Flow > Message Trace) — preserves delivery path, connector info, and spam confidence levels - >
EmailEvents table entries (Defender for Office 365) — AuthenticationDetails JSON field contains full SPF/DKIM/DMARC verdict details - >
Exchange Online audit logs in OfficeActivity — UserAgent field for Outlook client version that opened the message - >
Recipient mailbox rule changes post-delivery — New-InboxRule or Set-InboxRule entries in OfficeActivity logs - >
Threat intelligence indicators for sending IP — correlate with ThreatIntelligenceIndicator table in Sentinel - >
DNS TXT records for the spoofed domain — SPF (v=spf1), DKIM selector (_domainkey subdomain TXT), DMARC (_dmarc subdomain TXT)
Tuning Guidance
Start by building an authorized sender inventory: enumerate all third-party services legitimately sending on behalf of your domain (CRM, HR platforms, billing, marketing ESPs) and add their IP ranges and MailFrom domains to a watchlist. Filter these from alert results. For Display Name spoofing hunts, maintain a dynamic list of executive and privileged user display names and update it when organizational structure changes. For Direct Send detection, document all authorized relay devices and their source IPs in Exchange Admin Center and filter those IPs from the hunt. Set the severity to 'medium' for DMARC-fail detections on external domains and reserve 'high/critical' for internal domain spoofing and executive display name impersonation targeting finance roles. Consider enriching alerts with the recipient's department (from Azure AD) to auto-prioritize alerts where the recipient is in Finance, IT, or HR.
Hunting Queries
Hunts for visually similar (lookalike/typosquat) domains impersonating the organization's primary domain — a stealth spoofing method that avoids direct SPF/DKIM failures by registering a new domain. Update the OrganizationDomain and LookalikeDomains variables for your environment.
// Hunt for lookalike domain spoofing — domains visually similar to your organization's domain
// Replace 'contoso.com' with your organization's primary domain
let OrganizationDomain = "contoso.com";
let LookalikeDomains = dynamic(["c0ntoso.com", "cont0so.com", "contoso-corp.com", "contos0.com", "contosо.com"]);
EmailEvents
| where Timestamp > ago(7d)
| where EmailDirection == "Inbound"
| extend SenderDomain = tolower(SenderFromDomain)
| where SenderDomain in~ (LookalikeDomains)
or (SenderDomain contains "contoso" and SenderDomain != OrganizationDomain)
| project Timestamp, SenderFromAddress, SenderDomain, RecipientEmailAddress, Subject, DeliveryAction, ThreatTypes
| order by Timestamp desc index=o365 sourcetype="o365:management:activity" Workload=Exchange
| eval sender_domain = lower(replace(coalesce('P2Sender', 'SenderAddress'), "^[^@]+@", ""))
| eval org_domain = "contoso.com"
| where sender_domain != org_domain
AND (match(sender_domain, "c[o0]nt[o0]s[o0]") OR match(sender_domain, "contoso-") OR match(sender_domain, "-contoso"))
| table _time, P2Sender, sender_domain, Recipients, Subject, DeliveryStatus
| sort -_time Hunts for display name spoofing where an attacker sets their display name to match an internal executive while using an external email address. This bypasses email authentication checks entirely since the sending domain (gmail.com, etc.) passes its own SPF/DKIM — only the displayed name is deceptive.
// Hunt for Display Name spoofing — From header display name matches internal executive but email address is external
// Common BEC tactic: 'CEO Name <[email protected]>'
let ExecutiveNames = dynamic(["CEO", "CFO", "CISO", "CTO", "Chief Executive", "Chief Financial", "Vice President", "SVP", "EVP"]);
EmailEvents
| where Timestamp > ago(7d)
| where EmailDirection == "Inbound"
| where SenderFromDomain !endswith "contoso.com" // Replace with your domain
| extend DisplayName = tostring(parse_json(SenderDisplayName))
| where ExecutiveNames has_any (DisplayName)
or DisplayName matches regex @"(?i)(ceo|cfo|ciso|cto|vp |svp |evp |chief |president|director)"
| project Timestamp, SenderFromAddress, SenderFromDomain, DisplayName, RecipientEmailAddress, Subject, DeliveryAction
| order by Timestamp desc index=o365 sourcetype="o365:management:activity" Workload=Exchange
| eval sender_domain = lower(replace(coalesce('P2Sender', 'SenderAddress'), "^[^@]+@", ""))
| eval display_name = lower(coalesce('SenderDisplayName', 'DisplayName', ""))
| where sender_domain != "contoso.com"
| where match(display_name, "(ceo|cfo|ciso|cto|chief|president|director|vice president|svp|evp)")
| table _time, SenderDisplayName, P2Sender, sender_domain, Recipients, Subject
| sort -_time Hunts specifically for Microsoft 365 Direct Send abuse where emails are submitted directly to the MX record from internal infrastructure without SMTP authentication. These messages have no envelope sender (Return-Path is empty or <>) and fail DKIM, indicating a printer, scanner, or application relay that an insider or network-resident adversary could abuse to spoof any From address.
// Hunt for Microsoft 365 Direct Send abuse — emails sent from internal non-user devices
// Direct Send allows printers/applications to send via MX record without SMTP AUTH
// Adversaries on the internal network can abuse this to spoof any From address
EmailEvents
| where Timestamp > ago(7d)
| where EmailDirection == "IntraOrg"
| where SenderIPv4 !startswith "" // Filter known authorized relay IPs
| extend AuthDetails = tostring(AuthenticationDetails)
| where AuthDetails has "dkim=none" or AuthDetails has "dkim=fail"
| where SenderFromAddress !in~ ("[email protected]", "[email protected]") // Adjust known legit senders
| where SenderMailFromAddress == "" or isempty(SenderMailFromAddress)
| project Timestamp, SenderFromAddress, SenderMailFromAddress, SenderIPv4, RecipientEmailAddress, Subject, AuthDetails
| order by Timestamp desc index=o365 sourcetype="o365:management:activity" Workload=Exchange Operation IN ("MessageDelivered", "MessageReceived")
| eval auth_details = lower(coalesce('AuthenticationDetails', ""))
| eval direction = coalesce('MessageDirection', 'Direction', "")
| where direction = "IntraOrg" OR match(direction, "(?i)intra")
| where match(auth_details, "dkim=(none|fail)")
| eval envelope_from = coalesce('ReturnPath', 'P1Sender', "")
| where len(envelope_from) = 0 OR envelope_from = "<>"
| table _time, P2Sender, envelope_from, Recipients, Subject, ClientIP, auth_details
| sort -_time Atomic Red Team Tests
Simulates an adversary sending a spoofed email from a script using Python's smtplib to an open relay or Direct Send MX endpoint. The From header is set to an executive address while the envelope sender (Return-Path) uses a different attacker-controlled address, producing the header-envelope mismatch this detection targets. Run in an authorized lab environment only.
Command
python3 -c "
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# Configure these for your test environment
SMTP_SERVER = '127.0.0.1' # Local test SMTP server (e.g., smtp4dev, mailhog)
SMTP_PORT = 25
SPOOFED_FROM = '[email protected]' # Spoofed display/header From
ENVELOPE_SENDER = '[email protected]' # Actual envelope sender
TO_ADDR = '[email protected]'
msg = MIMEMultipart()
msg['From'] = f'CEO Name <{SPOOFED_FROM}>'
msg['To'] = TO_ADDR
msg['Subject'] = 'Atomic Test - Email Spoofing T1672'
msg['Reply-To'] = '[email protected]'
msg.attach(MIMEText('This is an atomic test for T1672 Email Spoofing detection validation.', 'plain'))
with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
server.sendmail(ENVELOPE_SENDER, TO_ADDR, msg.as_string())
print('Spoofed email sent. Check mail server logs for header mismatch.')
" Cleanup
Check test SMTP server (mailhog/smtp4dev) inbox and delete the test message. No system cleanup required. Expected Telemetry
Email delivery logs showing From header '[email protected]' with envelope sender '[email protected]' — triggering SenderFromDomain != SenderMailFromDomain mismatch. SPF will fail since [email protected] is not authorized to send for contoso.com.
Expected Detection
EmailEvents alert: DomainMismatch=true, SPFResult=fail, alert severity high — SenderFromDomain 'contoso.com' vs SenderMailFromDomain 'evil.com'
Simulates an adversary performing pre-attack reconnaissance to identify domains with weak or absent DMARC policies (p=none or no record) — a prerequisite step before executing email spoofing. Attackers enumerate SPF, DKIM, and DMARC TXT records to determine if spoofing will succeed without the email being quarantined or rejected.
Command
#!/bin/bash
TARGET_DOMAIN="contoso.com" # Replace with authorized test domain
echo "=== SPF Record ==="
dig +short TXT "${TARGET_DOMAIN}" | grep spf
echo "=== DMARC Record ==="
dig +short TXT "_dmarc.${TARGET_DOMAIN}"
echo "=== DKIM Default Selector ==="
dig +short TXT "default._domainkey.${TARGET_DOMAIN}"
dig +short TXT "selector1._domainkey.${TARGET_DOMAIN}"
dig +short TXT "selector2._domainkey.${TARGET_DOMAIN}"
echo "=== MX Records (Direct Send target) ==="
dig +short MX "${TARGET_DOMAIN}"
echo "=== Policy Analysis ==="
DMARC=$(dig +short TXT "_dmarc.${TARGET_DOMAIN}" | grep -o 'p=[a-z]*')
if [ -z "$DMARC" ]; then
echo "VULNERABLE: No DMARC record found — spoofing will succeed"
elif echo "$DMARC" | grep -q 'p=none'; then
echo "WEAK: DMARC p=none — spoofing delivers despite authentication failure"
elif echo "$DMARC" | grep -q 'p=quarantine'; then
echo "MODERATE: DMARC p=quarantine — spoofed mail goes to spam"
else
echo "PROTECTED: DMARC p=reject — spoofed mail blocked"
fi Cleanup
No system changes made — DNS queries only. No cleanup required. Expected Telemetry
DNS query logs (if captured via Sysmon Event 22 on Windows or auditd/bind logs on Linux) showing TXT record lookups for _dmarc and _domainkey subdomains. No email telemetry generated by this test step.
Expected Detection
This step alone does not trigger an email detection alert. Use output to inform which domains are viable spoofing targets for follow-on atomic test steps.
Simulates an adversary using a legitimate email delivery API to send a spoofed message with an arbitrary From header. This models the scenario where an attacker has obtained a free-tier ESP account and abuses it to send bulk spoofed emails at scale, bypassing gateway IP-reputation blocks because the sending IP belongs to a reputable ESP. Requires an authorized SendGrid or equivalent test account and must only be sent to a controlled test mailbox.
Command
# Requires: SENDGRID_API_KEY environment variable set to an authorized test API key
# ONLY send to a controlled test mailbox you own
curl -s --request POST \
--url https://api.sendgrid.com/v3/mail/send \
--header "Authorization: Bearer ${SENDGRID_API_KEY}" \
--header 'Content-Type: application/json' \
--data '{
"personalizations": [{
"to": [{"email": "[email protected]"}],
"subject": "Atomic Test T1672 - ESP Spoofing"
}],
"from": {
"email": "[email protected]",
"name": "CEO Display Name"
},
"reply_to": {
"email": "[email protected]"
},
"content": [{
"type": "text/plain",
"value": "This is an authorized atomic test for T1672 detection validation. The From header is spoofed but the envelope sender is SendGrid infrastructure. Check authentication results."
}]
}'
echo "Email submitted. Check [email protected] headers for authentication results." Cleanup
Delete the test email from the test-mailbox. Revoke the test API key from the SendGrid dashboard after testing. Expected Telemetry
Email delivery to test mailbox with From header showing [email protected] but Authentication-Results showing dkim=pass (SendGrid DKIM) and spf=pass (SendGrid IP) — but DMARC will fail due to domain alignment mismatch between contoso.com (From header domain) and sendgrid.net (DKIM/SPF domain). The SenderFromDomain vs SenderMailFromDomain mismatch will be logged in EmailEvents.
Expected Detection
EmailEvents alert: DMARCResult=fail with domain alignment mismatch — From domain 'contoso.com' does not align with authenticated sending domain. Demonstrates why DMARC p=reject is required to block ESP-based spoofing.