Not all settings and features provided by Microsoft in Azure Portal are properly configured and secured out of the box. Sometimes there are gems, such as Azure VM Extensions, which in some edge cases can lead to a takeover of your infrastructure and your entire domain! How? You’ll find out in this post.

Other series posts

This post is part of the Gain control over any Azure VM series.

The following entries are included in this series:

  1. [This post] Introduction to VM Extensions
  2. Introduction to Run Commands
  3. Run Commands and VM Extensions demo
  4. Run Commands and VM Extensions audit
  5. Securing against Run Commands and VM Extensions

Pssst: Some of the entries are still in progress, but as soon as I finish them, they will be linked above.

What are Azure VM Extensions?

Let’s start by explaining what Azure VM Extensions are. They are applications/packages available in Azure for additional configuration of our VM after deployment. For example, we can automatically install the Log Analytics agent or perform Defender for Servers onboarding. In addition to the built-in extensions, we also have the ability to create our own VM Extensions - Custom Script Extension, which are PowerShell or Bash scripts with arbitrary commands/cmdlets.

A guide on how to hack a Comain Controller using Custom Script Extension will be published in another blog post. As soon as I write it, you will find a link to that post here 😉

Reset password

An interesting case of VM extensions is the VMAccess extension. It allows you to reset local admin account password or reset RDP/SSH remote access configuration. This is also an option for lazy people who don’t want to create their own extensions to hack their Azure VM 😫 A ready-made local admin account password change wizard is available in Azure Portal, in the VM details under Help > Reset password.

However, the built-in option is quite problematic because:

  1. the user must exist on the machine.
  2. if our VM is a Domain Controller, the extension will not work.
  3. if the user account is locked, changing the password won’t help us and we won’t be able to access the Azure VM.

Lots of limitations, but at least, despite the description in the Azure portal, we can change the password of any local account, not just the built-in administrator 😀

But RBAC?

You might have thought, “That’s definitely turned off in our company”. It should be, but if you’re only using the built-in Azure roles, you might have missed it.

Assuming you don’t have Owner or Contributor privileges, another role you could get is Virtual Machine Contributor. After all, someone needs to create, delete, and power on/off virtual machines in the cloud. According to the documentation, the Virtual Machine Contributor role has the right to:

Create and manage virtual machines, manage disks, install and run software, reset password of the root user of the virtual machine using VM extensions, and manage local user accounts using VM extensions. This role does not grant you management access to the virtual network or storage account the virtual machines are connected to. This role does not allow you to assign roles in Azure RBAC.

Azure built-in roles - License requirements - Virtual Machine Contributor

…or in short, the Azure VM Extensions!

Where are our permissions hiding? Here, to be exact:

1
Microsoft.Compute/virtualMachines/*

We can perform all actions within Microsoft.Compute/virtualMachines, which means we have permissions to Microsoft.Compute/virtualMachines/extensions/write, which means we can deploy and run VM Extensions.

How to fix the problem

What is the fastest way to solve our problem? Create a new custom role from a copy of the Virtual Machine Contributor definition and restrict its rights to write/execute VM Extensions. Once it is created, we should scope any resources that are critical to us such as Domain Controllers to this role.

Find premade Custom Roles templates on my GitHub:

Use Azure Portal or Azure PowerShell to create roles.

Available Methods

Option 1 - Azure Portal - click to expand

Navigate to your subscription and select Access control (IAM) > Add > Add custom role

Portal Azure - Access control (IAM)

Then select the JSON tab, click Edit and paste the role definition from GitHub.

Portal Azure - Create a custom role - JSON

Done - save the new role with the Review + Create button.

Option 2 - Azure PowerShell - click to expand

Start Windows PowerShell and connect to your Azure subscription.

1
2
Connect-AzAccount
Select-AzSubscription -SubscriptionId "Your_subscription_ID"

Azure PowerShell- Connect to Azure

Next, create a new role from the custom role definition that you downloaded earlier.

1
New-AzRoleDefinition -InputFile "Custom_Role_FilePath.json"

Azure PowerShell- Create new role

Done - the custom role was created!

Custom Role tests

Now that the role has been created, it is time to test it. I assigned the role to the test user and tried to reset the VM password again.

The result? The request was blocked due to insufficient privileges 🛑

It wasn’t supposed to be like this…

Unfortunately, revoking permissions for VM Extensions also has negative consequences. For example, if we want to encrypt an Azure VM disk using Azure Disk Encryption, we will be blocked because the disk encryption process uses the AzureDiskEncryption VM extension.

In this case, we need to ask another administrator with full Virtual Machine Contributor privileges to encrypt the machine, or instead of revoking VM Extensions privileges, we can create an Azure policy that only allows run/deploy of whitelisted extensions.

The next blog post in this series will provide an example of such a policy 🙃

Conclusion

Congratulations, as usual, you made it to the end of this post Now you know how dangerous Azure VM Extensions are and that you can’t reset the local administrator password on a Domain Controller using the Reset Password option.

You may have noticed that this post is shorter than the previous ones. Good observation! This year I decided to break up longer topics into shorter posts. After all, not everyone has 15 minutes of free time to read a boring, long monologue….

We’ll see what comes of it 🤡

Additional resources

  1. Azure virtual machine extensions and features
  2. Azure built-in roles
  3. Install Azure PowerShell on Windows
  4. Ensure custom script extensions are not used in Azure Virtual Machine