August 26, 2026
Email Header Analysis: The Complete Digital Forensics Guide (2026)
How to read any email like an investigator, prove who really sent it, and never get fooled by a lookalike again.
By Daniel Absi
103 min read
TL;DR: The 60-Second Version
If you only read one section, read this one.
- The visible "From" name is decoration. Nothing in the original email standard forces it to be true. A message can say
security@paypal.comand have been sent from a laptop in a basement. - The truth lives in the headers, specifically the
Received:chain, theReturn-Path:, and theAuthentication-Results:line. - Read the
Received:chain from the bottom up. The bottom is the origin. The top is your own mailbox. - Count the hops. Four to six is normal. Eight or more deserves an explanation. Gaps of several minutes between hops are a red flag.
- Check the three authentication verdicts: SPF, DKIM, DMARC. All three must pass and be aligned with the domain in the visible From address.
- Never open a suspicious message in a normal client. A 1x1 transparent pixel tells the sender you exist, your IP, your device, and the time you read it.
- Save it as a
.emlfile before you touch anything. That is your evidence. - Investigate three things in parallel: the sending IP, the sending domain, and the sending address. Reputation, age, and validity.
- Look at the characters, not the words.
rnlooks likem. CapitalOlooks like zero.paypaI.comwith a capital i is notpaypal.com. - A perfect authentication pass does not mean the email is safe. It means the sender proved they control that domain. Criminals buy domains too.
Who This Guide Is For
- Security analysts and SOC teams who triage reported phishing all day.
- Fraud and risk teams at banks, marketplaces, and payment processors.
- IT admins who own a mail server and get asked "is this real?" ten times a week.
- Journalists, lawyers, and investigators who need to authenticate an email as evidence.
- Small business owners who just got an invoice that felt slightly wrong.
- Anyone who has ever hovered over a link and hesitated.
You do not need a security background. You need patience and a willingness to read a wall of text carefully. By the end of this article you will be able to take any email, extract its headers, and produce a defensible verdict on where it came from.
Table of Contents
- The 2026 numbers that should worry you
- What an email actually is
- SMTP and ESMTP: the conversation behind every message
- Port 25 and why it is the weakest link
- How to get the raw headers out of any mail client
- The .eml file format explained
- Reading a header field by field
- The Received chain: hop counting and timing analysis
- SPF, DKIM, DMARC, and ARC
- Transport security: STARTTLS, MTA-STS, TLS-RPT, DANE and TLSA
- BIMI, VMC, CMC, S/MIME and PGP
- How email spoofing actually works
- Homoglyphs, typosquats and the rn/m problem
- Domain intelligence: WHOIS, age, tasting and kiting
- IP intelligence with IPQualityScore
- Address validation: disposable, catch-all, role-based
- Why you should never open a suspicious email
- Body and payload forensics
- The investigator's toolchain
- A complete worked case study
- The scoring model and checklist
- Chain of custody and reporting
- Building defenses that actually hold
- Frequently asked questions
- Glossary
- Sources
1. The 2026 Numbers That Should Worry You
Email fraud is not a nuisance problem. It is one of the largest transfers of wealth from businesses to criminals happening right now, and the numbers keep climbing.
Here is the current picture, drawn from primary sources.
Losses
- The FBI's Internet Crime Complaint Center logged 1,008,597 complaints and $20.877 billion in reported losses in 2025, a 26 percent year-over-year increase and the first time complaints crossed one million. (FBI IC3 2025 Annual Report)
- Business Email Compromise alone accounted for $3,046,598,558 from just 24,768 complaints. That is roughly $123,000 per incident, making BEC the second-costliest cybercrime category behind investment fraud.
- Phishing and spoofing generated 191,561 complaints, the single most-reported crime type, with $215.8 million in direct losses.
- Add BEC, phishing/spoofing, and government impersonation together and you get over $4 billion in losses tied to crimes that exploit trust in email, roughly 19 percent of all IC3-reported losses.
- The 2025 report featured a dedicated artificial intelligence section for the first time: 22,364 AI-related complaints and $893,346,472 in losses.
- Roughly 85 percent of reported losses came from cyber-enabled fraud that manipulates people rather than exploiting an unpatched server.
Volume
- The Anti-Phishing Working Group observed 971,181 phishing attacks in Q1 2026, up 13.8 percent from 853,244 in Q4 2025. (APWG Phishing Activity Trends Report, Q1 2026)
- 766 unique brands were impersonated in that single quarter.
- The telecom sector became the most-attacked category at 33 percent of all attacks, up from 5.9 percent in Q3 2025. Telecoms bundle ISP service, branded email hosting, and phone service, which gives an attacker multiple pivots from one account takeover.
- Domain registrars NameSilo and NameCheap remained the registrars most often used by BEC scammers.
- Across social platforms, impersonation content made up 43.8 percent of observed threats and scams another 27.1 percent.
Defenses
- Global DMARC adoption reached 937,931 domains (52.1 percent of the top 1.8 million by traffic) in early 2026, up from 47.7 percent in 2025. (EasyDMARC 2026 DMARC Adoption Report)
- But more than half of those domains sit at
p=none, the monitoring-only policy that blocks precisely nothing. - In the United States, 95.8 percent of analyzed domains publish a DMARC record but only 49.0 percent enforce
p=reject, and MTA-STS adoption sits at 1.7 percent with DNSSEC at 18.0 percent. (PowerDMARC United States DMARC & MTA-STS Adoption Report 2026) - Fortune 500 companies reached 95 percent DMARC adoption with over 80 percent at enforcement. The Inc. 5000 lag badly, with more than half still at monitoring only.
- Verizon's 2026 Data Breach Investigations Report puts phishing at 16 percent of breach initial access, second only to vulnerability exploitation at 31 percent.
The takeaway: the industry has built excellent authentication standards and then largely failed to turn them on. That gap is exactly where header analysis earns its keep.
2. What an Email Actually Is
Most people picture an email as a single object, like a letter. It is closer to a parcel with three separate layers that do not have to agree with each other. This disagreement is the root of nearly every email fraud technique in existence.
Layer 1: The envelope
The envelope is what mail servers use to route the message. It exists only during the SMTP conversation and is never displayed to you. It contains two things:
MAIL FROM:the envelope sender, also called the return path or bounce address. Where delivery failures go.RCPT TO:the envelope recipient. Where the message is actually delivered.
Layer 2: The header
The header is a block of Name: value lines at the top of the message. This is what your mail client reads to build the display. It includes From:, To:, Subject:, Date:, Message-ID:, the whole Received: chain, and dozens of optional fields.
Layer 3: The body
The text, the HTML, the images, the attachments. Everything below the first blank line after the headers.
The critical insight
The envelope sender and the header From: are two different fields, written at two different times, by two different parts of the system, and nothing in the base protocol requires them to match.
This is not a bug that someone forgot to fix. When SMTP was standardized in 1982, the internet was a few hundred trusted academic and government hosts. Authentication was not a design goal. Every anti-spoofing standard you will read about later in this article (SPF, DKIM, DMARC) is a bolt-on added decades afterward to patch this original openness.
Think of it like postal mail. The address on the outside of the envelope is the envelope sender. The "Sincerely, Jane" at the bottom of the letter inside is the header From. You can write anything you want inside the letter. The post office does not check.
MIME: how the body got complicated
The original standard assumed plain 7-bit ASCII text. MIME (Multipurpose Internet Mail Extensions) added everything else: attachments, HTML, non-English character sets, inline images.
MIME works by splitting the body into parts separated by a boundary string, with each part declaring its own Content-Type and Content-Transfer-Encoding. A typical phishing email is multipart/alternative containing a plain text part (often deliberately bland) and an HTML part (containing the actual attack).
For forensics, MIME matters because:
- The plain text and HTML parts can say completely different things. Some filters only scan one.
- Base64 encoding hides content from simple keyword scanners. Everything in a base64 part must be decoded before you can read it.
- Boundary strings are often generated by the sending library and can fingerprint the tool used to build the message.
- Attachments carry their own filename, MIME type, and encoding, all three of which can lie about each other.
3. SMTP and ESMTP: The Conversation Behind Every Message
SMTP stands for Simple Mail Transfer Protocol. It is a text-based, line-oriented, request-response protocol defined in RFC 5321. It is simple enough that a human can speak it by hand over a terminal, which is exactly what makes it so easy to abuse.
The basic exchange
A sending server connects to a receiving server and they talk. The client sends commands, the server replies with a three-digit code and a message. Here is what a plain SMTP session looks like, with C: for client and S: for server:
S: 220 mail.example.com ESMTP Postfix
C: HELO client.example.net
S: 250 mail.example.com
C: MAIL FROM:<sender@example.net>
S: 250 2.1.0 Ok
C: RCPT TO:<recipient@example.com>
S: 250 2.1.5 Ok
C: DATA
S: 354 End data with <CR><LF>.<CR><LF>
C: From: "Someone Else" <someone@totally-different.com>
C: To: recipient@example.com
C: Subject: Hello
C:
C: This is the body.
C: .
S: 250 2.0.0 Ok: queued as 4B2K1P3xyz
C: QUIT
S: 221 2.0.0 ByeS: 220 mail.example.com ESMTP Postfix
C: HELO client.example.net
S: 250 mail.example.com
C: MAIL FROM:<sender@example.net>
S: 250 2.1.0 Ok
C: RCPT TO:<recipient@example.com>
S: 250 2.1.5 Ok
C: DATA
S: 354 End data with <CR><LF>.<CR><LF>
C: From: "Someone Else" <someone@totally-different.com>
C: To: recipient@example.com
C: Subject: Hello
C:
C: This is the body.
C: .
S: 250 2.0.0 Ok: queued as 4B2K1P3xyz
C: QUIT
S: 221 2.0.0 ByeRead that carefully. The envelope sender declared at MAIL FROM: is sender@example.net. The From: header written inside the DATA block is someone@totally-different.com. The server accepted both without complaint. That single fact is the entire foundation of email spoofing.
The response codes you need to know
CodeMeaningWhat it tells an investigator220Service readyBanner. Often leaks the MTA software and version.250Requested action OKAccepted.251User not local, will forwardRelay behavior.354Start mail inputServer is ready for the DATA block.421Service not available, closingOften rate limiting or greylisting.450Mailbox unavailable, try laterTemporary. Classic greylisting response.451Local error in processingTemporary failure, often filtering.452Insufficient storageTemporary.550Mailbox unavailableThe address does not exist. Key signal for validation.551User not localRelay refused.552Storage allocation exceededMailbox full.553Mailbox name not allowedOften policy rejection of the sender.554Transaction failedGeneric hard reject, often reputation-based.
Forensic note: the difference between a 550 and a 250 on RCPT TO: is how mailbox verification works. A server that returns 250 for every address regardless of whether it exists is a catch-all, and catch-alls are why email validation returns "unknown" rather than "valid" for many corporate domains.
ESMTP: the extended version
ESMTP (Extended SMTP, RFC 1869 and successors) is what everything actually uses now. The client opens with EHLO instead of HELO, and the server responds with a list of extensions it supports:
C: EHLO client.example.net
S: 250-mail.example.com
S: 250-PIPELINING
S: 250-SIZE 35882577
S: 250-STARTTLS
S: 250-AUTH LOGIN PLAIN
S: 250-8BITMIME
S: 250-DSN
S: 250-CHUNKING
S: 250 SMTPUTF8C: EHLO client.example.net
S: 250-mail.example.com
S: 250-PIPELINING
S: 250-SIZE 35882577
S: 250-STARTTLS
S: 250-AUTH LOGIN PLAIN
S: 250-8BITMIME
S: 250-DSN
S: 250-CHUNKING
S: 250 SMTPUTF8Each of those lines matters to an investigator:
- PIPELINING: the client can send multiple commands without waiting for each reply. Speeds things up, and is a precondition for certain smuggling attacks.
- SIZE: maximum message size the server accepts.
- STARTTLS: the server can upgrade the plaintext connection to encrypted. Note the word can, not must.
- AUTH: authentication mechanisms offered.
AUTH LOGIN PLAINover an unencrypted connection means credentials cross the wire in base64, which is encoding, not encryption. - 8BITMIME: raw 8-bit content allowed in the body.
- DSN: Delivery Status Notification support.
- CHUNKING: enables the
BDATcommand, which sends a byte count instead of relying on a terminator sequence. This turns out to matter enormously for SMTP smuggling, covered below. - SMTPUTF8: internationalized email addresses, which opens the door to Unicode lookalike addresses.
Why you should care about the banner
The 220 greeting banner and the EHLO response together fingerprint the receiving infrastructure. When you are investigating a domain that claims to be a legitimate business, connecting to its published MX host and reading the banner tells you what they are actually running. A Fortune 500 supplier running an unpatched, decade-old MTA on a bare IP with no TLS is a supplier whose email you should not trust, because someone else has probably already noticed.
4. Port 25 and Why It Is the Weakest Link
Port 25 is the original SMTP port. It was assigned in 1982 and it still carries essentially all server-to-server mail on the internet. It is also, structurally, the softest part of the entire email system.
The four ports and what each one is for
PortNamePurposeEncryptionAuthentication25SMTPServer to server relay (MTA to MTA)Optional via STARTTLSUsually none587SubmissionClient to server (your mail app sending)STARTTLS expectedRequired465SMTPS / SubmissionsClient to server, implicit TLSMandatory from the first byteRequired2525Unofficial alternateWorkaround when ISPs block 25DependsDepends
The distinction that matters: 587 and 465 are for submission, where the sender proves who they are with a username and password. Port 25 is for relay, where an anonymous server on the internet hands you a message for one of your users.
You cannot require authentication on port 25. If you did, no one on the internet could send you mail, because the sending server has no account with you. This is the fundamental design constraint, and it is not fixable without replacing the protocol.
Weakness 1: Anonymous by design
Any host on the internet can connect to your port 25 and start a conversation. It does not need credentials. It does not need an invitation. The only defenses available are reputation-based (is this IP on a blocklist?), rate-based (is this IP sending too fast?), and content-based (does this message look like spam?). All three are probabilistic. None of them are identity.
Weakness 2: STARTTLS is opportunistic, not mandatory
STARTTLS begins as an unencrypted connection and then upgrades. That means the negotiation itself happens in cleartext, and an attacker positioned between two mail servers can simply delete the 250-STARTTLS line from the server's capability list. The sending server sees no TLS offer, concludes the receiver does not support encryption, and sends the entire message in plaintext. This is called a STARTTLS stripping attack or a downgrade attack.
The sending server almost never notices, because the default behavior of nearly every MTA is "encrypt if possible, deliver anyway if not." Delivery is prioritized over confidentiality. MTA-STS and DANE exist specifically to close this hole, and as noted above, MTA-STS adoption sits around 1.7 percent of US domains.
Weakness 3: Open relays
An open relay is a mail server that accepts mail from anyone and delivers it to anyone. In the 1990s this was the default configuration. Today it is a catastrophic misconfiguration, but they still exist, usually on:
- Forgotten development servers
- Legacy appliances (printers, scanners, building management, industrial control panels)
- Misconfigured cloud instances spun up from an old image
- Internal SMTP relays that were never meant to be reachable from the internet but ended up behind a permissive firewall rule
An open relay lets an attacker send mail that appears to originate from a legitimate corporate IP, inheriting whatever reputation that IP has earned.
Weakness 4: Open resolvers and unauthenticated internal relays
Even when a server is not a fully open relay, many organizations run an internal relay that accepts anything from an RFC 1918 private address range with no authentication, on the theory that "internal traffic is trusted." Anyone who gets a foothold on any device in the network, including an IoT thermostat, can then send mail as anyone in the company, from inside, passing every SPF check because the mail genuinely left the corporate mail server.
Weakness 5: SMTP smuggling
This is the most important protocol-level attack of the past few years, and it is worth understanding properly.
RFC 5321 says the end of the message data is marked by the exact sequence <CR><LF>.<CR><LF>. That is: carriage return, line feed, a single period, carriage return, line feed.
The problem is that different mail servers historically accepted variations, such as <LF>.<LF> or <LF>.<CR><LF>, to be forgiving of badly written mail clients. When the outbound server and the inbound server disagree about what ends a message, an attacker can craft a body containing a fake terminator followed by fresh SMTP commands. The outbound server sees one message. The inbound server sees two, and the second one has whatever MAIL FROM: the attacker chose.
The devastating part: the second, smuggled message is delivered by the legitimate outbound server from the legitimate outbound IP, so it passes SPF, and often DKIM and DMARC too.
Timo Longin and SEC Consult published this in December 2023. It affected Postfix (CVE-2023–51764), Sendmail (CVE-2023–51765), and Exim (CVE-2023–51766), plus configurations of Microsoft Exchange Online, GMX, and Cisco Secure Email Gateway. At the time, Shodan scans indicated more than 1.5 million publicly accessible SMTP servers running Postfix or Sendmail. Follow-up research in 2024, including work by PayPal researchers, chained related flaws across hosting providers and demonstrated spoofing across more than 20 million domains.
Related CVEs from 2024, CVE-2024–7208 and CVE-2024–7209, cover multi-tenant hosted SMTP services where shared SPF records and inadequate sender verification let one authenticated tenant spoof another tenant's domain. CERT/CC tracked these under VU#244112.
Why this matters for header analysis: SMTP smuggling produces messages where the authentication results are genuinely clean but the message is genuinely forged. The tells are elsewhere: an odd Received: chain, a mismatch between the smuggled MAIL FROM: and normal traffic patterns for that domain, unusual line endings if you have the raw bytes, and duplicate or malformed headers.
Weakness 6: Address and command verification leaks
The VRFY and EXPN commands were designed to verify addresses and expand mailing lists. Almost every modern server disables them, because they hand attackers a free user enumeration tool. But RCPT TO: still leaks the same information: a 250 means the mailbox exists, a 550 means it does not. This is how mailbox verification services work, and how attackers build target lists.
What nmap and Shodan reveal, and why "reputable" companies fail
Here is a pattern anyone who has done reconnaissance work will recognize. A business looks completely legitimate. Professional website, real address, real people on LinkedIn, real invoices. Then you scan their published mail infrastructure and find:
- Port 25 open with an MTA banner disclosing a version that has known CVEs
- No STARTTLS offered at all, or STARTTLS offered with an expired or self-signed certificate
- Open relay behavior on a secondary MX host that nobody remembers deploying
- Ports 110 (POP3) and 143 (IMAP) open without TLS, so mailbox passwords cross the internet in cleartext
- Webmail on port 80 with no redirect to HTTPS
- A management interface exposed on a high port with default credentials
- Legacy protocol support still enabled for a client who stopped being a client in 2019
A basic service and version scan against a mail host looks like this:
nmap -sV -p 25,110,143,465,587,993,995 mail.example.comnmap -sV -p 25,110,143,465,587,993,995 mail.example.comAdding script scanning checks for the classic misconfigurations:
nmap -p 25 --script smtp-commands,smtp-open-relay,smtp-enum-users mail.example.comnmap -p 25 --script smtp-commands,smtp-open-relay,smtp-enum-users mail.example.comThis is standard defensive practice against your own infrastructure, and it is what your auditor will run. Scanning systems you do not own or have written permission to test is unauthorized access in most jurisdictions. Run it against your own domain, run it against domains you are contractually engaged to test, and nothing else.
The reason this matters to fraud investigation: a large share of BEC does not involve spoofing at all. The attacker compromises a real mailbox at a real supplier, reads six months of genuine invoice threads, and then replies to an existing conversation with new bank details. Every authentication check passes perfectly, because the email is genuinely from that supplier. The supplier looks legitimate because it is legitimate. It was just running an SMTP service that had been exposed and unpatched for years.
When you see a supplier's invoice change bank details, the correct response is never "check the SPF record." It is: call the number you already had on file, not the number in the email.
5. How to Get the Raw Headers Out of Any Mail Client
You cannot analyze what you cannot see. Every client hides headers by default because they are ugly. Here is how to expose them.
Gmail (web)
- Open the message.
- Click the three vertical dots at the top right of the message pane (not the ones at the top of the page).
- Choose Show original.
- A new tab opens with the full raw source, plus a summary panel showing SPF, DKIM, and DMARC verdicts.
- Click Download Original to save a
.emlfile, or Copy to clipboard for the raw text.
Gmail's summary panel is genuinely useful, but do not stop there. It shows the verdict, not the reasoning.
Outlook on the web (Microsoft 365 / Outlook.com)
- Open the message.
- Click the three dots in the message toolbar.
- Choose View then View message details, or in some versions View message source.
- Copy the text out.
Note that the web client sometimes only exposes headers, not the full body source. For the complete .eml you may need the desktop client.
Outlook desktop (Windows)
- Double-click the message so it opens in its own window (this step is required, it does not work from the reading pane).
- File then Properties.
- The headers appear in the Internet headers box at the bottom. Select all and copy.
To export the whole message, drag it from the message list onto your desktop. Outlook will save a .msg file, which is a Microsoft-proprietary compound format, not a .eml. See the next section for the difference.
Apple Mail (macOS)
- View then Message then All Headers, or press Command + Shift + H.
- To save the whole thing: File then Save As, and choose Raw Message Source as the format.
Apple Mail (iOS)
You cannot view full headers on iOS. Forward the message as an attachment to a desktop account, or use the web interface for your provider.
Thunderbird
- View then Headers then All, or press Command/Ctrl + U for the full source.
- To export: right-click the message, Save As, choose
.eml.
Thunderbird is the best free desktop client for this work because it saves clean .eml files by default and lets you view source without rendering.
Proton Mail
- Click the three dots on the message.
- Choose View headers or View message source.
- Export saves the
.eml.
Yahoo Mail
- Open the message.
- Click the three dots.
- Choose View raw message.
Zoho Mail
- Open the message.
- Click the three dots in the message header.
- Choose Show Original.
Command line (IMAP)
For bulk work, fetch messages directly. Tools like mbsync, offlineimap, or a short IMAP script give you .eml files without any client rendering anything. This is the safest approach when you expect the message to be hostile, because nothing ever renders.
The golden rule of extraction
Extract the headers before you do anything else, and save the full .eml alongside them. If you forward the message to a colleague, your mail server rewrites the headers and adds new Received: lines. The original chain is destroyed. Always forward as an attachment, or share the .eml file directly.
6. The .eml File Format Explained
A .eml file is the single most important artifact in email forensics. Understanding it takes about five minutes and pays off forever.
What it is
A .eml file is a plain text file containing exactly one email message in the format defined by RFC 5322 (originally RFC 822, then RFC 2822). That is it. There is no proprietary container, no compression, no binary structure. If you open a .eml in Notepad or cat it in a terminal, you will see the whole thing.
The structure is:
Header-Name: header value
Another-Header: another value
Subject: Example
Body starts here after exactly one blank line.Header-Name: header value
Another-Header: another value
Subject: Example
Body starts here after exactly one blank line.Headers, then one blank line, then body. The blank line is the delimiter and it is mandatory.
Why it is the forensic standard
- It is byte-for-byte the message as it arrived. Nothing is normalized, nothing is stripped.
- It preserves the full
Received:chain, including hops that a forwarded copy would lose. - It preserves DKIM signatures, which are cryptographic hashes over specific header fields and the body. Any modification breaks the signature, which means an intact signature is proof the message has not been altered. This makes
.emlfiles self-authenticating evidence in a way that a screenshot never can be. - It is universally readable. Every mail client, every analysis tool, every scripting language with a standard library can parse it.
- It hashes cleanly. Compute a SHA-256 of the file and you have an integrity anchor for your chain of custody.
Header folding and unfolding
Long header values are wrapped across multiple lines, with continuation lines starting with whitespace. A Received: header is almost always folded:
Received: from mail.example.net (mail.example.net [203.0.113.45])
by mx.recipient.com (Postfix) with ESMTPS id 4B2K1P3xyz
for <victim@recipient.com>; Tue, 18 Aug 2026 09:14:22 +0000 (UTC)Received: from mail.example.net (mail.example.net [203.0.113.45])
by mx.recipient.com (Postfix) with ESMTPS id 4B2K1P3xyz
for <victim@recipient.com>; Tue, 18 Aug 2026 09:14:22 +0000 (UTC)Those three lines are one header. When parsing, you unfold by joining any line that starts with a space or tab to the previous line. Miss this and your parser will produce nonsense.
Encoded-word headers
Non-ASCII characters in headers are encoded per RFC 2047, using a form like:
Subject: =?UTF-8?B?VXJnZW50OiBJbnZvaWNlIE92ZXJkdWU=?=Subject: =?UTF-8?B?VXJnZW50OiBJbnZvaWNlIE92ZXJkdWU=?=The structure is =?charset?encoding?encoded-text?= where encoding is B for base64 or Q for quoted-printable. That example decodes to "Urgent: Invoice Overdue."
This is an attack surface. Attackers use encoded words to hide keywords from filters, to smuggle right-to-left override characters that reverse how a filename displays, and to embed Unicode lookalikes. Always decode encoded words before you read a subject line or a display name.
.eml versus .msg versus .mbox versus .pst
FormatOriginContainsForensic quality**.emlRFC 5322 standardOne message, plain textExcellent. The reference format..msgMicrosoft proprietaryOne message plus Outlook-specific properties, OLE compound binaryUsable but requires conversion. Can contain extra metadata that .eml does not..mboxUnix standardMany messages concatenated, separated by From linesGood for bulk. Watch for From line escaping corrupting bodies..pst / .ostMicrosoft proprietaryAn entire mailbox, database formatRich but complex. Needs specialized tooling..emlx**Apple MailOne message plus a plist of Apple metadataFine, strip the trailing plist to get a valid .eml.
Converting .msg to .eml loses Outlook-specific properties, so in a legal context, preserve the original .msg as well.
Handling .eml files safely
A .eml file is inert text. Opening it in a text editor is completely safe. Opening it by double-clicking is not, because your operating system will hand it to your mail client, which will render the HTML, load remote images, and fire every tracking pixel in it.
Safe handling:
- Save the file with a
.txtextension, or open it from within a text editor rather than from the file manager. - Or open it in a terminal:
head -100 message.emlshows you the headers without touching the body. - Or use a purpose-built analyzer that parses without rendering.
- If you must render, do it in an isolated virtual machine with no network access.
Quick command line triage
Once you have a .eml, these one-liners cover most of what you need before you open any tool:
# Show just the headers (everything before the first blank line)
sed '/^$/q' message.eml
# Extract the Received chain in delivery order (bottom-up)
grep -i '^Received:' -A2 message.eml | tac
# Pull the authentication verdicts
grep -iE '^(Authentication-Results|Received-SPF|ARC-Authentication-Results):' message.eml
# Find every URL in the message
grep -oE 'https?://[^"'"'"' <>]+' message.eml | sort -u
# Hash the evidence
sha256sum message.eml# Show just the headers (everything before the first blank line)
sed '/^$/q' message.eml
# Extract the Received chain in delivery order (bottom-up)
grep -i '^Received:' -A2 message.eml | tac
# Pull the authentication verdicts
grep -iE '^(Authentication-Results|Received-SPF|ARC-Authentication-Results):' message.eml
# Find every URL in the message
grep -oE 'https?://[^"'"'"' <>]+' message.eml | sort -u
# Hash the evidence
sha256sum message.eml7. Reading a Header Field by Field
Here is the complete field reference. I have grouped these by trust level, because that is what matters operationally.
Group A: Fields the sender fully controls (trust: zero)
These are written by whoever composed the message. Treat every one of them as a claim, not a fact.
From: The display name and address shown in your inbox. Format: "Display Name" <address@domain.com>. Completely forgeable. The display name is the single most abused field in email, because most mobile clients show only the display name and hide the address entirely.
To: The stated recipient. Does not have to include you. If you received a message where your address is not in To: or Cc:, you were a Bcc: recipient or the envelope recipient differed from the header. Mass phishing often shows To: undisclosed-recipients or a single unrelated address.
Cc: Carbon copy. Same trust level as To:.
Bcc: Blind carbon copy. Normally stripped before delivery. If you see a populated Bcc: header in a received message, something is misconfigured or the message was assembled by a tool rather than a normal client.
Subject: Freeform text. Watch for RFC 2047 encoded words hiding content, and for Unicode homoglyphs.
Date: The claimed composition time, set by the sending client. This is a claim, not evidence. Compare it against the timestamps in the Received: chain. A Date: that is hours off from the first Received: timestamp means either a broken clock or a fabricated header.
Reply-To: Where replies go if it differs from From:. This is the field to check first in any suspected BEC case. A message that appears to come from ceo@yourcompany.com with Reply-To: ceo.yourcompany@gmail.com is a textbook executive impersonation. Legitimate uses exist (mailing lists, support desks), but a mismatch between From: and Reply-To: domains on a message asking for money is close to conclusive.
Message-ID: A globally unique identifier, format <unique-string@domain>. Assigned by the first server to handle the message, or by the client. Forensically valuable because:
- The domain part should match the sending infrastructure.
Message-ID: <abc123@gmail.com>on a message claiming to come from a corporate domain is a mismatch worth investigating. - The format fingerprints the generating software. Microsoft Exchange, Postfix, Sendmail, PHPMailer, and Python's
smtpliball produce recognizably different patterns. - A missing
Message-IDis a strong signal of a script-generated message. - Duplicate
Message-IDvalues across supposedly unrelated messages indicate the same tool and often the same campaign.
In-Reply-To: and References: Threading headers containing the Message-ID of the parent message. In a thread hijacking attack, these will contain real message IDs from a genuine conversation, because the attacker has read the victim's mailbox. Their presence is not reassurance. Their presence combined with a new external sending domain is alarming.
MIME-Version:, Content-Type:, Content-Transfer-Encoding: Structural headers describing the body. Content-Type: multipart/alternative; boundary="..." is normal. Note the boundary string, it fingerprints the sending library.
X-Mailer: / User-Agent: The claimed sending application. Trivially forgeable and often absent, but inconsistency is a signal. A message claiming to be from Outlook with a Message-ID in Postfix format and a X-Mailer: PHPMailer 6.x header is telling you exactly what built it.
X-Priority: / Importance: Priority flags. Overwhelmingly common in phishing because urgency is the core social engineering lever.
List-Unsubscribe: and List-Unsubscribe-Post: Required for bulk senders under Google and Yahoo's 2024 requirements. A "marketing" email with no List-Unsubscribe header is either not really marketing or comes from a sender who does not care about deliverability, which usually means they do not expect to keep the domain long.
Group B: Fields added by mail servers (trust: high, with caveats)
These are written by infrastructure as the message travels. The ones added by your own servers are trustworthy. The ones added by servers earlier in the chain are only as trustworthy as those servers.
Received: The routing log. The single most important header in forensics. Covered in depth in the next section.
Return-Path: The envelope sender, written into the headers by the final receiving server. This is the real bounce address. Compare it to From:. A mismatch is not automatically malicious (mailing lists and marketing platforms legitimately differ), but on a message from a bank or a colleague it is a serious flag.
Delivered-To: The mailbox that actually received the message. Multiple Delivered-To: headers indicate forwarding. Watch for mail loops.
Authentication-Results: The verdicts from SPF, DKIM, DMARC, and sometimes more, as computed by the receiving server. Format looks like:
Authentication-Results: mx.recipient.com;
spf=pass (recipient.com: domain of bounces@sender.com designates 203.0.113.45 as permitted sender) smtp.mailfrom=bounces@sender.com;
dkim=pass header.i=@sender.com header.s=selector1 header.b=A1b2C3d4;
dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=sender.comAuthentication-Results: mx.recipient.com;
spf=pass (recipient.com: domain of bounces@sender.com designates 203.0.113.45 as permitted sender) smtp.mailfrom=bounces@sender.com;
dkim=pass header.i=@sender.com header.s=selector1 header.b=A1b2C3d4;
dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=sender.comCritical caveat: this header is only trustworthy when it was added by a server you control or trust. An attacker can insert a fake Authentication-Results: header into the message body they submit. Your own server should strip or override any it did not write. Always read the topmost instance, added by your own boundary, and treat any lower ones as sender-supplied claims.
Received-SPF: The older, standalone SPF result header. Same caveats.
DKIM-Signature: The cryptographic signature itself. Not a verdict, the actual signature. Its tags:
v=version, always 1a=algorithm,rsa-sha256is standard,ed25519-sha256is newerd=the signing domain. This is what matters for DMARC alignment.s=the selector, which locates the public key atselector._domainkey.domainc=canonicalization, e.g.relaxed/relaxedh=the list of headers covered by the signature. Read this carefully. IfSubjectorFromis not in the list, those fields are not protected and can be altered without breaking the signature.bh=the body hashb=the signaturel=an optional body length limit. If present, this is a red flag. It means only the first N bytes of the body are signed and an attacker can append arbitrary content without breaking the signature.t=andx=signature timestamp and expiry
ARC-Seal:, ARC-Message-Signature:, ARC-Authentication-Results: The Authenticated Received Chain. Covered in section 9.
X-Originating-IP: Added by some webmail providers to record the IP of the client that composed the message. Extremely valuable when present. Most major providers stripped this years ago for privacy reasons, but smaller providers, self-hosted webmail, and some regional services still include it.
X-Forwarded-For: / X-Sender-IP: Proxy and forwarding indicators. Interpretation depends entirely on which infrastructure added them.
Group C: Vendor and filter headers (trust: high if you recognize the vendor)
X-Spam-Status: / X-Spam-Score: / X-Spam-Level: SpamAssassin output. The score and the list of triggered rules tell you exactly what the filter noticed.
X-Microsoft-Antispam:, X-Forefront-Antispam-Report:, X-MS-Exchange-Organization-SCL: Microsoft 365 filtering telemetry. SCL (Spam Confidence Level) ranges from -1 (trusted) through 9 (high confidence spam). X-Forefront-Antispam-Report contains fields like CIP (connecting IP), CTRY (country), SFV (spam filter verdict), and PTR (reverse DNS result). This header alone often answers half your questions on a Microsoft-hosted mailbox.
X-Google-DKIM-Signature: Google's own signature over messages it handles. Distinct from the sender's DKIM signature. Its presence tells you the message passed through Google, not that the sender is legitimate.
X-Proofpoint-*, X-Mimecast-*, X-Barracuda-*, X-IronPort-* Security gateway telemetry. Each vendor has its own scoring fields. If your organization runs one of these, learn its header vocabulary. It is the richest signal you have.
X-PHP-Originating-Script: Present when the message was generated by a PHP script. Common on compromised WordPress sites being used as spam relays. If you see this on a message claiming to come from a bank, you have found the answer.
Group D: Absence as evidence
What is missing tells you as much as what is present. Flag any of these:
- No
Message-ID - No
Date - No
MIME-Versionon a message with HTML content - No
Received:header at all (impossible for legitimately delivered mail) - Only one
Received:header on a message claiming to come from an external corporate sender - No
List-Unsubscribeon a bulk marketing message - No
DKIM-Signaturefrom a large brand that always signs (banks, cloud providers, and major SaaS all sign now)
8. The Received Chain: Hop Counting and Timing Analysis
This is the heart of email forensics. Everything else is supporting evidence.
How the chain is built
Every mail server that touches a message prepends a Received: header at the very top, above everything already there. Prepends, not appends. That means:
- The topmost
Received:header was added last, by the server closest to you. - The bottommost
Received:header was added first, by the server closest to the origin.
Read from the bottom up to trace the journey forward in time.
This ordering trips up almost everyone the first time. Write it on a sticky note.
Anatomy of a Received header
Received: from mail.sender-domain.com (mail.sender-domain.com [203.0.113.45])
by mx1.recipient.com (Postfix) with ESMTPS id 4B2K1P3xyz
for <victim@recipient.com>;
Tue, 18 Aug 2026 09:14:22 +0000 (UTC)Received: from mail.sender-domain.com (mail.sender-domain.com [203.0.113.45])
by mx1.recipient.com (Postfix) with ESMTPS id 4B2K1P3xyz
for <victim@recipient.com>;
Tue, 18 Aug 2026 09:14:22 +0000 (UTC)Break it into its clauses:
ClauseContentWhat it meansfrommail.sender-domain.comThe name the connecting server claimed in its HELO/EHLO. Attacker-controlled.(...)mail.sender-domain.com [203.0.113.45]The reverse DNS lookup result and the actual TCP source IP, both determined by the receiving server. Not forgeable.bymx1.recipient.comThe receiving server that wrote this header.withESMTPSThe protocol used.id4B2K1P3xyzThe queue ID on the receiving server. Correlates to that server's logs.for<victim@recipient.com>The envelope recipient at this hop.timestampTue, 18 Aug 2026 09:14:22 +0000When this server received it, with timezone offset.
The single most important thing in the whole header block is the IP address in square brackets on the bottommost Received: line that was added by infrastructure you trust. That is the origin IP.
The HELO mismatch
Compare the from claim against the parenthetical reverse DNS and IP:
Received: from paypal.com (unknown [45.147.230.12])Received: from paypal.com (unknown [45.147.230.12])The connecting server announced itself as paypal.com. The receiving server looked up 45.147.230.12 in reverse DNS and got nothing (unknown). PayPal does not send mail from unresolvable IPs on hosting ranges. This one line, on its own, is close to conclusive.
Variants to look for:
from mail.example.com (dsl-203-0-113-45.consumer-isp.net [203.0.113.45]): the HELO claims corporate infrastructure, the reverse DNS says residential broadband. Almost always a compromised home machine in a botnet.from [192.168.1.50] (host.attacker.net [198.51.100.9]): the HELO is a private RFC 1918 address, which is invalid on the public internet.from localhost (...): a HELO oflocalhostfrom an external IP is nonsense.- Reverse DNS that resolves but does not forward-confirm. Proper hosts have forward-confirmed reverse DNS (FCrDNS): the IP reverses to a name, and that name resolves back to the same IP. Check both directions.
Hop counting: how many is too many?
This is where experience helps, so here is a concrete framework.
What a normal hop count looks like:
ScenarioTypical hopsNotesGmail to Gmail1 to 2Internal, barely leaves GoogleCorporate to corporate, direct2 to 4Sender MTA, maybe an outbound gateway, recipient gateway, recipient MTAThrough a security gateway on both ends4 to 6Add Proofpoint, Mimecast, or similar at each endMarketing platform (Mailchimp, SendGrid, Klaviyo)3 to 5ESP infrastructure adds hopsOne forward or a mailing list5 to 7Each relay adds oneMultiple forwards or nested lists7 to 10Legitimate but should be explainable
The practical rule I use:
- 1 to 3 hops: normal for direct delivery. If it is 1 and the message claims to be external, be suspicious, because external mail cannot reach you in a single hop unless your MX is the first and only recipient.
- 4 to 6 hops: completely normal for modern business email with gateways on both ends. This is the sweet spot. Nothing to see here.
- 7 hops: the ceiling for routine mail. Start asking why.
- 8 or more hops: treat as anomalous until proven otherwise. Every hop beyond seven should have an identifiable reason: a forwarding rule, a mailing list, an archiving system, a legal hold appliance, a migration in progress.
- 10 or more: something is wrong. Either a mail loop, a deliberately obfuscated relay chain, or a message that has been laundered through open relays to hide its origin.
Why extra hops matter to an attacker. Bouncing a message through multiple relays buries the origin IP. Each intermediate relay adds a hop, and if any of those relays are compromised or attacker-controlled, they may add forged Received: headers below the real ones to fabricate a plausible history. That is why you only trust Received: headers from the point where the message entered infrastructure you control, and work downward with decreasing confidence.
Why extra hops matter to a defender. Every additional hop is another server that saw your message in cleartext if TLS was not enforced end to end. Long chains are a confidentiality problem as much as an authenticity one.
Timing analysis: the part almost everyone skips
Each Received: header carries a timestamp. Subtract each from the next and you get the transit time for that hop. This is where forged chains fall apart.
Baselines for a healthy chain:
GapInterpretation0 to 2 secondsNormal. Most hops are sub-second.2 to 10 secondsFine. Content scanning, sandbox detonation, DKIM verification all take time.10 to 60 secondsWorth noting. Usually queue depth or a slow content scanner.1 to 5 minutesInvestigate. Common causes: greylisting retry, rate limiting, a queue backup.5 to 30 minutesClassic greylisting. The receiving server issued a temporary 450, the sender retried later. Legitimate but notable.30 minutes to hoursSerious delay. Either infrastructure failure, or the message sat in a queue somewhere it should not have.NegativeImpossible in an honest chain. A message cannot arrive at hop 3 before it left hop 2. This means forged headers or a badly misconfigured clock.
How to do the arithmetic correctly. Timestamps carry timezone offsets like +0000, -0500, +0530. Convert everything to UTC before subtracting. A large number of false positives in timing analysis are just analysts forgetting to normalize timezones. A hop that appears to take five hours often took two seconds across a timezone boundary.
Patterns that indicate forgery:
- Non-monotonic timestamps. Times that go backward as you move up the chain.
- Identical timestamps across many hops. Real servers do not process instantly across four different machines at the exact same second, though one or two matching is fine.
- Suspiciously round intervals. Exactly 60 seconds between every hop suggests a script generated them.
- A gap between the
Date:header and the bottommostReceived:timestamp. The message claims to have been composed at 14:00 but the first server saw it at 09:00. Either the sender's clock is broken or theDate:was fabricated. - Timezone offsets that do not match the claimed geography. A message allegedly from a London office with
+0800offsets throughout. - A long gap between the origin hop and the second hop specifically. This often indicates the message was composed offline, or held in a queue on a compromised machine waiting for a send window.
Working example of a chain read
Here is a chain, presented in file order (newest first). We read it bottom-up.
Received: from mx1.acme-corp.com (localhost [127.0.0.1])
by mail.acme-corp.com (Postfix) with ESMTP id 9F3D1
for <finance@acme-corp.com>; Tue, 18 Aug 2026 09:14:26 +0000 (UTC)
Received: from gateway.securemail-vendor.net (gateway.securemail-vendor.net [198.51.100.20])
by mx1.acme-corp.com (Postfix) with ESMTPS id 8E2C0
for <finance@acme-corp.com>; Tue, 18 Aug 2026 09:14:24 +0000 (UTC)
Received: from relay-07.bulkhost.example (relay-07.bulkhost.example [192.0.2.77])
by gateway.securemail-vendor.net with ESMTP id 7D1B9;
Tue, 18 Aug 2026 09:14:19 +0000 (UTC)
Received: from vps-4471.cheap-cloud.example (vps-4471.cheap-cloud.example [203.0.113.199])
by relay-07.bulkhost.example with ESMTP id 6C0A8;
Tue, 18 Aug 2026 09:11:02 +0000 (UTC)
Received: from acme-corp.com (unknown [45.147.230.12])
by vps-4471.cheap-cloud.example with SMTP id 5B9F7;
Tue, 18 Aug 2026 09:10:58 +0000 (UTC)Received: from mx1.acme-corp.com (localhost [127.0.0.1])
by mail.acme-corp.com (Postfix) with ESMTP id 9F3D1
for <finance@acme-corp.com>; Tue, 18 Aug 2026 09:14:26 +0000 (UTC)
Received: from gateway.securemail-vendor.net (gateway.securemail-vendor.net [198.51.100.20])
by mx1.acme-corp.com (Postfix) with ESMTPS id 8E2C0
for <finance@acme-corp.com>; Tue, 18 Aug 2026 09:14:24 +0000 (UTC)
Received: from relay-07.bulkhost.example (relay-07.bulkhost.example [192.0.2.77])
by gateway.securemail-vendor.net with ESMTP id 7D1B9;
Tue, 18 Aug 2026 09:14:19 +0000 (UTC)
Received: from vps-4471.cheap-cloud.example (vps-4471.cheap-cloud.example [203.0.113.199])
by relay-07.bulkhost.example with ESMTP id 6C0A8;
Tue, 18 Aug 2026 09:11:02 +0000 (UTC)
Received: from acme-corp.com (unknown [45.147.230.12])
by vps-4471.cheap-cloud.example with SMTP id 5B9F7;
Tue, 18 Aug 2026 09:10:58 +0000 (UTC)Bottom-up reading:
- Origin hop. A host at
45.147.230.12connected to a VPS and announced itself asacme-corp.com. Reverse DNS:unknown. It is claiming to be the victim's own domain while having no reverse DNS at all. Flag 1: HELO impersonating the recipient domain. Flag 2: no reverse DNS. - Hop 2. A cheap cloud VPS accepted it. The protocol is plain
SMTP, notESMTPS, so this hop was unencrypted. Flag 3. - Hop 3. Delivered onward to a bulk hosting relay. Note the gap: 09:11:02 minus 09:10:58 is four seconds. Fine.
- Hop 4. Bulk relay to the security gateway. 09:14:19 minus 09:11:02 is three minutes and seventeen seconds. That is a queue delay, consistent with greylisting or rate limiting on a low-reputation sender. Flag 4.
- Hop 5 and 6. Through the recipient's gateway and into the mailbox. Two and five second gaps. Normal.
Total: 5 hops. Under the eight-hop threshold, so hop count alone is not damning. But the composition of the chain is: a residential or hosting IP with no reverse DNS, spoofing the recipient's own domain name in its HELO, routed through a cheap VPS and a bulk relay, with an unencrypted first hop and a three-minute queue delay.
Verdict from the chain alone: hostile. Everything else you check will confirm it.
The trust boundary
Draw a line in the chain at the point where the message entered infrastructure you control or trust (your gateway, your MTA). Everything above that line, you wrote, and you trust completely. Everything below it is testimony from servers you have never met, and it degrades in reliability the further down you go.
An attacker who controls the origin can write as many fake Received: headers as they like into the message before sending it. Those fakes will appear at the bottom of the chain. They will often be very convincing: correct format, plausible hostnames, sensible timestamps. The only thing they cannot fake is the IP address your own server observed on the TCP connection.
9. SPF, DKIM, DMARC, and ARC
These four standards exist to answer one question: is the domain in the From address the domain that actually sent this?
SPF: Sender Policy Framework (RFC 7208)
What it does. The domain owner publishes a DNS TXT record listing which IP addresses are allowed to send mail for that domain. The receiving server checks whether the connecting IP is on the list.
What it looks like:
example.com. IN TXT "v=spf1 ip4:203.0.113.0/24 include:_spf.google.com include:sendgrid.net -all"example.com. IN TXT "v=spf1 ip4:203.0.113.0/24 include:_spf.google.com include:sendgrid.net -all"Reading the mechanisms:
MechanismMeaningip4: / ip6:Literal IP address or CIDR rangeaThe A record of the domain itselfmxThe IPs of the domain's MX hostsinclude:Import another domain's SPF record (this is the recursive part)exists:Pass if a given DNS lookup succeedsredirect=Replace this record entirely with another domain'sallMatches everything. Always last.
Reading the qualifiers:
QualifierResultMeaning+ (default)PassAuthorized-FailExplicitly not authorized. Reject.~SoftFailProbably not authorized, but accept and mark?NeutralNo assertion
So -all is a hard fail policy and ~all is a soft fail. A domain ending in ~all or ?all is telling receivers "I am not confident about my own sending infrastructure." That is a meaningful signal about the domain's security maturity.
The three limits that break SPF:
- The 10 DNS lookup limit.
include:,a,mx,exists:, andredirect=each cost a lookup, andinclude:recurses. Exceed ten and the result ispermerror, which most receivers treat as no SPF at all. Large organizations with a dozen SaaS senders blow past this constantly. The fix is SPF flattening, which replaces includes with literal IPs, at the cost of needing maintenance whenever a provider changes IPs. - The 255-character string limit. A single TXT string cannot exceed 255 characters. Longer records must be split into multiple strings that concatenate.
- Forwarding breaks SPF completely. When a message is forwarded, the forwarding server becomes the connecting IP, and it is not in the original domain's SPF record. SPF fails. This is not a bug in your setup, it is inherent to how SPF works, and it is precisely why DKIM and ARC exist.
The critical limitation. SPF checks the envelope sender (MAIL FROM:), not the visible From: header. An attacker can use an envelope sender at a domain they control, pass SPF perfectly, and put anything they like in the From: header. SPF alone stops nothing. This is the single most misunderstood point in email security. Without DMARC to enforce alignment, a green SPF pass tells you nothing about the address the user sees.
Result values you will see: pass, fail, softfail, neutral, none (no record published), permerror (broken record), temperror (DNS failure).
DKIM: DomainKeys Identified Mail (RFC 6376)
What it does. The sending server cryptographically signs selected headers and the body with a private key. The public key sits in DNS. The receiving server fetches the key and verifies the signature.
What it proves. That the message was signed by someone holding the private key for that domain, and that the signed portions have not been modified in transit.
How the key lookup works. The signature contains d= (domain) and s= (selector). The public key lives at:
<selector>._domainkey.<domain><selector>._domainkey.<domain>So s=selector1; d=example.com means querying selector1._domainkey.example.com for a TXT record containing something like:
v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC...v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC...Why DKIM survives forwarding. The signature travels with the message. As long as the forwarder does not modify the signed headers or the body, the signature still verifies at the destination. This is DKIM's decisive advantage over SPF.
What breaks DKIM legitimately:
- Mailing lists that append footers or rewrite subject lines
- Gateways that add "EXTERNAL SENDER" banners to the body
- Anti-virus systems that rewrite attachments
- Any system that re-encodes the message body
Attacks and weaknesses to check for:
- The
l=tag. If present, only the first N bytes of the body are signed. An attacker can append unlimited content after that point without breaking the signature. Any message withl=deserves scrutiny. - Weak keys. DKIM keys below 1024 bits are factorable. 2048 bits is the current standard.
- Missing headers in
h=. IfFromis not listed in theh=tag, the From header is unsigned and can be altered freely. Some implementations also double-sign headers to prevent header injection attacks. - DKIM replay. An attacker obtains a legitimately signed message from a high-reputation domain and re-sends it to thousands of new recipients. The signature still verifies because the signed content has not changed. Mitigations include including
To:in the signed headers and using shortx=expiry times. - Third-party signing.
d=pointing to a marketing platform rather than the brand's own domain. Legitimate, but it means the brand has delegated its identity, and a compromise at that platform impersonates the brand.
DMARC: Domain-based Message Authentication, Reporting and Conformance (RFC 7489)
This is the standard that makes the other two matter. DMARC does two things SPF and DKIM cannot do alone:
- It requires alignment between the authenticated domain and the domain in the visible
From:header. - It publishes a policy telling receivers what to do when authentication fails, and requests reports.
What alignment means. For DMARC to pass, at least one of the following must be true:
- SPF alignment: SPF passed and the
MAIL FROM:domain matches theFrom:header domain. - DKIM alignment: DKIM passed and the
d=domain matches theFrom:header domain.
aspf= and adkim= control strictness: r (relaxed, the default, allows subdomains to match the organizational domain) or s (strict, requires exact match).
This is the fix for SPF's blind spot. An attacker using their own domain as the envelope sender passes SPF but fails alignment, so DMARC fails.
What a DMARC record looks like:
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; sp=reject; adkim=s; aspf=s; pct=100; rua=mailto:dmarc-reports@example.com; ruf=mailto:forensic@example.com; fo=1"_dmarc.example.com. IN TXT "v=DMARC1; p=reject; sp=reject; adkim=s; aspf=s; pct=100; rua=mailto:dmarc-reports@example.com; ruf=mailto:forensic@example.com; fo=1"Reading the tags:
TagMeaningv=DMARC1Version. Mandatory, must be first.p=Policy: none, quarantine, or rejectsp=Subdomain policy. Omit it and subdomains inherit p=.adkim=DKIM alignment: r relaxed or s strictaspf=SPF alignment: r or spct=Percentage of failing mail the policy applies to. Used for gradual rollout.rua=Where to send aggregate XML reports (daily summaries)ruf=Where to send forensic/failure reports (per-message)fo=When to generate failure reports: 0, 1, d, s
The p=none problem, and why it is the biggest gap in email security today.
p=none means "authenticate my mail, send me reports, but do not block anything." It is the correct starting point for a rollout. It is a disaster as a destination.
The 2026 data makes this stark. Of the 937,931 domains with valid DMARC records in EasyDMARC's analysis of the top 1.8 million, 525,996 (more than half) remain at p=none. Valimail's research indicates 75 to 80 percent of domains that publish DMARC never reach enforcement, staying at monitoring for months or years. Only 159,691 domains met the stronger benchmark of p=reject combined with aggregate reporting.
For an investigator, this means: when you look up a domain's DMARC record and see p=none, you have learned that anyone in the world can spoof that domain and the receiving server will deliver it anyway. That is not a hypothetical. It is the current operating condition of the majority of the internet.
Checking any domain's records yourself:
dig +short TXT example.com # SPF
dig +short TXT _dmarc.example.com # DMARC
dig +short TXT selector1._domainkey.example.com # DKIM (need the selector)
dig +short MX example.com # Mail servers
dig +short TXT _mta-sts.example.com # MTA-STS
dig +short TLSA _25._tcp.mail.example.com # DANE
dig +short TXT default._bimi.example.com # BIMIdig +short TXT example.com # SPF
dig +short TXT _dmarc.example.com # DMARC
dig +short TXT selector1._domainkey.example.com # DKIM (need the selector)
dig +short MX example.com # Mail servers
dig +short TXT _mta-sts.example.com # MTA-STS
dig +short TLSA _25._tcp.mail.example.com # DANE
dig +short TXT default._bimi.example.com # BIMIIf you prefer a browser, EmailVerifyerAPI publishes free, no-account lookup tools that do exactly this from your own device using DNS over HTTPS: an MX record checker that also reports MTA-STS and TLS-RPT status, an SPF record checker that counts your DNS lookups against the RFC 7208 limit of ten and rates the record, a DKIM record checker, a DMARC record checker that reads policy, alignment and reporting addresses, and an email DNS fingerprint tool that identifies the vendor behind any MX host, SPF include, DKIM selector or DMARC report address. That last one is genuinely useful in investigations: it tells you at a glance whether a domain's mail is handled by Google, Microsoft, Zoho, a regional host, or something nobody has heard of.
ARC: Authenticated Received Chain (RFC 8617)
The problem ARC solves. Mailing lists and forwarders break authentication. A list receives a message, appends a footer, rewrites the subject, and forwards it. SPF now fails (wrong IP) and DKIM now fails (body modified). The final recipient sees a DMARC failure on a message that was perfectly legitimate when it started.
How ARC works. Each intermediary that handles the message adds three headers:
ARC-Authentication-Results(AAR): the authentication verdict as this hop saw it, before any modifications.ARC-Message-Signature(AMS): a DKIM-like signature over the message as it looked at this hop.ARC-Seal(AS): a signature over the ARC headers themselves, chaining this hop to the previous one.
Each set carries an instance number i=1, i=2, and so on. The final receiver can walk the chain backward and see that although the message fails DMARC now, it passed DMARC when it arrived at the mailing list, and the chain from there is cryptographically intact.
Forensic use. ARC headers give you an authentication history rather than a single final verdict. If a message fails DMARC but has a valid ARC chain showing a pass at i=1 from a mailing list you recognize, that is very different from a DMARC failure with no ARC at all.
Important caveat: ARC is a trust assertion. It says "this intermediary vouches that authentication passed before I modified the message." You only benefit if you trust the intermediary. An attacker can add ARC headers claiming anything. Receivers maintain lists of ARC sealers they trust, and Google, Microsoft, and the major providers all do this.
Reading the whole stack at once
Here is a real-shaped Authentication-Results block with a mixed verdict:
Authentication-Results: mx.recipient.com;
spf=pass (recipient.com: domain of bounce@mailer-service.net designates 192.0.2.55 as permitted sender) smtp.mailfrom=bounce@mailer-service.net;
dkim=pass header.i=@mailer-service.net header.s=s1 header.b=Qw3rT9;
dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yourbank.comAuthentication-Results: mx.recipient.com;
spf=pass (recipient.com: domain of bounce@mailer-service.net designates 192.0.2.55 as permitted sender) smtp.mailfrom=bounce@mailer-service.net;
dkim=pass header.i=@mailer-service.net header.s=s1 header.b=Qw3rT9;
dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yourbank.comWalk through it:
- SPF passed, but for
mailer-service.net, notyourbank.com. - DKIM passed, but signed by
mailer-service.net, notyourbank.com. - DMARC failed, because the
From:header saysyourbank.comand neither authenticated domain aligns with it. p=NONE, soyourbank.comhas told receivers to deliver failures anyway.
This message is spoofed and it landed in the inbox. Two green checkmarks and one red one, and the red one is the only one that mattered.
That pattern, SPF pass plus DKIM pass plus DMARC fail, is the signature of a competent spoofing operation. The attacker set up their own domain properly, authenticated it correctly, and then put your bank's name in the From field.
10. Transport Security: STARTTLS, MTA-STS, TLS-RPT, DANE and TLSA
SPF, DKIM, and DMARC answer "who sent this?" Transport security answers a different question: "could anyone have read or altered it on the way?"
STARTTLS and its fatal flaw
STARTTLS (RFC 3207) upgrades a plaintext SMTP connection to TLS. The sender connects on port 25 in the clear, sees 250-STARTTLS in the server's capability list, issues STARTTLS, and the connection becomes encrypted.
The flaw is in the sequence. The capability list is transmitted before encryption exists. An attacker in the path deletes that one line. The sending server concludes TLS is unavailable and, because every MTA defaults to "deliver anyway," sends the message in cleartext. Nothing alerts anyone.
There is a second flaw: even when STARTTLS succeeds, most MTAs do not validate the certificate. They accept expired certificates, self-signed certificates, and certificates for the wrong hostname. This is called opportunistic TLS, and it protects against passive eavesdropping but not against an active attacker.
Two standards fix this, from opposite directions.
MTA-STS: SMTP MTA Strict Transport Security (RFC 8461)
How it works. The domain publishes a DNS TXT record pointing to a policy file served over HTTPS.
DNS record:
_mta-sts.example.com. IN TXT "v=STSv1; id=20260818T120000Z"_mta-sts.example.com. IN TXT "v=STSv1; id=20260818T120000Z"Policy file at [https://mta-sts.example.com/.well-known/mta-sts.txt](https://mta-sts.example.com/.well-known/mta-sts.txt:):
version: STSv1
mode: enforce
mx: mail.example.com
mx: mail2.example.com
max_age: 604800version: STSv1
mode: enforce
mx: mail.example.com
mx: mail2.example.com
max_age: 604800What it means. A sending server fetches this policy over HTTPS (which is authenticated by the web PKI), caches it for max_age seconds, and from then on refuses to deliver mail to that domain over an unencrypted or uncertified connection. Because the policy is cached, a later downgrade attempt fails against the cached policy rather than being silently accepted.
Modes:
testing: report violations but deliver anyway. The rollout mode.enforce: refuse to deliver if TLS cannot be established with a valid certificate matching a listed MX host.none: withdraw the policy.
Adoption reality: PowerDMARC's 2026 US analysis found MTA-STS adoption at 1.7 percent of domains, against 95.8 percent DMARC coverage. Almost nobody has turned this on. When you find a domain that has, it is a strong positive signal about that organization's security maturity.
TLS-RPT: SMTP TLS Reporting (RFC 8460)
The companion to MTA-STS. It publishes a reporting address so that sending servers can tell you when TLS negotiation failed:
_smtp._tls.example.com. IN TXT "v=TLSRPTv1; rua=mailto:tls-reports@example.com"_smtp._tls.example.com. IN TXT "v=TLSRPTv1; rua=mailto:tls-reports@example.com"You receive daily JSON reports listing successful and failed TLS sessions, with failure reasons. This is how you find out that a partner's certificate expired, or that someone is attempting downgrade attacks against your inbound mail. Without TLS-RPT, downgrade attacks are silent by design.
DANE and TLSA: DNS-Based Authentication of Named Entities (RFC 6698, RFC 7672)
DANE takes a different approach. Instead of relying on the web PKI and a separate HTTPS fetch, it publishes the expected certificate in DNS, protected by DNSSEC.
A TLSA record for a mail server looks like:
_25._tcp.mail.example.com. IN TLSA 3 1 1 a1b2c3d4e5f6..._25._tcp.mail.example.com. IN TLSA 3 1 1 a1b2c3d4e5f6...The four fields:
FieldNameCommon valuesFirstCertificate Usage0 PKIX-TA, 1 PKIX-EE, 2 DANE-TA (your own CA), 3 DANE-EE (this exact certificate)SecondSelector0 full certificate, 1 public key onlyThirdMatching Type0 exact match, 1 SHA-256, 2 SHA-512FourthCertificate Association DataThe hash itself
3 1 1 is by far the most common combination for mail: "this exact end-entity public key, hashed with SHA-256."
The DNSSEC dependency is absolute. DANE only works if the zone is DNSSEC-signed, because otherwise an attacker who can spoof DNS can also spoof the TLSA record. PowerDMARC's 2026 US report puts DNSSEC adoption at 18.0 percent, which is why DANE for SMTP remains largely a European and technical-infrastructure phenomenon. The Netherlands, Germany, and the Czech Republic have far higher deployment than the US.
MTA-STS versus DANE
MTA-STSDANETrust anchorWeb PKI (certificate authorities)DNSSECPrerequisiteHTTPS web serverSigned DNS zoneFailure modeCached policy, so downgrade failsHard fail if TLSA does not matchDeployment difficultyModerateHigh (DNSSEC first)Who uses itGoogle, Microsoft, most US enterprisesEuropean ISPs, government, technical hosts
They are not mutually exclusive. Publishing both is the strongest configuration, and costs nothing extra once each is deployed.
What this means for an investigator
When you examine a Received: header, the with clause tells you whether that hop was encrypted:
with SMTP: plaintextwith ESMTP: plaintext, extendedwith ESMTPS: TLS was usedwith ESMTPSA: TLS plus authenticationwith ESMTPA: authenticated but not encrypted
Some servers include the cipher suite in a comment:
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))A chain with a plaintext hop in the middle means the message was readable by anyone on that path. For a message containing invoice details, bank information, or credentials, that is a finding in its own right, separate from whether the message was forged.
11. BIMI, VMC, CMC, S/MIME and PGP
These standards operate above authentication. They answer "can I see, at a glance, that this is really them?" and "was this message signed by a specific human?"
BIMI: Brand Indicators for Message Identification
What it does. Displays your verified brand logo next to your messages in supported inboxes.
How it works.
- Your domain must have DMARC at enforcement (
p=quarantineorp=reject).p=nonedoes not qualify. This is a hard requirement and it is the entire point. - You publish a logo in SVG Tiny Portable/Secure format, a deliberately restricted SVG profile with no scripts, no external references, and no animation.
- You publish a BIMI TXT record:
default._bimi.example.com. IN TXT "v=BIMI1; l=https://example.com/logo.svg; a=https://example.com/vmc.pem"default._bimi.example.com. IN TXT "v=BIMI1; l=https://example.com/logo.svg; a=https://example.com/vmc.pem"l=the logo URLa=the mark certificate URL (optional for some providers, required for others)
- The receiving provider verifies DMARC, fetches the logo, validates the certificate, and renders the logo.
Why BIMI is a security control, not just branding. It creates a visible, verifiable trust signal that a phisher cannot replicate without controlling the domain and holding a certificate. And because it requires DMARC enforcement, it gives marketing teams a business reason to demand the security work that IT has been deferring for years. In practice, BIMI has driven more DMARC enforcement than any security argument ever did.
VMC: Verified Mark Certificate
A digital certificate issued by a recognized Certificate Authority that binds your registered trademark logo to your organization and domain.
- Requires an active trademark registration with an approved intellectual property office. As of 2026 the BIMI Group recognizes more than a dozen jurisdictions including the USPTO, EUIPO, UK IPO, and IP Australia.
- Issued by Mark Verifying Authorities. DigiCert, Sectigo, GlobalSign, and SSL.com are current issuers. Entrust, an original issuer, exited the BIMI certificate business in 2025 after selling its public certificate operations.
- Only a VMC earns the Gmail blue verified checkmark.
- Pricing runs roughly USD 749 to 1,752 per year depending on CA and reseller, excluding trademark costs, with validation typically taking two to four weeks.
- Trademark registration itself takes 10 to 18 months at the USPTO, which is the real bottleneck.
CMC: Common Mark Certificate
The AuthIndicators Working Group introduced CMC support in late 2024, and Google announced Gmail support in September 2024.
- No registered trademark required. Instead, the CA verifies that your logo has been in continuous public use on a domain you control for at least 12 months, typically evidenced through web archive records.
- Cheaper and faster than a VMC.
- Displays your logo in Gmail but does not produce the blue checkmark. The checkmark is reserved for VMCs because only a VMC is backed by a registered mark.
- Yahoo Mail supports both. Apple Mail's documented path requires a VMC.
GMC: Government Mark Certificate
For government entities, verified against official government records rather than trademark registries.
Current provider support (as of 2026)
ProviderRequirementGmailVMC or CMC. Blue checkmark only with VMC. Checkmarks now shown on Android and iOS Gmail apps.Yahoo MailDisplays logos without requiring a certificate, for senders with good reputationApple MailSupported on iOS 16, iPadOS 16, macOS Ventura 13 and later, plus iCloud.com. Requires the receiving provider to validate a BIMI Evidence Document.FastmailSupports without requiring a VMCAOLSupported with authentication requirementsOutlook / MicrosoftNot yet supported
Adoption is low. Valimail's 2026 reporting put BIMI adoption at roughly 4 percent globally, and a URIports analysis found 53.6 percent of published BIMI records contain at least one error.
The critical warning about logos
Do not train users to trust a logo.
In Gmail, any user can set a profile picture. When one Gmail user emails another, that profile picture appears in the same visual position as a BIMI logo. A criminal can upload a brand's logo as their Gmail profile picture and, to a recipient who has been taught "the logo means it is real," look identical to the genuine article.
The reliable signal is the blue checkmark, which requires a VMC. The logo alone is not.
Seeing a BIMI logo is a mild positive signal. Not seeing one tells you essentially nothing, because 96 percent of legitimate senders do not have it.
S/MIME: Secure/Multipurpose Internet Mail Extensions
A fundamentally different layer. Where SPF, DKIM, and DMARC authenticate the domain, S/MIME authenticates the individual sender and can encrypt the message content end to end.
How it works. The sender holds an X.509 certificate issued by a CA that has verified their identity (typically by validating control of the email address, and for higher assurance levels, by validating the organization or the individual). The certificate contains a public key. The sender signs the message with the corresponding private key.
What a signed message looks like in the headers:
Content-Type: multipart/signed;
protocol="application/pkcs7-signature";
micalg=sha-256;
boundary="----=_NextPart_000_0012"Content-Type: multipart/signed;
protocol="application/pkcs7-signature";
micalg=sha-256;
boundary="----=_NextPart_000_0012"Or for an opaque signature:
Content-Type: application/pkcs7-mime; smime-type=signed-data; name="smime.p7m"Content-Type: application/pkcs7-mime; smime-type=signed-data; name="smime.p7m"For encryption:
Content-Type: application/pkcs7-mime; smime-type=enveloped-data; name="smime.p7m"Content-Type: application/pkcs7-mime; smime-type=enveloped-data; name="smime.p7m"What it gives you:
- Authentication of the individual sender, not just the domain
- Integrity of the entire message including attachments
- Non-repudiation, which matters legally
- Confidentiality when used for encryption
What to check on a signed message:
- Does the certificate's email address match the
From:header? - Is the certificate within its validity period?
- Does it chain to a CA your client trusts?
- Has it been revoked? Check CRL or OCSP.
- What assurance level was it issued at? A domain-validated certificate proves control of an address, not the identity of a person.
Why it is not more common. Key distribution is genuinely hard. To send someone an encrypted message you need their certificate first. Certificates expire and must be renewed. Lose the private key and every archived encrypted message is gone forever. Mobile support is inconsistent. It works well within a single organization or a closed group of partners, and poorly across the open internet.
Where it shines: legal, healthcare, financial services, government, and any sector where a specific individual's signature carries weight. If your finance team receives payment instructions, requiring S/MIME signatures on those instructions from a known certificate is one of the few controls that genuinely stops BEC, because the attacker would need the private key, not just the mailbox.
PGP and OpenPGP
The other end-to-end option, using a web-of-trust model instead of certificate authorities. Common in journalism, activism, open source, and security research. In the headers it shows as:
Content-Type: multipart/signed; protocol="application/pgp-signature"Content-Type: multipart/signed; protocol="application/pgp-signature"or an inline block wrapped in -----BEGIN PGP SIGNED MESSAGE-----.
Same forensic questions apply: whose key signed it, is that key the one you expect, and how did you obtain it.
The complete stack, in order
LayerStandardQuestion answeredTransport encryptionSTARTTLSWas the connection encrypted?Transport enforcementMTA-STS, DANE/TLSAWas encryption guaranteed and verified?Transport reportingTLS-RPTDo I get told when it fails?Path authorizationSPFWas the sending IP allowed?Content integrityDKIMWas the message altered, and who signed it?Alignment and policyDMARCDoes the authenticated domain match what the user sees, and what should happen if not?Forwarding preservationARCDid it pass before an intermediary modified it?Visual identityBIMI + VMC/CMCCan the user see it is really them?Individual identityS/MIME, PGPDid a specific person sign this?
A message that passes every layer is very likely genuine. A message that fails any layer is not automatically malicious, but every failure needs an explanation.
12. How Email Spoofing Actually Works
Understanding the attack is what makes the defense make sense.
The core fact
The From: header is a text field that the sender writes. Nothing in the base protocol validates it.
That is the whole vulnerability. Everything else is detail.
Look back at the SMTP session in section 3. The client declared an envelope sender, then wrote a completely different address into the From: header inside the DATA block, and the server accepted it. That is not a bug in that server. That is SMTP working exactly as specified in 1982.
The four kinds of spoofing, ranked by difficulty
1. Display name spoofing (trivially easy, works constantly)
The attacker sends from an address they legitimately control, but sets the display name to something trustworthy:
From: "PayPal Security Team" <accounts-verify-7734@gmail.com>From: "PayPal Security Team" <accounts-verify-7734@gmail.com>Every authentication check passes, because the message genuinely is from that Gmail account. SPF passes. DKIM passes. DMARC passes.
And it works because mobile mail clients display the name and hide the address. On a phone, the user sees "PayPal Security Team" and nothing else. They have to tap the name to reveal the address, and most people never do.
This requires no technical skill whatsoever. It is the most common form of executive impersonation in BEC.
2. Lookalike domain spoofing (easy, cheap, effective)
The attacker registers a domain that resembles the target and sets it up properly, with correct SPF, DKIM, and DMARC:
paypa1.com(digit one for letter l)paypal-security.compaypal.com.verify-account.net(the real domain appears as a subdomain of the attacker's domain)paypaI.com(capital I for lowercase l)paypal.coinstead of.com
Because the attacker owns the domain, all authentication passes. This is the pattern that produces "SPF pass, DKIM pass, DMARC pass" on a message that is entirely fraudulent. The green checkmarks are telling you the truth: this message really did come from paypa1.com. They just cannot tell you that paypa1.com is not PayPal.
Cost: about ten dollars and fifteen minutes. This is the highest return-on-investment attack in the entire field.
3. Direct domain spoofing (easy against unprotected domains, impossible against protected ones)
The attacker puts the real target domain in the From: header and sends it. Whether this works depends entirely on the target's DMARC policy:
- Target has
p=reject: the message is rejected. The attack fails. - Target has
p=quarantine: the message lands in spam. Mostly fails. - Target has
p=none: the message is delivered to the inbox. The attack succeeds. - Target has no DMARC record at all: delivered. The attack succeeds.
Given that more than half of DMARC-publishing domains sit at p=none, and roughly 70 percent of the broader internet publishes no enforcing policy at all, this attack still works against most of the world.
4. Infrastructure abuse (hard, but devastating)
- Compromised mailbox. The attacker has the real credentials. Everything is genuinely legitimate. No header analysis will save you, because there is nothing wrong with the headers. This is the dominant BEC method.
- Open relay abuse. Sending through a misconfigured server to inherit its reputation.
- SMTP smuggling. Exploiting parser differences, as covered in section 4, to have a legitimate server deliver a forged message with valid authentication.
- Multi-tenant SPF abuse. CVE-2024–7208 and CVE-2024–7209. On shared hosting where many customers share an SPF record, one authenticated tenant can send as another.
- Subdomain takeover. A dangling DNS record pointing to a decommissioned cloud resource that the attacker re-registers, giving them a genuine subdomain of the target.
The tools that make this accessible
You do not need to be a programmer. Public web forms exist that will compose an SMTP message with arbitrary header values and send it, complete with fields for the From address, display name, Reply-To, priority flags, and attachments. emkei.cz is the best-known example and has been running for well over a decade. There are dozens of others.
These sites are, on their face, legitimate testing tools. Mail administrators genuinely use them to verify that their own SPF, DKIM, and DMARC configurations reject forged mail. That is a real and valid use case. But the same form, filled in with someone else's domain and pointed at someone else's inbox, is a phishing kit with a friendly interface.
On the code side, the standard library of essentially every programming language includes an SMTP client, and every one of them lets you set the From: header to an arbitrary string. This is not a security flaw in those libraries. Header fields are, by specification, free text. A legitimate application sending mail on behalf of its users needs exactly that capability.
I am not going to publish a working spoofing script here, because there is no defensive reason to. What matters for your understanding is this: the barrier is zero, the required knowledge is zero, and the cost is zero. Anyone reading this could send you a message that says From: security@paypal.com in the next five minutes.
Why "security@paypal.com" means nothing
Let us be completely explicit about this, because it is the point that changes how people read email forever.
A message arrives. The From line reads:
From: PayPal Fraud Department <security@paypal.com>From: PayPal Fraud Department <security@paypal.com>Here is what that tells you: nothing.
It does not tell you PayPal sent it. It tells you that whoever composed the message typed those characters into a text field.
To know whether PayPal sent it, you must check:
- Does the
Return-Path:match? If it saysbounce@random-vps-host.example, the envelope sender is not PayPal. - Did SPF pass, and for which domain? SPF might pass for the attacker's domain.
- Did DKIM pass, and what is the
d=value? Ifd=is anything other thanpaypal.comor a domain PayPal actually signs with, it is not PayPal. - Did DMARC pass with alignment to
paypal.com? This is the only check that actually answers the question. - What does the origin IP in the bottommost trusted
Received:header resolve to? PayPal sends from PayPal's infrastructure, which has consistent, resolvable reverse DNS on ranges registered to PayPal. - Is
Reply-To:present and does it differ?
PayPal, for the record, publishes DMARC at enforcement, so direct spoofing of paypal.com fails at most major providers. Which is exactly why criminals impersonating PayPal use paypal-secure-verify.com or a display name instead. The strong policy pushed the attack sideways rather than eliminating it, and that is true of every well-protected brand.
The signature pattern of a competent spoof
Once you have seen a few hundred of these, the pattern becomes obvious:
- SPF: pass. DKIM: pass. DMARC: pass. All green, all for a domain you have never heard of.
- From display name: a well-known brand or a real executive at your company.
- From address domain: registered in the last 30 days.
- Reply-To: a free webmail address or a second lookalike domain.
- Return-Path: the attacker's domain, matching the From domain, because they set it up properly.
- Content: urgency, a payment instruction, a credential request, or a "quick favor."
- Sending IP: a cheap VPS provider, clean reputation because the IP was allocated last week.
Everything technical is correct. Everything contextual is wrong. That is why header analysis alone is not enough, and why domain age and IP reputation are as important as authentication verdicts.
13. Homoglyphs, Typosquats, and the rn/m Problem
Your brain does not read domain names character by character. It pattern-matches on shape. Attackers exploit this directly, and it is startlingly effective even on people who know about it.
The classic character confusions
Read each pair carefully. In most sans-serif fonts, including the ones your mail client and browser use, these are nearly indistinguishable at normal size:
Looks likeActually isExamplemrn (r followed by n)modern.com vs rnodern.commrrirare but useddclcloud.com vs clloud.comO (capital o)0 (zero)MICROSOFT.COM vs MICR0SOFT.COMl (lowercase L)I (capital i)paypal.com vs paypaI.coml (lowercase L)1 (one)paypal.com vs paypa1.comwvv (two v's)www.com vs vvvvvv.comhbat small sizesqgat small sizesnnmreverse of the rn trick
The rn versus m substitution is the most effective of all of them. In a typical sans-serif rendering at 14 pixels, rn and m are visually almost identical. arnazon.com reads as amazon.com to nearly everyone who is not specifically looking for it.
Try it yourself: rnicrosoft.com and microsoft.com. Look at the first two characters after the initial letter.
Unicode homoglyphs and the IDN problem
The confusions above use only ASCII. Unicode makes it dramatically worse.
Internationalized Domain Names (IDN) let domains contain non-ASCII characters, encoded in DNS using Punycode with the prefix xn--. This is necessary and good: people writing in Cyrillic, Greek, Arabic, Chinese, and dozens of other scripts need domains in their own alphabets.
The problem is that many characters in those scripts are visually identical to Latin ones:
LatinCyrillicGreekNotesaа (U+0430)α (U+03B1)Cyrillic а is pixel-identical in most fontseе (U+0435)εoо (U+043E)ο (U+03BF)pр (U+0440)ρcс (U+0441)xх (U+0445)χyу (U+0443)γiі (U+0456)ιUkrainian іsѕ (U+0455)
A domain spelled аpple.com with a Cyrillic а is a completely different domain from apple.com, registers separately, and renders identically. In Punycode it becomes xn--pple-43d.com.
The most famous demonstration was аррӏе.com, registered in 2017 entirely from Cyrillic characters, which rendered as apple.com in Chrome and Firefox with a valid HTTPS certificate. Browsers now apply script-mixing rules that force Punycode display in many cases, but mail clients are far behind browsers on this, and the rules do not cover every case.
How to check. Any domain you see rendered in a mail client should be verified in its raw form:
# Check what a domain actually is
python3 -c "print('аpple.com'.encode('idna'))"
# Look for non-ASCII in a header
grep -P '[^\x00-\x7F]' message.eml# Check what a domain actually is
python3 -c "print('аpple.com'.encode('idna'))"
# Look for non-ASCII in a header
grep -P '[^\x00-\x7F]' message.emlIf the domain contains xn--, it is an IDN, and you should decode it and examine which scripts it mixes. A domain mixing Latin and Cyrillic characters has essentially no legitimate purpose.
The right-to-left override attack
Unicode includes bidirectional control characters for languages written right to left. U+202E (RIGHT-TO-LEFT OVERRIDE) reverses the display order of everything after it.
An attacker names a file:
invoice_annexU+202Efdp.exeinvoice_annexU+202Efdp.exeThe display shows:
invoice_annexexe.pdfinvoice_annexexe.pdfThe user sees a PDF. The operating system sees an executable. This works in filenames, display names, and subject lines. Strip or flag all bidirectional control characters (U+202A through U+202E, plus U+2066 through U+2069) in anything you display to a user.
Domain-level tricks beyond character swaps
Subdomain impersonation:
paypal.com.account-verify.netpaypal.com.account-verify.netRead it right to left. The registrable domain is account-verify.net. paypal.com is just a subdomain label the attacker created. On a narrow mobile screen the URL truncates and the user sees paypal.com.acc....
Hyphen insertion:
pay-pal.com, paypal-security.com, secure-paypal.compay-pal.com, paypal-security.com, secure-paypal.comLegitimate companies do use hyphenated domains, which makes this harder to filter than it should be.
TLD swapping:
paypal.co, paypal.net, paypal.org, paypal.app, paypal.supportpaypal.co, paypal.net, paypal.org, paypal.app, paypal.supportWith hundreds of generic TLDs available, there is a plausible-looking option for every brand.
Character omission, doubling, and transposition:
paypl.com (omission)
payypal.com (doubling)
payapl.com (transposition)paypl.com (omission)
payypal.com (doubling)
payapl.com (transposition)Combosquatting:
paypal-billing.com, paypalsupport.com, paypalverification.compaypal-billing.com, paypalsupport.com, paypalverification.comThe real brand plus a plausible word. Extremely common because it does not require any visual trickery, just a domain nobody bothered to defensively register.
Practical detection
- Copy the domain out of the email and paste it into a plain text editor. Rendering differences vanish and Unicode surprises become visible.
- Read domains right to left, starting from the TLD, to identify the actual registrable domain.
- Count the characters against the real domain.
arnazonhas seven characters,amazonhas six. - Search the domain in a monospace font. Homoglyph tricks are much more visible in monospace.
- Use
whoisor RDAP to check the registration date. A lookalike registered eleven days ago answers the question by itself. - Check for
xn--anywhere in the domain. - Compare against a known-good reference rather than against memory. Pull up the real domain from a bookmark or a search engine and compare side by side.
In a mail client, hovering over a link and reading the status bar is not enough, because that is the same font and the same rendering that fooled you in the first place. Copy it out.
14. Domain Intelligence: WHOIS, Age, Tasting and Kiting
The domain is often the single most informative artifact in the entire investigation. Here is how to squeeze it.
Domain age: the highest-signal, lowest-effort check
If a domain was registered in the last 30 days and it is asking you for money, it is fraud until proven otherwise.
This one check catches an enormous share of attacks. Real businesses have old domains. A supplier you have worked with for three years does not suddenly start emailing you from a domain created last Tuesday.
Typical registration ages:
AgeInterpretation0 to 7 daysExtreme risk. Almost certainly malicious if it is contacting you unsolicited.7 to 30 daysVery high risk. Phishing infrastructure is usually burned within weeks.30 to 90 daysHigh risk. Could be a new legitimate business, but verify independently.90 days to 1 yearModerate. Look at other signals.1 to 5 yearsNormal for an established small business.5+ yearsNormal. Age alone is no longer informative.
Important caveat: aged domains are bought and sold. A criminal with budget can purchase a ten-year-old expired domain with clean reputation and history. Age is a strong negative signal when it is short and a weak positive signal when it is long.
WHOIS and RDAP
WHOIS is the legacy protocol. RDAP (Registration Data Access Protocol) is the modern JSON-based replacement and is what registries are moving to.
whois example.com
# RDAP, better structured output
curl -s https://rdap.org/domain/example.com | jqwhois example.com
# RDAP, better structured output
curl -s https://rdap.org/domain/example.com | jqWhat to extract:
FieldWhat it tells youCreation dateDomain age. The most important field.Updated dateRecent changes. A domain updated yesterday with nameserver changes may have just been hijacked or repurposed.Expiry dateA domain registered for exactly one year is cheaper and more disposable than a ten-year registration.RegistrarCertain registrars appear disproportionately in abuse data. APWG's Q1 2026 report identified NameSilo and NameCheap as the registrars most often used by BEC scammers. Cloudflare's registrar has also appeared in top-ten abuse lists, which researchers attribute to scammers feeling protected behind its proxying.NameserversRecently changed nameservers, or nameservers on free/parking services, are signals.Registrant detailsUsually redacted post-GDPR, but privacy service choice is itself a data point.Status codesclientHold, serverHold mean the domain has been suspended. pendingDelete means it is being removed.
The GDPR reality. Since 2018, registrant name, address, and email are redacted for most domains. You will see "REDACTED FOR PRIVACY" constantly. Do not treat that as suspicious in itself, it is the default. What is informative is the registrar's abuse contact, which is always published, and which you will need for reporting.
Passive DNS and historical records
Current WHOIS shows you now. Historical data shows you the story.
- Passive DNS (SecurityTrails, RiskIQ, DomainTools, Farsight) records what a domain resolved to over time. A domain that pointed to a parking page for five years and suddenly pointed to a VPS last week has been repurposed.
- Certificate Transparency logs (
crt.sh) list every TLS certificate ever issued for a domain and its subdomains. Searchcrt.shfor a brand name and you will find every lookalike domain that has ever obtained a certificate. This is one of the best free brand-monitoring techniques available. - Wayback Machine shows what the site looked like historically. A "twenty-year-old company" whose website first appeared three weeks ago is not a twenty-year-old company.
Domain tasting: the exploit that was mostly closed
This deserves proper explanation because it is frequently mentioned and rarely understood correctly.
The mechanism. ICANN's Add Grace Period (AGP) is a five-day window after registering a domain during which the registrar can delete it and receive a full refund of the registration fee. It was created for a legitimate reason: to let registrars correct typos and processing errors without penalty.
The abuse. Speculators realized they could register domains in bulk, park them with pay-per-click advertising for five days, measure the traffic and revenue, keep the profitable few, and return everything else for free. Effectively a free trial on the entire domain namespace.
The scale it reached. In February 2007, GoDaddy's CEO reported that of 55.1 million domain names registered, 51.5 million were cancelled and refunded just before the five-day grace period expired, with only 3.6 million actually kept. ICANN's registry report for that month showed 55,794,877 .com and .net domains deleted. At the peak, over 95 percent of all registrations were speculative tasting.
Why this mattered for fraud. Free domains meant disposable domains. A phisher could register a batch, run a campaign, and return them all at no cost.
How it was killed. ICANN's GNSO approved a policy in April 2008. The ICANN Board adopted it on 26 June 2008 and implementation was announced on 17 December 2008. The AGP Limits Policy states that registries will not refund AGP deletions exceeding 10 percent of a registrar's net new registrations that month, or 50 domain names, whichever is greater, absent a granted exemption.
The result. ICANN's August 2009 status report was titled "The End of Domain Tasting." AGP deletions fell 99.7 percent, from millions per month to roughly 55,000 to 65,000 per month, which is about 0.3 percent of the previous volume.
Domain kiting, the related practice of repeatedly deleting and re-registering the same domain to hold it indefinitely for free, was eliminated by the same policy.
What this means today. Domain tasting as a mass phenomenon is dead. But the underlying economics did not disappear, they just cost money now. What replaced it:
- Bulk cheap registrations. New gTLDs and promotional pricing put domains at one to three dollars. At that price, disposability is affordable without any refund.
- Snowshoe spamming. Spreading a campaign thinly across hundreds of domains and IPs so no single one accumulates enough reputation damage to be blocked.
- Compromised legitimate domains. Free, aged, and already trusted. Why register when you can steal?
- Subdomain abuse on free hosting.
victim-brand.pages.dev,victim-brand.web.app,victim-brand.r2.dev. No registration required, and the parent domain has excellent reputation. - Expired domain purchases. Buying an established domain with existing backlinks and clean reputation from a drop-catch service.
The forensic takeaway: you will not see five-day-old domains that were free. You will see thirty-day-old domains that cost two dollars, and you will see legitimate ten-year-old domains that were compromised. Check registration date, check whether the domain has actual history, and check whether the current use matches the historical use.
Fast flux and infrastructure rotation
Some campaigns rotate the IP addresses behind a domain every few minutes using very low DNS TTL values. This is fast flux. Double flux rotates the nameservers as well.
Detection: query the domain repeatedly and see whether the A record changes.
for i in $(seq 1 10); do dig +short A suspicious-domain.example; sleep 30; donefor i in $(seq 1 10); do dig +short A suspicious-domain.example; sleep 30; doneLegitimate CDN usage also returns different IPs, so check whether the returned IPs belong to a known CDN's ASN or to scattered consumer ISPs across multiple countries. The latter is a botnet.
15. IP Intelligence with IPQualityScore
You have extracted the origin IP from the bottommost trusted Received: header. Now find out what it is.
The free tool that does most of the work
IPQualityScore is the most useful free IP reputation service available. A free account is genuinely sufficient for investigative work. You do not need a premium subscription to get the answers that matter.
Paste the IP into their IP reputation lookup and you get back:
SignalWhy it matters**Fraud Score (0–100)**Composite risk rating. Above 75 is high risk, above 85 is very high.Proxy / VPN / Tor detectionLegitimate corporate mail servers do not sit behind consumer VPNs or Tor exit nodes. This flag alone often ends the investigation.Recent abuse activityWhether this IP has been reported for abuse recently.Bot statusAutomated traffic indicators.ISP and organizationWho owns the address space.ASNThe autonomous system number. Some ASNs are notorious for hosting abuse.Country, region, cityGeolocation.Connection typeResidential, corporate, data center, mobile. This is one of the most valuable fields.TimezoneCross-check against header timestamps.
How to interpret what you get back
Connection type is often decisive.
- Corporate or data center IP with clean reputation and proper reverse DNS: consistent with a legitimate mail server.
- Residential broadband IP: legitimate mail servers do not run on residential connections. Almost every major ISP blocks outbound port 25 from residential ranges specifically to prevent this. A residential origin means a compromised home machine in a botnet, with near-certainty.
- Mobile carrier IP: same reasoning. Nobody runs a corporate MTA on a phone connection.
- Data center IP with no reverse DNS and recent registration: a VPS spun up for this campaign.
- VPN or proxy detected: whoever sent this took steps to hide their location.
Geolocation is context, not evidence. An IP in Nigeria on a message from your Nigerian supplier is fine. An IP in a country where your CFO has never been on a message claiming to be from your CFO, sent at 3 AM their local time, is a finding. Geolocation databases are also imprecise, frequently off by hundreds of kilometers and occasionally by continents, particularly for mobile and satellite ranges.
Fraud score is a starting point, not a verdict. A clean score on a freshly allocated VPS IP means only that nobody has reported it yet. Fresh infrastructure always looks clean. That is why criminals use fresh infrastructure.
The checks to run alongside it
Reverse DNS (PTR):
dig -x 203.0.113.45 +shortdig -x 203.0.113.45 +shortA legitimate mail server has a PTR record, and that PTR name resolves back to the same IP. This is forward-confirmed reverse DNS. Verify both directions:
dig -x 203.0.113.45 +short # gives mail.example.com
dig +short A mail.example.com # should give back 203.0.113.45dig -x 203.0.113.45 +short # gives mail.example.com
dig +short A mail.example.com # should give back 203.0.113.45If the PTR is generic (45-230-147-12.static.cheap-vps.example), auto-generated, or missing entirely, that is a strong negative for anything claiming to be corporate mail infrastructure.
ASN and network ownership:
whois -h whois.cymru.com " -v 203.0.113.45"whois -h whois.cymru.com " -v 203.0.113.45"Returns the ASN, the network prefix, the country, and the registered owner. Ask: does this network belong to the organization the email claims to come from? PayPal's mail comes from PayPal's networks. If the ASN belongs to a bulletproof hosting provider or a reseller of reseller VPS capacity, you have your answer.
DNS blocklists:
Check the IP against the major reputation lists: Spamhaus (SBL, XBL, PBL, CSS), Barracuda, SORBS, SpamCop, and the composite lists. MXToolbox's blacklist check queries dozens at once. Note that:
- PBL (Policy Block List) listings indicate the IP is in a range that should not be sending mail directly, typically residential. A PBL hit is nearly conclusive for a botnet origin.
- XBL indicates known compromised or exploited machines.
- A clean result proves nothing for new infrastructure.
Historical hosting:
Reverse IP lookup shows what else is or was hosted on that address. An IP hosting four hundred domains is shared hosting. An IP hosting one domain registered last week is dedicated attack infrastructure.
Building the IP picture
For each candidate origin IP, record:
- The IP itself and which
Received:header it came from - PTR record and whether FCrDNS confirms
- ASN, network owner, and network name
- Geolocation and timezone
- Connection type (residential / data center / mobile / corporate)
- VPN, proxy, or Tor detection
- IPQualityScore fraud score
- Blocklist status across major lists
- Other domains on the same IP
- Whether the IP falls within the claimed sender domain's published SPF ranges
Point 10 is worth emphasizing. Pull the claimed sender's SPF record, expand every include:, and check whether the origin IP is inside any of the authorized ranges. If the domain publishes SPF and the origin IP is not in it, the message did not come from that domain's authorized infrastructure, regardless of what any header says.
16. Address Validation: Disposable, Catch-All, Role-Based
Domain and IP tell you about infrastructure. The address itself tells you about the mailbox.
The verdicts and what each one means
Valid. The syntax is correct, the domain has MX records, and (where deep verification is available) the receiving server confirms the specific mailbox exists. This is what you want for a real correspondent.
Invalid. Malformed syntax, no MX records, or the server explicitly rejects the mailbox with a 550. A Reply-To: address that does not exist means replies vanish, which is common in one-way scam campaigns.
Disposable. The domain is a temporary inbox service: Mailinator, GuerrillaMail, 10MinuteMail, Temp-Mail, and hundreds of others. These exist to receive one message and be forgotten. A disposable address on a business communication is close to conclusive. No supplier sends invoices from a ten-minute mailbox.
Catch-all. The domain is configured to accept mail for every possible address before the @ symbol. anything@catchall-domain.com returns a 250. This means verification cannot confirm whether a specific mailbox exists, so the honest verdict is "unknown," not "valid." Catch-alls are legitimate and common at small businesses that do not want to lose mail to typos. They are also heavily used by attackers, because a catch-all domain lets them receive replies at any address they invent, which makes lookalike domains far more effective.
Role-based. Shared function addresses: info@, support@, admin@, noreply@, billing@, sales@. Not suspicious in themselves, but they generate disproportionate spam complaints and they are shared, which means "who actually sent this?" has no single answer. A payment instruction from a role address deserves out-of-band verification on principle.
Free-mail. Gmail, Yahoo, Outlook.com, iCloud, Proton. Entirely normal for individuals. A red flag on a business communication that should come from a corporate domain. APWG data has consistently shown Gmail as the dominant free webmail provider used to set up BEC accounts, at roughly 73.5 percent of scammer-created free accounts, with Microsoft's properties a distant second at 13.8 percent.
Typo / did-you-mean. gmial.com, yaho.com, hotnail.com, outlok.com. Sometimes an honest mistake. Sometimes a deliberately registered typosquat harvesting misdirected mail.
The tool
EmailVerifyerAPI is the cleanest free option for this, and it has one property that matters a great deal in an investigative context: it runs entirely in your browser.
The addresses you check never leave your device. They are not sent to a server, not logged, and there is no account or database. For an investigator handling addresses that may be evidence, or a security team checking addresses belonging to real victims, that is a meaningful privacy property. Most verification services upload your list to their infrastructure. This one does not.
It runs six checks:
- Syntax validation against RFC 5322, catching malformed addresses, illegal characters, double dots, and missing TLDs
- Disposable domain detection against known temporary inbox providers
- Role-based address detection
- Free-mail provider detection, useful for scoring B2B versus B2C
- Catch-all heuristic, flagging the result as risky rather than falsely reporting valid
- Did-you-mean typo correction for common domain misspellings
Each address returns valid, risky, or invalid with a per-signal breakdown, so you can see why rather than just getting a pass or fail. Single-address checks and bulk CSV upload are free with no signup. MX record lookup and live mailbox verification are on their roadmap for the API release.
The free DNS lookup tools mentioned in section 9 (MX, SPF, DKIM, DMARC checkers and the DNS fingerprint tool) sit alongside it and cover most of what you would otherwise need dig for.
Where address validation fits in the investigation
Run it on every address in the message, not just the From:
- The
From:address - The
Reply-To:address (this is the one that matters most in BEC) - The
Return-Path:address - Any addresses in the body signature block
- Any addresses in
Cc:you do not recognize - The address on any invoice or attachment
The single highest-value check: if From: resolves to a valid corporate address and Reply-To: resolves to a free-mail or disposable address, you have found an impersonation attempt. That pattern is the most common technical signature of BEC in existence.
Why this matters beyond fraud
The same checks protect deliverability. Marketing lists decay by roughly 22 percent per year as people change jobs and abandon inboxes. Sending to dead addresses drives hard bounces, and hard bounce rates above roughly 2 percent trigger reputation damage at major providers. Google and Yahoo's bulk sender requirements, effective February 2024 for senders of 5,000+ messages per day, require keeping the spam complaint rate below 0.3 percent, ideally under 0.1 percent, alongside SPF, DKIM, DMARC, and one-click unsubscribe. In November 2025, Gmail escalated from soft warnings to actively rejecting non-compliant mail at the SMTP level.
Clean lists are a security control as well as a marketing one. A compromised address on your list is a delivery path into your customer base.
17. Why You Should Never Open a Suspicious Email
This section is the one most likely to change your daily behavior.
What a tracking pixel is
A tracking pixel is an image, typically 1 pixel by 1 pixel, fully transparent, loaded from a remote server, embedded in the HTML body of an email:
<img src="https://track.example.com/o.gif?id=a7f3d9e2b8c1" width="1" height="1" style="display:none" alt=""><img src="https://track.example.com/o.gif?id=a7f3d9e2b8c1" width="1" height="1" style="display:none" alt="">You cannot see it. It occupies no visible space. When your mail client renders the HTML, it makes an HTTP request to that server to fetch the image, and that request tells the sender:
Data pointHow they get itThat you opened itThe request happened at allWhenServer timestamp, to the secondHow many timesEach render is another requestYour IP addressSource of the HTTP requestYour approximate locationGeolocated from the IPYour device and OSUser-Agent headerYour mail clientUser-Agent headerWhich specific messageThe unique ID in the URLWhich specific recipientThe ID maps to your address in their databaseWhether you forwarded itRequests from new IPs with the same ID
That last point is worth pausing on. The tracking ID is unique per recipient. If you forward the message to your security team and three more people open it, the attacker sees three additional opens from your corporate IP range and learns your organization is investigating.
Why this matters more than people think
1. It confirms you are real. An unverified address on a scraped list is worth very little. An address confirmed to belong to a human who reads email is worth substantially more, and gets promoted to targeted campaigns and sold on.
2. It reveals your infrastructure. Your public IP, your egress point, your client software and version. That is reconnaissance for a follow-up attack against a known-vulnerable client version.
3. It reveals your habits. Open times across multiple messages map your working hours, your timezone, and your travel. Very useful for timing a BEC attempt for a Friday at 4:45 PM when your CFO is boarding a flight.
4. It tells them the attack got through. Confirmation that your filtering did not catch this particular technique, so they will use it again.
5. It can carry a payload. Remote content is not limited to a transparent GIF. It can be a large image, a font, a CSS file, or a redirect chain. Image parsers have had remotely exploitable vulnerabilities. Loading remote content from a hostile server is not risk-free.
6. Some clients leak more than the request. Historically, various clients have leaked NTLM credentials, local file paths, and other data when rendering remote content or certain HTML constructs.
The legitimate uses, and why they are still the same technology
Tracking pixels are not exclusively criminal. They are the foundation of email marketing analytics.
- Every ESP uses them. Mailchimp, HubSpot, Klaviyo, SendGrid, Salesforce Marketing Cloud, Constant Contact. Every "open rate" figure in every marketing dashboard comes from a tracking pixel.
- Mailtrack, the Chrome extension, adds tracking to ordinary Gmail messages. It is installed by millions of people, including sales professionals, recruiters, and job seekers, and it is where the familiar double-checkmark read-receipt behavior comes from.
- Streak, Yesware, HubSpot Sales, Mixmax, Bananatag, Snov.io and dozens of similar tools do the same thing.
- Read receipts in corporate mail systems work on the same principle, though usually with an explicit prompt.
The technology is identical. A marketing pixel and a reconnaissance pixel are the same three lines of HTML. The only difference is intent, and you cannot determine intent from the HTML.
This means: if you open marketing email with images enabled, you are being tracked constantly, by dozens of organizations, every day. Most people are entirely unaware of the volume.
How to block it
Disable automatic remote content loading. This is the single most valuable email privacy setting, and every client has it.
- Gmail: Settings → General → Images → "Ask before displaying external images." Note that Gmail proxies images through its own servers by default, which hides your IP but still confirms the open. Turning off automatic loading blocks the request entirely.
- Outlook desktop: File → Options → Trust Center → Trust Center Settings → Automatic Download → check "Don't download pictures automatically in standard HTML email."
- Outlook web: Settings → Mail → Message handling → turn off external image loading.
- Apple Mail: Mail → Settings → Privacy → enable Protect Mail Activity. This routes all remote content through Apple's proxy and hides your IP. It does still fetch the content, so it does not prevent open confirmation.
- Thunderbird: Blocks remote content by default and shows a bar offering to load it. Leave it alone.
- Proton Mail: Settings → Email → Images → block by default.
Read in plain text. The strongest option. If you never render HTML, no remote content ever loads. Thunderbird and most desktop clients support forcing plain text view. It is ugly. It is also completely safe.
The correct procedure for a suspicious message
- Do not open it in your normal client. If your preview pane already rendered it, the pixel already fired. Turn off your preview pane.
- Extract the raw source using the "show original" or "view source" function, which does not render.
- Save the
.eml. - Analyze the headers in a text editor. Text editors do not fetch remote content.
- If you must examine the body, do it as source code, not as rendered HTML.
- If you must render it, use an isolated VM with no network access, or a purpose-built sandbox.
- Never click any link, even to "check where it goes." Every link in a phishing email contains a unique identifier for you. Clicking confirms you not only opened it but engaged with it, which is worth far more than an open. Use a URL analysis service that fetches from its own infrastructure instead.
- When forwarding to your security team, forward as an attachment, not inline. Forwarding inline in HTML mode causes their client to render the same pixels.
Reading the pixel as evidence
When you have the source, tracking infrastructure tells you about the sender:
# Find all remote resources
grep -oE '(src|href)="https?://[^"]+"' message.eml | sort -u
# Find 1x1 images specifically
grep -iE 'width=.?1.?\s+height=.?1.?|width:\s*1px' message.eml# Find all remote resources
grep -oE '(src|href)="https?://[^"]+"' message.eml | sort -u
# Find 1x1 images specifically
grep -iE 'width=.?1.?\s+height=.?1.?|width:\s*1px' message.emlThen ask:
- What domain hosts the tracking? A known ESP domain suggests a real marketing platform, which may itself be compromised or abused, but is different from custom infrastructure.
- Is the tracking domain different from the sending domain? Normal for ESPs, notable otherwise.
- How many distinct external domains does the message contact? A legitimate newsletter touches two or three. A message contacting eleven different domains is doing something else.
- Does the pixel URL contain an encoded email address? Many do, base64 or hex encoded. Decoding it confirms the message was individually targeted rather than blasted.
18. Body and Payload Forensics
Headers tell you where a message came from. The body tells you what it wants.
URL analysis
Extract every URL first:
grep -oE 'https?://[^"'"'"' <>]+' message.eml | sort -ugrep -oE 'https?://[^"'"'"' <>]+' message.eml | sort -uRemember to decode quoted-printable (=3D is =, =20 is a space) and base64 parts before extracting, or you will miss most of them.
What to check on each URL:
- Does the anchor text match the destination? The classic mismatch:
<a href="https://evil-site.example/login">https://www.yourbank.com/login</a><a href="https://evil-site.example/login">https://www.yourbank.com/login</a>The user reads the second URL and lands on the first.
- Is it a redirect chain? Most phishing links go through several hops: a URL shortener, a compromised legitimate site, an open redirect on a trusted domain, then the final page. Trace the chain with a tool that fetches from its own infrastructure, never your browser.
- Is it abusing an open redirect on a trusted domain?
https://trusted-brand.com/redirect?url=https://evil.examplehttps://trusted-brand.com/redirect?url=https://evil.exampleThe visible domain is legitimate. The destination is not. Open redirects on major platforms are found and abused constantly.
- Is it a URL shortener? bit.ly, tinyurl, t.co, and hundreds of others. Expand before visiting. Most shorteners let you append + or
/infoto preview the destination without following it. - Does it contain your email address? Often base64 encoded in a path segment or parameter. Its presence proves individual targeting.
- Is the domain in the URL different from the sending domain? Normal for ESPs and click-tracking, but on a message claiming to be from a bank, the login link should be on the bank's domain.
- Is it an IP address instead of a hostname?
http://203.0.113.45/login.php. Legitimate organizations do not do this. - Does it use a non-standard port?
https://example.com:8443/. Unusual for public-facing consumer services. - Punycode or Unicode in the hostname? See section 13.
- What is the file extension of the destination? A "PDF invoice" link ending in
.exe,.hta,.scr,.js,.vbs,.iso, or.lnkis malware delivery.
QR codes: the vector that bypasses everything
QR code phishing, sometimes called quishing, has exploded because it defeats the entire email security stack in one move. There is no URL in the message for a filter to scan. The malicious link exists only as an image, and the user's action moves the attack to a personal phone that has none of your corporate controls.
Microsoft's telemetry showed QR-code phishing detections rising from 7.6 million in January 2026 to 18.7 million in March 2026, an increase of about 146 percent in a single quarter. APWG contributors have reported detecting hundreds of thousands of unique malicious QR codes per quarter.
How to handle a QR code in a suspicious email:
- Extract the image from the MIME parts.
- Decode it offline with a local tool (
zbarimgon Linux, or any offline decoder). Do not point your phone camera at it. - Analyze the decoded URL like any other URL.
Attachments
The dangerous types, in rough order of prevalence:
TypeRisk.html / .htmLocal credential harvesting pages that never touch a URL filter. Currently one of the most common vectors..pdfUsually a container for a link or a QR code rather than an exploit. Check embedded URLs and JavaScript..docm, .xlsm, .pptmMacro-enabled Office. Less effective since Microsoft began blocking macros from internet-sourced files by default, but still used..iso, .img, .vhdDisk images. Historically bypassed Mark-of-the-Web propagation, so contents lost their "downloaded from internet" flag..zip, .7z, .rarArchives, often password-protected with the password in the message body specifically to defeat scanning..lnkWindows shortcuts that execute arbitrary commands..js, .vbs, .hta, .wsfDirect script execution..svgCan contain JavaScript. Increasingly used for credential phishing pages..oneOneNote files, which can embed and execute attachments.
Analysis procedure:
- Never open it. Extract it from the MIME structure without executing.
- Hash it:
sha256sum attachment.ext - Look up the hash in VirusTotal or a similar service. Searching a hash does not upload the file, so it does not leak potentially confidential content.
- Check the true file type rather than the extension:
file attachment.ext. Magic bytes do not lie the way extensions do. - Examine structure without executing.
oletools(olevba,oleid,rtfobj) for Office documents.pdfidandpdf-parserfor PDFs.binwalkfor embedded content. - Detonate only in a sandbox if you need behavioral analysis: Any.Run, Joe Sandbox, Hybrid Analysis, or your own isolated VM.
Uploading files to public sandboxes makes them public. If the attachment might contain your organization's confidential data, hash-only lookup is the correct approach.
Content and language signals
Technical analysis catches the infrastructure. Reading the message catches the intent.
Urgency and time pressure. "Within 24 hours." "Your account will be suspended." "Before end of business today." Urgency exists to prevent verification. It is the most reliable single indicator across every fraud type.
Authority and hierarchy. Impersonating a CEO, a regulator, a tax authority, a law enforcement agency. Combined with urgency, it discourages the junior employee from checking.
Secrecy. "Do not discuss this with anyone." "This is confidential until the announcement." Isolating the target from the colleague who would have spotted it.
Unusual channel or process. A request to move to WhatsApp or personal email. A payment process that skips the normal approval chain. A request to buy gift cards.
Payment detail changes. Any email changing bank details is a BEC attempt until proven otherwise, without exception. This is the highest-value pattern in the entire field. Verify by phone, using a number you already had, never a number in the email.
Generic or slightly wrong salutation. "Dear Customer" from a company that knows your name. Or the correct name spelled slightly wrong.
Quality is no longer a signal. This matters. Historically, bad grammar was a reliable indicator. Generative AI eliminated that. IBM X-Force reported in 2026 that AI has reduced phishing email creation time from roughly 16 hours to about 5 minutes, and the FBI's 2025 IC3 report logged 22,364 AI-related complaints with $893 million in losses, its first year formally tracking the category. Modern phishing is grammatically perfect, contextually accurate, and tonally correct. Stop teaching "look for typos." It is now actively harmful advice, because it gives people a false confidence signal that attackers have already defeated.
Thread hijacking. The message appears inside a real conversation, with real quoted history, real In-Reply-To headers, and real participants, because the attacker has read the mailbox. This defeats almost every heuristic a user has. The only reliable defense is out-of-band verification of the specific request, not assessment of the message.
19. The Investigator's Toolchain
Everything here is free or has a genuinely useful free tier.
Header analysis
Sublime Security Email Analyzer: Paste raw headers or upload an .eml and get back a structured breakdown plus detection signals and a risk verdict. It runs the message against Sublime's open detection rule set, so you see not just a score but which behavioral rules fired and why. Free, no account required. This is my default first stop for any message I cannot immediately classify, because the reasoning it exposes is educational in a way that a bare score is not.
Google Admin Toolbox Messageheader (toolbox.googleapps.com/apps/messageheader/): Simple, fast, excellent at one thing: visualizing the Received: chain with per-hop delay times calculated for you. If you only want the timing analysis, start here.
Microsoft Message Header Analyzer (mha.azurewebsites.net): Similar, with better parsing of Microsoft-specific X- headers. Essential if you work in a Microsoft 365 environment.
MXToolbox Email Header Analyzer: Header parsing integrated with their DNS and blacklist tooling, so you can pivot from a header to a blacklist check in one place.
Authentication and DNS
EmailVerifyerAPI: Free browser-based address verification (six checks, nothing leaves your device) plus free lookup tools for MX (including MTA-STS and TLS-RPT status), SPF (with RFC 7208 lookup counting), DKIM, DMARC, and email DNS fingerprinting to identify the vendor behind any mail infrastructure.
MXToolbox: The general-purpose DNS and blacklist Swiss army knife. dig-equivalent lookups plus blacklist checks against dozens of lists at once.
dmarcian, EasyDMARC, PowerDMARC, Red Sift: DMARC record inspection and report parsing. All have free checkers.
dig / nslookup / host: Nothing beats the command line for speed and for seeing exactly what the DNS returned.
swaks: The Swiss Army Knife for SMTP. Test your own server's behavior, verify STARTTLS, check authentication requirements, confirm that your SPF and DMARC actually reject what they should. Use it against infrastructure you own.
IP and domain intelligence
IPQualityScore: IP reputation, fraud score, proxy/VPN/Tor detection, connection type, and ASN data. Free account is sufficient.
Spamhaus: The authoritative blocklists. Free lookup for individual IPs.
AbuseIPDB: Community-reported abuse history with categorization.
Shodan / Censys: What services an IP or domain exposes to the internet. Use for your own infrastructure and for understanding a suspicious host.
Team Cymru IP-to-ASN (whois -h whois.cymru.com): Fast, scriptable ASN lookup.
crt.sh: Certificate Transparency search. The best free tool for finding lookalike domains that have obtained certificates for your brand.
SecurityTrails / DomainTools / ViewDNS: Passive DNS and historical WHOIS. Free tiers are limited but often enough.
RDAP (rdap.org): Structured, modern replacement for WHOIS.
Wayback Machine: Historical site content. Confirms whether a "long-established" business actually existed.
URL and file analysis
urlscan.io: Fetches a URL from its own infrastructure, records the redirect chain, screenshots the page, lists every resource loaded, and captures the DOM. Your IP is never exposed. Use the unlisted or private scan setting when investigating targeted attacks, because public scans are visible to everyone, including the attacker monitoring for investigation.
VirusTotal: Multi-engine scanning for URLs, files, IPs, and domains. Hash lookup avoids uploading content.
Any.Run: Interactive sandbox. You watch the malware execute in real time and can interact with it.
Hybrid Analysis / Joe Sandbox: Automated behavioral analysis with detailed reports.
PhishTool: Purpose-built phishing analysis with a free community tier. Upload an .eml and get a structured investigation workspace.
oletools / pdfid / pdf-parser / binwalk: Local static analysis of Office documents, PDFs, and arbitrary binaries.
CyberChef: Browser-based decoder for base64, quoted-printable, URL encoding, hex, Punycode, and about two hundred other operations, all locally in your browser. Indispensable.
Reference and threat intelligence
PhishTank / OpenPhish: Community phishing URL databases.
MITRE ATT&CK: Technique mapping for your reports. Phishing is T1566, with sub-techniques for attachment (T1566.001), link (T1566.002), and service (T1566.003).
APWG eCrime eXchange: Industry phishing intelligence sharing.
Building a workflow
For routine triage, this sequence takes about four minutes per message:
- Save the
.emland hash it. - Paste into Sublime Analyzer for a first read and detection signals.
- Paste into Google Messageheader for the hop timing visualization.
- Extract the origin IP, run it through IPQualityScore, check PTR and ASN.
- Extract every domain, check registration age via RDAP, check
crt.shfor related certificates. - Run every address through EmailVerifyerAPI.
- Check the claimed sender's SPF, DKIM, and DMARC records.
- Extract URLs, run through urlscan.io as an unlisted scan.
- Hash attachments, look up in VirusTotal.
- Score, document, decide, report.
20. A Complete Worked Case Study
Let us run one end to end. The finance manager at Acme Corp receives this and forwards it to you as an attachment.
The message as displayed
From: Sarah Mitchell (CFO) <s.mitchell@acme-corp.com>
Subject: Urgent - Updated wire details for Nordstream contract
Date: Tuesday, 18 August 2026 at 10:14From: Sarah Mitchell (CFO) <s.mitchell@acme-corp.com>
Subject: Urgent - Updated wire details for Nordstream contract
Date: Tuesday, 18 August 2026 at 10:14Body: a short, well-written note explaining that the supplier has changed banks, new details attached, please process today because the payment is already late, and Sarah is in meetings all afternoon so please do not call.
Nothing about the visible message looks wrong. Sarah's name is right. Her title is right. The contract name is real.
The headers
Delivered-To: finance@acme-corp.com
Received: from mx1.acme-corp.com (localhost [127.0.0.1])
by mail.acme-corp.com (Postfix) with ESMTP id 9F3D1A2B
for <finance@acme-corp.com>; Tue, 18 Aug 2026 10:14:31 +0000 (UTC)
Received: from gateway.securemail-vendor.net (gateway.securemail-vendor.net [198.51.100.20])
by mx1.acme-corp.com (Postfix) with ESMTPS id 8E2C0B4D
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
for <finance@acme-corp.com>; Tue, 18 Aug 2026 10:14:28 +0000 (UTC)
Received: from mail.acme-corp.net (mail.acme-corp.net [203.0.113.199])
by gateway.securemail-vendor.net with ESMTPS id 7D1B9C3E;
Tue, 18 Aug 2026 10:14:24 +0000 (UTC)
Authentication-Results: mx1.acme-corp.com;
spf=pass (acme-corp.com: domain of bounce@acme-corp.net designates 203.0.113.199 as permitted sender) smtp.mailfrom=bounce@acme-corp.net;
dkim=pass header.i=@acme-corp.net header.s=default header.b=K8m2Nq4P;
dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=acme-corp.net
Return-Path: <bounce@acme-corp.net>
From: "Sarah Mitchell (CFO)" <s.mitchell@acme-corp.net>
Reply-To: "Sarah Mitchell" <sarah.mitchell.cfo@gmail.com>
To: finance@acme-corp.com
Subject: Urgent - Updated wire details for Nordstream contract
Date: Tue, 18 Aug 2026 10:13:52 +0000
Message-ID: <20260818101352.7F3A1@mail.acme-corp.net>
X-Priority: 1 (Highest)
X-Mailer: Microsoft Outlook 16.0
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="----=_Part_8821_1073741824.1755511432"Delivered-To: finance@acme-corp.com
Received: from mx1.acme-corp.com (localhost [127.0.0.1])
by mail.acme-corp.com (Postfix) with ESMTP id 9F3D1A2B
for <finance@acme-corp.com>; Tue, 18 Aug 2026 10:14:31 +0000 (UTC)
Received: from gateway.securemail-vendor.net (gateway.securemail-vendor.net [198.51.100.20])
by mx1.acme-corp.com (Postfix) with ESMTPS id 8E2C0B4D
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
for <finance@acme-corp.com>; Tue, 18 Aug 2026 10:14:28 +0000 (UTC)
Received: from mail.acme-corp.net (mail.acme-corp.net [203.0.113.199])
by gateway.securemail-vendor.net with ESMTPS id 7D1B9C3E;
Tue, 18 Aug 2026 10:14:24 +0000 (UTC)
Authentication-Results: mx1.acme-corp.com;
spf=pass (acme-corp.com: domain of bounce@acme-corp.net designates 203.0.113.199 as permitted sender) smtp.mailfrom=bounce@acme-corp.net;
dkim=pass header.i=@acme-corp.net header.s=default header.b=K8m2Nq4P;
dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=acme-corp.net
Return-Path: <bounce@acme-corp.net>
From: "Sarah Mitchell (CFO)" <s.mitchell@acme-corp.net>
Reply-To: "Sarah Mitchell" <sarah.mitchell.cfo@gmail.com>
To: finance@acme-corp.com
Subject: Urgent - Updated wire details for Nordstream contract
Date: Tue, 18 Aug 2026 10:13:52 +0000
Message-ID: <20260818101352.7F3A1@mail.acme-corp.net>
X-Priority: 1 (Highest)
X-Mailer: Microsoft Outlook 16.0
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="----=_Part_8821_1073741824.1755511432"Step 1: The From domain
The display shows s.mitchell@acme-corp.com.
The actual header says s.mitchell@acme-corp.net.
.net, not .com. The finance manager's mail client displayed only "Sarah Mitchell (CFO)" and she never saw the address.
Finding 1: lookalike domain. This is the whole case, found in the first ten seconds of looking at the raw header.
Everything else is corroboration, but let us do it properly, because in a real investigation you need the full picture for the report and for the follow-up.
Step 2: The authentication verdicts
spf=pass smtp.mailfrom=bounce@acme-corp.net
dkim=pass header.i=@acme-corp.net
dmarc=pass header.from=acme-corp.netspf=pass smtp.mailfrom=bounce@acme-corp.net
dkim=pass header.i=@acme-corp.net
dmarc=pass header.from=acme-corp.netAll three pass. And they are all correct. The message genuinely came from acme-corp.net, which is genuinely configured with SPF and DKIM, and DMARC genuinely aligns because the From domain and the authenticated domain are the same domain.
This is the crucial teaching point of the entire article. Three green checkmarks. Zero protection. The authentication stack answered the question it was designed to answer: "did acme-corp.net send this?" Yes, it did. It cannot answer "is acme-corp.net the company you think it is?" because that is not a question DNS can answer.
Finding 2: authentication pass on an attacker-controlled domain.
Step 3: Reply-To
Reply-To: "Sarah Mitchell" <sarah.mitchell.cfo@gmail.com>Reply-To: "Sarah Mitchell" <sarah.mitchell.cfo@gmail.com>The From is a corporate-looking domain. The Reply-To is Gmail. Any reply goes to a free webmail account the attacker controls.
Finding 3: Reply-To mismatch to free webmail. This is the classic BEC signature.
Step 4: The Received chain
Three hops. Read bottom-up:
mail.acme-corp.net [203.0.113.199]→ the vendor gateway, 10:14:24- Vendor gateway → Acme's MX, 10:14:28 (4 seconds)
- Acme's MX → mailbox, 10:14:31 (3 seconds)
Three hops for external mail through a gateway is on the low side but plausible. Timing is clean, monotonic, no gaps. TLS on both of the last two hops.
The chain itself is unremarkable. The attacker did not need to hide anything, because they were not spoofing. They were sending legitimate mail from their own legitimate domain.
Finding 4: no chain anomalies, which is itself informative. This is not a botnet spray, it is targeted infrastructure.
Step 5: The Date header
Date: Tue, 18 Aug 2026 10:13:52 +0000 First Received: at 10:14:24.
32-second gap. Entirely normal for composition-to-transmission latency.
No finding. Worth checking every time, because when it is wrong, it is very wrong.
Step 6: Message-ID
Message-ID: <20260818101352.7F3A1@mail.acme-corp.net>Message-ID: <20260818101352.7F3A1@mail.acme-corp.net>Domain matches the sending infrastructure, so it is internally consistent. But the format, a timestamp followed by a short hex string, is characteristic of Postfix or a scripted sender, not Microsoft Exchange.
Compare to X-Mailer: Microsoft Outlook 16.0.
Finding 5: the claimed mail client does not match the Message-ID format. Real Outlook via Exchange produces Message-IDs in a very different format, typically long and containing the Exchange organization identifiers. This message was not sent from Outlook. The X-Mailer header is decoration.
Step 7: Domain intelligence on acme-corp.net
$ whois acme-corp.net | grep -iE 'creation|updated|registrar'
Creation Date: 2026-08-04T11:22:07Z
Updated Date: 2026-08-04T11:22:07Z
Registrar: NameSilo, LLC$ whois acme-corp.net | grep -iE 'creation|updated|registrar'
Creation Date: 2026-08-04T11:22:07Z
Updated Date: 2026-08-04T11:22:07Z
Registrar: NameSilo, LLCRegistered 14 days before the attack. Never updated since. NameSilo, one of the two registrars APWG identified as most used by BEC scammers in Q1 2026.
Check crt.sh for acme-corp: certificates issued for acme-corp.net and mail.acme-corp.net on 2026-08-04, both Let's Encrypt, both issued within an hour of registration. Full infrastructure stood up in one sitting.
Wayback Machine: no captures. The domain has no web presence at all.
Finding 6: domain age 14 days, registrar with elevated abuse association, no web history, infrastructure built in a single session.
Step 8: IP intelligence on 203.0.113.199
IPQualityScore returns:
- Fraud Score: 72
- Proxy: No, VPN: No, Tor: No
- Connection type: Data center
- ISP: a budget VPS provider
- ASN: a reseller network
- Recent abuse: none reported
- Country: does not match Acme's operating region
Reverse DNS:
$ dig -x 203.0.113.199 +short
mail.acme-corp.net.
$ dig +short A mail.acme-corp.net
203.0.113.199$ dig -x 203.0.113.199 +short
mail.acme-corp.net.
$ dig +short A mail.acme-corp.net
203.0.113.199FCrDNS confirms, which means the attacker set the PTR correctly. Competent.
Finding 7: data center IP on a budget VPS reseller, clean reputation because it is new, geolocation inconsistent with the claimed sender.
Note the clean abuse history. Fresh infrastructure always looks clean. Absence of a bad reputation is not the presence of a good one.
Step 9: Address validation
Running each address through EmailVerifyerAPI:
AddressResults.mitchell@acme-corp.netRisky. Catch-all domain detected, so mailbox existence cannot be confirmed.sarah.mitchell.cfo@gmail.comValid. Free-mail provider detected.bounce@acme-corp.netRisky. Catch-all, role-based.
The catch-all configuration on acme-corp.net is deliberate: it means the attacker receives mail sent to any address at that domain, so they can use s.mitchell@, accounts@, ceo@, whatever fits the pretext.
Finding 8: attacker domain is catch-all configured; Reply-To confirmed as free webmail.
Step 10: The attachment
Updated_Banking_Details_Nordstream.pdf, 84 KB.
$ file Updated_Banking_Details_Nordstream.pdf
PDF document, version 1.7
$ sha256sum Updated_Banking_Details_Nordstream.pdf$ file Updated_Banking_Details_Nordstream.pdf
PDF document, version 1.7
$ sha256sum Updated_Banking_Details_Nordstream.pdfVirusTotal hash lookup: no detections. Not surprising, because it is not malware. It is a genuine PDF containing genuine-looking bank details for an account the attacker controls.
pdfid shows no JavaScript, no embedded files, no launch actions. It is exactly what it claims to be.
Finding 9: the attachment is benign. The payload is the bank account number. This is important, because a security stack tuned to find malware will find nothing here. There is nothing to find.
The verdict
Business Email Compromise via lookalike domain, targeting a wire transfer. High confidence. Active campaign.
The attacker:
- Researched Acme Corp, identified the CFO by name and title, and identified a real supplier contract by name. That research came from LinkedIn, the company website, and possibly a prior compromise or a public tender document.
- Registered
acme-corp.net14 days before the attack. - Configured SPF, DKIM, and DMARC correctly, and set up a catch-all so any address at the domain would work.
- Obtained TLS certificates and set forward-confirmed reverse DNS.
- Sent a well-written, contextually accurate message with a plausible reason to avoid a phone call.
- Set Reply-To to a Gmail account so the conversation would continue under their control.
- Attached a clean PDF with their own bank details.
Every technical control passed. Every contextual signal failed.
The response
Immediate:
- Do not process the payment. Confirm no payment has been initiated. If one has, call the bank immediately and file with IC3 at ic3.gov the same day, because the FBI's Recovery Asset Team can initiate a Financial Fraud Kill Chain hold only while the funds are still in the first receiving account.
- Call Sarah Mitchell on the number already in your directory. Confirm she did not send it.
- Block
acme-corp.netand203.0.113.199at the gateway. - Block
sarah.mitchell.cfo@gmail.com. - Search all mailboxes for other messages from that domain. Attackers rarely send only one.
Short term: 6. Report the domain to NameSilo's abuse contact with the evidence. 7. Report to APWG (reportphishing@apwg.org) and to Google for the Gmail account. 8. Register defensive variants of your own domain: .net, .co, .org, and the obvious hyphenated and homoglyph forms. 9. Set up Certificate Transparency monitoring on your brand name via crt.sh so you are alerted the next time someone provisions a certificate for a lookalike.
Structural: 10. Implement a mandatory callback policy for any change to payment details, to a number held on file, with no exceptions for urgency or seniority. This is the control that would have stopped this attack, and it is the only one that would have. 11. Configure your gateway to tag external mail whose display name matches an internal employee name. This is a standard feature in Microsoft 365 and most gateways, and it directly counters display name impersonation. 12. Move your own DMARC to p=reject so nobody can spoof acme-corp.com directly. 13. Train finance staff on this specific pattern with this specific example.
21. The Scoring Model and Checklist
Consistency beats intuition. Here is a weighted model you can apply to every message.
Scoring table
IndicatorPointsAuthenticationDMARC fail with p=reject published+30DMARC fail+25SPF fail (hard)+20DKIM signature present but invalid+25No authentication at all from a domain that normally signs+20DKIM l= tag present+10DomainSending domain under 7 days old+35Sending domain 7 to 30 days old+25Sending domain 30 to 90 days old+15Domain is a homoglyph or typosquat of a known brand+40Domain contains xn-- (Punycode)+25Domain has no web presence or history+15Registrar with elevated abuse association+5AddressFrom domain differs from Reply-To domain+25Reply-To is free webmail on a business message+30From address is disposable+40Return-Path domain differs from From domain+15Display name matches a known internal employee but domain is external+35InfrastructureOrigin IP has no PTR record+20PTR does not forward-confirm+15Origin IP is residential or mobile+30Origin IP is on a blocklist+25IPQualityScore fraud score above 75+20VPN, proxy, or Tor detected+20HELO name does not match reverse DNS+15HELO claims the recipient's own domain+25ChainMore than 8 hops+15Non-monotonic or negative timestamps+35Gap over 5 minutes between hops with no explanation+10Any plaintext hop+10Date header more than 1 hour off first Received+20ContentRequests a change to payment or banking details+40Requests credentials or a login+30Urgency or deadline pressure+15Requests secrecy or bypassing normal process+25Link anchor text does not match href+30Contains a QR code+20Dangerous attachment type+30Password-protected archive with password in body+35Contains tracking pixels from unknown infrastructure+10Mitigating factorsFull DMARC pass aligned to a domain over 2 years old-20Valid S/MIME or PGP signature from a known key-30Established thread with verified prior participants-15Sender is in your verified contact list with matching history-15
Bands
ScoreVerdictAction0 to 20Likely legitimateDeliver21 to 45SuspiciousTag, warn the user, monitor46 to 75Probably maliciousQuarantine, notify security76 to 120MaliciousBlock, purge from all mailboxes, hunt for related messages120+Confirmed attack campaignFull incident response, report externally
The one-page checklist
Preservation
- Saved as
.emlwithout opening - SHA-256 hash recorded
- Original left untouched in the mailbox
- Remote content loading confirmed disabled
Headers
- From address extracted (address, not display name)
- Reply-To checked against From
- Return-Path checked against From
- Message-ID domain and format checked
- Date compared to first Received
- X-Mailer consistency checked
- Authentication-Results read from the topmost trusted instance
- SPF result and the domain it applied to
- DKIM result and the
d=value - DMARC result and alignment
- ARC chain examined if DMARC failed
Chain
- Hop count recorded
- Read bottom-up, origin IP identified
- All timestamps converted to UTC
- Per-hop delays calculated
- HELO compared to reverse DNS at each hop
- Encryption status of each hop noted
- Trust boundary identified
Domain
- Registration date via WHOIS or RDAP
- Registrar noted
- Nameservers noted
- Compared character-by-character against the legitimate domain
- Checked for
xn--and mixed scripts - SPF, DKIM, DMARC, MTA-STS, BIMI records retrieved
crt.shchecked for related certificates- Wayback Machine checked for history
IP
- Origin IP run through IPQualityScore
- PTR record and forward confirmation checked
- ASN and network owner identified
- Connection type recorded
- Blocklist status checked
- Checked against the claimed domain's SPF ranges
Addresses
- Every address validated (From, Reply-To, Return-Path, body, attachments)
- Disposable, catch-all, role-based, free-mail flags recorded
Payload
- All URLs extracted and decoded
- Anchor text compared to href
- Redirect chains traced via urlscan.io (unlisted)
- QR codes decoded offline
- Attachments hashed and hash-looked-up
- True file types verified with
file - Tracking pixels catalogued
Decision
- Score calculated
- Verdict recorded with reasoning
- Indicators of compromise extracted
- Related messages hunted across all mailboxes
- Blocks applied
- Reported externally
- User notified and, if the pattern is novel, briefed
22. Chain of Custody and Reporting
If your analysis might ever be used in a dispute, an insurance claim, an internal disciplinary process, or a prosecution, how you handle the evidence matters as much as what you find.
Preserving the original
A screenshot is not evidence. It shows a rendering, not a message. It contains no headers, no DKIM signature, and no verifiable integrity. It proves only that someone's screen displayed something.
The .eml file is evidence, because the DKIM signature is a cryptographic hash over specific headers and the body. If the signature still verifies, the signed portions are provably unmodified since the sending server signed them. That is a stronger integrity guarantee than most digital evidence carries.
Procedure:
- Export the original as
.emlwithout opening it in a rendering client. - Hash it immediately:
sha256sum message.eml > message.eml.sha256 - Record the metadata: who exported it, from which mailbox, at what time (in UTC), using what tool and version.
- Store read-only. Set filesystem permissions, or better, write to write-once media or an evidence management system.
- Work only on copies. Never modify the original for any reason.
- Log every access. Who touched it, when, why.
- Preserve the mailbox copy too. Do not delete the original from the mailbox. Place a legal hold if your platform supports it.
- Capture server logs. The
id=value in eachReceived:header correlates to a queue entry in that server's logs. Those logs corroborate the headers independently and often survive longer than people expect. They also expire, so pull them early.
Documenting the analysis
A defensible report contains:
Summary. What arrived, who received it, what it asked for, your verdict, your confidence level.
Preservation record. Hashes, timestamps, custody log.
Technical findings. Each finding, the evidence supporting it, and the reasoning. Show your working. "The domain was registered 14 days prior" with the raw WHOIS output is a finding. "The domain looked suspicious" is not.
Indicators of compromise. A clean list of domains, IPs, addresses, URLs, and file hashes for blocking and for sharing.
Attribution, carefully. State what the infrastructure indicates. Do not name individuals. IP geolocation is not identity, VPNs exist, and infrastructure is rented, stolen, and resold. Say "the message originated from an IP allocated to a hosting provider in country X," not "the attacker is in country X."
Remediation. What you blocked, what you hunted for, what you found, what you recommend.
Where to report
RecipientWhatHowFBI IC3Any US-connected fraud, urgently if money movedic3.govAPWGPhishing samplesreportphishing@apwg.orgThe impersonated brandBrand abuseMost large brands have abuse@ or a dedicated reporting page. PayPal, Microsoft, and the major banks all do.The hosting providerMalicious infrastructureabuse@ for the ASN owner, found via WHOISThe registrarMalicious domainThe registrar abuse contact is always published, even under GDPR redactionGoogleMalicious Gmail account or Google-hosted contentReport abuse formYour national CERTSignificant incidentsVaries by countryAction Fraud (UK) / equivalentNational reportingVariesYour ISACSector intelligence sharingFS-ISAC, H-ISAC, and others
On timing for BEC specifically: the FBI's Recovery Asset Team can initiate a Financial Fraud Kill Chain to freeze funds, but only while the money is still in the first receiving account. Once it moves onward, recovery probability drops sharply. File within hours, not days. Call your bank's fraud line simultaneously. This is the single most time-sensitive action in the entire response.
A note on legality
Analyzing an email sent to you is entirely lawful. So is DNS lookup, WHOIS, certificate transparency search, and IP reputation checking, all of which query public records.
Where the line sits:
- Scanning infrastructure you do not own or have written authorization to test is unauthorized access in most jurisdictions, including under the US Computer Fraud and Abuse Act and the UK Computer Misuse Act. Point
nmapat your own mail servers and at clients who have engaged you in writing. Nothing else. - Do not attempt to access the attacker's infrastructure. Not their C2, not their phishing page's admin panel, not their mailbox. It is illegal and it destroys evidence.
- Handle personal data lawfully. Email content contains personal data. GDPR, CCPA, and equivalents apply to your investigation records as much as to anything else.
- Preserve rather than delete. If litigation is foreseeable, deleting evidence is spoliation.
23. Building Defenses That Actually Hold
Analysis without remediation is a hobby. Here is the stack, in order of return on effort.
Tier 1: Do these this week
1. Get DMARC to enforcement. Not published. Enforced.
The rollout:
- Publish
p=nonewithrua=and collect reports for two to four weeks. - Read the reports. Identify every legitimate sender: your ESP, your CRM, your ticketing system, your HR platform, your payroll provider, the marketing tool someone signed up for without telling IT.
- Fix SPF and DKIM for each one.
- Move to
p=quarantine; pct=25, then 50, then 100. - Move to
p=reject. - Set
sp=rejectexplicitly so subdomains are covered.
This typically takes 60 to 90 days done properly. Given that more than half of DMARC-publishing domains never get past p=none, completing it puts you ahead of most of the internet.
2. Enforce callback verification for payment changes. Written policy. No exceptions. Any request to change bank details, add a payee, or make an out-of-cycle payment requires a phone call to a number held on file, made by the person executing the payment, to a named individual they can identify by voice. No exceptions for urgency. No exceptions for seniority. The urgency is the attack.
This single control stops the majority of BEC losses and costs nothing.
3. Tag external mail, and tag display-name impersonation. Every message from outside gets a visible banner. Additionally, configure your gateway to flag any external message whose display name matches an internal employee's name. Microsoft 365, Google Workspace, and every commercial gateway support this. It directly defeats the most common attack in the field.
4. Turn off automatic remote content loading organization-wide.
5. Enforce MFA on every mailbox, and prefer phishing-resistant factors (FIDO2 security keys, passkeys) over SMS or push. Adversary-in-the-middle phishing kits defeat push and OTP routinely by proxying the real login page and stealing the session cookie.
Tier 2: Do these this quarter
6. Deploy MTA-STS in enforce mode and publish TLS-RPT. At 1.7 percent US adoption, this is low-hanging fruit that almost nobody has picked.
7. Register defensive domains. The obvious TLD swaps (.net, .co, .org), the hyphenated forms, and the highest-risk homoglyphs for your brand. It costs a few hundred dollars a year. One prevented BEC pays for a century of it.
8. Monitor Certificate Transparency. Set up alerting on crt.sh for your brand name. When someone provisions a certificate for yourbrand-secure.com, you find out that day rather than after the campaign.
9. Configure DKIM properly. 2048-bit keys, no l= tag, sign From, Subject, To, Date, Message-ID, and Content-Type at minimum. Rotate keys periodically.
10. Audit your exposed mail infrastructure. Scan your own perimeter. Close port 25 on anything that is not an MX host. Verify no open relays. Patch your MTA, specifically against the SMTP smuggling CVEs. Disable VRFY and EXPN. Check that your internal relay does not blindly trust RFC 1918 sources.
11. Retire the "look for typos" training. Replace it with process-based training: verify payment changes by phone, check the domain not the display name, report anything unusual without fear of looking foolish. Measure reporting rate, not just click rate. A high reporting rate is a functioning immune system.
Tier 3: Do these this year
12. Deploy BIMI with a VMC or CMC. It requires DMARC enforcement, which is the real benefit. The logo is the incentive that gets it funded.
13. Consider S/MIME for high-value workflows. Finance, legal, executive communications. Requiring a valid signature on payment instructions from a known certificate is one of the very few controls that stops a compromised-mailbox attack.
14. Deploy DANE if your DNS is DNSSEC-signed, and sign your zone if it is not.
15. Add behavioral detection. Signature-based filtering cannot catch a clean PDF containing the wrong bank account. Look for anomalies: first-time senders, display name and domain mismatches, unusual payment language, new external domains in established threads, sudden changes in a correspondent's writing patterns.
16. Build a documented, rehearsed BEC response runbook, with the IC3 filing step and the bank fraud line at the top, and rehearse it. The recovery window is measured in hours.
The uncomfortable truth
If you implement every item on this list perfectly, you will stop nearly all spoofing and a large share of phishing. You will not stop a compromised supplier mailbox. That message will pass every technical control because it is genuinely from your supplier.
The only defense against that is process: out-of-band verification of anything involving money, access, or data. Technology narrows the attack surface. It does not close it. Design your processes assuming that a perfectly authenticated, perfectly written email from a genuine, trusted correspondent may still be fraudulent, because in the highest-loss cases, it is.
24. Frequently Asked Questions
What is email header analysis?
Email header analysis is the practice of examining the metadata attached to an email message to determine its true origin, its routing path, and whether the sender is who the message claims. It involves reading the Received: chain to trace the servers the message passed through, checking SPF, DKIM, and DMARC authentication verdicts, comparing the envelope sender against the visible From address, and correlating timestamps, IP addresses, and domain registration data. It is the primary technical method for detecting spoofed and fraudulent email.
How do I view email headers?
In Gmail, open the message, click the three dots, and select "Show original." In Outlook desktop, open the message in its own window, then File → Properties → Internet headers. In Apple Mail, press Command+Shift+H. In Thunderbird, press Ctrl+U. Each produces the raw message source including all headers.
Which header shows the real sender?
No single header is definitive. The Return-Path: shows the envelope sender used for bounces. The bottommost Received: header added by infrastructure you trust contains the actual IP address that connected, which is the strongest evidence available because the receiving server observes it directly and the sender cannot forge it. The From: header shows only what the sender typed.
Can email headers be faked?
Partially. A sender can write arbitrary values into From:, Reply-To:, Subject:, Date:, Message-ID:, and any X- header. A sender can also insert fake Received: headers into the message before sending, which will appear at the bottom of the chain. What a sender cannot fake is the Received: header written by your own mail server, including the source IP address of the TCP connection, because that is observed rather than declared.
Why do I read the Received chain from the bottom up?
Because each server prepends its Received: header to the top of the existing headers. The bottom line was written first, by the server nearest the origin. The top line was written last, by the server nearest you. Reading bottom to top follows the message forward in time.
How many hops is too many for an email?
Four to six hops is normal for modern business email with a security gateway at each end. Seven is the practical ceiling for routine traffic. Eight or more should be treated as anomalous until you can identify a specific reason such as a forwarding rule, a mailing list, or an archiving system. Ten or more usually indicates a mail loop or a deliberately obfuscated relay chain.
What does a long delay between hops mean?
Most hops complete in under two seconds. Delays of five to thirty minutes typically indicate greylisting, where the receiving server issued a temporary rejection and the sender retried. Delays of over thirty minutes suggest queue problems or an unusual routing path. Negative delays, where a message appears to arrive at a later hop before leaving an earlier one, are impossible in an honest chain and indicate forged headers or a badly misconfigured clock. Always convert every timestamp to UTC before comparing, since offsets differ across hops.
Does SPF pass mean the email is safe?
No. SPF validates the envelope sender domain, not the From header that users see. An attacker can pass SPF perfectly using a domain they control while putting any address they like in the From: field. Only DMARC checks alignment between the authenticated domain and the visible From domain, and even a full DMARC pass only proves the message came from that specific domain, not that the domain belongs to the organization it appears to represent.
Can an email pass SPF, DKIM, and DMARC and still be fraudulent?
Yes, and this is the most important thing to understand about email authentication. If an attacker registers yourcompany-payments.com and configures SPF, DKIM, and DMARC correctly on it, every check will pass. The authentication stack proves the sender controls that domain. It cannot tell you whether that domain belongs to the company you think it does. Authentication answers "who sent this?" not "should I trust them?"
What is email spoofing?
Email spoofing is forging the sender information in a message so it appears to come from someone else. It works because the From: header is free text written by the sender and the base SMTP protocol never validates it. There are four main forms: display name spoofing (real address, fake name), lookalike domain spoofing (a similar domain the attacker owns), direct domain spoofing (the real domain, which only works if the domain lacks an enforcing DMARC policy), and infrastructure abuse such as compromised mailboxes or SMTP smuggling.
Does an email from security@paypal.com mean PayPal sent it?
No. The From header is a text field that the sender fills in. To determine whether PayPal actually sent a message, you must check whether DMARC passed with alignment to paypal.com, whether the DKIM d= value is paypal.com, whether the Return-Path: is PayPal infrastructure, and whether the origin IP belongs to PayPal's networks. PayPal publishes an enforcing DMARC policy, so direct spoofing of paypal.com fails at most major providers, which is why criminals impersonating PayPal use lookalike domains or display name spoofing instead.
What is emkei.cz?
It is a long-running public web form that composes and sends SMTP messages with user-specified header values, including an arbitrary From address. It exists nominally as a testing tool for mail administrators verifying their own anti-spoofing configuration, which is a legitimate use. The same form pointed at someone else's inbox with someone else's domain is a phishing tool. Its existence illustrates that email spoofing requires no technical skill at all.
Why is port 25 considered insecure?
Port 25 handles server-to-server mail relay, which by definition must accept connections from anonymous servers worldwide, so authentication cannot be required. Encryption via STARTTLS is opportunistic and can be stripped by an attacker in the path, since the capability announcement happens before encryption exists. Historically, open relays on port 25 allowed anyone to send mail through misconfigured servers. And SMTP smuggling attacks, disclosed in December 2023 as CVE-2023–51764, CVE-2023–51765, and CVE-2023–51766, exploit disagreements between servers about what sequence ends a message, allowing forged messages to be delivered by legitimate infrastructure with valid SPF, DKIM, and DMARC results.
What is the difference between port 25, 465, 587, and 2525?
Port 25 is server-to-server relay and cannot require authentication. Port 587 is the submission port, used by mail clients to send through their own provider, and requires authentication with STARTTLS. Port 465 is submission with implicit TLS, encrypted from the first byte. Port 2525 is an unofficial alternate used when an ISP blocks port 25.
What is SMTP smuggling?
An attack technique disclosed by Timo Longin and SEC Consult in December 2023. Different mail servers historically accepted different sequences as the end-of-data marker in an SMTP session. When the outbound and inbound servers disagree, an attacker can embed a fake terminator followed by new SMTP commands in the message body. The outbound server sees one message, the inbound server sees two, and the smuggled second message is delivered by legitimate infrastructure from a legitimate IP, so it passes SPF and often DMARC. It affected Postfix, Sendmail, Exim, and configurations of Microsoft Exchange Online, GMX, and Cisco Secure Email Gateway.
What is a .eml file?
A .eml file is a plain text file containing one complete email message in the RFC 5322 format: header lines, one blank line, then the body. It is the standard format for email evidence because it preserves the full Received: chain, all headers, and the DKIM signature, which means an intact signature proves the message has not been altered. Every mail client and analysis tool can read it.
Is it safe to open a .eml file?
Opening a .eml in a text editor is completely safe, because it is inert text. Double-clicking it is not safe, because your operating system hands it to your mail client, which renders the HTML, loads remote images, and fires every tracking pixel. Open it in a text editor, view it in a terminal, or use a purpose-built analyzer.
Why should I not open a suspicious email?
Because of tracking pixels: 1x1 transparent images loaded from a remote server. Rendering the message fetches that image, which tells the sender that you opened it, when, how many times, your IP address, your approximate location, your device, your operating system, and your mail client. It confirms your address is real and actively monitored, which increases its value and gets you promoted to targeted campaigns. The same technology powers legitimate marketing analytics and tools like Mailtrack, Streak, and HubSpot Sales, which means the volume of routine tracking most people are subject to is far higher than they realize.
How do I stop email tracking pixels?
Disable automatic remote content loading in your mail client. Gmail: Settings → General → Images → "Ask before displaying external images." Outlook: Trust Center → Automatic Download → block pictures. Apple Mail: enable Protect Mail Activity. Thunderbird blocks remote content by default. The strongest option is reading mail in plain text, which never renders HTML at all.
What is a catch-all email domain?
A domain configured to accept mail addressed to any username before the @ symbol. Because the server returns a success code for every address, verification services cannot confirm whether a specific mailbox actually exists, so the honest verdict is "unknown" rather than "valid." Catch-alls are legitimate at small businesses that do not want to lose mail to typos, and they are also heavily used by attackers, because a catch-all lookalike domain lets them receive replies at any address they invent.
What is a disposable email address?
A temporary inbox from a service like Mailinator, GuerrillaMail, or 10MinuteMail, created to receive one or two messages and then abandoned. A disposable address on a business communication, particularly in a Reply-To: field, is close to conclusive evidence of fraud. You can check any address for free at emailverifyerapi.com, which runs the check entirely in your browser so the address never leaves your device.
What is domain tasting?
Domain tasting was the practice of registering domains in bulk, monetizing them with advertising during ICANN's five-day Add Grace Period, then deleting the unprofitable ones for a full refund, making the trial free. At its peak in February 2007, of 55.1 million domains registered, 51.5 million were cancelled and refunded within the grace period. ICANN's Add Grace Period Limits Policy, adopted 26 June 2008 and implemented from 2009, removed refunds for deletions exceeding 10 percent of a registrar's net new registrations or 50 domains per month, whichever is greater. AGP deletions fell 99.7 percent, and ICANN titled its status report "The End of Domain Tasting."
Does domain tasting still happen?
Not at meaningful scale. The AGP Limits Policy effectively ended it. What replaced it: extremely cheap registrations in new gTLDs where disposability is affordable without refunds, snowshoe spamming across hundreds of low-volume domains, abuse of free subdomain hosting on services like pages.dev and web.app, purchases of expired domains with existing reputation, and compromise of legitimate domains, which is free and comes with established trust.
Why do rn and m look the same?
In most sans-serif fonts at normal reading sizes, the letters r and n placed together render almost identically to the single letter m. Your brain pattern-matches word shapes rather than reading character by character, so arnazon.com reads as amazon.com to most people. The same applies to capital O versus the digit 0, lowercase l versus capital I versus the digit 1, and vv versus w. The defense is to copy the domain into a plain text editor or a monospace font, where the differences become obvious.
What is a homoglyph attack?
Registering a domain using characters that look identical to those in a legitimate domain. It works with ASCII (rn for m, 0 for O) and far more powerfully with Unicode, where Cyrillic а, е, о, р, с, х and their Greek equivalents are visually indistinguishable from Latin letters. Internationalized domain names encode these in DNS using Punycode with an xn-- prefix. A domain mixing Latin and Cyrillic script has essentially no legitimate purpose.
What is BIMI, and does it prove an email is genuine?
BIMI displays a verified brand logo next to messages in supported inboxes, and it requires DMARC at enforcement, so it is a genuine trust signal. But be careful: in Gmail, any user can set a profile picture that appears in the same visual position as a BIMI logo, so a criminal can display a brand's logo without any verification. The reliable signal is the blue checkmark, which requires a Verified Mark Certificate backed by a registered trademark. A Common Mark Certificate displays the logo without the checkmark. With BIMI adoption around 4 percent globally, the absence of a logo tells you almost nothing.
What is the difference between a VMC and a CMC?
A Verified Mark Certificate requires a trademark registered with an approved intellectual property office, costs roughly USD 749 to 1,752 per year, and is the only path to the Gmail blue checkmark. A Common Mark Certificate, which Google began supporting in Gmail in September 2024, requires only proof that your logo has been in continuous public use on a domain you control for at least 12 months, is cheaper and faster, and displays your logo without the checkmark. Apple Mail's documented path requires a VMC. Yahoo displays logos without any certificate for senders with good reputation.
What is MTA-STS?
SMTP MTA Strict Transport Security, defined in RFC 8461. A domain publishes a policy over HTTPS declaring that inbound mail must be delivered over TLS with a valid certificate matching a listed MX host. Sending servers cache the policy, which means a later attempt to strip STARTTLS fails against the cached policy rather than being silently accepted. It closes the downgrade attack that plain STARTTLS leaves open. US adoption sits at roughly 1.7 percent.
What is DANE and TLSA?
DANE (DNS-Based Authentication of Named Entities) publishes the expected TLS certificate or public key directly in DNS as a TLSA record, protected by DNSSEC. It achieves the same goal as MTA-STS but anchors trust in DNSSEC rather than the web PKI. It requires a DNSSEC-signed zone, which is why adoption is concentrated in Europe. US DNSSEC adoption is around 18 percent.
What is ARC and when does it matter?
Authenticated Received Chain, RFC 8617. Mailing lists and forwarders break SPF and DKIM by changing the sending IP and modifying the body. ARC lets each intermediary record the authentication result it observed before modifying the message, and cryptographically seal that record. The final receiver can see that a message failing DMARC now actually passed DMARC when it reached the mailing list. It only helps if you trust the intermediary that sealed the chain.
What is the DKIM l= tag and why does it matter?
The l= tag limits the DKIM signature to the first N bytes of the message body. Any content appended beyond that point is unsigned, so an attacker who obtains a legitimately signed message can append arbitrary content without breaking the signature. Any message carrying an l= tag deserves additional scrutiny, and no sender should use it.
What is a DKIM replay attack?
An attacker obtains a message legitimately signed by a high-reputation domain and re-sends it to many new recipients. The signature still verifies because the signed content is unchanged, so the message inherits the reputation of the signing domain. Mitigations include signing the To: header, using short x= expiry values, and rate-limiting outbound signatures per recipient.
What does p=none mean in a DMARC record?
It means the domain owner has asked receivers to report authentication failures but to take no action on them. Messages that fail DMARC are still delivered. It is the correct starting point for a rollout and a serious exposure as a permanent state. In EasyDMARC's 2026 analysis, more than half of all domains with valid DMARC records remained at p=none, and Valimail reports 75 to 80 percent of DMARC-publishing domains never reach enforcement.
How much does business email compromise cost?
The FBI's IC3 recorded $3,046,598,558 in reported BEC losses in the US in 2025 across 24,768 complaints, an average of roughly $123,000 per incident. It was the second-costliest cybercrime category behind investment fraud. Total reported cybercrime losses reached $20.877 billion across 1,008,597 complaints, a 26 percent increase over 2024. Actual figures are higher, since most incidents go unreported.
What percentage of phishing emails pass authentication?
There is no single reliable figure, but the mechanism is clear: attackers using lookalike domains they own configure SPF, DKIM, and DMARC correctly, so those messages pass all three checks. Since roughly 70 percent of domains publish no enforcing DMARC policy, direct spoofing also frequently succeeds. Authentication reduces one class of attack and pushes attackers toward lookalike domains rather than eliminating the threat.
Can I trace an email to a physical person?
Rarely, and not reliably. Headers give you an IP address, which gives you a network operator and an approximate location. Beyond that you need the network operator's records, which generally require legal process. VPNs, proxies, compromised machines, and rented infrastructure all break the chain. Report what the infrastructure indicates. Do not attribute to individuals. State that a message originated from an IP allocated to a hosting provider in a given country, not that a person in that country sent it.
Is a screenshot of an email valid evidence?
Weak evidence at best. A screenshot shows a rendering, not a message. It contains no headers, no DKIM signature, and nothing that can be independently verified. Always export the .eml, hash it, and preserve the mailbox copy. The DKIM signature over an intact .eml is a cryptographic integrity guarantee that a screenshot cannot provide.
What should I do if I already paid a fraudulent invoice?
Act within hours, not days. Call your bank's fraud line immediately and request a recall. File with the FBI's IC3 at ic3.gov the same day if there is any US connection, because the Recovery Asset Team can initiate a Financial Fraud Kill Chain hold, but only while the funds remain in the first receiving account. Contact the receiving bank directly. Notify your insurer. Preserve every email as .eml with hashes. Then hunt your mailboxes for other messages from the same infrastructure, because there is rarely only one.
Does AI make phishing harder to detect?
Yes, and it has invalidated the most widely taught detection heuristic. IBM X-Force reported in 2026 that generative AI cut phishing email creation from roughly 16 hours to about 5 minutes. The FBI's 2025 IC3 report logged 22,364 AI-related complaints with $893 million in losses, including more than $30 million attributed to BEC with a confirmed AI component. Grammar, tone, and formatting are no longer reliable signals. Technical analysis and process controls have become correspondingly more important.
25. Glossary
AGP (Add Grace Period): A five-day window after domain registration during which a registrar may delete the domain for a full refund. Created for error correction, abused for domain tasting, restricted by ICANN's AGP Limits Policy in 2008.
Alignment: The DMARC requirement that the domain authenticated by SPF or DKIM must match the domain in the visible From: header. Relaxed alignment allows subdomains; strict requires an exact match.
ARC (Authenticated Received Chain): RFC 8617. Preserves authentication results across intermediaries that modify messages, such as mailing lists.
ASN (Autonomous System Number): Identifier for a network under a single administrative authority. Used to determine who operates the IP address a message came from.
BEC (Business Email Compromise): Fraud in which an attacker impersonates or compromises a trusted party to redirect payments or extract data. $3.046 billion in reported US losses in 2025.
BIMI: Brand Indicators for Message Identification. Displays a verified brand logo next to authenticated messages. Requires DMARC at enforcement.
Catch-all: A domain configured to accept mail for any address at that domain, which makes mailbox verification impossible.
CMC (Common Mark Certificate): A BIMI certificate requiring 12 months of documented public logo use rather than a registered trademark. Displays the logo but not the Gmail checkmark.
DANE: DNS-Based Authentication of Named Entities. Publishes expected certificates in DNS as TLSA records, secured by DNSSEC.
DKIM: DomainKeys Identified Mail. Cryptographic signature over selected headers and the body, verified against a public key in DNS.
DMARC: Domain-based Message Authentication, Reporting and Conformance. Requires SPF or DKIM alignment with the From domain and publishes a policy for failures.
Disposable address: A temporary inbox from a service like Mailinator or GuerrillaMail.
Domain kiting: Repeatedly deleting and re-registering a domain within the grace period to hold it indefinitely at no cost. Eliminated by the AGP Limits Policy.
Domain tasting: Registering domains in bulk, testing their traffic value during the AGP, and returning the unprofitable ones for a refund. Effectively ended in 2009.
.eml: A plain text file containing one email in RFC 5322 format. The standard forensic evidence format.
Envelope sender: The MAIL FROM: address in the SMTP conversation. Appears in the headers as Return-Path:. Distinct from the From: header.
ESMTP: Extended SMTP. Uses EHLO and advertises server capabilities.
FCrDNS: Forward-Confirmed Reverse DNS. The IP reverses to a hostname and that hostname resolves back to the same IP.
Fast flux: Rapidly rotating the IP addresses behind a domain using very short DNS TTLs to evade blocking.
Greylisting: Temporarily rejecting mail from unknown senders on first attempt, on the basis that legitimate servers retry and many spam tools do not. Produces characteristic multi-minute gaps in the Received: chain.
HELO / EHLO: The SMTP greeting in which a connecting server announces its hostname. Attacker-controlled and frequently forged.
Homoglyph: A character visually identical or near-identical to another, used to construct deceptive domains.
IDN (Internationalized Domain Name): A domain containing non-ASCII characters, encoded in DNS using Punycode with an xn-- prefix.
MIME: Multipurpose Internet Mail Extensions. Allows attachments, HTML, and non-ASCII content in email bodies.
MTA (Mail Transfer Agent): A mail server. Postfix, Sendmail, Exim, Exchange.
MTA-STS: SMTP MTA Strict Transport Security. RFC 8461. Requires TLS with a valid certificate for inbound mail, via a cached HTTPS-published policy.
Open relay: A mail server that accepts and forwards mail from anyone to anyone. A serious misconfiguration.
Punycode: The encoding that represents Unicode domain names in ASCII DNS, prefixed with xn--.
Received chain: The sequence of Received: headers recording each server the message passed through. Read bottom to top.
Return-Path: The envelope sender, written into the headers by the receiving server.
Role-based address: A shared functional mailbox such as info@ or support@.
S/MIME: Secure/Multipurpose Internet Mail Extensions. Certificate-based signing and encryption of individual messages.
Snowshoe spam: Spreading a campaign across many domains and IPs so no single one accumulates enough reputation damage to be blocked.
SMTP smuggling: Exploiting disagreement between mail servers about the end-of-data sequence to inject a second, forged message that inherits the legitimate sender's authentication.
SPF: Sender Policy Framework. A DNS record listing IP addresses authorized to send for a domain. Checks the envelope sender, not the From header.
STARTTLS: The SMTP command that upgrades a plaintext connection to TLS. Vulnerable to stripping because the capability is announced before encryption exists.
Tracking pixel: A tiny remote image embedded in an email that reports back when the message is rendered.
TLS-RPT: SMTP TLS Reporting. RFC 8460. Provides reports on TLS negotiation successes and failures.
TLSA: The DNS record type used by DANE to publish expected certificate data.
Typosquatting: Registering domains that are common misspellings of a target domain.
VMC (Verified Mark Certificate): A BIMI certificate backed by a registered trademark. The only path to the Gmail blue checkmark.
26. Sources
Primary data
- FBI Internet Crime Complaint Center, 2025 Internet Crime Report: https://www.ic3.gov/AnnualReport/Reports/2025_IC3Report.pdf
- FBI Press Release, Cryptocurrency and AI Scams Bilk Americans of Billions: https://www.fbi.gov/news/press-releases/cryptocurrency-and-ai-scams-bilk-americans-of-billions
- Anti-Phishing Working Group, Phishing Activity Trends Report, Q1 2026: https://docs.apwg.org/reports/apwg_trends_report_q1_2026.pdf
- APWG Trends Report archive: https://apwg.org/trendsreports
- EasyDMARC, 2026 DMARC Adoption & Enforcement Report: https://easydmarc.com/blog/ebook/dmarc-adoption-report-2026/
- PowerDMARC, United States DMARC & MTA-STS Adoption Report 2026: https://powerdmarc.com/united-states-dmarc-adoption-rates/
- dmarc.org DMARC deployment statistics: https://dmarc.org/stats/dmarc/
Standards and specifications
- RFC 5321, Simple Mail Transfer Protocol: https://www.rfc-editor.org/rfc/rfc5321
- RFC 5322, Internet Message Format: https://www.rfc-editor.org/rfc/rfc5322
- RFC 7208, Sender Policy Framework: https://www.rfc-editor.org/rfc/rfc7208
- RFC 6376, DomainKeys Identified Mail: https://www.rfc-editor.org/rfc/rfc6376
- RFC 7489, DMARC: https://www.rfc-editor.org/rfc/rfc7489
- RFC 8617, Authenticated Received Chain: https://www.rfc-editor.org/rfc/rfc8617
- RFC 8461, SMTP MTA Strict Transport Security: https://www.rfc-editor.org/rfc/rfc8461
- RFC 8460, SMTP TLS Reporting: https://www.rfc-editor.org/rfc/rfc8460
- RFC 6698, DNS-Based Authentication of Named Entities: https://www.rfc-editor.org/rfc/rfc6698
- RFC 7672, SMTP Security via Opportunistic DANE TLS: https://www.rfc-editor.org/rfc/rfc7672
- RFC 3207, SMTP Service Extension for Secure SMTP over TLS: https://www.rfc-editor.org/rfc/rfc3207
- RFC 2047, MIME Part Three: Message Header Extensions: https://www.rfc-editor.org/rfc/rfc2047
- RFC 8551, S/MIME Version 4.0 Message Specification: https://www.rfc-editor.org/rfc/rfc8551
Vulnerability research
- SEC Consult, SMTP Smuggling: Spoofing E-Mails Worldwide: https://sec-consult.com/blog/detail/smtp-smuggling-spoofing-e-mails-worldwide/
- CERT/CC VU#302671, SMTP end-of-data uncertainty: https://kb.cert.org/vuls/id/302671
- CERT/CC VU#244112, Multiple SMTP services susceptible to spoofing: https://www.kb.cert.org/vuls/id/244112
- USENIX Security 2025, Email Spoofing with SMTP Smuggling: https://www.usenix.org/system/files/conference/usenixsecurity25/sec25cycle1-prepub-621-wang-chuhan.pdf
Policy and governance
- ICANN, Add Grace Period (AGP) Limits Policy: https://www.icann.org/resources/pages/agp-policy-2008-12-17-en
- ICANN, The End of Domain Tasting: AGP Deletes Decrease 99.7%: https://www.icann.org/en/announcements/details/the-end-of-domain-tasting--agp-deletes-decrease-997-12-8-2009-en
- BIMI Group, Announcing Common Mark Certificates: https://bimigroup.org/announcing-common-mark-certificates/
- Google Workspace Updates, Gmail allows more senders to protect their brand using BIMI Common Mark Certificates: https://workspaceupdates.googleblog.com/2024/09/gmail-additional-bimi-protections.html
- Google, Email sender guidelines: https://support.google.com/mail/answer/81126
Tools referenced
- Sublime Security Email Analyzer: https://analyzer.sublime.security/
- IPQualityScore: https://www.ipqualityscore.com/
- EmailVerifyerAPI: https://www.emailverifyerapi.com
- Google Admin Toolbox Messageheader: https://toolbox.googleapps.com/apps/messageheader/
- Certificate Transparency search: https://crt.sh
- urlscan.io: https://urlscan.io
- CyberChef: https://gchq.github.io/CyberChef/
- MITRE ATT&CK, Phishing (T1566): https://attack.mitre.org/techniques/T1566/
Cite This Article
If this guide was useful in your research, reporting, or training material, you are welcome to cite it:
Email Header Analysis: The Complete Digital Forensics Guide (2026). Covering SMTP and ESMTP internals, the Received chain and hop timing analysis, SPF, DKIM, DMARC, ARC, MTA-STS, DANE/TLSA, BIMI, VMC and CMC, S/MIME, email spoofing techniques, homoglyph and typosquat detection, domain and IP intelligence, tracking pixels, and the .eml evidence format.
All statistics are attributed to their primary sources in section 26 with direct links. Corrections and additions are welcome.
Final Word
Email is a protocol from 1982 carrying twenty-first-century money. Every security standard layered on top of it (SPF, DKIM, DMARC, ARC, MTA-STS, DANE, BIMI) is a patch over an original design that assumed everyone on the network could be trusted.
Those patches work. They work well enough that direct domain spoofing against a properly configured organization is now genuinely hard. But they answer a narrower question than most people assume. They tell you which domain sent a message. They cannot tell you whether that domain deserves your trust.
That gap is where the $3 billion goes.
So learn to read the headers. Read the chain from the bottom up. Count the hops. Check the alignment, not just the pass. Look up the domain's age before you look at anything else. Copy the domain into a text editor and read it character by character. And when an email asks you to move money, pick up the phone and call a number you already had.
The technical work narrows the attack surface. The phone call closes it.