This post is part 2 in the Hunting Azure Admins for Vertical Escalation series. Part 1 of this series detailed the usage and functionality of Azure authentication tokens, file locations that cache the tokens during a user session (“%USERPROFILE%\.Azure\TokenCache.dat”), methods for locating user exported Azure context files containing tokens, and leveraging them to bypass password authentication, as well as, multi-factor authentication. This blog post will focus on methodology to extract Azure authentication tokens when the end-user is disconnected and hasn’t exported an Azure context file.
Disconnected Azure PowerShell Sessions
When a user connects to Azure from PowerShell, a TokenCache.dat file is created and populated with the user’s Azure authentication token. This is detailed at great lengths in Part 1. However, if the user disconnected their Azure session, the TokenCache.dat file is stripped of the token. So, obtaining an Azure cached token from the TokenCache.dat file requires an active logged-in session.
So, what can be done in a scenario where the Azure PowerShell session is disconnected, and the user hasn’t saved an Azure context file to disk?
PowerShell Process Memory
Thinking about traditional Windows credential theft and lateral movement brought to mind the LSASS.exe process and Mimikatz. In short, Windows has historically stored hashed and cleartext account credentials in the LSASS.exe process memory space and penetration testers have leveraged tools like Mimikatz to extract those credentials. This has gone on for years and has forced Microsoft into developing new security controls around the storage and access of credentials in Windows. On newer Windows systems, you will likely only extract hashed credentials from accounts that are actively logged onto the machine, as Windows has improved its scrubbing of credentials from memory after a user disconnects.
This leads to the PowerShell process and identifying information it maintains in memory. Let’s start by dumping the PowerShell process memory to disk in minidump format.
Although we used a custom tool, SnappyKatz, to dump the PowerShell process memory other publicly available tools exist that can do this, such as, ProcDump from the Sysinternals Suite. We can then leverage our favorite hex editor to explore the contents of the dump. Referring back to the contents inside the TokenCache.dat file, we can quickly search for keywords to locate the Azure context Json in the dump.
This is great, but the required CacheData field that would contain the base64 encoded cached token was empty. At first, it was thought the field was empty because the session had been disconnected and due diligence had been done on the part of Microsoft to remove sensitive information from memory. In true Microsoft fashion, the missing cached token data was identified, in full, at a different offset in the dump.
We had now located the two pieces of information needed to reconstruct an Azure context file. To create the context file, we saved the JSON context data found at the first location to a file and populated the CacheData field with the base64 encoded token cache located at the second location.
In order to save a tremendous amount of time on engagements, we created a tool in Python that automates the extraction of required data and properly exports it to a usable Azure context JSON file.
This tool produces the following Azure context JSON output:
The last step is to import the extracted Azure context file and see if we are able to access Azure.
As we can see, Azure access has been obtained, leveraging disconnected session tokens extracted from PowerShell process memory. To make it easy to replicate our findings, we've published the AzureTokenExtractor tool to extract Azure authentication tokens from PowerShell process minidumps.
We hope you have enjoyed this blog post. Keep checking back as we add more research, tool, and technique-related posts in the future!