Posts Introducing AzurEnum

Introducing AzurEnum

As time goes on, organizations keep moving more and more IT assets into the cloud. More importantly, the Azure cloud plays a paramount role in the IT structure of most companies due to its merging capabilities with on-prem environments, leading to hybrid Active Directory landscapes. Hybrid environments are attractive for many reasons, but they also include another layer of complexity that opens new attack surface to attackers. In order to speed up the analysis of Azure environments, AzurEnum was developed. You can find it now on GitHub:

When talking about the Azure cloud, one can differenciate three branches:

  • Microsoft Entra ID: Entra ID contains the users, groups and most of the important permissions that extend to all branches of the Azure cloud. Entra ID acts as Single Sign-on (SSO) platform for all of the Azure resources and is therefore extremely critical from a security perspective.
  • Infrastructure in the Azure cloud: Virtual machines, storage accounts and many other products are available to perform cloud computing as one may expect it from any public cloud.
  • Microsoft 365: Many Microsoft applications, such as Teams, Sharepoint or Outlook, integrate seemingless with Azure and are present by default in every tenant. These are usually meant under the Microsoft 365 umbrella term.

AzurEnum focuses on the Microsoft Entra ID side of things. It aims to provide a lightweight overview of the most relevant security configurations concerning the Azure environment.

If you are familiar with Azure administration, you know it’s a lot of clicks. Click, click, click, oh no, the option I was looking for has been moved to a new portal. Yeah, I know that feeling, too. Further, you could argue that some of the most critical security information is not even present in the masks you would expect it to. A nice example of this is gone through in a post of SpecterOps.

Resorting to APIs and command line tools is thus a must if you want to understand Azure. Even more if you want to enumerate information quickly. AzurEnum does the heavy lifting of handling tokens, querying interesting API endpoints and parsing the results for you to see only what really matters. This does not mean that all important information is displayed, but at least most of it is.

AzurEnum is a script written in python and can run on both Windows and Linux systems. However, for a smoother experience, Linux systems are preferred. AzurEnum can run with any Azure user, too, but in order to get the most out of it you should run it with a user having the Entra ID role Global Reader or greater (read) access. You do not have to worry about AzurEnum performing some changes to your environment, since all it does is perform read-only queries to the Azure APIs.

Note that when running AzurEnum with a low-privileged user, the MFA methods information will most likely be unreliable.

Quick start

In order to run AzurEnum, you will need python3 and the msal library, which you can install with pip.

$ pip3 install msal

You can open the help menu as follows.

$ ./ -h
usage: [-h] [-o OUTPUT_TEXT] [-j OUTPUT_JSON] [-nc] [-ua USER_AGENT] [-t TENANT_ID]

  -h, --help                                 show this help message and exit
  -o OUTPUT_TEXT, --output-text OUTPUT_TEXT  specify filename to save TEXT output
  -j OUTPUT_JSON, --output-json OUTPUT_JSON  specify filename to save JSON output (only findings related to insecure settings will be written!)
  -nc, --no-color                            don't use colors
  -ua USER_AGENT, --user-agent USER_AGENT    specify user agent (default is MS-Edge on Windows 10)
  -t TENANT_ID, --tenant-id TENANT_ID        specify tenant to authenticate to

To run the tool with the default options, you can just leave out all the arguments:

Running the tool

Currently, the only authentication flow supported is device-code login. Follow the instructions to complete the authentication in a browser. AzurEnum will perform the flow with the client ID of Microsoft Office and, after successful authentication, will exchange the obtained refresh token for a few additional access tokens. After that, AzurEnum will prompt the user to authenticate again. This is currently necessary in order to obtain access tokens through a different, non foci client ID without relying on the user having to grant any sort of application consent, which may not be possible in a penetration test or red team engagement.

Once that is done, AzurEnum will proceed to gather and parse all the data.

Basic information

AzurEnum divides its outputs in blocks. The first block shows some general information about the tenant. You may think of it as the “Microsoft Entra ID” blade of the Azure Portal, but with more information.

Basic information

You should watch out for some interesting lines here. First, the number of users that have not set any MFA methods yet. Even if your tenant enforces a 100% MFA coverage with conditional access policies, your users need to get MFA methods setup for it to really work. Otherwise, a user with no MFA methods will simply be prompted to set up MFA on a successful login, which of course does not prevent a remote attacker from compromising that user.

Another interesting point is the amount of modifiable groups. These are groups where any tenant member can join without having any special rights. Often, you see this arise when configuring public teams or sites in some M365 applications.

As you can see in the last line, for some important options that AzurEnum is not able to enumerate yet, it will prompt you to check it manually by visiting the given link.

General settings

The list of general settings will take care of putting together the security-relevant options to quickly provide you an overview of them. The following example corresponds to a tenant where the default settings have never been changed, which, as you can see, is by no means the most secure configuration.

General settings

Again, portal links are given to quickly jump to the respective setting on the Azure portal.

Entra ID roles

Using the Azure portal to find out who has Entra ID roles is quite a pain, and it is even worse when Privileged Identity Management (PIM) is active. AzurEnum will first provide you with a clean list of all Entra ID role assignments, showing even those that can not be found in the “Roles and Administrators” menu of the portal, such as “Directory Synchronization Accounts”. Additionally, if a user does not have any MFA methods set, it will be marked. Same goes to users that are synced from an on-prem Active Directory.

Entra ID role assignments

If PIM is active, a list of all PIM assignments will be shown too, including those that are in an “eligible” state.

Entra ID PIM role assignments

Service Principal API permissions

Azure apps, aka. service principals, can have a second type of permissions that you will not find when enumerating Entra ID roles, but may grant the same level of access as global admin. You will see the portal refer to those as “API permissions” or “permissions”. The most important of them are the “application” type permissions, which will grant apps some rights without the need of users consenting to them to delegate their permissions. This can lead to users that control apps, such as app owners or users with particular Entra ID roles, being able to escalate their privileges. Note that the Directory Synchronization Accounts, whose credentials can be extracted from Entra ID Connect servers, control all apps, too. This may open the door to obtaining high-privileged access to the Azure tenant to an attacker that controls the Entra ID Connect server on-prem.

Another important line to draw when talking about apps’ API permissions is that some service principals may correspond to applications that are defined in an external tenant. If you give excessive permissions to one of these apps, the external tenant may be able to even obtain full administrative privileges on your tenant by exploiting that service principal, as it likely happened in the recent Microsoft breach.

In the portal, you would need to click through every single app in your tenant. AzurEnum just provides a list of all service principals with application-level permissions to cover both topics above.

Service principal application-level API permissions

Administrative units

Administrative units are a nice protection feature that allows for more granular role management in Entra ID. Some important information about them will be shown in this section.

Administrative units

Dynamic groups

The so-called “dynamic groups” are groups which regularly update their membership based on configured rules. These rules may allow an attacker to get in the group by, for example, inviting a guest account with a specially crafted display name. Reviewing them with AzurEnum is quite easy.

Dynamic groups

Named locations and conditional access

Conditional Access Policies (CAPs) are quite detailed objects that determine whether a user is allowed to login to the Azure tenant or not, based on multiple factors. One of the most interesting ones is the source IP of the connection used to authenticate, which can be restricted to given ranges called “named locations”. AzurEnum will provide some insight about these, but you should definitely review the CAPs manually.

Named locations and conditional access

Devices overview

Not much at the moment, but some information concerning devices is shown as well.

Devices overview

Credential search in principal and groups attributes

Last but not least, users, groups and apps’ attributes will be searched for credentials. This is a typical tactic for attackers to use in on-prem environments, specially with the “description” field of users. In Entra ID, it could happen too, that credentials end up in some of the searched properties. To be honest, however, I have never seen this in actual environments, but who knows.

Credential search in principal and groups attributes

Additional arguments

AzurEnum supports output logging in both plaintext and json, although the json output will only contain information that could be mapped directly into a finding in a penetration test without additional context, which is not much. When authenticating to a tenant that is not the native one of your user, you will need to provide its tenant ID with the relevant parameter. Finally, specifying the user agent that AzurEnum uses to perform the device-code authentication may help you run the tool through CAPs that restrict some device platforms.

Wrapping up

After going through the output of AzurEnum you should have a pretty good idea of the main security issues on your tenant and its permission structure. If you are a pentester or a red teamer, you may have found some synced user or high-privileged app to abuse for lateral movement from on-prem to cloud. If you are an administrator or blue teamer, maybe you noticed that some administrator user is not needed anymore, or that you are not using administrative units (and you definitely should!). But no matter who you are, you will surely appreciate reading all this stuff without having to click yourself through 300 portal blades, or without having to carefully study all Microsoft Graph API endpoints!

Of course, AzurEnum has its flaws and it does not cover everything you should know about Entra ID security, but I hope that it helps you attacking or securing your tenant.

This post is licensed under CC BY 4.0 by the author.