DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Eng Soon Cheah
Eng Soon Cheah

Posted on

Abusing Managed Identities

Original Research: 0xPwN Blog - Create an Azure Vulnerable Lab: Part #4 – Managed Identities

Using Managed Identities it is possible to grant a resource (such as VM/WebApp/Function/etc) access to other resource (such as Vaults/Storage Accounts/etc.) For example, if we want to give our web application access to a private storage account container without having to deal with how we safely store connection strings in config files or source code, we could use a managed identity.

First we enable the managed identity for the web application:

Azure Managed Identities

Once enabled, we are given the possibility to configure the roles assigned for this identity (i.e: permissions granted to the service that we enabled the identity for).

Azure Managed Identities

Lastly, we assign one or more roles (which is a set of permissions) for that identity. A role can be assigned assigned at Subscription level, Resource group, Storage Account, Vault or SQL and it propagates β€œdownwards” in the Azure architecture layer.

Azure Managed Identities

Under each role, we can see in details what permissions are included. Azure allows also to configure custom roles in case the built-in ones are not suitable for your case.

Azure Managed Identities

Similarly, to see who has permissions granted for a give resource, we can check that under the Access Control (IAM) -> View access to this resource.

Azure Managed Identities

So in our case, we should see under the Storage Account that the web application has Reader and Data Access:

Azure Managed Identities

Now that we have the basics of how Managed Identity works, let’s see how can we exploit this. Since the web application has access to the storage account, and we compromised the web application we should be able to get as well access to the storage account. Long story short, we get the same permissions that the resource we compromised had. Based on how poorly the Identity roles are assigned, it can be the case that the permissions are assigned at Subscription level, effectively granting us access to all resources inside it!

Azure Managed Identities

While in our case it looks that the permissions are proper (we are limiting access only to the Storage Account that we need access to) and limit the roles to Reader and Data Access (instead of Contributor or Owner), there is still a catch. Our web app needs permissions only to the β€œimages” container, but the managed identity configured has enough permissions to list the access keys to the whole Storage Account granting us access to any other containers hosted on the same account.

Exploiting Azure Managed Identity

Abusing the command injection on the web app, we can make a curl request to the $IDENTITY_ENDPOINT URL stored in the environment variables and get an access token and account id (client id in the response) which can be used to authenticate to Azure.

curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2017-09-01" -H secret:$IDENTITY_HEADER
Enter fullscreen mode Exit fullscreen mode

Azure Managed Identities

Using the Azure Powershell module, we can connect to Azure with the access token:

PS> Install-Module -Name Az -Repository PSGallery -Force
PS> Connect-AzAccount -AccessToken <access_token> -AccountId <client_id>
Enter fullscreen mode Exit fullscreen mode

Once connected, you should see details about the Subscription and Tenant that the Managed Identity we are impersonating has access to. Using the Get-AzResource Azure Powershell cmdlet, we can check which resources inside the subscription we can access:

Azure Managed Identities

To list the roles assigned to the managed, we can use the Azure Powershell cmdlet Get-AzRoleAssignment. This cmdlet requires additionally a graph token which we can get from the https://graph.microsoft.com/ endpoint, but also the permission to list roles and permissions for identities which our Identity does not have.

However, we can still try to access the Storage Account keys without these permissions and see if we are successful. For that we will use the Get-AzStorageAccountKey cmdley with the Resource Group Name and Account Name that we found in the previous step.

Get storage account keys:

>Get-AzStorageAccountKey -ResourceGroupName "0xpwnlab" -AccountName "0xpwnstorageacc"

KeyName Value                       Permissions CreationTime
------- -----                       ----------- ----------
key1    L175hccq[...]lH9DJ==        Full 3/12/20...
key2    vcZiPzJp[...]ZkKvA==        Full 3/12/20...
Enter fullscreen mode Exit fullscreen mode

If the command returns two keys, than it means that our identity had permissions to list them. Let’s use these keys in azure storage explorer and see if there are other containers stored on the same account. In the azure storage explorer, we click the connect icon and select storage account or service

Azure Managed Identities

On the second step, this time we select the Account name and key option:

Azure Managed Identities

For the Account name we use the name that we enumerated in the Get-AzResource step, while for the key we can use either of the two we found:

Azure Managed Identities

Once we connect, on the left side menu we should find a new storage account, we 2 containers: the images container used by the web app, but also a new one containing the flag.

Azure Managed Identities

And that’s it! We just seen how abusing a command injection into a web app we discovered that it had a managed identity associated to it. After we got the JWT access token, we connected to the Azure Powershell and enumerated the resources that we have access to. The improper permissions set for the managed identity allowed us to read the access key for the whole Storage Account and discover another private container that was not referenced anywhere, containing the flag sensitive information.

Top comments (0)

🌚 Life is too short to browse without dark mode