Understanding the Azure RBAC structure
RBAC is an authorization system used to control who has access to Azure resources, and the actions users can take against those resources. At a high level, you can think of it as granting security principals (users, groups, and applications) access to Azure resources, by assigning roles to the security principals.
For example, RBAC can be used to grant a user access to manage all VMs in a subscription, while another user is granted access to manage all storage accounts in the same subscription. That would be an odd choice for separation of duties in a subscription, but cloud environments tend to foster creative solutions for making things work.
RBAC concepts get far more complex when we start introducing the different scopes of role assignments (management groups, subscriptions, and so on), but keep the preceding description in mind as we progress.
Azure RBAC is made up of the following components—security principals, role definitions, and role assignment. Let's look at each of these components in detail.
Security principals
A security principal is a fancy term to describe an Azure AD object that we want to assign privileges to. This could be a user account, a group, a service principal, or a managed identity. These are all different types of identities that exist in Azure AD, as shown in the following screenshot:
Important note
Do not confuse ''security principal'' with ''service principal." Security principal is an overall term used to describe objects in Azure AD (including users, groups, and service principals). Service principal is a specific type of security principal.
While there are many facets to a security principal, keep in mind that every security principal has an object ID that uniquely identifies it in Azure AD. This object ID is typically used as a reference when assigning a role to the security principal. Next, we will cover the different types of security principals.
User accounts
A user account is a standard user identity in Azure AD. These accounts can be internal to the Azure AD tenant, or an external ''guest'' account. In either case, the general administration of the users will occur at the Azure AD tenant level.
Internal user accounts are user identities created in the Azure AD tenant by an administrator. Additionally, these may be user identities that are synchronized from an on-premises AD environment to Azure AD (see Figure 1.2).
The accounts are commonly addressed by their User Principal Name (UPN), which is typically an email address. For example, a user named karl
in the Azure AD tenant, with a domain name of azurepentesting.com
, will have a UPN of [email protected].
The following screenshot shows an internal user account in the Azure portal. Most Azure AD accounts that you interact with will fall under this category:
External user accounts are user identities from other Azure AD tenants, or Microsoft accounts (outlook.com
, hotmail.com
, and so on) that are invited as guest users to an Azure AD tenant. The UPN format for external user accounts is shown here:
<alias>_<HomeTenant>#EXT#@domain.suffix
For example, if a user named david
, from the cloudsecnews.com
AD tenant, is invited as a guest user of the globaladministratorazurepen.onmicrosoft.com
Azure AD tenant, the UPN will be david_cloudsecnews.com#EXT#@
globaladministratorazurepen.onmicrosoft.com
(see Figure 1.5).
External accounts are typically used to grant access to vendors or third-party users that may be working on a subscription. The user accounts are not directly managed by the Azure AD tenant, so account policies (password length, multi-factor authentication (MFA), and so on) would be out of the control of the Azure AD tenant.
Here is a screenshot of an external user account:
For both internal and external accounts, we will be targeting credentials for the accounts during an Azure penetration test to get access to resources in the Azure AD tenant. As we will see in later chapters, these accounts are a great place to get an initial foothold in an environment.
Service principal
A service principal is an application identity in Azure AD. You can think of it as an Azure AD object representing an application that needs access to Azure resources. This is the preferred way to grant access to an application instead of creating a dummy user account.
Service principals will be very important when we get to automation account attacks, but for now, just know that applications can be registered in Azure AD and they can also be granted permissions in the tenant. For example, you may have an automation account that runs maintenance scripts in a subscription, so you will want to have specific rights granted to the account that runs the scripts. These rights would be applied to the service principal that is created in the Azure AD tenant when the automation account is created.
Service principals can also be assigned certificates and secrets that can be used for authentication. These credentials will be important to note when we want to use the app registrations for privilege escalation, and/or persistence in the Azure AD tenant. The process of creating a service principal is called an app registration.
In the following screenshot, we can see some basic information about an app registration in our sample tenant. As an attacker, we may have situations where it makes sense to create a new service principal that would allow us to persist in an environment. If we choose a generic display name (Backup Service
) for creating a backdoor service principal, we may have a better chance of going undetected for longer in the tenant:
Finally, service principals can have owners set within Azure AD. The owners of the service principals can control the credentials associated with the accounts, so the owners are useful targets for escalation in an environment where service principals have elevated privileges.
Managed identity
There are times that Azure services (VMs, AKS, applications, and so on) may need access to other Azure resources. The easiest way to grant this access is to enable a managed identity for the Azure service. A managed identity is an automatically created and managed service principal that is assigned to a supported Azure service. At the time of writing, there are 27 services that support managed identities in Azure.
Important note
If you're interested in learning more about all of the services that support managed identities in Azure, Microsoft has them documented here: https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/services-support-managed-identities.
A managed identity can either be system-assigned or user-assigned. A system-assigned identity is tied directly to the resource that the identity is created for. A user-assigned identity is first created in a subscription, and then applied to resources. A user-managed identity can be shared by many services, while a system-assigned identity cannot.
In later chapters, we will see that these identities can be used to escalate privileges in a tenant. The important thing to note for now is that anyone who has modification rights on a resource with an assigned managed identity can potentially assume the rights of that managed identity. This is service-dependent, but there are several services (that we will review later) that can readily be used to generate tokens for managed identities.
Groups
Groups are used in Azure AD to organize users and to make it easier to manage access to Azure resources. For example, it is more effective to assign permissions to 200 users in a group than to 200 individual users. Once Azure resource access is granted to a group, future access can then be granted—or revoked—through group memberships.
Similar to user accounts, groups can either be created by administrators in Azure AD or synchronized from an on-premises AD environment. There is also a third scenario, whereby users can be allowed to create their own groups, or join existing public groups, but those groups are typically associated with Microsoft 365 services.
Much as with app registrations, groups can have owners (either user accounts or service principals), and the owners do not have to be a member of the group. Group owners can manage the group and its membership.
Azure AD supports two main types of groups: security groups that are primarily used to manage access to shared resources, and Microsoft 365 groups that serve a similar function to email distribution groups that you may be familiar with in AD. These can also be used to assign access to Azure resources.
Membership of an Azure AD group can either be assigned or dynamic. Assigned memberships are direct user assignments by an administrator or group owner. Dynamic group memberships use rules that are automatically evaluated to determine group membership based on user or device attributes. The rules for dynamic group membership can allow for soft matching, which could be abused to escalate privileges. See the Dynamic group membership section in Chapter 4, Exploiting Reader Permissions, for more information on this attack.
In Azure environments that sync with on-premises AD domains, the complexity of organizing users can increase exponentially as there can be a large number of groups that are imported from the on-premises domain. While there may be a limited number of groups that are actually utilized in the Azure tenant, you may need to deal with hundreds (or thousands) of groups that are in an Azure AD tenant. This shouldn't cause any issues while assessing the Azure environment, but it may complicate things as you begin to pivot to on-premises environments. We will cover tools that help simplify assessing AD groups in Chapter 7, Exploiting Owner and Privileged Azure AD Role Permissions.
Role definition
After security principals, the second component of Azure RBAC is a role definition. This term describes a collection of permissions. A permission describes an action that may or may not be performed on a resource, such as read, write, and delete. We can examine the permissions under a default Azure role to see what it allows us to do.
Here are the permissions for the Contributor role in Azure:
{ "assignableScopes": [ "/" ], "description": "Grants full access to manage all resources, but does not allow you to assign roles in Azure RBAC, manage assignments in Azure Blueprints, or share image galleries.", "id": "/subscriptions/{subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c", "name": "b24988ac-6180-42a0-ab88-20f7382dd24c", "permissions": [ { "actions": [ "*" ], "notActions": [ "Microsoft.Authorization/*/Delete", "Microsoft.Authorization/*/Write", "Microsoft.Authorization/elevateAccess/Action", "Microsoft.Blueprint/blueprintAssignments/write", "Microsoft.Blueprint/blueprintAssignments/delete", "Microsoft.Compute/galleries/share/action" ], "dataActions": [], "notDataActions": [] } ], "roleName": "Contributor", "roleType": "BuiltInRole", "type": "Microsoft.Authorization/roleDefinitions" }
We can see in the preceding permissions that a role definition supports two types of operations, as follows:
- Control-plane operations that describe the management actions that the role can perform. These are defined in the
''actions'': [ ]
section. An example of a management action is the permission to create a storage account. - Data-plane operations describe the data actions (within a resource) that the role can perform. These are defined in the
''dataActions'': [ ]
section. An example of a data action is the permission to read the data that is stored in a storage account.
We can also see in the preceding permissions that certain operations can be excluded for a role. The ''notActions'': [ ]
section defines management actions that a role is restricted from performing. The ''notDataActions'': [ ]
section defines data actions that a role is restricted from performing.
In the preceding example for the Contributor role, the role has the permission to perform all management (*
) actions, but it is restricted (by the notActions
definition) from performing authorization-related management actions, which means that the role cannot be used to assign permissions to others. Also, the role does not have the permissions to perform any data action.
It should also be noted that this role definition also contains the ''assignableScopes '': [ ''/'' ]
section, which denotes how the role can be applied in the tenant. /
indicates that it can be applied at the root of the management group structure, but it can also be applied to any scopes (child management g, subscriptions, and so on) under the root.
Default RBAC roles
At the most basic level, there are three primary roles that are commonly applied in Azure: Reader, Contributor, and Owner. Beyond these three primitive roles, you will find service-specific roles that act as restricted versions of these base roles. These restricted roles are useful for reducing a user's permissions in a specific subscription, but they can still allow for privilege escalation in the environment.
For example, the Virtual Machine Contributor role (applied at the subscription level) does not allow an Azure AD user to be a contributor for all of the services in the subscription. However, the role does allow Microsoft.Compute/virtualMachines/*
actions, which means it would allow the user to run commands on any of the VMs in the subscription.
If this VM is configured with a privileged managed identity, that VM Contributor user could run commands on the VM to assume the rights of the managed identity and escalate their privileges. We will dive deeper into this concept in Chapter 5, Exploiting Contributor Permissions on IaaS Services, where we learn about using contributor rights on VMs.
An important point to note is that Azure resources and the Azure AD tenant have separate permission systems. This means that the roles used to grant access to Azure AD are different from the roles used to grant access to Azure resources, as depicted in the following screenshot:
Azure AD roles are used to manage access to Azure AD resources and operations, such as user accounts and password resets, while Azure RBAC roles are used to manage access to Azure resources such as storage accounts, SQL databases, and so on.
Both Azure AD and Azure resources have multiple built-in roles with predefined permissions that organizations may use to grant access to users and applications. Both support custom roles that are created by administrators. At the time of writing, there are currently 60 built-in Azure AD roles and over 220 Azure RBAC built-in roles.
Important note
Microsoft has the best documentation on these roles and has a comprehensive list of the available Azure AD roles (https://docs.microsoft.com/en-us/azure/active-directory/roles/permissions-reference) and Azure RBAC roles (https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles).
Role assignment
Next, we need to understand how the roles are applied in an Azure AD tenant. Returning to Figure 1.1, we noted the Azure resource organization hierarchy. One of the interesting design choices in the Azure cloud is the way that RBAC roles are applied to this hierarchy. As noted previously, RBAC roles can be applied at the root management group, child management group, subscription, resource group, and individual resource levels.
Any role-based access that is assigned at the root management group level propagates throughout the organization and cannot be overridden at a lower level. If an attacker manages to steal a credential that gives access at the root management group level, they could leverage this access to move laterally across different subscriptions in the organization.
Now that we have a better understanding of the RBAC structure, let's take a look at how we can interact with the Azure environment.