Note: The following is an intuitively obvious result of default configurations note in the public documentation.
TLDR: Office 365 turns DMARC reject actions into quarantine actions, and then throws messages in Junk folder.
How email works
Most of you have probably used email. And you most likely used it via one of the large email providers like Gmail, Hotmail, Office 365, Yahoo! Mail, or AOL. These environments lock you down as to who you can claim to be in your from address. But that is a (sensible) limitation that these providers have built into their systems. Run your own email system (which isn’t hard to do if your only plan is to abuse it), and you quickly see that you can claim to be anyone you want in the world. Email from addresses (the one you see when you get an email) are as secure as the return address on a piece of mail you get. You can put whatever you want there. Coincidentally, at the moment caller ID is as secure.
This is less than ideal. So specifications have been added on top of the original email specifications that let domain owner assert how their email should be handled.
SPF: Sender Policy Framework
There is a little lie up two paragraphs. The from address you see on email isn’t like the return address on a piece of mail. The from address on email is more like the signature on the paper in the envelope. There is a separate header for where to send the message back to in case it doesn’t work. Kind of like return to sender in physical mail. This the the envelope from, or return path. SPF allows a sending domain to list the IPs (basically servers on the Internet) that are allowed to have a return path back to their domain. In addition, they can assert how strictly a receiving system should interpret a message from an unapproved IP.
Domain owners can say that an unapproved IP should be treated as a SOFTFAIL (soft failure). This is when they aren’t entirely sure which IPs are sending on their behalf. This is useful for transitioning to the next level, which is FAIL. A message that triggers FAIL should be rejected according to spec. This means that the person being sent the message should never have anyway of seeing the message. It should disappear into the ether.
DMARC: Domain-based Message Authentication, Reporting, and Conformance
Most people don’t go through reading return path headers. And there are very legitimate reasons why the return path might be different from the visible from address. A lot of organizations like to use mass mailing products like Constant Contact or Mailchimp. These have the return path set back to the mass mailing company so that they can track the undeliverable address automatically, while the visible from address is from the customer paying them to send the email.
The goal of DMARC is to protect that valuable visible from address. Why does this matter? If an email address claims to be from your bank, you want to be assured that it is from your bank and not an attacker.
DMARC has has three different levels of how to handle failures to the DMARC checks: none, quarantine, reject. None is likely set by sending organizations to get some level of reporting. If a message passes DMARC, that’s a good sign to the receiving email system. If it doesn’t, that is less sure. DMARC offers a mechanism for nice organizations to send a report of what DMARC messages they saw, where they came from, and what the DMARC, SPF, and DKIM status was. This is help for an organization switching to strong levels of DMARC. And you want organizations to switch to strong levels of DMARC.
The quarantine level likely should make the mail be delivered to the quarantine. The reject level once again means that the message should disappear into the ether.
There are two different ways a message can pass DMARC. One is if it passes SPF with an aligned domain. If the visible from address is rfrovarp@frovarp.dev and the return path is the same domain. That is in alignment, so SPF passing would make DMARC pass. If the return path frovarp.com, that isn’t the same. So even if SPF passes on frovarp.com, DMARC wouldn’t pass. This is also true about messages from Mailchimp and similar.
There is another option called DKIM (DomainKeys Identified Mail) Signatures. With this, parts of messages, including the subject and from address, are cryptographically signed. The receiving system is told what domain signed the message, and can verify the signed values. If the signature is correct, and the signing domain is the same as the from address, then this too passes DMARC.
The problem
There are three problems with how Office 365 handles email using the above specs. First is that while Microsoft requests that DMARC reports are sent to them, so they can better protect their domain, Office 365 will not provide DMARC reports to others. It’s hard to transition your domain to a stricter level of DMARC when your primary destination for email doesn’t provide reports. Yahoo!, Gmail, Mail.ru, and many others helpfully provide DMARC reports.
The slightly more severe problem is there is an extra setting in Office 365 to have SPF FAILs be treated as a sign of strong spam. SPF FAILs should be immediately dropped. That is what the owner of the domain has specifically asked to happen. This can help allow impersonation. However, avoiding SPF failures if you are launching an email attack shouldn’t be hard, as no one visually inspects the return path anyway.
The bad problem is in the TLDR above. Office 365 treats DMARC rejects and quarantines as the same thing. And by default the message only goes to junk. An email admin would need to know to look for these settings and to turn up the protection. And even then, by default the best you can do is get the rejects into the quarantine. I am going to guess that most email admins these days at best don’t understand DMARC, DKIM, and SPF as well as they should, and more likely than aren’t even aware of what they mean.
Microsoft’s docs says that they are loosing up the handling of DMARC failures for your benefit, because things like mailing list usually ruin DMARC. While it is true that this can happen, one can also correctly configure mailing list software to handle this. I would prefer it that if my bank says that an email isn’t sent by them, that I never have to see it.
So, if you are a pentester and your customer is on O365, there is a good chance you can get a message from any domain you want into the target’s junk folder. Microsoft even helpfully provides a way to get into the inbox:
If desired, users can still get these messages in their inbox through these methods: Users add safe senders individually by using their email client.
https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/use-dmarc-to-validate-email?view=o365-worldwide#how-microsoft-365-handles-inbound-email-that-fails-dmarc