top of page

Cloud Confessions: When Azure Storage Becomes the Backdoor



In the world of cloud computing, seemingly benign configurations can sometimes open the door to significant security threats. One such configuration is the FunctionApp in Azure, which, under certain circumstances, can be exploited by attackers to escalate privileges through its associated storage account. At first glance, this setup appears to be a straightforward mechanism used for application hosting. However, attackers can leverage its configuration to gain unauthorized access to sensitive data in cloud environments. From an Incident Response (IR) perspective, it’s crucial to understand how these simple configurations can be turned against us and what can be done to mitigate the threat.


Understanding the Threat


Azure FunctionApp is a serverless compute service that enables you to run code without provisioning or managing infrastructure. It is commonly used for executing code in response to events. However, its associated storage account, which is used for managing triggers and storing logs, can become a vector for privilege escalation if not properly secured.


For example, an attacker with access to the FunctionApp’s storage account can potentially gain higher privileges by exploiting shared key authorization or misconfigurations. This could allow unauthorized access to sensitive data or enable the attacker to manipulate the FunctionApp’s behavior, leading to broader compromise within the cloud environment.


The Attacker's Perspective


From an attacker's viewpoint, the FunctionApp’s storage account is a valuable target for evasion and persistence. By gaining access to this storage account, they can manipulate function triggers, access logs, and even modify the function code. This can help them to establish persistence, exfiltrate data, or disrupt operations while avoiding detection by blending in with legitimate activities.


To illustrate this, consider a scenario where an attacker uses shared key authorization to access the storage account. Once inside, they can modify function bindings or inject malicious code, effectively escalating their privileges and extending their control over the cloud environment.


Storage Account Access Keys


Storage account access keys in Azure are essential for authenticating and authorizing access to storage account resources. These keys grant full permissions to access and manage data in the storage account, including blobs, queues, tables, and files. Each storage account has two keys to facilitate seamless key rotation without downtime. Due to their powerful capabilities, it is crucial to protect these keys and limit their use to secure applications only, minimizing the risk of unauthorized access.


Deep Dive


As previously mentioned, for an attacker to compromise a Function App, they first need access to the associated storage account in order to list its access keys. Let’s assume an attacker has managed to obtain a Service Principal credential that was accidentally exposed in a public repository.


With this credential, the attacker can start by searching for storage accounts associated with the Function App. Azure stores critical files for the Function App in a file share that it generates. Specifically, these files are housed in directories such as site/wwwroot. Additionally, Azure stores certain files in two containers: azure-webjobs-hosts and azure-webjobs-secrets. Both of these storage methods can be used to identify the relevant storage accounts.


Simple script to enumerate all storage accounts
Simple script to enumerate all storage accounts

Once the attacker has access, they can list all files within the Function App, including:


  • function_app.py: The default file name for Python functions within the Function App.


  • host.json: This file contains encrypted keys for the Function App. In Azure, these keys are essential for securing and controlling access to the functions hosted within the app. They play a crucial role in determining who can invoke the functions and how they are triggered.


Additionally, each function within the Function App has its own JSON file containing specific keys for that function.


Listing all files in the associated file share
Listing all files in the associated file share
Listing all json files in the associated containers
Listing all json files in the associated containers

The attacker could then download the host.json file and modify its masterKey section - changing the key to a new value and disabling the encryption.


masterKey section - 1.1
masterKey section - 1.1
masterKey section - 1.2
masterKey section - 1.2

After making these modifications, the attacker can upload the altered host.json file back to the storage account. Azure will take a few minutes to synchronize the changes, after which it will accept the new, unencrypted key.


Uploading the modified host.json file to the storage account
Uploading the modified host.json file to the storage account

At this point, the attacker can modify the Function App’s code to execute malicious actions. For example, they might download the function_app.py file and alter its source code to return the Function App’s managed identity access token (assuming the Function App has a managed identity attached). The function App’s managed identity access token! (Requires a managed identity attached to the function).


Downloading the function_app.py file
Downloading the function_app.py file
Modify function app code to get the Function App Managed Identity’s access token
Modify function app code to get the Function App Managed Identity’s access token
Triggering the function App using the new masterKey (wrong value does not work!)
Triggering the function App using the new masterKey (wrong value does not work!)

By taking these steps, the attacker could potentially gain unauthorized access to sensitive resources within the Azure environment, demonstrating the critical importance of securely managing access keys and monitoring for any unauthorized changes.


Only Storage accounts actions were performed!


Mitigation Strategies


To defend against the potential abuse of the storage account associated with Azure Function App, Cyngular Security recommends implementing the following mitigation strategies:


  • Storage Account Key Management: Regularly rotate storage account access keys and use Azure Key Vault to securely store and manage these keys. This minimizes the risk of unauthorized access through compromised keys.


  • Use Managed Identities: Wherever possible, replace shared key authorization with Azure Managed Identities for authenticating the FunctionApp to access storage accounts. Managed Identities eliminate the need for manual key management and reduce the attack surface.


  • Implement Network Security Controls: Use Virtual Network (VNet) integration for the FunctionApp and storage account, along with network security groups (NSGs) and firewalls, to restrict access to the storage account from only trusted sources.


  • Enforce Least Privilege: Ensure that roles and permissions related to the FunctionApp and its associated storage account are configured according to the principle of least privilege. This limits the potential damage in case of a security breach.


  • Education and Awareness: Educate your DevOps and security teams about the risks associated with improper storage account configurations and the importance of using secure access methods. Regular training and awareness programs can significantly reduce the chances of misconfigurations.


  • Implement Monitoring and Logging: Monitor user data scripts' execution and maintain logs to detect unauthorized changes or malicious activity. Regularly review these logs for signs of potential threats.


By applying these strategies and leveraging Cyngular Security's CIRA platform, organizations can effectively protect their Azure FunctionApps and associated storage accounts from unauthorized access and potential exploitation.


The essence of cloud security lies in proactive measures, and Cyngular Security's Cloud Investigation and Response Automation (CIRA) platform incorporates this principle - automated, efficient cloud environment investigations. By integrating Cyngular Security's CIRA, you equip your team with the capability to quickly address and mitigate threats, ensuring robust protection for your cloud assets. Embrace Cyngular Security's CIRA for a deep, effective security strategy that keeps you ahead of threats.

28 views

Comments


bottom of page