I Know What Azure Did Last Summer

March 18, 2020 Omer Tsarfati

More and more companies are deciding to move their infrastructures into cloud environments offered by Microsoft Azure, Google Cloud Computing, Amazon AWS and many more.

In our modern and rapidly changing times, companies big and small find cloud infrastructures both convenient and cost-effective, but the need for more computing power has been an issue…and now there is a good solution for that.

While there is a lot of honey in the Cloud Computing solutions, there is also a sting to be aware of.  Relying on “someone else’s computer” also means relying on someone else’s security measures.  We’ve seen a lot of attacks that have focused on cloud configuration weaknesses – and seeing and understanding these vulnerabilities helps us fortify our cloud environments.  But, what about the vulnerabilities we don’t know of? Are we ready for those?

This blog explores a vulnerability I found in the Microsoft Azure Portal that could lead to a take over of an Azure environment by malicious attackers.

TL;DR

Taking over your cloud environment is a real risk.  With this Microsoft Azure vulnerability, attackers could take over Azure Accounts by exploiting a misconfiguration bug in Azure Portal’s manifest. Manifest is a configuration file – in this case, a JSON file, which states the settings to the web application.

During our research on the Azure Portal, we saw telemetry reports being sent to a non-existing domain and most of those telemetry requests included access tokens.  In this case, the access token has the user’s permissions (“user_impersonation” scope) and is valid for any Azure resource, including virtual machines and storage servers (BLOBs), traffic managers, etc.  Leaking this sensitive token could let malicious attackers compromise numerous Azure accounts.

There are several ways to exploit this bug through various DNS manipulation techniques that we cover in this blog post.

The Azure Vulnerability Explained
In case you are not familiar with Azure, it is Microsoft’s ever-expanding set of cloud services.
It is designed to let the customers build, manage, and deploy applications on a massive, global network.

Azure portal is the name of the Azure management web platform, which lets you access and manage all your applications in one place.  It also allows you to manage, build, deploy and monitor other types of resources as well – anything from simple apps to complex cloud environments.  Because of this, Azure environments often contain many sensitive and valuable resources like production environments, customer data, secrets and other confidential information.

Imagine a scenario in which a malicious attacker manages to get access to your most privileged user credentials in such an environment – it would be a disaster, right?  This scenario could serve up all your virtual machines, storage servers and your customer data to be encrypted by ransomware – or render all your passwords, secrets and confidential data up for grabs.  In short, an attacker could either destroy or steal any sensitive or valuable resource in this cloud compromised environment.

Extensions, Manifests and What Could Go Wrong
The Azure portal is built from many components, called extensions, and every extension stands for a different feature the portal provides. Usually, the extensions’ settings are specified in one place – in this case, it is located in a JSON file called “ExtensionManifest.” The manifest tells the extensions’ JavaScript code how it should behave and which external resources it should fetch and use.  A good example of an extension is the “My Dashboard” page, as shown in in Figure 1.

Figure 1: The “My Dashboard” page from Azure Portal.The manifest file specifies the resource URLs and domain names that the JavaScript code extension can use.

Now with the background out of the way, let’s dig into the research.

While surfing in the Azure portal, I noticed odd requests going out of my browser.  In the beginning, I thought that this must be some temporary server bug or that maybe there was something wrong with my browser, but, shortly, I figured out that this bug affected every Azure user.  Well, that piqued my interest and I needed to investigate further.

I started by looking for anything that had a connection to the hostname “urehubs,” which is where the requests were being sent (as shown in Figure 2).  In one of the files, I managed to find a clue that shed some light on this bug.

 

Figure 2: Requests sent to https://urehubs/ sent from portal.azure.com.

ExtensionManifest bug

Inside the ExtensionManifest, there is an extension named “HubsExtension.”
The “HubsExtenstion” was a bit different from the other extension, as its URI attribute was missing “//” or any proper domain format attributes (like portal.azure.com), instead it looks like it’s only a URL path. (See Figure 3.)

Figure 3: Snapshot of the HubsExtension object from the Azure Portal Manifest.

While that was interesting, it still wasn’t clear why this odd bug happened – I needed to find the specific JavaScript code that makes those requests.  I looked into the JavaScript code for the specific code handling the parsing of this extension object… and I found it. I started to set breakpoints in the JavaScript code to better understand the bug.

The JavaScript Parsing Bug

The “tt” function (as shown in Figure 4) is called as part of the regular process of loading the Manifest (either cached or fresh), which happens every time you surf to the Azure portal.

Figure 4: A snapshot of the “tt” function from “Content_Dynamic_uLKj31Z9Yqa.js.”

The “tt” function is located in “Content_Dynamic_uLKj31Z9Yqa.js” and takes as a parameter the URI attribute from the extension object, which is located in the Manifest file, and parses it.

Check out Figure 5 for non-obfuscated code with similar functionality, which I created to make the code in Figure 4 easier to follow.

Figure 5: Snapshot of rewritten, non-obfuscated “tt” function code. Now let’s dive into the code logic.

The function gets the URI parameter and then looks for the two forward slashes (“//”) that should be at the beginning of the URI. As we know, the problematic URI attribute from the “HubsExtenstion,” “AzureHubs/Hubs” is missing those “//,” so the slashesLocation variable will be 0.
The protocol variable will get the current page protocol schema string, which will be “https:.”
The endOfUrlPath will be nine, as the first “/” in the URI is located just before the second “Hubs” string.  The domainName variable will be the substring of the URI starting with the second character (slashesLocation + 2 -> 0 + 2) and running up to the 9 character index. The result of this is “urehubs.”

It looks familiar, doesn’t it?

And in the end, the return value will be the object in Figure 6.

Figure 6: Snapshot of the return object from the “tt” function.

In a closer look at the results, we can see that the origin property in the returned object sets to the local server “urehubs.”

Now, to connect all the dots:

  • The “HubsExtenstion” URI attribute is missing the “//” string.
  • The string doesn’t parse well in the JavaScript code, so the function returns an object with the origin attribute set to “https://urehubs.”
  • Telemetry requests with sensitive access tokens are then sent to “https://urehubs/.”

In addition, the specific access tokens sent by the telemetry requests have a “user_impersonation” permissions scope to the “https://management.core.windows.net/” resource.

This means that, if you have that token, you can take action on behalf of its owner.

This combination of factors makes it possible to steal the Authorization token and take actions on behalf of the victim in his Azure environment.

But, can it be exploited in real life? Yes, indeed.

The Attack Vectors

During our research, we leveraged two main attack vectors – local domain exploitation and exploiting this in the wild web.

Local Environment Exploitation

For exploiting this bug in a local domain environment, the attacker would need to set up the following components:

  1. An HTTP Server with the hostname “ureuhbs”
  2. A signed certificate by a root CA or by the local domain root CA

Eventually, every Azure user in this local domain who surfs to the Azure portal unintended will send its access token to the attacker’s server.

Exploiting the Bug in the Wild
DNS servers, most of the time, do their job and they do it well – but some DNS servers may actually do it “too well”.  Let me explain.

Some DNS servers’ configurations may add a suffix from the commonly known TLD (com, net, org, etc.) to local hostnames when they don’t manage to resolve it by their local record.

In this case, the DNS server, when it’s trying to resolve “urehubs,” is also trying to resolve urehubs.com, urehubs.net, etc.

A potential attacker could abuse this behavior by buying many different “urehubs” domains with different suffixes and exploit them.

Yet, it won’t be enough, as the attacker still needs a valid certificate for the local server signed by a public root CA.

As of  November 1st, 2015, CA/Browser Forum no longer allows publicly trusted SSL Certificates to include these local names, such as internal server names and reserved IP addresses (as it could lead to MiTM in a local network.) But, there are still malicious root CAs that have been compromised over the years (Commodo in 2011 or DigiNotar in 2013, for example).

As a responsible and protective measure, we bought 27 “urehubs” domains with different suffixes to prevent malicious attackers from exploiting this bug, including urehubs.com, urehubs.net, urehubs.org, etc.

Another important point to make is that security features are great, but only when they are turned on.  Some users turn off the certificate validation function in their browser because of browser surfing errors or the need to access unsigned websites from time to time.  And, seriously, please don’t do that – when you do, you expose yourself to risks.


Exploitation POC
In a POC we did, we were able to successfully exploit this vulnerability and got an Azure token of an external organization (See Figure 7).

Figure 7: Snapshot of the compromised access token.

The Fix
On Friday, 6 September 2019, we noticed that there was a change in the Azure portal in some JavaScript files.  Microsoft added three lines of code to patch the vulnerability (See Figure 8).  By adding the URL to the href attribute, Microsoft managed to mitigate the vulnerability by ensuring that the URL is not only the path, but also a full valid URL.

If a URL does not include any schema at the beginning, the JavaScript will handle it as a relative path to the current page domain.  Which, in this case, means that instead of getting “https://urehubs” we will now get https://portal.azure.com/AzureHubs/Hubs.

Figure 8: Snapshot of the patched “tt” function, which we renamed “l.”

Microsoft fixed the issue with a simple JavaScript code change that fixed the URL parsing bug was in the JavaScript file and left the ExtensionManifest as is.

Regarding the URI formats in the ExtensionsManifest, I think that it might be worth sticking to one URI format, as not doing that could be a root cause for many other bugs that could pop up over time.


Conclusion

We believe that the vulnerability existed for almost two weeks, so a potential attacker could have exploited it to access many networks by registering domains and providing a valid certificate for a local domain on each request.  It’s important to note that there might be similar vulnerabilities out there that we aren’t aware of that could potentially expose cloud infrastructure in order to take over.

Cloud services are great options for many companies. Still, you must remember that relying on “someone else’s infrastructure” is relying on someone else security measures – which can be a risky endeavor.  When embarking on any cloud initiative, remember that you aren’t tied to only using the security measures of your provider. In essence, you also have a responsibility to ensure the security of applications, OS, supporting infrastructure and other assets running in the cloud.

It’s important to note that while this research was related to Microsoft Azure specifically, this type of vulnerability could happen in other similar solutions.  So, when you see strange traffic or behavior in a service, program or similar, don’t ignore it – try to understand it better. There might be a vulnerability or a bug lying just under it just waiting to be discovered.

Disclosure TimeLine

28/08/19 — The vulnerability was found.

05/09/19 –We managed to exploit the vulnerability and create a fully working POC.

06/09/19 — Microsoft patched the bug before we could report it to them.

Previous Article
Explain Like I’m 5: Remote Desktop Protocol (RDP)
Explain Like I’m 5: Remote Desktop Protocol (RDP)

Table of Contents Introduction RDP Connection Connection Sequence | Basic Input and Output Channels in RDP ...

Next Article
CoronaVirus Ransomware
CoronaVirus Ransomware

These days, when the world is focused on getting a handle on the COVID-19 crisis, cybercriminals are taking...