More and more companies use Microsoft 365, well even we at Compass Security use it. Moving to the cloud solves many issues that our DFIR team had to deal with in the past years. Managed infrastructure means no ProxyShell, Hafnium, etc. We’re grateful for that.

Email authentication and security is another complex topic that was often misconfigured in the past. We often could send phishing email in the name of our clients during assessments. Office 365 makes the life of scammers and phishers somehow harder. We’re also grateful for that.

However we still encounter some O365 environments where it’s possible to send spoofed emails. Why is that, you ask? We also wondered and dug into the O365 features and settings!

Email protections in Office 365

Email authentication

Email authentication is used to verify if the email server is allowed to send emails on behalf of the sender. O365 supports the well-known triad SPF, DKIM and DMARC.

Sender Policy Framework (SPF)

SPF allows to specify which servers are allowed to send emails for your domain through a DNS record. This will be verified by the receiving server. It is active by default and the following policy will be configured (for fully-hosted O365) automatically:

$ dig -t txt +short sender.com
"v=spf1 include:spf.protection.outlook.com -all"

In turn, due to the include mechanism, the following two records will be queried and taken into account:

$ dig -t txt +short spf.protection.outlook.com
"v=spf1 ip4:40.92.0.0/15 ip4:40.107.0.0/16 ip4:52.100.0.0/14 ip4:104.47.0.0/17 ip6:2a01:111:f400::/48 ip6:2a01:111:f403::/48 include:spfd.protection.outlook.com -all"

$ dig -t txt +short spfd.protection.outlook.com
"v=spf1 ip4:51.4.72.0/24 ip4:51.5.72.0/24 ip4:51.5.80.0/27 ip4:20.47.149.138/32 ip4:51.4.80.0/27 ip6:2a01:4180:4051:0800::/64 ip6:2a01:4180:4050:0800::/64 ip6:2a01:4180:4051:0400::/64 ip6:2a01:4180:4050:0400::/64 -all"

As an example, a message which does not match the SPF policy will have the following headers in O365:

Authentication-Results: spf=fail (sender IP is 1.2.3.4)
 smtp.mailfrom=sender.com; dkim=none (message not signed)
 header.d=none;dmarc=none action=none header.from=sender.com;compauth=fail
 reason=001
Received-SPF: Fail (recipient.com: domain of sender.com
 does not designate 1.2.3.4 as permitted sender)
 receiver=recipient.com; client-ip=1.2.3.4;
 helo=mail.sender.com;

Such a mail (without any other aggravating factor) will not be blocked by O365 without a DMARC policy! SPF alone is not protecting against email spoofing.

DomainKeys Identified Mail (DKIM) 

DKIM allows you to add a cryptographic signature to outgoing emails in the message header. The public key is also published in a DNS record. The advantage of DKIM over SPF is that mails can be authenticated even if they get forwarded by a relay server.

This is not enabled by default in O365 but is supported. A DKIM record looks as follows:

$ dig -t txt +short selector1._domainkey.recipient.com
selector1-recipient-com01i._domainkey.csnc365.onmicrosoft.com.
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0/Cy8ivpKumzFbBGkAxA2ydbglgrwrBss2FT0UmcsveVcE4xC61zuTmEZEWI2LR5HGLElHlgvv83I3C2YvJmuh4i2e+/TLVpLkFxpwYQTkzQT81MazCShfeUS29Zjwr5nBoGAKdAeuL1OOPwWeXznezFIPQxBhe0oWNyYpslD4bKx1bgO+sjvbPLm61ZzEopX" "8yQzvyU8XNJX9fLlUJbyo10FLeEU0S3Gs9IfIarucc0gktFMcVsEs72XEJoACkKagL0l5UYqN9CgUg+wuIScbJp6TskN8LQqX+CmHgPPJJLLfaYVuBpbo5oC9F1znN7xPliUDuKxznSDn1CQk49HQIDAQAB;"

A message which contains a DKIM signature will have the following headers in O365:

Authentication-Results: spf=pass (sender ip is
 1.2.3.4) smtp.rcpttodomain=recipient.com
 smtp.mailfrom=sender.com; dmarc=pass (p=reject sp=reject pct=100)
 action=none header.from=sender.com; dkim=pass (signature was
 verified)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sender.com;
 s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=yslZcsqEU3doAnzIBv+IiXhdA9VgmTBEY7w17G6s3Ag=;
 b=cD8dhgH352qUE0HvmLeYaWlC4E7xtUl26Sju41TUTDXIKSB/EUNhiOd2K46Q0VdISshkAFieExTbRfHksyl4hK6Ctuzaeaq5m+cPquzZba4Idt2WSNhwxCZyPsTRf7h7cj++t86lexZDfwrfra+8QJsAwInYAXVmC4tC4/lLGS13+FXWWh8/A/eVu+dGP5iuojZtmSAiKc51sRGya89Oup70MeNIz3NarhMbT/0b0o20XuLGWsdrLykMOhNOSoTRlxALyEEQuR2E7tRIA23OtClZt0i6YqtK1lG+VSs1RwNySGlptNnM+Nnf3NMggGkzCuvU4/FpvZ2yMUcucqe5lw==

DKIM adds an extra layer of security to your emails, you should configure it if it’s not already done. But how does the recipient knows that it should expect a DKIM signature?

Domain-based Message Authentication, Reporting and Conformance (DMARC)

DMARC helps the recipient server to decide what to do if SPF and/or DKIM checks fail. This feature is also not enabled by default for outgoing emails but supported in O365. It also consists of a TXT DNS record. For instance:

$ dig -t txt +short _dmarc.sender.com
"v=DMARC1; p=reject; sp=reject; rua=mailto:security@sender.com!10m; ruf=mailto:security@sender.com!10m; rf=afrf; pct=100; ri=86400"

What does this mean? This can be parsed easily using mtoolbox:

TagTagValueNameDescription
vDMARC1VersionIdentifies the record retrieved as a DMARC record.
prejectPolicyPolicy to apply to email that fails the DMARC test.
sprejectSub-domain PolicyRequested Mail Receiver policy for all subdomains.
ruamailto:security@sender.com!10m
ReceiversAddresses to which aggregate feedback is to be sent.
rufmailto:security@sender.com!10m
Forensic ReceiversAddresses to which message-specific failure information is to be reported.
rfafrfForensic FormatFormat to be used for message-specific failure reports. 
pct100PercentagePercentage of messages from the Domain Owner’s mail stream to which the DMARC policy is to be applied.
ri86400Reporting IntervalIndicates a request to Receivers to generate aggregate reports separated by no more than the requested number of seconds.

For instance, a message passing SPF but without DKIM will be rejected due to a DMARC policy could have the following headers in O365:

Authentication-Results: spf=pass (sender IP is 1.2.3.4)
 smtp.mailfrom=sender.com; dkim=none (message not signed)
 header.d=none;dmarc=fail action=oreject
 header.from=sender.com;compauth=fail reason=000

According to the documentation:

oreject or o.reject: Stands for override reject. In this case Microsoft 365 uses this action when it receives a message that fails the DMARC check from a domain whose DMARC TXT record has a policy of p=reject. Instead of deleting or rejecting the message, Microsoft 365 marks the message as spam.

This email will land in the junk folder in O365, if no bypass is configured. Furthermore, this will gives insight to the company that someone is trying to impersonate their name. For instance here is one such feedback:

<?xml version="1.0"?>
<feedback>
	<version>0.1</version>
	<report_metadata>
		<org_name>AMAZON-SES</org_name>
		<email>postmaster@amazonses.com</email>
		<report_id>670e469b-4307-4c2a-870a-7a07869d7c02</report_id>
		<date_range>
			<begin>1660953600</begin>
			<end>1661040000</end>
		</date_range>
	</report_metadata>
	<policy_published>
		<domain>compass-security.com</domain>
		<adkim>r</adkim>
		<aspf>r</aspf>
		<p>reject</p>
		<sp>reject</sp>
		<pct>100</pct>
		<fo>0</fo>
	</policy_published>
	<record>
		<row>
			<source_ip>52.100.1.208</source_ip>
			<count>1</count>
			<policy_evaluated>
				<disposition>none</disposition>
				<dkim>pass</dkim>
				<spf>fail</spf>
			</policy_evaluated>
		</row>
		<identifiers>
			<envelope_from></envelope_from>
			<header_from>compass-security.com</header_from>
		</identifiers>
		<auth_results>
			<dkim>
				<domain>compass-security.com</domain>
				<result>pass</result>
			</dkim>
			<spf>
				<domain>CHE01-GV0-obe.outbound.protection.outlook.com</domain>
				<result>none</result>
			</spf>
		</auth_results>
	</record>
</feedback>

Anti-spoofing

Spoofing is a technique often used by attackers to make a message appear as if it would come from someone else. The authentication techniques above are countermeasures against email spoofing.

O365 include so-called “anti-phishing” policies per default (which is actually anti-spoofing). These can not be disabled. Any mail that is recognized as spoofing (using SPF, DKIM and DMARC) will be automatically put in the junk folder, as the example below show:

Although the sender appears to be Doris Mc Jannet, this email was sent from another mail server.

Additional tips and indicators can be enabled through the anti-phishing policy:

Anti-phishing policy configuration (at https://security.microsoft.com/antiphishing)

These will change the way the mail is shown only in the Outlook client and not in the webmail as follows:

The so-called “spoof intelligence” feature could not be tested, because even spoofed messages seemed not to trigger it during our testing.

Anti-phishing, anti-spam and anti-malware

Unlike spoofing, phishing, spam and malware are categories of attacks that cannot be identified based on the sender only. In O365, anti-spam and anti-malware policies also exist and are active by default. These cannot be disabled, however can and maybe should be made stricter.

Exceptions

There are several ways to create exceptions in O365 to let spoofed mails through.

Allowed senders and domains

Administrators can define exceptions to the anti-spam policies. One might think that this disables anti-spam but not anti-spoofing. However, the documentation hints that:

Never add your own accepted domains or common domains (for example, microsoft.com or office.com) to the allowed domains list. If these domains are allowed to bypass spam filtering, attackers can easily send messages that spoof these trusted domains into your organization.

Indeed, when adding the domain “insecure.technology” to the allowed domain, any spoofed email gets into the inbox:

Configured exception
Spoofed email received in the inbox

The recommended settings from Microsoft even states:

Adding domains to the allowed senders list is a very bad idea. Attackers would be able to send you email that would otherwise be filtered out.

If this is such a bad idea, why is this even possible?

Safe senders and domains

Now, one might expect from O365 administrators that they read the documentation, but it’s another story for users. When receiving an email in the junk folder, users can choose to add the sender to the safe senders.

We encounter different behavior depending on whether the sender is part of the organization or not.

Intra-organization spoofing

Outlook online (web)

If the sender is a valid user inside your organization, O365 offers the possibility to add it to the safe senders list:

Menu option to add sender to the safe senders list
Popup confirming the action

This has no effect whatsoever when done through the web client (outlook.office.com) and the email or domain will not be added to the list (without any error or warning though). Is this a bug or a feature?

Outlook client (desktop)

When this is done in Outlook for desktop, however, the setting is taken into account:

Menu option to add sender to the safe senders list
Popup confirming the action
The setting is taken into account

One could expect that all spoofing policy still apply to safe senders, but they don’t. Spoofed emails from safe senders will be received in the inbox:

Intra-organization spoofed email received in the inbox

Extra-organization spoofing

Invalid users in the organization or valid users outside the organization can also be added to the safe sender list, be it in the web or desktop version of outlook:

Senders added to the safe senders in Outlook web

The same applies to spoofed emails from safe senders outside your organization, they will be received in the inbox:

Extra-organization spoofed emails received in the inbox

Fine print

The following insights from Microsoft’s documentation are interesting:

The documentation states that safe sender lists should be avoided

Conclusion

We’ve seen that email authentication protects effectively against phishing but needs to be configured. Implement DKIM and DMARC today for your domains!

Allowed senders and Safe senders are not safe at all! They will bypass O365 security (except for mails identified as malware or high confidence phishing), Administrator should be aware of this, use the other methods mentioned in this article to create exceptions (mail flow rules or Tenant Allow/Block rules) and monitor safe senders lists.

On the Outlook desktop client, Safe senders can be disabled by group policy:

GPO configuration for hiding the Safe Senders GUI

However, user will still be able to add safe sender via the web client. Safe senders can be audited over the organization using Exchange PowerShell:

  • From an Azure Cloud Shell, connect to Exchange or directly from an Exchange server:
    Connect-EXOPSSession
  • Audit safe senders:
$AllUsers = Get-Mailbox -ResultSize unlimited -RecipientTypeDetails UserMailbox
$AllUsers | foreach {Get-MailboxJunkEmailConfiguration -Identity $_.UserPrincipalName} | Format-Table -Auto Identity,Enabled,TrustedSendersAndDomains