Cloud pentesting in Azure: one access key to rule them all

As cloud computing is on the rise, more of our penetration testing efforts will shift towards services hosted in the cloud. Testing a web app for vulnerabilities is no different regardless if it’s hosted on-premise, in the cloud or in your basement. What does change is how the application interacts with other services. Take for example the database: not anymore located on your own SQL server but in the cloud as well. The solution used by Azure is called Azure Storage, and in this article we explore its weaknesses.

Azure Storage

The type of data that can be stored on an Azure Storage account is wide-ranging. You should think of it as the cloud-replacement for file servers. Some examples:

  • Logs
  • Virtual machine hard disk images
  • Backups
  • Documents and files

There are multiple ways in which a user or an application can access this data. One of them is by use of a key.

By default, every storage account has two keys that provide full access to its data. They are called the primary key and the secondary key, although they both provide the same level of access. Multiple services using the storage account are using these keys, so we are dealing with:

  • A full access key
  • Shared between services
  • Inconvenient to replace

It’s a scary thought. To view these keys, we have to browse the Azure Portal as can be seen from below image.

The access keys are accessible to the Azure administrator by browsing to the storage account settings.

Attacker value

It’s immediately clear that this is an attractive lure for an attacker: lots of data and shared keys that give full access.

So where do we find this key? The first place to look is in source code and configuration files. Developers need to write code to access the storage, and might place the key inside their code (instead of the much more secure option, the Azure Key Vault). Storage account keys are 64-byte values, encoded in Base64.

Because code bases can be large, you can start by searching for usage of these classes and libraries:

  • Microsoft.WindowsAzure.Storage.Auth (.NET)
  • com.microsoft.azure.storage.StorageCredentials (Java)
  • AzureStorage.createBlobService (JavaScript)

In config files, you can try to grep on:

  • StorageConnectionString
  • StorageServiceKeys
  • StorageAccountKey

For example, you can see from this GitHub screenshot that many repositories expose such keys within code. It’s not unthinkable that the same is possible for the assignment you are working on.

Azure storage keys can be found on github
Searching all repositories of GitHub for the string “StorageConnectionString” returns more than 35.000 results. Take for example this recently updated config file exposing the storage key.

Developer tools

A second place of finding these keys is by obtaining them from the tools that developers use to access Azure Storage. For this scenario, you will need foothold on a developers machine. There are a number of tools which are frequently used for this purpose:

  • Azure Storage Explorer
  • CloudXplorer
  • TableXplorer
  • Redgate Azure Explorer

Having access to these tools, it is often straightforward to find the keys: they are usually set in the preferences or configuration section of the application.

Using the Azure Storage key

Once you have obtained the key, you should start identifying the type of storage accessible. Azure distinguishes between blob data, table data, queues and files. How to exactly determine this is out of scope for this article, but I want to share with you one quick and easy way of accessing files.

By default, Azure files are reachable via SMB 3.0, on port 445, with only one account, and it has Full Controll permissions. All of this is not configurable. You can just establish an SMB session using the key as the password:

net use * \\<storage_account_name>.file.core.windows.net\<share_name> /USER:AZURE\<storage_account_name> <primary_key>

Just by using the primary key we get full access to the files stored in Azure Storage.

SAS tokens

Next to keys there is another interesting method of access penetration testers should be aware of: SAS tokens. As can be seen from below image, they can be created with more restrictions than the storage keys which give full access. The Azure administrator can restrict data type, set a time limit and even restrict the IP addresses from which the data may be accessed.

No file level restrictions can be made for SAS tokens created in the Azure Portal

This makes them way less powerful than storage keys, however, if you find them they may still be useful. One thing that can’t be restricted from the Azure Portal is which objects exactly can be accessed with the SAS token: it just provides access to all files (or, all blobs; all queues; etc.).

It is possible to restrict access to only one file for example, but for that the SAS token would have to be generated via Powershell, which means more effort for the administrator and thus less likely to be the case.

Conclusion

Hunting for storage access keys and tokens should be a top priority for penetration testers and red teamers conducting exercises on Azure environments. Access to storage means access to files, logs, virtual machine hard drive images and will almost in any case mean game over for the target.

Join us at Blackhat Las Vegas this year with our Practical Web Application Hacking Advanced Course on 1-2 August and 3-4 August! We look forward to see you there!

Meanwhile, follow us on twitter: https://twitter.com/redtimmysec