Head in the Clouds: Microsoft Azure
Sep 16 2018
By: Christopher Maddalena • 8 min read

Introduction
This article is a companion piece for this primer:
Head in the Clouds – Christopher Maddalena – Medium
In the cloud space, there are three major providers at this time: Amazon Web Services (AWS), Microsoft Azure, and…
posts.specterops.io
IP Address Ranges
Microsoft’s offers their up-to-date list of IP addresses as an XML document. The document is always changing and must be downloaded from the Microsoft Download Center:
Download Microsoft Azure Datacenter IP Ranges from Official Microsoft Download Center
This file contains the Compute IP address ranges (including SQL ranges) used by the Microsoft Azure Datacenters
www.microsoft.com
The downloaded document will have a name that includes the date it was last updated, e.g. PublicIPs_20180813.xml. The XML is made-up of Region nodes that name the region, such as “australiac2,” and includes the IP address ranges in lines like this one:
<IpRange Subnet=”20.36.64.0/19" />
Making Use of the IP Addresses
An up-to-date list of these IP addresses is useful for identifying assets hosted in an Azure environment. Any domain or subdomain that points back to an IP address in the list will lead to an Azure file share or virtual server.
Maintaining an Updated Master List
The collection of these IP addresses has been automated in the following script:
The script fetches the latests IP address ranges used by each provider and then outputs one list in a CloudIPs.txt file. Each range is on a new line following a header naming the service, e.g. “# Microsoft Azure.”
Storage: Azure File Shares
Azure file shares are different from the other options offering by Amazon and Google. They can actually be accessed as Windows file shares and created and managed using some PowerShell cmdlets. The web address for an Azure resource looks like this:
https://cmaddy.file.core.windows.net/test/foo.bar
The first part is a storage account name (e.g. cmaddy). The part following the windows.net domain is a file share name (e.g. test).
Requesting that address is not enough to retrieve a file or list the contents of a share. A “Shared Access Signature” is required as part of the URI. This is a long signature that must be added to the request before the resource can be retrieved. From Azure’s dashboard:
A shared access signature (SAS) is a URI that grants restricted access rights to Azure Storage resources. You can provide a shared access signature to clients who should not be trusted with your storage account key but whom you wish to delegate access to certain storage account resources. By distributing a shared access signature URI to these clients, you grant them access to a resource for a specified period of time.
A user must configure and then generate an SAS to be used for the request. Users may configure an SAS to allow only certain IP addresses access to the resource, restrict time of day for access, delegate privileges, and even enforce access over HTTPS. This SAS is then added to the end of the web address. If the SAS is valid, the resource is returned.
It is possible to detect if a storage account name exists using a web request, but only so much can be learned. Requesting a non-existent name will return an HTTP 404 response. Requesting a valid name, like the one above, will return:
<Error>
<Code>InvalidQueryParameterValue</Code>
<Message>
Value for one of the query parameters specified in the request URI is invalid.
</Message>
<QueryParameterName>comp</QueryParameterName>
<QueryParameterValue/>
<Reason/>
</Error>
Appending a file share name to the end returns a different XML error response, but it is the same regardless of whether or not the name corresponds to a file share that exists under the storage account name. The response only changes if a valid SAS and valid file share names is provided.
Computing: Virtual Machines
Azure’s virtual machine offering is simply called Virtual Machines. Microsoft’s documentation for the virtual machine metadata service can be found here:
Azure Instance Metadata Service
The Azure Instance Metadata Service provides information about running virtual machine instances that can be used to…
docs.microsoft.com
The metadata service is covered in the main primer article.
Authentication: Azure Users
An Azure account is managed by a root user which can be used to add an additional user accounts and other types of users to the account. Similar to Compute, Azure requires a user account to be named using a verified domain. A domain name can be configured and verified by following the steps outlined here:
Add a custom domain to Azure AD
Explains how to add a custom domain in Azure Active Directory.
docs.microsoft.com
Azure also allows the root user to create various types of accounts, such as Automation Accounts, that can be used in different ways and do not require a “verified domain.” Azure’s documentation is dense, but the most interesting type of user from a “someone just stole some credentials” point of view may be the Azure Service Principal Name (SPN). Azure’s documentation explains:
If you want to create a separate sign in with access restrictions, you can do so through a service principal. Service principals are separate identities that can be associated with an account. Service principals are useful for working with applications and tasks that must be automated.
SPNs can be created using the Azure command line tool:
# az ad sp create-for-rbac — name TestSPN — password PASSWORD
Retrying role assignment creation: 1/36
{
“appId”: “9fe5ea08–569d-48dd-9b15–6c9b84486ff5”,
“displayName”: “TestSPN”,
“name”: “http://TestSPN“,
“password”: “PASSWORD”,
“tenant”: “<TENANT_OBJECT_ID>”
}
Then an SPN can be used to authenticate:
# az login — service-principal -u http://TestSPN -p PASSWORD — tenant <TENANT_OBJECT_ID>
[
{
“cloudName”: “AzureCloud”,
“id”: <OBJECT_ID>,
“isDefault”: true,
“name”: “Free Trial”,
“state”: “Enabled”,
“tenantId”: <TENANT_OBJECT_ID>,
“user”: {
“name”: “http://TestSPN”,
“type”: “servicePrincipal”
}
}
]
If an Azure SPN’s password were to be found in a script, it is possible it could be abused.
What may be more interesting, though, is how these command line tools might be used on a compromised Azure host. If an attacker were to gain access to an Azure host as one of the Azure users, the CLI will automatically login as that user when az login
is run. This, along with Azure SPNs and other user types, requires additional investigation.
Credential Files
When the Azure CLI tool is used, the tools creates local credential files in the user’s home folder:
MacOS and Linux: ~/.azure/
Windows: C:\Users\USERNAME\.azure\
This includes two JSON files, accessTokens.json and azureProfile.json. The azureProfile.json file contains the username/email address of the authenticated user, the user account name’s tenantId value, some Azure subscription information, and a few more details. The accessTokens.json file contains the tokens used for authentication with Azure.
Stealing Credentials
If Azure credential files are found they can be reused for authentication on a machine the Azure CLI installed.
First, create the ~/.azure/accessTokens.json and ~/.azure/azureProfile.json files and copy the contents.
Test the credential files by executing: az account list
If the credential files were copied and pasted correctly and the JSON is valid, the compromised account will be listed.
Otherwise, a JSONDecoder error is likely to be returned. Example:
File “/usr/local/Cellar/azure-cli/2.0.44/libexec/lib/python3.7/site-packages/azure/cli/core/__init__.py”, line 52, in __init__
ACCOUNT.load(os.path.join(azure_folder, ‘azureProfile.json’))…
json.decoder.JSONDecodeError: Extra data: line 1 column 335 (char 334)
Automating Credential Theft
As a proof of concept, this tool was created to search for and collect credential files associated with Azure, Compute, and AWS:
chrismaddalena/SharpCloud
github.com
SharpCloud is a simple, basic C# console application that checks for the credential and config files associated with each cloud provider. If found, the contents of each found file is dumped for collection and potential reuse.
Command Line: Azure CLI 2.0 & Cloud Shell
Azure users the Azure CLI, currently v2.0. Microsoft offers an in-browser option called Azure Cloud Shell and options for installing the CLI tools on Windows, Linux, and macOS. These options are detailed here:
You can, of course, interact with Azure via PowerShell as well.
The CLI can be installed via an MSI installer on Windows, apt
and other options on Linux, and homebrew on macOS. All of the details for each option are listed here:
Command Structure
The command structure for Azure CLI / Cloud Shell is:
az SUBGROUP COMMAND
The output of any command can be modified using the output option:
--output
+ json
, jsonc
(colorized JSON), tsv
(Tab-Separated Values), or table
Useful Commands by Service
Useful Documentation
Interacting with files via az storage
for file share enumeration and other interactions requires using a SAS and some other information. This is detailed here:
Manage Azure file shares using Azure CLI
Learn how to use Azure CLI to manage Azure Files.
docs.microsoft.com