Bypassing Azure AD Conditional Access

This article will explore the less known ways to authenticate and access resources protected by Azure AD.

This article assumes you know what conditional access is. It’s the identity security “firewall” of Azure AD, if you will. It lets you set rules on which apps can be accessed by whom under which conditions. Restrictions can be set like you need a managed device, or MFA is required. If you are using Azure AD and are not using Conditional Access, well you are doing it wrong. Although conditional access is great, it however doesn’t protect you against all forms of authentication. It is exactly these scenarios on which I want to focus in this article.

CA1.png

Application Permissions

Let's start with application permissions. Application permissions are used for applications that need access to data without a user being present. Some backup solutions or a scheduled task or cron job might need to access a list of users, an individual mailbox, or even all mailboxes. When you create an application in your Azure Active Directory and provide it with a secret or a certificate it basically becomes a special kind of service account. Anyone who knows the ClientID (basically the username) and has access to the certificate or the secret (the password) will be able to use it. Because this will normally only be used for service to service of scripted authentications these authentications are not restricted by conditional access policies.

 In practice we find that most app developers prefer ClientID/Secret over ClientID/Certificate. It’s just easier. Although secrets can be set to expire in 1 or 2 years, in most implementations I have come across, secrets are set to never expire. Again, easy, low maintenance. Combined with sometimes outrages amounts of permissions, this is something to really watch out for. Your Conditional Access policies might be water tight, but it takes only one ClientID/Secret with enough permissions to leak and you will have a serious security breach. Also, these ClientID/Secret logins don’t show in your login audit log. Updates and modifications will show in the audit log but I was not able to find a record of a login or a read.

So what to do about this?

I wrote a PowerShell script that will list all applications with a secret or cert that have application permissions. I would really recommend making sure you rotate the secrets every now and then, especially with any apps with lots of permissions. 

Delegated Application Permissions

In most cases it will take an administrator to configure application permissions. This makes data loss through application permissions, well, your own stupid fault :). The administrator should / or could have known. The recent SANS “hack”, in which 28.000 emails where stolen, used a very different technique which might not seem that scary at first. Delegated application permissions.

Let me explain what a delegated application permission is. A delegated permission allows the application to access things on behalf of the user. Meaning the app can never access anything the user doesn’t have permissions to access. This is the not so scary part. Delegated application permissions come in two forms, user consented and administrator consented. When an application requests users.readwrite.all (permission that allows read write on all users) this will always require an admin consent, not a user consent. See, not so scary.

But mail.read (reading an individual users mail) is open for user consent. It’s exactly this user consented delegated application permissions that enabled the hack at SANS. The problem with user delegated application permissions is that the application doesn’t necessarily need to be in your Azure AD for a user to be able to consent. Yes, that is right, I can create an app in my Azure AD and set it up as a multi-tenant app. Then setup permissions to ask for user consent for mail.read. Then I can send you (the user) a link to my new cool app and tell you that it uses SSO, you can just use your corporate credentials. It will pop-up a consent screen, asking you if it is ok for my app to log you in (oh, and read your email). If you click yes on the consent screen, the app is now automatically registered in your AzureAD and has access to the individual user’s mail.

This makes delegated application permissions very different from application permissions. By default no admin is required to register the app or even hand out permissions. As long as the application only requests a permission that can be "user consented". In most cases the admin will never even know that a user has consented and that a new app was registered. This is the scary bit.

The security here hinges on the fact that you can get the user to click the consent screen. Are you sure your users can't be tricked into clicking consent? Someone at SANS, a security training institute, apparently fell for this trick.

I said using a delegated application permission the application can only access things the user has permissions to. That is still true  the app however is not restricted by Conditional Access when it wants to access the things you (the user) might not be able to access due to Conditional Access policies. Are you scared yet?

So really, the user consented delegated application permissions are the ones you should worry about, because you probably don’t know which users have consented to which apps and what permissions these apps have requested.

 So what to do about this?

  1. Check your current state. Which users have consented to which apps and what permissions have they consented to? This PowerShell script will show you.

  2. Monitor what users consented to what apps. You can do that by running the PowerShell script regularly, but you might be way to late when you find out. The better way would be to send you Azure AD audit logs to a SIEM and configure an alert for user consents.

  3. The default behavior is to allow all users to consent to any app. You might want to consider changing that.

There is a simple block option, disabling user consent altogether. Request approval by admin, setting up a workflow that allows users to request an admin to consent for them. This would make social engineering so much harder but also introduces additional work load. Recently Microsoft is adding more options allowing users to consent only certain permissions or applications and not others. You will find these settings in your Azure AD configuration under enterprise apps and then user settings.

You might actually be using conditional access without knowing it. If you have “security defaults” turned on, you will have a hand full of standard conditional access policies enabled. The problem with these security defaults is that for most larger customers this is not flexible enough.