Microsoft JSON Web Token Extractor

Microsoft JSON Web Token Extractor

When connecting to Azure using, for example, the PowerShell Az module, a JSON Web Token is created and sometimes stored in plain text on disk and memory. I will show where to find the JSON Web Tokens on disk in this blog post, including a tool I wrote to get JSON Web Tokens from memory that contains the JSON Web Tokens, including those found on disk.

JSON Web Tokens

To securely exchange information between parties, authenticating and authorizing a JSON Web Token is commonly used.

A JSON Web Token encodes any sets of identity claims into a payload, including a header that contains how it is to be signed.

The client authenticates to an Identity Provider, and the Identity Provider creates and signs, using a private key, a JSON Web Token. When the client connects to a service, it provides the signed JSON Web Token. The service validates the token using the public key of the Identity Provider and authenticates the client.

Image 1: JSON Web Token Authentication

Let us look at a JSON Web Token example:

Image 2: JSON Web Token example

The encoded part consists of three parts: A header, a payload, and a verify signature. If you tamper with the header or payload, the signature is not valid, and the token becomes invalid.

So, in short, having a valid JSON Web Token is the key to the kingdom.


The first and most obvious path to look for JSON Web Tokens is the HistorySavePath.

HistorySavePath is a setting that saves all PowerShell console history. When a user or admin connects to Azure using PowerShell, the command is stored to file in plain text.

Image 3: HistorySavePath
Image 4: Logging saved to file

Note: Since HistorySavePath loads when PowerShell starts, “Microsoft JSON Web Token Extractor” also displays these tokens.

User Profile

Depending on how a user or admin connects to Azure, the following JSON files contains the JSON Web Token in plain text:

Image 5: File location for JSON Web Tokens

Note: Since the JSON files load when PowerShell starts, “Microsoft JSON Web Token Extractor” also displays these tokens.

Script Block Logging

Script Block Logging saves blocks of code as PowerShell executes them. When a user or admin runs the following command in PowerShell and Script Block Logging is enabled, the event viewer contains the JSON Web Token.

Note: Script Block Logging setting is disabled by default but enabled by many companies due to monitoring.

Microsoft JSON Web Token Extractor

A JSON Web Token is created in memory when connecting to Azure using PowerShell using the following command:

I wondered if I could extract the JSON Web Token from memory without dumping anything on disk to avoid a trigger from any Endpoint Detection and Response solution.

The result is a C# tool to extract all JSON Web Tokens found in memory used by PowerShell, including those found on disk.

Image 6: Microsoft JSON Web Token Extractor


My idea was to jump from on-premises to the cloud without dumping the process to disk using standard tools. The token still needs to be valid, and a user or an admin needs to connect to Azure using PowerShell, but if they do, an attacker can connect to the cloud without touching any other device in the network and stay low-profile.

Microsoft PrintDemon vulnerability

Microsoft PrintDemon vulnerability

PrintDemon (CVE-2020-1048) is a vulnerability that uses the Windows Printer Spooler to escalate privileges, bypass Endpoint Detection & Response (EDR), and gain persistence. The Windows Printer Spooler has a long history of vulnerabilities, including a vulnerability (CVE-2010-2729) used by the well-known Malware called Stuxnet in 2010.

Printer Attributes

A printer must be associated with two attributes: A printer port and a printer driver. Setup the printer port to ‘PORTPROMPT, makes it possible to print to a file. There is no check when using the PowerShell command ‘Add-PrinterPort’ if the user has permission to access the location set as the printer port. So the user is free to set any location for the printer port as a low-privileged user. When you print to the printer, it uses the printer port to print to a file. If the user does not have write permission to the location, the print job gets queued. Once you restart the spooler service, the print job will execute with SYSTEM privileges, and the file will also get dropped with these privileges. Since SYSTEM is a high-privileges account, you can drop a file anywhere on the system as a low-privileged user, hence the name privilege-escalation.

Markup Bytes

There was one problem, however. When you print a string to the printer, it looks like there are some markup bytes at the beginning of the file as the printer thinks you are printing and not to a file. Since the first few bytes of a file is the signature (magic bytes) of a file, it can not be touched if you want to execute it in a usual way.

Figure 1: PowerShell commands used during the attack

I wanted to check if I was able to write a valid executable file to disk without any markup bytes at the beginning of the file. The script linked below creates a printer with a malicious printer port and write a byte array to the newly created printer. This way, it is possible to dump a valid binary on disk as SYSTEM once you restart the spooler service.


Attacks like DLL hijacking is possible as a low-privileged user using the PrintDemon bug. Microsoft released a patch last week. After installing the patch, the system checks if the user has permissions, which you set as a port on a printer, before creating the port. Unfortunately, the patch prevents creating a new malicious port, but malicious ports created before the patch still work.

The C# code can be found here and the PowerShell code can be found here.

Microsoft PowerShell Unhide

Microsoft PowerShell Unhide

PowerShell supports a command line parameter “WindowStyle” as shown below. The parameter “WindowStyle” sets the window style for that session. Valid values are Normal, Minimized, Maximized, and Hidden.

    [-PSConsoleFile <file> | -Version <version>]
    [-InputFormat {Text | XML}]
    [-OutputFormat {Text | XML}]
    [-WindowStyle <style>]
    [-EncodedCommand <Base64EncodedCommand>]
    [-ConfigurationName <string>]
    [-File - | <filePath> <args>]
    [-ExecutionPolicy <ExecutionPolicy>]
    [-Command - | { <script-block> [-args <arg-array>] }
                | { <string> [<CommandParameters>] } ]

Unhide PowerShell

Most malicious PowerShell scripts run PowerShell with the window style “Hidden”. When the process starts with WindowStyle hidden, no PowerShell console is displayed, so it runs unnoticed for the logged-in user. I created a script to unhide all PowerShell processes. This script can be used during a CERT incident when you want to unhide all PowerShell shells to see what commands are used.

Figure 1: WindowStyle Hidden and unhide PowerShell


There are ways to log PowerShell commands, but when logs are cleared, unhiding is an option.

The PowerShell script can be found here.