{
	"id": "0c818a97-f5cb-4502-b711-156778fb57a4",
	"created_at": "2026-04-06T00:21:09.294447Z",
	"updated_at": "2026-04-10T03:20:35.291197Z",
	"deleted_at": null,
	"sha1_hash": "ca8aaf355cc93d059be6ae2cea95d2372ea865e2",
	"title": "Azure Privilege Escalation via Service Principal Abuse",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 2508933,
	"plain_text": "Azure Privilege Escalation via Service Principal Abuse\r\nBy Andy Robbins\r\nPublished: 2021-10-12 · Archived: 2026-04-05 15:53:32 UTC\r\nIntro and Prior Work\r\nOn-prem Active Directory is here to stay, and so is Azure Active Directory. While these products have similar\r\nnames, they in fact work very differently from one another. There are hints of vanilla AD’s discretionary access\r\ncontrol model in Azure, but permissions in Azure are mostly controlled through granted roles. Regardless of these\r\ndifferences, configuration-based attack primitives are alive and well in Azure, and researchers discover new attack\r\nprimitives in Azure all the time.\r\nIn this blog post, I’ll explain how a particular kind of attack path can emerge in Azure based on Azure’s RBAC\r\nsystem – an attack path we have seen in the vast majority of Azure tenants we’ve gotten access to. I’ll show you\r\nhow the attack primitive works, how to protect yourself against it, and offer my own commentary on the\r\nopportunity this presents to Microsoft.\r\nThis work is not new – in fact, Microsoft’s own documentation describes these attack paths. Additionally, two\r\ngreat researchers have discussed this attack primitive at length:\r\nDirk-jan Mollema wrote about abusing the Application Administrator role to add new secrets for service principals\r\nand escalate privileges here: https://dirkjanm.io/azure-ad-privilege-escalation-application-admin/ \r\nKarl Fosaaen spoke about Azure privilege escalation techniques in this talk:\r\nhttps://www.netspi.com/webinars/lunch-learn-webinar-series/adventures-in-azure-privilege-escalation\r\nAzure’s Built-In Privesc Prevention System\r\nBefore we talk about the Service Principal-based privilege escalation, I want to describe Azure’s built-in attack\r\npath prevention system. Azure Active Directory has a built-in system to protect against the emergence of attack\r\npaths, particularly around password reset privileges. When looking at the documentation for administrator roles\r\nthat provide password reset privileges, you will often see wording like this:\r\nSource: https://docs.microsoft.com/en-us/azure/active-directory/roles/permissions-reference#helpdesk-administrator\r\nhttps://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5\r\nPage 1 of 10\n\nIn particular, note the highlighted text: “Whether a Helpdesk Administrator can reset a user’s password and\r\ninvalidate refresh tokens depends on the role the user is assigned.”\r\nThis, to me, is confusing. So I set out to understand all the different possibilities for password reset privileges in\r\nAzure, and wound up creating this table:\r\nThis brings a little more clarity, but look at what happens when we model these permissions using a graph:\r\nhttps://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5\r\nPage 2 of 10\n\nThis is where the brilliance of this system finally becomes clear. Looking at the top row, we can see that Global\r\nAdmins and Privileged Authentication Admins can reset each others’, plus all other users’ passwords, but the\r\nopposite is not true. In other words, only GA and PAA users can reset a GA password. This is part of the back-end\r\nAzure system and something that Azure admins have no control of. \r\nI love this system because it provides a highly effective, non-configurable, frictionless safety rail for admins that\r\nprevents the emergence of attack paths that include resetting a Global Admin’s password. Azure admins can safely\r\ndole out the “Password Admin” role without worrying about the safety of their Global Admins – at least within the\r\ncontext of this particular attack primitive.\r\nEscalating Rights via Service Principal Abuse\r\nWhen you create or register an application in your Azure tenant, an application object is created with a unique\r\napplication (client) ID:\r\nHere, the app “MyCoolApp” has a unique identifier starting with d6f118bc. Below that, you can see the ID of my\r\ntenant as well. This app object “resides” within my tenant. Let’s start to think of this in terms of a graph and see\r\nhow the attack path emerges:\r\nBecause the app “resides” in my tenant, anyone with control of my tenant has control of the app. Let’s model this\r\nwith showing how my own Global Admin user has control of the tenant:\r\nhttps://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5\r\nPage 3 of 10\n\nNothing scary here: my user is a global admin against the tenant, the tenant contains the app, therefore the “path”\r\nhere is that I have control of the app. Now let’s extend this model to include service principals.\r\nAzure apps needing to authenticate to the tenant to perform some action do so using an object called a Service\r\nPrincipal. Service Principals work kind of like users – you authenticate to the tenant with a “username” (object id)\r\nand a “password” (a certificate or secret). You can see the object id of the app’s service principal in this\r\nscreenshot:\r\nLet’s go ahead and add that to our graph model:\r\nAgain, nothing surprising here: my Global Admin user has control of everything here.\r\nService Principals can have admin roles in Azure just like users. For example, we have seen several Azure\r\nenvironments where at least one Service Principal has the Privileged Role Admin role. Let’s recreate that in my\r\nown tenant:\r\nhttps://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5\r\nPage 4 of 10\n\nAnd let’s extend the graph model to include this:\r\nAgain, nothing scary: an attack path from a Global Admin to the PRA role isn’t a problem. Let’s bring another\r\nuser into the mix: Alice App Admin. Like the user’s name suggests, we will grant this user the “Application\r\nAdministrator” role in my tenant:\r\nLet’s also add this user and their role assignment into our graph model:\r\nhttps://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5\r\nPage 5 of 10\n\nAnd… there it is. Our attack path has emerged, connecting the Alice App Admin user to the PRA role. The attack\r\npath works like this:\r\n1. Alice App Admin has the Application Admin role, scoped to the tenant.\r\n2. The tenant contains the MyCoolApp app, granting Alice App Admin control of the app.\r\n3. Alice App Admin can add a new secret for this app’s service principal.\r\n4. MyCoolApp authenticates to the tenant as the MyCoolApp service principal.\r\n5. The MyCoolApp service principal has the PRA role.\r\n6. Alice App Admin can authenticate to the tenant as the MyCoolApp service principal and use that service\r\nprincipal’s rights as a PRA to promote themself or another user to Global Admin.\r\nHere’s a video of the attack path in action, escalating from “Application Administrator” to “Global\r\nAdministrator”:\r\nPrevention\r\nAs discussed earlier, Azure has built-in mechanisms to prevent privilege escalation through role-based attack\r\npaths. Only those users with Global Admin or the Privileged Authentication Administrator role can reset a Global\r\nAdmin’s password. This simple, brilliant mechanism provides a highly effective safety rail to protect Azure\r\nadmins from unknowingly introducing attack paths into their tenants. But this mechanism could go further.\r\nI believe the best possible prevention against the privilege escalation technique described in this blog post is for\r\nMicrosoft themselves to extend this mechanism to cover service principals as well. Just as the system provides\r\nbuilt-in protections for Global Admin users, Azure could (perhaps should) also provide built-in protection for\r\nGlobal Admin service principals. I don’t know the inner-workings of this system and whether this extension is\r\neven technically feasible, but I believe Microsoft can completely eliminate this attack primitive by extending the\r\nsystem to cover service principals, creating an even more secure platform for all of their customers.\r\nIn the meantime, Azure administrators should audit roles held by service principals, and determine the exposure of\r\nthose service principals to the rest of their identities.\r\nhttps://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5\r\nPage 6 of 10\n\nAzure admins can prevent this attack path by auditing roles held by service principals and comparing those roles\r\nto the other identities with control of apps. The most dangerous role in Azure is “Global Admin”, so let’s start\r\nthere. Open the Azure portal, navigate to your tenant, then click “Roles and Administrators”:\r\nScroll down to and click on “Global Administrator”. Here, you will see the list of identities with this role currently\r\nactivated. In the “type” column, look for “ServicePrincipal” entries:\r\nThere are two service principals in my tenant with the Global Admin role: “CanYouAddASecretToMe” and\r\n“ThisAppHasGlobalAdminRole”. These are the names of the service principals, and they are also the names of the\r\napps associated with these service principals.\r\nThis is your first prevention opportunity: determine whether these apps actually need Global Admin rights in order\r\nto function. If these are third party apps, work with your vendor to get this level of privilege reduced to only the\r\nlevel required for the application to function.\r\nIf these roles must persist, then your next step is to look at the identities in your tenant with the tenant-level roles\r\nthat grant a principal the ability to abuse service principals. Those roles are:\r\nApplication Administrator\r\nCloud Application Administrator\r\nHybrid Identity Administrators\r\nAdditionally, these legacy/hidden roles can be abused to take over service principals:\r\nDirectory Synchronization Accounts\r\nPartner Tier1 Support\r\nPartner Tier2 Support\r\nLet’s audit the “Application Administrator” role by navigating to our tenant, clicking “Roles and Administrators”,\r\nthen click on the Application Administrator role:\r\nhttps://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5\r\nPage 7 of 10\n\nHere we see all users and service principals with this role currently active. This is your second opportunity for\r\nprevention: do all these users need the ability to manage credentials for all service accounts in your tenant?\r\nWe also need to check the app-level roles and per-app owners. Earlier we saw that the service principal,\r\n“ThisAppHasGlobalAdminRole”, was currently a Global Admin. Navigate to your tenant, click on “App\r\nregistrations”, click on “All Applications”, then find the app associated with that Service Principal:\r\nFirst, click on “Owners”, which will show you all principals that own the app (there can be more than one):\r\nhttps://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5\r\nPage 8 of 10\n\nDo you trust Matt Nelson to add a secret to an app with Global Admin powers? I wouldn’t.\r\nNext, click on “Roles and administrators”, which will show the app-level roles particular to this app. Click on\r\n“Cloud Application” administrator, for example, which will show the principals that have this role against the app\r\nboth explicitly (scoped to the app), and where that role inherits down from the tenant:\r\nThese are your third and fourth opportunities for prevention: do you trust all these principals to have control of a\r\nservice principal with Global Admin rights?\r\nYou should repeat this process for Service Principals that hold the following roles:\r\nApplication Administrator\r\nAuthentication Administrator\r\nAzure AD joined device local administrator\r\nCloud Application Administrator\r\nCloud device Administrator\r\nExchange Administrator\r\nGroups Administrator\r\nHelpdesk Administrator\r\nHybrid Identity Administrator\r\nIntune Administrator\r\nhttps://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5\r\nPage 9 of 10\n\nPassword Administrator\r\nPrivileged Authentication Administrator\r\nUser Administrator\r\nThis is also the point where the built-in password reset protections against Global Admins can break, creating\r\nattack paths from low-privilege users all the way to Global Admin by abusing control of service principals. In the\r\nreal world, this is the most common avenue of escalating to Global Admin we have seen without needing to pivot\r\ndown to on-prem AD first.\r\nConclusion\r\nMicrosoft is continually making improvements to Azure, whether those improvements are related to uptime,\r\nfeatures, or security. There is an opportunity here for Microsoft to extend its existing design choices related to\r\npassword reset rights to also cover Service Principals. I do not know the inner-workings of how that system\r\nworks, or whether it’s even feasible to extend that system to cover Service Principals. Either way, this is a great\r\nopportunity for Microsoft to protect all of its customers and make Azure an even more secure platform.\r\nPost Views: 1,841\r\nSource: https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5\r\nhttps://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5\r\nPage 10 of 10",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"references": [
		"https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5"
	],
	"report_names": [
		"azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5"
	],
	"threat_actors": [],
	"ts_created_at": 1775434869,
	"ts_updated_at": 1775791235,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/ca8aaf355cc93d059be6ae2cea95d2372ea865e2.pdf",
		"text": "https://archive.orkl.eu/ca8aaf355cc93d059be6ae2cea95d2372ea865e2.txt",
		"img": "https://archive.orkl.eu/ca8aaf355cc93d059be6ae2cea95d2372ea865e2.jpg"
	}
}