Andy Robbins Profile picture
Aug 6 22 tweets 8 min read
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:

$ git clone github.com/BloodHoundAD/A…
$ cd AzureHound
$ go build .
Now we will run this command:

$ ./azurehound -u "phisheduser@specterdev.onmicrosoft.com" -p "Password1" list -o initial-scan.json --tenant "specterdev.onmicrosoft.com"

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.

To do this, we're going to use a trick I learned by reading this post by @kfosaaen: netspi.com/blog/technical…
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
 

Keep Current with Andy Robbins

Andy Robbins Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @_wald0

Jun 24
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.

THIS FORM TAKES 30 SECONDS TO COMPLETE: actforwomen.org/take-action/
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.

EMAIL THIS LINK TO YOUR DOCTOR: secure.everyaction.com/p/QCHf7o5do0Sn…
Read 4 tweets
Jun 1
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: Image
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: Image
Read 11 tweets
May 27
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.
Read 25 tweets
May 25
MSRC came back on my case and said:

"...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:
Read 10 tweets
Apr 29
Neo4j's cypher query language can seem strange at first, but it starts to make sense once you realize one simple thing:

It's ASCII art.

A quick thread on some very basic cypher concepts: 🧵
Nodes and edges are the two foundational building blocks of a graph. Nodes have labels (User, Group), and edges have types (MemberOf): Image
Consider the following graph, which we will use to explore patterns with cypher: Image
Read 9 tweets
Apr 21
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: 🧵 Image
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: Image
Read 13 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Don't want to be a Premium member but still want to support us?

Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Or Donate anonymously using crypto!

Ethereum

0xfe58350B80634f60Fa6Dc149a72b4DFbc17D341E copy

Bitcoin

3ATGMxNzCUFzxpMCHL5sWSt4DVtS8UqXpi copy

Thank you for your support!

Follow Us on Twitter!

:(