This article is part of a blog series where I explain common Azure vulnerabilities, how to create a lab such that it reproduces the issues, and how to exploit it. To follow this tutorial, you’ll need an Azure account and Azure CLI tool installed on your machine both of which you can get for free.
- You can can create an account for free at https://azure.microsoft.com/
- You can install Azure CLI from https://docs.microsoft.com/en-us/cli/azure/install-azure-cli
- You can find the source code of the challenges at https://github.com/andrei8055/Azure-security-challenges
- Consider getting Azure certified? Check my article on how to get Certified Azure Red Team Proffessional
- Part #1: Create an Azure Vulnerable Lab: Part #1 – Anonymous Blob Access
- Part #3: Create an Azure Vulnerable Lab: Part #3 – Soft Deleted Blobs
- Part #4: Create an Azure Vulnerable Lab: Part #4 – Managed Identities
- Part #5: Create an Azure Vulnerable Lab: Part #5 – Cloud Init
- Part #6: Create an Azure Vulnerable Lab: Part #6 – AAD Enumeration and Password Spraying
1. Environment Variables
An environment variable is a variable whose value is set outside the program, typically through functionality built into the operating system or microservice. An environment variable is made up of a name/value pair, and any number may be created and available for reference at a point in time.
Storing sensitive information (API keys, passwords, SQL connection strings) in the environment variables is totally fine, unless it’s not. You can read more about Why you shouldn’t use ENV variables for secret data, but to keep things short Azure will protect you as much as it can, but it won’t protect you shoot yourself in the foot.
Imagine a web application that connects to an API using a private key and saves the results in a local database to display it later. You don’t keep the API key and connection string in the source code, because that will be committed to source control (i.e: Github) and you don’t want everyone to see the credentials. Alternatively, you store this information in the environment variables and that’s fine unless your application is vulnerable to command injection for example.
For this tutorial, we will create and deploy a web application to Azure. The application is vulnerable to command injection. We will then store some dummy sensitive information in the environment variables and see how to dump this information and what else is stored there. Let’s begin!
2. Creating a vulnerable web app
Since our application is developed in python, we will need to install python3 locally. If you developed something in python before, you know that most of the time the applications would have some kind of dependency on libraries. When an application is deployed to Azure, these libraries are pushed together with the source code. To keep our local machine python packages “clean”, we will use python’s virtual environment which you can install using something similar to:
python3 -m pip install --user virtualenv
All packages that have to be installed (such as azure-code, Flask, etc) together with their versions are mentioned in the requirements.txt and are installed in a virtual environment dedicated to this project such that other applications that are using the same packages won’t break. Cool, so how do we do that?
cd .\webapp python3 -m venv .venv .venv\scripts\activate pip install -r requirements.txt deactivate cd ..
Now that our application has all the dependencies installed, we will login to Azure with azcli, and make sure we start clean by deleting and creating again the resource group. (Note, if you already have the resource group created from previous challenge and you want to keep both challenges, you can skip the deletion and creation of the resource group).
az login az group delete --name $resourceGroupName --yes az group create --name $resourceGroupName --location $location
Deploying application to Azure is quite straightforward, and it only takes one command: “az webapp up”. This will create an “App Service” on Azure if it doesn’t exist, pack the source code of our application, upload it, and unpack it. The only thing to be careful about is that we are running the command in the right folder. Pretty cool, right?
cd ".\webapp" az webapp up --sku S1 --name $webappName --resource-group $resourceGroupName --plan $appserviceplanName --location $location cd ..
Then, we can create an environment variable that will contain the sensitive information. It could be an API key, password, connection string to database, etc. For the sake of this challenge, we will call it simply “flag”:
az webapp config appsettings set --resource-group $resourceGroupName --name $webappName --settings "flag=e98bd50154903c87ecce53e1ecd217a9"
Lastly, since this is a web application that gives command execution to anyone, it would be wise to restrict the access and only allow traffic coming from our IP address. Using the “az webapp config access-restriction” we add a firewall rule
$ip = Invoke-RestMethod http://ipinfo.io/json az webapp config access-restriction add --priority 200 --resource-group $resourceGroupName --name $webappName --rule-name "CTF Only" --action Allow --ip-address $ip.ip
To check if this worked, we can go to Azure portal under our App Service -> Settings -> Networking -> Access Restriction
To triple check this works as intended, you can turn on your VPN and browse to the web app, or use an online proxy such as proxysite.com which in both cases should return a 403 error.
3. Exploiting Azure environment variables
To check if everything went just fine, navigate to the web app and try to see our permissions. In this case we are root:
6 thoughts on “Create an Azure Vulnerable Lab: Part #2 – Environment Variables”