In every penetration test that involves Azure, we want to escalate our privileges up to a global administrator of the tenant. Once we’ve escalated our privileges in an Azure tenant, we want to have the ability to maintain our access to each subscription and the tenant as a whole. Aside from the benefits of controlling the Azure tenant, it can be really handy to have an Azure backdoor that could (potentially) be used to pivot back into the main AD environment.
After escalating privileges in the Azure Tenant, we can make use of Automation Runbooks to persist in the Azure environment. There are multiple ways to persist in Azure, but for this post, we will focus on using Automation Accounts that are configured with excessive privileges, automation runbooks, and webhook triggers that will allow us to regain access to an Azure environment, with a single POST request.
Want to maintain privileges in Azure? Add an Automation Account with excessive privileges that can be used to add new accounts (with Subscription Owner permissions) to AzureAD via a single POST request.
Potential Persistence Scenario
For the purposes of this blog, imagine this fairly standard Azure attack life cycle:
Attacker compromises an Azure account/system
Attacker escalates Azure privileges up to Global Administrator
Blue team revokes initial access and/or Global Administrator access
In this type of scenario, we will want to have some type of persistence option available to re-enable our access into a tenant. Based off of my experience, Automation accounts typically fly under the radar. If they are set up properly, they can be use to regain Owner (or higher*) permissions to subscriptions in the Azure tenant with a new AzureAD account.
Since newly created Azure accounts are more likely to get noticed, they should be used for short term access. While the Automation Accounts will act as the long haul persistence account. The Automation Accounts can also be configured for password access, or cert-based authentication, so those can also be an option for getting back into the subscription.
Create a new Automation Account
Import a new runbook that creates an AzureAD user with Owner permissions for the subscription*
Assign “User Administrator” and “Subscription Owner” rights to the automation account
Add a webhook to the runbook
Eventually lose your access…
Trigger the webhook with a post request to create the new user
*This runbook could be modified to be run as a global admin that creates a new global admin, but that’s really noisy. Let me know if you do this. I’d be interested to see how well it works.
I realize this is a bit of a legwork just to maintain persistence. The eventual goal is to automate this process with some PowerShell and integrate it with the existing MicroBurst tools.
Creating the Automation Account
Navigate to the “Automation Accounts” section of the Azure portal and create a new automation account. Naming it something basic, like BackupAutomationProcess, should avoid raising too many suspicions. Make sure that you set the “Create Azure Run As account” to yes, as this will be needed to run the backdoor runbook code.
If you want to blend in with the default runbooks, the imported runbook name should follow the same naming strategy as the tutorials (AzureAutomationTutorial*). If you follow this naming convention, you will want to import and publish your malicious runbook into the account as soon as possible. The closer the timestamp is to your other tutorial runbooks, the less suspicious it will be.
Can you tell which of these runbooks is the malicious one?
Once imported, you will also need to publish the runbook. This will then allow you to set a webhook for remote triggering of the runbook. To set the webhook, go to the Webhooks tab under the runbook.
Depending on how long your operation is running, you may want to set your expiration date way off in the future to protect your ability to trigger the webhook.
Important Step – Copy the webhook URL and keep it for when you need to trigger your backdoor.
Since the AzureAD module is not standard for Automation Accounts, you will need to import it into your account. Go to the Modules tab for the Automation account and use the “Browse Gallery” feature to find the “AzureAD” module. Import it into your account, wait a few (5-10) minutes for it to deploy. The modules can sometimes take a while to populate to the Automation Accounts, so be patient.
Additionally, your Automation Account may not play nicely with the current/old version of the AzureRM modules. I don’t really know why this is still an issue for Azure, but you may need to update your Azure Automation Modules.
Since we’re using a new Automation Account, the updates shouldn’t cause any issues with existing runbooks. Alternatively, if you’re using an existing Automation account for all of this, updating the modules could cause compatibility issues with existing runbooks. You would also need to assign the additional rights to the existing automation account, which is what we will cover next.
Setting Automation Account Rights
Once the automation account is configured and the webhook is set, the automation account will need the proper rights to add a new user, and give it owner rights on the subscription. To add these rights, navigate to the Azure Active Directory tab with a tenant admin account, and open the “Roles and Administrators” section. Within that section open the “User Administrator” role and add the automation account to the group. The Automation Account will be labeled with the name of the account, and a base64 string appended at the end.
Given the fact that this username may stick out against the other users in the group, you may want to rename the Automation Account. This can be done in the AzureAD->App Registrations section, under “Branding”.
After adding user administrator rights, the automation account user will needed to be added as an owner on the subscription. This can be done through the subscriptions tab. Select the subscription that you want to persist in, and go to the Access Control (IAM) tab. Add the Owner role assignment to your Automation account, and you should be all set. This will also take a few minutes to populate, so give it a little while before you actually try to trigger the webhook.
Triggering the Webhook
Let’s say that after escalating privileges and setting a persistence backdoor, the compromised tenant admin account gets flagged, and now you’re locked out. Using the webhook URL from the earlier steps, and the example caller function below, you can now create a new subscription owner account (BlogDemoUser- Password123) for yourself in Azure.
Necessary cookies help make a website usable by enabling basic functions like page navigation and access to secure areas of the website. The website cannot function properly without these cookies.
YouTube session cookie.
Marketing cookies are used to track visitors across websites. The intention is to display ads that are relevant and engaging for the individual user and thereby more valuable for publishers and third party advertisers.
Analytics cookies help website owners to understand how visitors interact with websites by collecting and reporting information anonymously.
Preference cookies enable a website to remember information that changes the way the website behaves or looks, like your preferred language or the region that you are in.
Unclassified cookies are cookies that we are in the process of classifying, together with the providers of individual cookies.
Cookies are small text files that can be used by websites to make a user's experience more efficient. The law states that we can store cookies on your device if they are strictly necessary for the operation of this site. For all other types of cookies we need your permission. This site uses different types of cookies. Some cookies are placed by third party services that appear on our pages.
Discover why security operations teams choose NetSPI.