You dont have javascript enabled! Please enable it! Investigating Storm-0558 Security Issue - CHARBEL NEMNOM - MVP | MCT | CCSP | CISM - Cloud & CyberSecurity

Investigating Storm-0558 Security Issue

8 Min. Read

As you have seen in the news, Microsoft released a threat analysis on Storm-0558 activity on July 11, 2023. Additionally, Microsoft released additional defense-in-depth security fixes to help customers improve token validation in their custom applications.

In this post, we will share the technical details on how to investigate the Storm-0558 security issue in your Microsoft Entra ID (formerly Azure AD) environment.

Introduction

On July 11, 2023, Microsoft published two blogs detailing a malicious campaign by a threat actor tracked as Storm-0558 that targeted customer emails that they’ve detected and mitigated – See Microsoft Security Response Center and Microsoft on the Issues.

Microsoft should be commended for their commendable transparency and their willingness to share crucial information with the community. They recently released an update to their initial investigative report on Storm-0558, a threat actor associated with China. This report, dated September 6th, 2023, builds upon their findings from July 11th and focuses on how this actor acquired a signing key, enabling them to illicitly access Exchange and Outlook accounts. You can read more about this report here: Results of major technical investigations for the Storm-0558 key acquisition.

Now when it comes to investigating the Storm-0558 security issue and based on what we can learn from Microsoft’s latest report, organizations should follow these steps whenever possible:

1) Between April 2021 and June 2023, organizations should conduct log scans (if possible) to identify any evidence about the security concern associated with Storm-0558. It’s worth noting as a reminder that, based on many statistics, attackers will often lay dormant for many months before getting discovered. If possible, increasing your log retention for a year or two would be ideal and will provide the ability to go back and possibly find the time of initial access and indicators of a compromise.

2) Whenever feasible, organizations should use a hardware security module (HSM) for safeguarding key storage. By doing so, they can guarantee that key data remains excluded from crash dumps.

3) Signing keys should be rotated regularly, ideally every few weeks. As was written by Wiz’s research (Compromised Microsoft Key: More Impactful Than We Thought), it is necessary to examine suspicious authentication attempts via OpenID tokens signed by the compromised key (more on this in the next section).

4) Regular monitoring and testing of the efficacy of secret scanning mechanisms, especially those established to prevent key leaks from high-risk to low-risk environments, is crucial.

5) It’s essential to maintain a clear separation between sensitive production environments and corporate environments that have a higher susceptibility to compromise.

6) Whenever feasible, organizations should use Security information and event management (SIEM) and security orchestration, automation, and response (SOAR) such as Microsoft Sentinel.

7) Furthermore, it’s important for organizations to keep a record of assets where debugging and crash dump data is gathered, stored, or organized, and to establish access controls that restrict the exposure of these assets.

The list above is by no means exhaustive but it should serve as a good starting point to follow, monitor, and protect your digital asset. In the following sections, we will go through all the learnings and experiences that we went through while auditing multiple customer environments.

If you are still unsure, we will be happy to support you in analyzing your environment. You can arrange a non-binding preliminary meeting with us by filling out this form.

Let’s begin!

Investigating Storm-0558

The focus of this post is how to check and audit any suspicious authentication attempts via OpenID tokens signed by the compromised key in our Microsoft Entra ID (formerly Azure AD) environment.

As was written by Wiz’s thorough investigation research, this can be done by unpacking the access tokens used against the application and searching for the string 1LTMzakihiRla_8z2BEJVXeWMqo within the kid field of the Javascript Object Signing and Encryption (JOSE) Header, as well as to look at the MSA tenant ID 9188040d-6c67-4c5b-b112-36a304b66dad that may indicate the use of a compromised key.

// The question is, how this can be done and audited?

Let’s go through all the steps in more detail, so you can audit any suspicious authentication attempts via OpenID tokens signed by the compromised key.

Prerequisites

To follow this guide, you need to have the following:

1) Tenant – Microsoft 365 / Microsoft Entra (formerly Azure AD) Tenant.

2) You need to be a Global Administrator or Security Administrator on the Tenant. We strongly recommend using the Security Admin role and NOT the Global Admin.

3) You need the Azure CLI installed on your machine or using the Azure Cloud Shell. At the time of this writing, we are using Azure CLI version 2.52.0. You can check the CLI version on your machine and upgrade its version with the following commands:

# Check Azure CLI version
az --version

# Upgrade Azure CLI
az upgrade

4) Optionally, but highly recommended is to install the JWT PowerShell module on your machine. The JSON Web Tokens (JWT) module will help to create and verify JSON Web Tokens (JWTs). We need to use this module to decode the access token locally of the affected Azure AD application by Storm-0558. JSON Web Tokens are an open, industry-standard RFC 7519 method for representing claims securely between two parties.

# Install JWT (JSON Web Tokens) implementation in PowerShell per RFC7519
Install-Module -Name JWT

Import-Module -Name JWT -Verbose

You could also use JWT.io created by Okta to decode the header and payload of the access token, but as indicated clearly – JWTs are credentials, that can grant access to resources. Be careful where you paste them!

Assuming you have all the prerequisites in place, take the following steps:

Detect Compromised Key in Microsoft Entra ID

To the best of our knowledge and based on what Microsoft shared in their report, the only affected applications by Storm-0558, were those that utilized Microsoft v2.0 access token verification using the following two endpoints: “https://login.microsoftonline.com/common/discovery/v2.0/keyscommon” And “https://login.microsoftonline.com/consumers/discovery/v2.0/keys“.

First, we need to sign in to the environment assuming you have the right privileges. You can run the following Azure CLI command to have tenant-level access. Replace “azure-ad-tenant-id” with your Tenant ID.

az login `
 --allow-no-subscriptions `
 --tenant "azure-ad-tenant-id"

Next, we need to identify which Microsoft Entra ID (Azure AD) applications in the environment might be affected. You can run the following Azure CLI command to get the list of all the exposed applications:

az ad app list `
 --filter "(signinaudience eq 'AzureADMultipleOrgs' or signinaudience eq 'AzureADandPersonalMicrosoftAccount' or signinaudience eq 'PersonalMicrosoftAccount')" `
 --query "[?id].{AppName:displayName, AppID:appId, ObjID:id, HomePageURL:web.homePageUrl}" 

In this environment, we have three affected applications by the Storm-0558 security issue. In this example, we blurred the details in the image for obvious reasons. Take note of the “AppID” field, we need to use it in the next step.

Get the list of the exposed Azure AD applications
Get the list of the exposed Azure AD applications

Now, some of those Azure AD applications might also be associated with Azure App Service (Web Apps). To identify which Azure AD applications are redirecting to any of your Web Apps, you can run the following CLI command to get the list of the exposed Web Apps:

az ad app list `
 --filter "(signinaudience eq 'AzureADMultipleOrgs' or signinaudience eq 'AzureADandPersonalMicrosoftAccount' or signinaudience eq 'PersonalMicrosoftAccount')" `
 --query "[?web && web.homePageUrl && contains(web.homePageUrl, 'azurewebsites.net')].{AppName:displayName, AppID:appId, ObjID:id, HomePageURL:web.homePageUrl}"

In this Azure environment, we have none of the applications associated with any Azure Web Apps.

Get the list of the exposed Azure Web Apps
Get the list of the exposed Azure Web Apps

Unpacking Access Tokens

As mentioned earlier, we need to identify potential malicious activities in those affected Azure AD applications, so it is necessary to examine suspicious authentication attempts via OpenID tokens signed by the compromised key.

To do this, we need to unpack the access tokens used against the application and then search manually for the string 1LTMzakihiRla_8z2BEJVXeWMqo within the kid field of the Javascript Object Signing and Encryption (JOSE) Header. Follow the steps below:

1) First, take note of all the affected applications ID “AppID” field.

2) Next, you need to get the “client secret” password of those affected applications. If your client secret (password) is expired, then you can reset/create an application’s password or certificate credentials in the Microsoft Entra admin center portal > App registrations > {your app} > Certificates & secrets > Client secrets > Add “New client secret“.

Or you could also run the following Azure CLI command to reset the app credential. Replace the “AppID” with your affected application ID.

az ad app credential reset `
 --id "AppID" `
 --append

Take note of the “appId“, “password“, and “tenant” fields. We need to use them in Step 3 below. We blurred the details in the image for obvious reasons.

az ad app credential reset
az ad app credential reset

Please note that by default, this command clears all passwords and keys, and lets the graph service generate a new password credential as shown in the figure below.

Azure AD application | Certificates & secrets
Azure AD application | Certificates & secrets

3) Next, you need to log in with the affected Azure AD Application (service principal) by running the following Azure CLI command:

az login `
 --allow-no-subscriptions `
 --service-principal `
 --username "appid" `
 --password "clientsecret" `
 --tenant "tenantid"
Azure CLI login with an Azure service principal
Azure CLI login with an Azure service principal

4) Next, you need to get the Application ID URI. You can run the following Azure CLI command to check the current Application ID URI. Replace the “AppID” with your affected application ID.

az ad app show `
 --id "AppID" `
 --query "{appId:appId, displayName:displayName, identifierUris:identifierUris[0]}"
Get Azure AD Application ID URI
Get Azure AD Application ID URI

Now, if the “identifierUris” field is empty, then you need to create one. You can do that directly in the Microsoft Entra admin center portal > App registrations > {your app} > Expose an API > Add “Application ID URI“.

Or you could run the following Azure CLI command to create an App ID URI. The “identifierUris” acts as the prefix for the scopes you’ll reference in your API’s code, and it must be globally unique. You can use the default value provided, which is in the form of “api://“, or specify a more readable URI like “https://app.domain.com/api“.

# Update existing Application ID URI: api://App-ID-URI
az ad app update `
 --id "AppID" ` 
 --identifier-uris api://App-ID-URI

# Update existing Application ID URI: https://app.domain.com/api
az ad app update `
 --id "AppID" `
 --identifier-uris https://app.domain.com/api

5) Once you have the Application ID URI set, you need to get the access token(s) of the affected application by running the following Azure CLI command and storing the content in a variable called $jwt. Replace the “Application-ID-URI” with the “identifierUris” that you are using for (API or HTTPS).

$jwt = az account get-access-token ` 
 --resource api://Application-ID-URI 
| ConvertFrom-JSON

$jwt = az account get-access-token `
 --resource https://Application-ID-URI
| ConvertFrom-JSON

6) You can view the application access token content by typing “$jwt.accessToken“.

Get Azure AD Application Access Token
Get Azure AD Application Access Token

7) Last, assuming that you have installed the JWT PowerShell module on your machine. You can run the following PowerShell command to decode and unpack the access tokens Header.

# Decode JWT Header Access Token
$jwt.accessToken | Get-JwtHeader | ConvertFrom-Json -AsHashtable

If we look at the kid field of the Javascript Object Signing and Encryption (JOSE) Header, we don’t see the string 1LTMzakihiRla_8z2BEJVXeWMqo. So, this Azure AD application was not compromised.

Get JWT Header Access Token
Get JWT Header Access Token

According to Microsoft, if a certain encryption key was hacked, any permission token signed with that key should be seen as suspicious.

Unfortunately, when it comes to keeping records specific to a particular application, there aren’t any universally accepted standards. Consequently, in most cases, those who own applications don’t have detailed records showing the original permission token or the key used to sign it. This makes it very hard for application owners to identify and investigate such incidents.

When looking at the Microsoft Entra ID (Azure Active Directory) application that’s set up exclusively for multi-tenant authentication (without support for Microsoft personal accounts), it’s possible to spot fake tokens by checking for specific claims called “iss“, “idp“, and “tid” in the Payload access token. You can run the following PowerShell command to decode and unpack the access tokens Payload.

# Decode JWT Payload Access Token
$jwt.accessToken | Get-JwtPayload | ConvertFrom-JSON

These claims are frequently used by applications and are more likely to be recorded in application logs. Furthermore, if someone tries to access your application using a permission token signed by the following tenant ID “9188040d-6c67-4c5b-b112-36a304b66dad“, then it could indicate the use of a hacked key. In this environment, we can see a different tenant ID in the “iss” field, so this application was not hacked.

Get JWT Payload Access Token
Get JWT Payload Access Token

Lastly, if you’ve enabled HTTP Logs for your Azure Web Apps, you might be able to see which IP addresses have been accessing your application. According to the Microsoft analysis report (under the Actor infrastructure section), certain IP addresses are linked to a potential security threat.

Diagnostic Settings | App Service HTTP Logs
Diagnostic Settings | App Service HTTP Logs

To determine if your Web App may have been affected, you can use the following Kusto Query Language (KQL) in Log Analytics to look for each of your Web Apps that might have been targeted in the last 90 days. If you have the Data Retention set in Log Analytics for more than 90 days, then use the full retention range where applicable.

AppServiceHTTPLogs 
| where TimeGenerated > ago(90d)
| where Result == "Success" 
 and CIp in ("195.26.87.219","185.236.228.183","85.239.63.160","193.105.134.58", 
       "146.0.74.16","91.231.186.226","91.222.174.41","185.38.142.249", 
       "51.89.156.153","176.31.90.129","137.74.181.100","193.36.119.45", 
       "185.158.248.159","131.153.78.188","37.143.130.146","146.70.157.45", 
       "185.195.200.39","185.38.142.229","146.70.121.44","31.42.177.181", 
       "185.51.134.52","173.44.226.70","45.14.227.233","185.236.231.109", 
       "178.73.220.149","45.14.227.212","91.222.173.225","146.70.35.168", 
       "146.70.157.213","31.42.177.201","5.252.176.8","80.85.158.215", 
       "193.149.129.88","5.252.178.68","116.202.251.8")

In this environment, no results were found for the specified time range (90 days).

Audit Azure Web Apps for the Storm-0558 security issue
Audit Azure Web Apps for the Storm-0558 security issue

There you have it. Happy Storm-0558 Investigation!

Wrapping Up

Auditing and investigating a Storm-0558 security issue is a complex but necessary process in our increasingly digital world. By following these steps and leveraging our insights, you can effectively address this security concern and protect your digital assets.

The full impact of the Storm-0558 incident is much larger than we understood it to be. We believe this event will have long-lasting implications for our trust in the cloud and the core components that support it. Above all, the identity layer (Microsoft Entra ID) is the basic fabric of everything we do in Microsoft Azure and Microsoft 365.

Stay vigilant, keep your systems up to date, and collaborate with experts when needed to ensure your ongoing cloud security.

References

__
Thank you for reading my blog.

If you have any questions or feedback, please leave a comment.

-Charbel Nemnom-

Photo of author
About the Author:
Charbel Nemnom
Charbel Nemnom is a Senior Cloud Architect with 21+ years of IT experience. As a Swiss Certified Information Security Manager (ISM), CCSP, CISM, Microsoft MVP, and MCT, he excels in optimizing mission-critical enterprise systems. His extensive practical knowledge spans complex system design, network architecture, business continuity, and cloud security, establishing him as an authoritative and trustworthy expert in the field. Charbel frequently writes about Cloud, Cybersecurity, and IT Certifications.
Previous

Mastering Azure Point-to-Site VPN and DNS Private Resolver

Top 9 Ultimate SaaS Security Checklist

Next

Let us know what you think, or ask a question...