Bloodhound

Managed Identity Attack Paths, Part 2: Logic Apps

Intro and Prior Work

In this three part blog series we are exploring attack paths that emerge out of Managed Identity assignments in three Azure services: Automation Accounts, Logic Apps, and Function Apps.

In part 1 we looked at how attack paths emerge out of Automation Account configurations. In part 2 we are looking at Logic Apps.

Managed Identity assignments are an extremely effective security control that prevent the accidental exposure of credentials by removing this requirement to store or use credentials in the first place. Instead of storing and sending credentials, Azure knows that your script is allowed to authenticate as a specific Service Principal.

You should absolutely be using Managed Identity assignments in Azure instead of storing or accessing credentials.

But Managed Identities introduce a new problem: they can quickly create identity-based attack paths in Azure that may lead to escalation of privilege opportunities. In this series we will explore how those attack paths emerge, how they can be practically abused by an attacker, and how we as defenders can discover, mitigate, and prevent the future emergence of those attack paths.

Prior work involving abusing or exploiting Logic Apps:

What are Logic Apps?

Logic Apps are another Azure service falling under the general umbrella of “Azure Automation”. Admins can use Logic Apps to construct what are called “workflows”. Workflows are comprised of triggers and actions that occur as a result of those triggers.

Here’s a very basic example. In this Logic App I’m using the visual designer to first define a trigger — an HTTP POST, in this example. When the Logic App receives a POST to that URL, it will then take the “name” input and return a body saying, “Hello, <name>!”

We can test the workflow right here in the GUI. We’ll say that our name is “David” in the “Input” tab and submit the request:

Then we’ll see the result, “Hello, David!” in the “Output” tab:

Logic Apps of course allow for much more complex and powerful workflows than this, including workflows where the actions may need to authenticate to some other service to perform a privileged action. And that’s where Managed Identities and Service Principals enter the picture.

Logic Apps and Service Principals

Logic Apps are great for automating tasks. But what if that task requires some sort of privilege to perform? For example, what if instead of saying “Hello, David!”, we want to grant David some Azure admin role?

Enter Managed Identities. As discussed in the introduction of this blog post, Managed Identities are a fantastic way to securely, automatically authenticate as a service principal without needing to store or retrieve credentials. Enabling a Managed Identity for a Logic App couldn’t be easier. Just click “Identity” under “Account Settings” and toggle the “Status” option from “Off” to “On”, then click “Save”:

Let’s start thinking of these things in the form of a graph and how the various objects fit into a hierarchy. Our Logic App, “MyExampleLogicApp”, has a Managed Identity assignment to the service principal whose object ID starts with “faf5c7…”:

As you can see, the Logic App finds itself within the greater hierarchy of AzureRM and AzureAD. The Service Principal associated with the Logic App does not have any privileges by default. Let’s give this Service Principal some privileges and try to stay without the bounds of least privilege by giving it “Contributor” access on the subscription the Logic App resides in. This would let the Service Principal create and manage resources in this subscription:

As configured, this setup doesn’t introduce any privilege escalation opportunities: if an attacker gains control of either the Service Principal or Logic App, they’re just stuck in a loop. Let’s flesh this environment out a bit more by adding another subscription and some more descendent objects, including a Function App in another resource group:

Let’s also grant “My Cool Function App” an identity it can authenticate as, and this time we’re going to grant its associated Service Principal Global Admin (or understand that it can escalate itself to Global Admin):

And now have have created a privilege escalation opportunity — if an attacker gains control of “MyExampleLogicApp” or its associated Service Principal, they will be able to escalate up to Global Administrator, gaining control of everything in the Azure environment:

Abusing Logic App Managed Identity Assignments

If an attacker has sufficient privilege to create or edit an existing workflow, they can turn that into control of the Service Principal, gaining whatever privileges the Service Principal holds. These Azure role assignments allow for creating or editing an existing workflow:

  • Owner
  • Contributor
  • Logic App Contributor

Additionally, the following privilege allows one to grant themselves any of the above role assignments against the Logic App:

  • User Access Administrator

There are several ways to tackle this problem, but for me the most straight-forward abuse is to extract a JSON Web Token (JWT) for the Service Principal, then use that JWT to authenticate as the Service Principal outside the scope of the Logic App. Using the Azure Portal GUI, we will modify an existing workflow to include the following action:

This action will make a POST request to my evil attacker-controlled web server at 159.223.206.196:8000. That evil web server is running a Python SimpleHTTPServer which will simply print any headers received to the console. At the bottom of the action you can see that the action will attempt to authenticate to my evil server using the Logic App’s system-assigned managed identity.

When the workflow runs, this action will get an MS Graph-scoped token for the Logic App’s Managed Identity, then include that token in the authorization header in the POST to my evil server:

Now that we have this JWT we can authenticate to MS Graph as the Service Principal, gaining any privileges held by that Service Principal.

Prevention

There are several steps you should take, as a defender, to ensure these attack paths do not exist in your Azure environment:

Step 1: Audit and Remove Privileges Held by Service Principals

Your first step should be to find any service principals that have been granted the most dangerous privileges in Azure. Audit both the active and eligible assignments for the following AzureAD admin roles:

  • Global Administrator
  • Privileged Role Administrator
  • Privileged Authentication Administrator

You should also audit for any Service Principals that have been granted any of the following MS Graph app roles:

  • RoleManagement.ReadWrite.Directory
  • AppRoleAssignment.ReadWrite.All

If any service principal has been granted any of the above roles in AzureAD or MS Graph, you should immediately investigate that service principal for existing signs of misuse. You should also remove those role assignments from the service principals, if possible.

Step 2: Audit Privileges Held by Other Principals

Unfortunately you may not be able to easily or immediately remove privileges that have been granted to a service principal. Your next step then will be to limit the exposure of those highly privileged service principals by auditing the users, groups, and service principals that have been granted any of the following AzureAD admin roles:

  • Application Administrator (including those scoped specifically to the Service Principal)
  • Cloud Application Administrator (including those scoped specifically to the Service Principal)
  • Directory Synchronization Accounts
  • Hybrid Identity Administrator
  • Partner Tier1 Support
  • Partner Tier2 Support

You should also audit the explicit owners of service principals you identified in Step 1 that you cannot easily or immediately remove privileges from.

You should also audit other service principals that have been granted any of the following MS Graph app roles:

  • Application.ReadWrite.All
  • ServicePrincipalEndpoint.ReadWrite.All

Any user, group, or service principal that has been granted any of the above AzureAD admin roles, explicit ownership, or MS Graph app roles will be able to take over the service principals identified in Step 1. If possible, and if necessary, remove all of these privileges.

Step 3: Audit Privileges Held Against the Logic App

Unfortunately you may not be able to immediately or easily remove privileges held by service principals associated with a Logic App. In that case, you can prevent the emergence of a privilege escalation opportunity by removing these Azure role assignments against the Logic App where those principals have less privilege than the service principal associated with the Logic App:

  • Owner
  • Contributor
  • Logic App Contributor
  • User Access Administrator

Detection

Azure logs come in handy several different ways here:

Detecting Logic App Workflow Edits

An attacker may choose to edit an existing workflow, adding their own malicious action to the workflow. Modifying a workflow fires the “Set Workflow” log, which includes a very helpful change history showing you exactly what changed in the workflow:

Detecting New, Dangerous Privileges Granted to Service Principals

Once you’ve verified that no service principals have the most dangerous privileges in AzureAD, you will want to put alerting in place to warn you if someone grants a Service Principal one of those dangerous privileges. When a Service Principal is granted an AzureAD admin role, the “Add member to role” log fires, telling you who granted what privilege to what principal:

You should produce and triage an alert any time a service principal is granted one of the following most dangerous AzureAD admin roles:

  • Global Administrator (aka “Company Administrator”)
  • Privileged Role Administrator
  • Privileged Authentication Administrator

Additionally, when a service principal is granted an MS Graph app role, the “Add app role assignment to service principal” log fires, telling you who gave what app role to what:

You should produce and triage alerts any time a service principal is granted one of the following app roles against the MS Graph resource app:

  • RoleManagement.ReadWrite.Directory
  • AppRoleAssignment.ReadWrite.All

Conclusion

In Part 2 of this 3-part series we saw how attackers can abuse risky Logic App Managed Identity assignments. We also saw how you as a defender can identify and protect your organization against the emergence and exploitation of attack paths that abuse Logic Apps.

In part 3 we will look at how attack paths emerge that include Function Apps and Managed Identity assignments.

References

https://www.netspi.com/blog/technical/cloud-penetration-testing/illogical-apps-exploring-exploiting-azure-logic-apps/

https://posts.specterops.io/attacking-azure-azure-ad-part-ii-5f336f36697d

https://docs.microsoft.com/en-us/azure/automation/automation-services


Managed Identity Attack Paths, Part 2: Logic Apps was originally published in Posts By SpecterOps Team Members on Medium, where people are continuing the conversation by highlighting and responding to this story.