From initial access to Global Admin with #BloodHound and BARK.
In this thread let's walk, step by step, through an example attack path based on real configurations we've seen in real environments:
There are MANY ways to achieve initial access into AzureAD. For this example we will go with something simple: we were able to phish a user and get their username and clear text password.
This user has no MFA/CAP restrictions - we'll discuss how to deal with these later.
We now want to collect data with AzureHound. We'll clone the repo, inspect the source code, then build the binary ourselves:
This instructs AzureHound to attempt to list ALL data and output the results to a file called initial-scan.json.
Collection finished after 45 seconds, BUT you might have noticed the following warning:
"unable to process azure management groups; either the organization has no management groups or azurehound does not have the reader role on the root management group."
Our user can read all the relevant info at the AzureAD level (most users *can* by default in all tenants), but our user CANNOT read anything in AzureRM. That's ok, we can keep going.
Now we will drag and drop initial-scan.json into the BloodHound GUI:
Ok! Now we're ready to find an attack path to Global Admin! We'll find our user, enable path finding mode, select Global Admin to find a path, aaaaaaaaaaaand...
"No data returned from query" - damn, this means we don't have an attack path to Global Admin. But not all hope is lost, remember that there is an entire world of enumeration we haven't done in AzureRM.
Let's see whether our user DOES have anywhere to go by clicking the user and inspecting the "Outbound Object Control" section.
Indeed, we find this user can add members to several non role eligible security groups, including one called "Subscription Admins":
When we click on "Subscription Admins", we see that that group has no privileges -- as far as we can tell so far! Let's take a chance and use BARK to add ourselves to this group and re-run AzureHound, maybe we'll be able to read the subscriptions.
To perform this abuse, we need to use two functions. First we will use BARK's Get-MSGraphTokenWithUsernamePassword function to get an MS Graph-scoped JWT for our phished user:
We will now feed this token, the ID for our user, and the ID for the target group to BARK's Add-AZMemberToGroup function.
Then we will verify the user was added to the group with BARK's Get-AZGroupMembers function:
Now that our user belongs to this group, does it have any more privileges than it previously had? Let's re-run AzureHound again and see!
Collect -> Import -> Explore outbound object control for our user:
Ok! It turns out the "Subscription Admins" group has "User Access Admin" rights on pretty much everything in AzureRM. Now that our user belongs to this group, our user now also has that right.
That's great, but do we have a path to Global Admin now? Let's try path finding in the BloodHound GUI again from our phished user to the Global Admin role and see:
Here's our attack path to Global Admin:
"But no admin in their mind would grant Global Admin to a VM's managed identity service principal."
We're already a member of the "Subscription Admins" group, so our next step is to grant ourselves the ability to execute commands on BHESpecterDevWin10-01.
To do this, we need to use a number of functions from BARK:
Get-ARMTokenWithUsernamePassword to do... exactly what it says.
Get-AzureRMRoleDefinitions to get the names and IDs for Azure roles
New-AzureRMRoleAssignment to grant ourselves the "Owner" role over the VM.
and
Get-AzureRMRoleAssignment to verify the new Owner assignment:
Bing bang boom. We now have "Owner" role against the VM. The next step in our attack path is to abuse our Ownership of the VM to take over the VM's managed identity.
We are going to remotely execute a command on the VM, and that command is going to give us an MS Graph-scoped JWT for the managed identity service principal.
To do this we will use BARK's Invoke-AzureRMVMRunCommand function:
And... we're done! That heavily censored token will let us perform any action in AzureAD as a Global Admin now!
Defenders: The "Prevention" section of this blog post offers guidance to find/fix/prevent these attack paths in your own environments: medium.com/p/82667d17187a
• • •
Missing some Tweet in this thread? You can try to
force a refresh
If you're like me, you are angry and disappointed at SCOTUS striking down Roe v Wade. You might also be exhausted and feel defeated.
Here are three things you can do RIGHT NOW to help defend women's rights in the United States. This will take you THREE minutes. Do these NOW: 🧵
First and most importantly, contact your congressional rep and tell them you support the Women's Health Protection Act, which will protect abortion access for every person in every state.
Second, contact your healthcare provider and ask them to do the same thing. Lawmakers need to hear from healthcare professionals that abortion is safe, abortion is normal, and that abortion is health care.
Where do #Azure attack paths come from? Attack paths that abuse (mis)configurations generally emerge from two types of control in Azure: explicit control and implicit control.
Let's see what that means and how you as a defender can eliminate the most dangerous paths:🧵
Explicit control means there is a one-to-one control relationship clearly defined on the controlled object. For example, Azure Users can be made explicit owners of Azure Service Principals:
David owns MyCoolAzureApp, meaning David can add a new credential to that Service Principal and authenticate as it, taking over the identity.
But this explicit configuration does not exist in isolation: there are paths INTO the user OUT of the SP:
One year ago this week I published The Attack Path Management Manifesto, which you can read here: medium.com/p/3a3b117f5e5
It's a long read, so in this thread I'm going to give you the most succinct version of the manifesto I can:
Adversaries have been abusing identity-based attack paths -- in particular those that emerge in Active Directory environments -- for over 20 years. Why? There are three major reasons:
1. Active Directory is the FOUNDATION upon which all identity and access in the enterprise is built. Your workstation? AD auth. Your CI/CD pipeline? AD via ADFS. Your network devices? AD via RADIUS.
Control the foundation and you control the enterprise.
"...this case does not meet the bar for servicing by MSRC and we will be closing this case..."
and:
"...This is considered by-design..."
A quick thread on what the "issue" is and why MSRC is right 🧵
While preparing for my @WWHackinFest talk, I was creating demo videos showing Managed Identity abuse primitives in various Azure services. For example, you can remotely extract the JWT for a VM's managed identity like this:
My abuse primitive demo for Logic Apps was a little different: I was using the Logic App to add a secret to another Service Principal, then capturing the output in the Logic App, showing the other Service Principal's new key credential in plain text:
Yesterday in my webinar on ACR Task abuse, I shared this slide with the question, "What privileges are needed to bridge this trust boundary?"
A thread about the differences between Explicit and Emergent IDP Trusts: 🧵
In its default state, an Azure tenant enforces a trust boundary around itself. The Azure Security Token Service (STS) for this tenant will only authenticate principals within this tenant. In other words: only users in your tenant can access anything in your tenant.
"Global Admins" and "External Identity Provider Administrators" can configure various types of Explicit Trusts with other Identity Providers (IDPs), and then allow foreign users to access resources in the tenant: