Email Fundamentals Pt 2: Bypassing SPF & Hello DMARC
Why SPF alone isn't enough, and how to implement DMARC
In part 1 (and part 1.5) we talked about email spoofing and how SPF was developed to prevent spoofing. So why isn’t that the end of the story?
Email Headers
Every email message requires Header information to tell mail servers how to handle it. The most common headers are:
From: Specifies the sender’s email address (e.g.,
From: user@example.com
).To: Indicates the recipient’s email address (e.g.,
To: recipient@example.com
).Date: The date and time the email was sent (e.g.,
Date: Wed, 08 Sep 2024 10:00:00 GMT
).Subject: The subject line of the email (e.g.,
Subject: Meeting Reminder
).
However, headers are a little more complicated than that. In addition to the From: header, there are some additional headers tasked with identifying the sender. Most notably, there is a Return-Path header, also referred to as an Envelope From header. This works kind of how you would think it would — just like the return address on an envelope is used by the Post Office when they can’t deliver a piece of mail, a mail server uses this address when a message “bounces” or is returned to the sender due to an error. It literally indicates the Return Path and processes it like “return to sender” on a letter.
Beating SPF
We learned from the last article that SPF makes it more difficult for an attacker to spoof your email because mail servers check the domain of the sender and compare it to the list of authorized senders indicated in the SPF record.
However, this gets complicated because there is more than one type of header used to identify the sender of an email. In the below example, andy@edtechirl.com (1) sent a message to andy@k12levelup.com (2):
What the user sees as the sender above (1) is the name the attacker wants you to think the message is from. However, in this scenario, the attacker is sending the message from the return-path: header address of attacker@pleasepleasedont.click and they set the from: header to be the desired address of andy@edtechirl.com.
How Does SPF Fall Short on Defense?
So why doesn’t SPF stop this attack? Because SPF evaluates the authenticity of the message based on the return-path: address — which is the address the recipient doesn’t see! — and NOT the from: address.
If the attacker controls their own domain that they are using in the return-path: address, as long as they have configured their own domain’s SPF correctly, it will still pass SPF for the recipient. In this scenario, the attacker isn’t andy@edtechirl.com… they are really attacker@pleasepleasedont.click, so technically, as far as the Mail Transfer Agent is concerned, the message has correct SPF alignment and is legit, because SPF doesn’t evaluate a message’s visible from: address.
DMARC: Defeating the Reply-to Header
To resolve this issue, another protocol named Domain-based Message Authentication, Reporting & Conformance — DMARC — was created. The purpose of DMARC is to verify alignment between the from: header and the SPF or DKIM results for the return-path: address (more on DKIM in part 3). DMARC checks the domain in the from: header, and if its SPF record and the return-path:’s SPF record are out of alignment, DMARC categorizes it as a failure. For example, imagine an email with the following characteristics:
To: andy@edtechirl.com
From: dolly@dollywood.com
Return-Path: andy@k12levelup.com
To evaluate this message like DMARC would, we need to know all of the applicable SPF records.
The SPF record for dollywood.com is:
v=spf1 ip4:66.64.154.209 ip4:4.14.50.9 include:mtasv.net include:sendgrid.net include:spf.protection.outlook.com include:_spf.ultipro.com include:us._netblocks.mimecast.com -all
The SPF record for k12levelup.com is:
v=spf1 include:icloud.com ~all
The SPF record for icloud.com is:
v=spf1 ip4:17.41.0.0/16 ip4:17.58.0.0/16 ip4:17.142.0.0/15 ip4:17.57.155.0/24 ip4:17.57.156.0/24 ip4:10.162.0.0/16 ip4:144.178.36.0/24 ip4:144.178.38.0/24 ip4:112.19.199.64/29 ip4:112.19.242.64/29 ip4:222.73.195.64/29 ip4:157.255.1.64/29 ip4:106.39.212.64/29 ip4:123.126.78.64/29 ip4:183.240.219.64/29 ip4:39.156.163.64/29 ~all
When this message is evaluated, the fact that the IP addresses listed for the k12levelup.com domain (by way of icloud.com) do not match any of the IP addresses listed for dollywood.com makes this a failure, which will be treated as described below.
DMARC Configuration
To check if a domain has DMARC configured, you can take similar steps to how we found SPF records in the previous article. While we could use MXToolbox, it’s also easy to Dig it in Mac or Linux using
dig _dmarc.edtechirl.com txt
Which will output a DMARC policy like below:
v=DMARC1; p=none
Notice in this instance that p=none. Those 6 characters tell me that my domain is using DMARC, but that it has no enforcement policy. So when andy@k12levelup.com emails me, iCloud evaluates the message, sees that it doesn’t align with the from: address and the from: address’s SPF, but it doesn’t take any action on it because enforcement is set to none.
To move to enforcement, all I need to do is go to DNS for my domain and edit the DMARC TXT record to say
v=DMARC1; p=quarantine
or
v=DMARC1; p=reject
When I make that change, if any messages come to my domain, and the SPF of the Return-path: header address doesn’t match the SPF of the From: header address, it will be either sent to quarantine or will be rejected (depending on my choice when configuring the record in DNS).
Additional DMARC Configurations
If you explore DMARC records for other sites, you’ll notice a handful of other options. Take walmart.com for example. Its DMARC record is:
v=DMARC1; p=reject; fo=1; rua=mailto:dmarc_rua@emaildefense.proofpoint.com; ruf=mailto:dmarc_ruf@emaildefense.proofpoint.com
1. v=DMARC1
:
This specifies the version of DMARC being used, which is always
DMARC1
. It just indicates that this is a valid DMARC record.
2. p=reject
:
This is the policy directive for how receiving mail servers should handle emails that fail DMARC authentication (i.e., emails that fail both SPF and DKIM or have domain alignment issues).
Impact: Emails that fail DMARC validation will be rejected outright by the receiving mail servers. This means the emails will not be delivered to the recipient at all. This is the most strict policy and is often implemented when an organization wants to fully prevent spoofed or fraudulent emails from being delivered. DMARC misconfiguration is still prevalent enough that many times, I receive emails in my organization that are legitimate, but fail DMARC. This frequently seems to happen with smaller businesses that are sending us invoices for goods or services we’ve published, so it’s helpful in my situation to choose “quarantine” for my enforcement policy to help me have a place to go search for missing messages when the vendor complains that we haven’t responded to their invoices.
3. fo=1
:
This is the Failure Reporting Option (fo): This defines when detailed failure reports (also known as Forensic Reports) should be sent.
Impact:
fo=1
specifies that a forensic report should be generated and sent if either SPF or DKIM fails, but not necessarily both. These forensic reports provide detailed information about individual messages that failed DMARC validation.For example, if an email fails SPF but passes DKIM, or vice versa, a forensic report will be sent.
This option can be useful for diagnosing specific issues with email authentication.
4. rua=mailto:dmarc_rua@emaildefense.proofpoint.com
:
Aggregate Reporting URI (rua): This specifies where aggregate reports should be sent. Aggregate reports are summary reports (usually sent daily) that give insights into how emails from the domain are being handled and whether they are passing or failing DMARC, SPF, and DKIM checks.
Impact: Aggregate reports, which will likely come from many mail servers that receive emails from this domain, will be sent to
dmarc_rua@emaildefense.proofpoint.com
. These reports are in XML format and provide a high-level overview of the domain's email authentication performance.
5. ruf=mailto:dmarc_ruf@emaildefense.proofpoint.com
:
This is the Forensic Reporting URI (ruf): This specifies where failure reports should be sent. These reports contain detailed information about individual email messages that fail DMARC validation, including the headers and sometimes even parts of the message itself.
Impact: Forensic reports will be sent to
dmarc_ruf@emaildefense.proofpoint.com
. These reports are more detailed and can help identify specific instances of email spoofing or misconfigured email authentication.
How Can I tell if my domain uses DMARC?
Command Line
Like in the example earlier, you can run the dig command from a Linux or Mac terminal and see the output of your domain’s DMARC record (if present).
dig _dmarc.exampledomain.com txt
If it returns v=DMARC1; p=quarantine or v=DMARC1; p=reject then DMARC enforcement is enabled for your domain.
AboutMy.Email
A quick and easy way to see how your domain’s DMARC configuration works is to try out the AboutMy.Email tool from this previous article on Simplifying Email Diagnostics. AboutMy.Email gives you a temporary address to send messages to, and the service quickly analyzes your sending infrastructure by reading your message headers and checking your domain’s DNS records, and it reports back compliance wtih SPF, DMARC, and DKIM, among many other metrics. It will be displayed on the Summary page like this:
MailFail
An Additional level-up that deserves its own article, Jack Hylund at Black Hills Information Security has a kick-ass tool called MailFail (https://m.ail.fail/) that is a Firefox extension (https://addons.mozilla.org/en-US/firefox/addon/mailfail/) that identifies a TON of email-related misconfigurations for the domain you’re visiting in Firefox. It also provides the applicable commands and methodology an attacker would use to compromise the domain based on the security and DNS configs. This tool is impressive and expansive, and it digs way deeper into the topic than I’m currently equipped for. Every time I use it, I pick a random setting and make that a learning goal. Awesome stuff. And his Youtube video on email spoofing is EXCELLENT. I learn something new every time I watch it.
A screen capture of the MailFail extension in action is below, but it literally only takes seconds to install in Firefox, so it’s definitely worthwhile to download it and play with it. All of the i logos send you to documentation to learn about that feature/setting, and the link icons take you to sources for where the information was gathered. If you’re using MailFail to evaluate your own domain, anything in red is something potentially exploitable or that needs more investigation.
Setting Up DMARC
So, if you don’t have DMARC, should you just go ahead and create a v=DMARC1;p=reject policy and call it done? Depending on the volume of mail your tenant receives and how important or time-sensitive it is, starting by creating a DMARC reject policy could cause some real issues. Instead, it’s advisable to take a staged rollout approach and begin with no enforcement, monitor implementation, and increase the strictness of the policy until you’re at full enforcement. This allows you to monitor email flows, reduce errors, and ensure legitimate emails aren’t accidentally blocked.
1. Start with a “Monitor Only” Policy that receives Aggregate and Forensice reports (v=DMARC1; p=none; rua=mailto:you@email.com; ruf=mailto:you@email.com )
Set DMARC to “none” (p=none) in your DNS. This policy means that no emails will be blocked or quarantined, but configuring the rua (Aggregate) and ruf (Forensice) will allow you to receive DMARC reports on all email activity. These Aggregate reports will help you understand which sources are sending emails on behalf of your domain, and the Forensic reports will provide details of any authentication failures.
2. Review and Analyze DMARC Reports
In the emails you receive with Aggregate and Forensic reports, check for authorized and unauthorized senders. Identify all legitimate senders (your own servers, marketing services, third-party tools) and spot any unauthorized sources that could be spoofing your domain. If you utilize 3rd party sending infrastructure like Mailgun, MailChimp, Constant Contact, etc., it’s doubly important to make sure you’ve identified all of the legitimate services that could be sending as you and make sure they’re accounted for in your SPF records. This might involve configuring SPF for each third-party service and enabling DKIM signing for each authorized source.
3. Gradually Move to a “Quarantine” Policy for a percentage of your messages (v=DMARC1; p=quarantine; pct=10; rua=mailto:you@email.com; ruf=mailto:you@email.com )
Once you’re confident that most legitimate emails pass SPF and DKIM, update the DMARC policy to p=quarantine; pct 10. This policy flags failing emails as spam or places them in the recipient’s quarantine folder instead of outright rejecting them. By starting with a low percentage (pct=10), only 10% of failing messages are quarantined. You can increase this percentage in increments as you verify that legitimate emails aren’t affected. As you go through this process, continue monitoring your DMARC reports to ensure that legitimate emails are quarantined as expected. This gives you time to adjust any remaining misconfigurations.
4. Move to Full Enforcement with Reject Policy (v=DMARC1; p=reject; pct=10; rua=mailto:you@email.com; ruf=mailto:you@email.com)
Once you’re sure all legitimate email sources are configured correctly and passing DMARC checks, change the policy to p=reject. This policy tells receiving servers to reject any email that fails DMARC, stopping it from reaching the recipient’s inbox entirely. Like with the Quarantine policy, continue incremental increases (pct=10, 20, etc.). You can gradually increase the percentage to 100 for full enforcement.
5. Maintain Ongoing Monitoring and Adjustment
This one isn’t a set it and forget it. Keep reviewing reports regularly. Even after moving to full enforcement, regularly review your DMARC reports to catch new services or changes in email sources that may need adjustment. Especially if your org likes to switch vendors rapidly or without including all stakeholders, this could need some attention periodically. I do this quarterly, but occasionally I will field tickets because messages from a new sending infrastructure aren’t being delivered, and it’s usually because either it’s an existing vendor who has changed their IP ranges, or it’s a new vendor that we’ve not yet configured SPF for. If you add or change email services, it is necessary to update your SPF, DKIM, and DMARC settings as needed to maintain alignment and prevent legitimate messages from being rejected.
What’s Next?
In Part 3, we’ll look at DKIM and the role it plays in the SPF/DMARC/DKIM relationship and how it impacts mail security. We’ll also look at how attackers can bypass DKIM, or how it’s possible to crack DKIM keys (and, of course, how to check and see if your DKIM keys are susceptible to cracking).