The Attackers Guide to Azure AD Conditional Access

Conditional Access is one of Microsoft’s most powerful security features and the central engine for their zero trust architecture. It’s no secret that I love working with Conditional Access and I truly believe that it should be the hearth and soul of every cloud enabled organisations zero trust strategy. But, if you don’t understand how Conditional Access works, it might bring you a false sense of security. In this blog post, I will show you why it is important to understand the Conditional Access policy evaluation process and how to find and exploit flaws in a policy design.

About Conditional Access

Conditional Access is a premium feature of Azure AD and it is disabled by default. There is a feature called security defaults that kicks in if you have no policies configured but it is out of scope for this article, and security defaults is always disabled when you have one or more Conditional Access policies in place.

In Conditional Access, everything is allowed by default. And even if you create one or two or three policies, everything you don’t explicitly block is allowed. I’ve put a lot of effort into my Conditional Access policy design baseline, so if you are unsure how your policy design holds up, or how to get started, you can use that as a starting point.

In almost every tenant I see out there, there are holes in the Conditional Access design because the designers put too much focus on what use cases they want to allow, not what should be blocked. Conditional Access policies are often designed backwards, and that leaves the tenant vulnerable to attacks.

To educate and raise awareness, I decided to create this guide with examples of how a poorly designed Conditional Access policy design can be exploited to gain access. Use this knowledge for good!

Passwords and Conditional Access

It’s important to understand that Conditional Access policies in Azure AD are evaluated after the first factor has been approved, namely the user password. I will not go through any password stealing techniques in this post, and everything that I explain here happens after the password has been successfully verified by Azure AD (or the on-prem AD with PTA or AD FS). It is after the first factor that the Conditional Access policies are evaluated and the user are granted or denied access based on the requirements in the targeted policies.

How Multiple Conditional Access Policies Work Together

I wrote this blog post back in 2018 and to this day, it is still one of my most read posts. I guess that’s because Conditional Access works differently from traditional security solutions like firewalls where rules are evaluated one by one, and the first policy that has a match tells the firewall what to do with the connection. This is different and people are trying to figure it out.

In Conditional Access, all policies are evaluated at every sign in, and each policy where the conditions are met get’s applied. The sum of all requirements from all matching policies are what the user and the device are required to fulfil to be granted access. For example, one matching policy might require MFA and another might require the device to be Intune compliant. Since both policies match, both requirements must be fulfilled.

The only priority among policies are that block policies always win. This menas that if one or more block policies match during a sign-in, the authentication attempt is blocked, even if there are other policies granting access at the same time.

This is very important to remember when designing policies, and when attacking Conditional Access.

Some Common Weak Spots

Of course, the best way of attacking Conditional Access is to never trigger it at all, to avoid it. There are some common weak spots in almost every organisation that can be abused.

Exclusion Group Abuse

It’s best practice to always exclude one security group from all Conditional Access policies. This group should contain two break glass accounts for you to use during an emergency. This group should not include any other accounts, but in reality it almost always does. Admins get sloppy and adds themselves, service accounts, or complaining users to this group. By stealing the the password from one of these accounts, we can skip Conditional Access all together. Game over!

Missing Block Policies

Admins tend to create policies to enforce MFA for certain, or all, applications in a tenant. But they often include conditions in these policies, like allowed platforms or allowed locations. What they don’t understand is that if we don’t block the unwanted scenarios with a corresponding block policy, an attacker can simply spoof the location or the platform to bypass the policy and sign right in. This is very much what the rest of this guide will showcase.

The following is the general error message a user receives when denied access by a block policy. Note that the block error message might differ depending on which conditions were in the blocking policy. This is to help the user understand what went wrong (see each condition further down).

Use the More details info to see if there are any clues of what condition that triggered the block, like the IP address location, device management state, or targeted app. This is important info going forward.

Condition Abuse

Conditions are used to determine if a policy should apply or not. If all conditions are met during sign-in, the access controls of that policy is applied, like require MFA or require compliant device. I will give some examples of how each type of condition can be tricked.

User risk / Sign-in risk

User risk and Sign-in risk are part of Azure AD Identity Protection (Azure AD Premium P2). This means that most Microsoft 365 customers don’t have this enabled and that it won’t be an issue for an attacker. But if it is enabled, the attacker must try to behave like the user who owns the stolen account used in the attack. Azure AD Identity Protection will detect sign-ins from new countries, anonymous IP addresses, black marked leaked credentials, etc. An attacker would have to research the user and then use VPN’s and other techniques to make the sign in appear as legit as possible.

This is what you see if a block policy is triggered by this condition:

Device platforms

The device platform is easy to spoof. It is based on the client applications user agent string. If a policy includes the platform condition that requires Windows, iOS or Android, you could just change your user agent string to anything else, like a Mac device, Linux device, or a space station. It’s just a text string and Conditional Access interprets it to look for the OS. It’s recommended to have a block policy blocking all non-wanted platforms but this is rare in the wild and, like I said, easily spoofed.

This is how you can change your user agent string with the dev tools in Microsoft Edge:

This is what you see if a block policy is triggered by this condition:

Locations

The location condition is based on IP address. This is called named locations in Azure AD and can be set to certain IP address ranges or to certain countries. If there is a policy blocking certain countries, an attacker can easily bypass this with a VPN service terminating in the same country as the organisation does. If there is a policy only allowing particular IP addresses like the corporate public IP address it gets a bit trickier. If the attacker already has a foothold on the internal network, this would let him bypass this. Since most attacks these days originates from on-prem, this is very likely. I don’t like to exclude corporate IP addresses, as zero trust teaches us to treat all networks as compromised.

This is what you see if a block policy is triggered by this condition:

Client apps

Client apps actually means protocols. What protocol is the client using when authenticating to Azure AD. Many organisations are starting to block legacy protocols like POP3, IMAP, and SMTP by blocking Other and ActiveSync with Conditional Access. But there are almost always weaknesses like excluded accounts, break glass accounts, excluded admin roles, etc. Test different protocols to see if the attempt is blocked. This can help you understand what is allowed in the policy design.

Modern authentication might be blocked from unmanaged devices and in that case you could try to access a corporate device (if on-prem was compromised) or you could try a tool like AAD Internals which includes the possibility to add a fake Azure AD joined- and if needed intune compliant device to the target tenant. You might be lucky to pull such an attack of.

Browser access is almost never blocked by anyone so the browser portals would probably be your way in.

This is what you see if a block policy is triggered by this condition:

Device state

The device state condition is not applicable since it only excludes, never includes devices.

Access Control Abuse

If you are lucky, you were able to bypass all implemented condition above. In that case you are already signed in and won’t need to read any further. But if there are stubborn policies in the way, your next step would be to abuse the access controls. This is harder and requires some more work.

When all conditions in a policy match, the requirements under Access Controls in that policy must be met, or else the authentication attempt is blocked. A policy can have one or more requirements, and the policy can be set to require one or all of them to be fullfilled. As I mentioned before, multiple policys can match at the same time as well and require different controls. In this case, all of the policies different requirements must be fullfilled.

Require multi-factor authentication

This is by far the most common access control used. It requires the user to verify its identity with MFA. There are many known MFA attacks like MFA token stealing, telecom abuse (SMS OTP forwarding), and different phishing techniques to lure the user into approving MFA. An attacker would need to succeed in one of these attack techniques to gain access. Note that the MFA access control always triggers when enabled, even if one of the other access controls also applies but fails. Such fail messages are shown after the MFA verification. This is to protect the tenant from Conditional Access fuzzing attacks.

You know that you are targeted by this access control when you see this:

Require Hybrid Azure AD joined device

This condition requires a hybrid tenant with on-prem synked devices. When you see this message, you know that the tenant is a hybrid. To get around this requirement you could launch the attack from on-prem. An on-prem device is probably hybrid Azure AD joined already. Note that this access control error message is always displayed before the Intune compliance error message if both are enabled.

You know that you are targeted by this access control when you see this:

Require device to be marked as compliant

If there is a requirements that the device must comply with Intune policies, there are two ways to proceed. You could use a compromised corporate device enrolled with Intune and execute the attack from there, or you could try to register a fake device with a tool like AAD Internals to gain access. Note that if you see this error message when you try to sign in from an unmanaged device, there are no policies requiring hybrid Azure AD join in place.

You know that you are targeted by this access control when you see this:

Require approved client app

This access control is only for iOS and Android and won’t work with other platforms. It makes sure that the user signs in with an approved Microsoft app from the app store. Bypass this by using Windows or Linux.

Require app protection policy

This requires Intune App Protection. This can only be applied to Android and iOS so an attacker can simply use Windows or Linux instead.

Summary

Conditional Access is a powerful zero trust engine and it should be the hearth and soul of any Microsoft 365 customers security design, however, with a poor design it won’t be very effective and an attacker could easily gain access with a stolen username and password.

Regurlarly pentest your Conditional Access design by:

  • Trying to exploit legacy authentication
  • Trying to find CAP excluded users
  • Trying to find CAP excluded apps
  • Trying to avoid each available condition by interpreting the Conditional Access error messages
  • And if you still are denied access, trying different access control attacks as already mentioned

As a defender, make sure you monitor your Azure AD sign-ins, use a good SIEM solution like Microsoft Sentinel, and implement Azure AD Identity Protection for advanced risk-based Conditional Access protection.

Please follow me here, on LinkedIn and on Twitter!

@DanielChronlund

14 thoughts on “The Attackers Guide to Azure AD Conditional Access

  1. Hello, it’s not a good practice to use a group containing breakglass accounts to exclude it in CAP. Some roles have privilege to modify groups (helpdesk, Exchange admin) and could use to add some accounts in this group. If you define account directly, two roles are required to modify or bypass CA (Global admin or CA administrator).

  2. An easier way to manage the sensitivity of BTG groups that are excluded from all CA would be to make those groups role assignable during creation. This prevents tempering with the group by all but the highest privileged admins (and group owners, but you shouldn’t). You don’t have to assign a role to the group, the role assignable property is enough to protect it. https://docs.microsoft.com/en-us/azure/active-directory/roles/groups-concept

  3. What is the recommended approach for service accounts which need to be excluded from MFA (both onPrem synced to AAD and cloudonly)? Thanks

  4. I like to compensate for the lack of MFA by blocking service account sign-ins from unknown IP addresses, and also by enabling monitoring in Sentinel. Monitor for falied sign-in atempts and accoutn modifications.

  5. @Oliver, Daniel is correct.
    Make an AAD group specifically for Service Account that cant use MFA and use a consistent naming policy for the Service Accounts. Add this group as exclusion to your MFA required policies.
    Per service account create at least 1 separate Conditional Access policy where you block the respective service account from any IP except the known IP’s.
    If the service account needs higher permissions you could create an additional Conditional Access policy to restrict the app from use any application except the ones it should be using, although this is situational.

    If you are lucky enough to have a Azure AD Premium P2 license you can use the new feature:
    Identity protection for Service Accounts.
    https://docs.microsoft.com/en-us/azure/active-directory/identity-protection/concept-workload-identity-risk
    This allows risk based alerting based on account behavior like changing IP’s, user agent, adding credentials and some other things.

  6. Is it true that all accounts must have azure premium p1 or p2 license before we include them for mfa requirement in CA? Same for guest and external account?

    Thanks

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s