diff --git a/docs/attack-techniques/azure/azure.privilege-escalation.root-user-access-administrator.md b/docs/attack-techniques/azure/azure.privilege-escalation.root-user-access-administrator.md
new file mode 100755
index 000000000..ad5bae830
--- /dev/null
+++ b/docs/attack-techniques/azure/azure.privilege-escalation.root-user-access-administrator.md
@@ -0,0 +1,105 @@
+---
+title: Elevate to User Access Administrator at Root Scope
+---
+
+# Elevate to User Access Administrator at Root Scope
+
+
+
+
+Platform: Azure
+
+## Mappings
+
+- MITRE ATT&CK
+ - Privilege Escalation
+
+
+
+## Description
+
+
+Elevates the current principal to the User Access Administrator role at root scope (/),
+by abusing the "Access management for Azure resources" capability available to Global Administrators in Entra ID.
+
+This technique allows a Global Administrator to gain control over all Azure subscriptions and management groups
+in the tenant, enabling arbitrary role assignments across all Azure resources.
+
+Warm-up: None
+
+Detonation:
+
+- Call the elevateAccess REST API endpoint, which assigns the User Access Administrator role at root scope (/) to the current principal
+
+Revert:
+
+- Remove the User Access Administrator role assignment at root scope (/)
+If you are getting a 403 error when attempting to revert, you may need to refresh your credentials with az login
+
+References:
+
+- https://learn.microsoft.com/en-us/azure/role-based-access-control/elevate-access-global-admin
+- https://microsoft.github.io/Azure-Threat-Research-Matrix/PrivilegeEscalation/AZT402/AZT402/
+- https://www.invictus-ir.com/nieuws/the-azure-log-you-probably-didnt-know-existed
+- https://permiso.io/blog/azures-apex-permissions-elevate-access-the-logs-security-teams-overlook
+
+
+## Instructions
+
+```bash title="Detonate with Stratus Red Team"
+stratus detonate azure.privilege-escalation.root-user-access-administrator
+```
+## Detection
+
+
+Identify when the elevateAccess action is called through either the Entra ID Audit Logs or the Azure Activity Log.
+
+Sample Entra ID Audit Log entry:
+
+``` json hl_lines="2 5"
+{
+ "operationName": "User has elevated their access to User Access Administrator for their Azure Resources",
+ "category": "AuditLogs",
+ "properties": {
+ "category": "AzureRBACRoleManagementElevateAccess",
+ "activityDisplayName": "User has elevated their access to User Access Administrator for their Azure Resources",
+ "loggedByService": "Azure RBAC (Elevated Access)",
+ "result": "success",
+ "initiatedBy": {
+ "user": {
+ "id": "00000000-0000-0000-0000-000000000000",
+ "userPrincipalName": "user@example.com",
+ "ipAddress": "1.2.3.4"
+ }
+ }
+ }
+}
+
+```
+
+Sample Azure Activity Log entry:
+
+``` json hl_lines="3 8"
+{
+ "authorization": {
+ "action": "Microsoft.Authorization/elevateAccess/action",
+ "scope": "/providers/Microsoft.Authorization"
+ },
+ "caller": "user@example.com",
+ "operationName": {
+ "value": "Microsoft.Authorization/elevateAccess/action",
+ "localizedValue": "Assigns the caller to User Access Administrator role"
+ },
+ "properties": {
+ "statusCode": "OK",
+ "eventCategory": "Administrative",
+ "entity": "/providers/Microsoft.Authorization",
+ "message": "Microsoft.Authorization/elevateAccess/action",
+ }
+ "status": {
+ "value": "Succeeded"
+ }
+}
+```
+
+
diff --git a/docs/attack-techniques/azure/index.md b/docs/attack-techniques/azure/index.md
index 45a565425..9fc59e672 100755
--- a/docs/attack-techniques/azure/index.md
+++ b/docs/attack-techniques/azure/index.md
@@ -16,6 +16,11 @@ Note that some Stratus attack techniques may correspond to more than a single AT
- [Create Azure VM Bastion shareable link](./azure.persistence.create-bastion-shareable-link.md)
+## Privilege Escalation
+
+ - [Elevate to User Access Administrator at Root Scope](./azure.privilege-escalation.root-user-access-administrator.md)
+
+
## Exfiltration
- [Export Disk Through SAS URL](./azure.exfiltration.disk-export.md)
diff --git a/docs/attack-techniques/list.md b/docs/attack-techniques/list.md
index 5e3685595..37e3da007 100755
--- a/docs/attack-techniques/list.md
+++ b/docs/attack-techniques/list.md
@@ -61,6 +61,7 @@ This page contains the list of all Stratus Attack Techniques.
| [Azure ransomware via Storage Account Blob deletion](./azure/azure.impact.blob-ransomware-individual-file-deletion.md) | [Azure](./azure/index.md) | Impact |
| [Delete Azure resource lock](./azure/azure.impact.resource-lock.md) | [Azure](./azure/index.md) | Impact |
| [Create Azure VM Bastion shareable link](./azure/azure.persistence.create-bastion-shareable-link.md) | [Azure](./azure/index.md) | Persistence |
+| [Elevate to User Access Administrator at Root Scope](./azure/azure.privilege-escalation.root-user-access-administrator.md) | [Azure](./azure/index.md) | Privilege Escalation |
| [Create Admin EKS Access Entry](./EKS/eks.lateral-movement.create-access-entry.md) | [EKS](./EKS/index.md) | Lateral Movement |
| [Backdoor aws-auth EKS ConfigMap](./EKS/eks.persistence.backdoor-aws-auth-configmap.md) | [EKS](./EKS/index.md) | Persistence, Privilege Escalation |
| [Backdoor Entra ID application through service principal](./entra-id/entra-id.persistence.backdoor-application-sp.md) | [Entra ID](./entra-id/index.md) | Persistence, Privilege Escalation |
diff --git a/docs/attack-techniques/mitre-attack-coverage-matrices.md b/docs/attack-techniques/mitre-attack-coverage-matrices.md
index f85359429..d1e73b39f 100644
--- a/docs/attack-techniques/mitre-attack-coverage-matrices.md
+++ b/docs/attack-techniques/mitre-attack-coverage-matrices.md
@@ -43,11 +43,11 @@ This provides coverage matrices of MITRE ATT&CK tactics and techniques currently
elevateAccess REST API endpoint, which assigns the User Access Administrator role at root scope (/) to the current principal
+
+Revert:
+
+- Remove the User Access Administrator role assignment at root scope (/)
+If you are getting a 403 error when attempting to revert, you may need to refresh your credentials with az login
+
+References:
+
+- https://learn.microsoft.com/en-us/azure/role-based-access-control/elevate-access-global-admin
+- https://microsoft.github.io/Azure-Threat-Research-Matrix/PrivilegeEscalation/AZT402/AZT402/
+- https://www.invictus-ir.com/nieuws/the-azure-log-you-probably-didnt-know-existed
+- https://permiso.io/blog/azures-apex-permissions-elevate-access-the-logs-security-teams-overlook
+`,
+ Detection: `
+Identify when the elevateAccess action is called through either the Entra ID Audit Logs or the Azure Activity Log.
+
+Sample Entra ID Audit Log entry:
+
+` + codeBlock + ` json hl_lines="2 5"
+{
+ "operationName": "User has elevated their access to User Access Administrator for their Azure Resources",
+ "category": "AuditLogs",
+ "properties": {
+ "category": "AzureRBACRoleManagementElevateAccess",
+ "activityDisplayName": "User has elevated their access to User Access Administrator for their Azure Resources",
+ "loggedByService": "Azure RBAC (Elevated Access)",
+ "result": "success",
+ "initiatedBy": {
+ "user": {
+ "id": "00000000-0000-0000-0000-000000000000",
+ "userPrincipalName": "user@example.com",
+ "ipAddress": "1.2.3.4"
+ }
+ }
+ }
+}
+
+` + codeBlock + `
+
+Sample Azure Activity Log entry:
+
+` + codeBlock + ` json hl_lines="3 8"
+{
+ "authorization": {
+ "action": "Microsoft.Authorization/elevateAccess/action",
+ "scope": "/providers/Microsoft.Authorization"
+ },
+ "caller": "user@example.com",
+ "operationName": {
+ "value": "Microsoft.Authorization/elevateAccess/action",
+ "localizedValue": "Assigns the caller to User Access Administrator role"
+ },
+ "properties": {
+ "statusCode": "OK",
+ "eventCategory": "Administrative",
+ "entity": "/providers/Microsoft.Authorization",
+ "message": "Microsoft.Authorization/elevateAccess/action",
+ }
+ "status": {
+ "value": "Succeeded"
+ }
+}
+` + codeBlock + `
+`,
+ IsIdempotent: false,
+ Detonate: detonate,
+ Revert: revert,
+ })
+}
+
+func detonate(_ map[string]string, providers stratus.CloudProviders) error {
+ ctx := context.Background()
+ cred := providers.Azure().GetCredentials()
+ clientOptions := providers.Azure().ClientOptions
+
+ globalAdminClient, err := armauthorization.NewGlobalAdministratorClient(cred, clientOptions)
+ if err != nil {
+ return fmt.Errorf("failed to create global administrator client: %w", err)
+ }
+
+ log.Println("Elevating access to User Access Administrator at root scope (/)")
+ _, err = globalAdminClient.ElevateAccess(ctx, nil)
+ if err != nil {
+ return fmt.Errorf("failed to call elevateAccess: %w", err)
+ }
+
+ log.Println("Successfully elevated access: User Access Administrator role assigned at root scope (/)")
+ return nil
+}
+
+func revert(_ map[string]string, providers stratus.CloudProviders) error {
+ ctx := context.Background()
+ cred := providers.Azure().GetCredentials()
+ clientOptions := providers.Azure().ClientOptions
+
+ // Get a management token to extract the current principal's object ID
+ token, err := cred.GetToken(ctx, policy.TokenRequestOptions{
+ Scopes: []string{"https://management.azure.com/.default"},
+ })
+ if err != nil {
+ return fmt.Errorf("failed to get access token: %w", err)
+ }
+ principalID, err := getOIDFromToken(token.Token)
+ if err != nil {
+ return fmt.Errorf("failed to extract principal object ID from access token: %w", err)
+ }
+ log.Println("Current principal object ID: " + principalID)
+
+ roleAssignmentsClient, err := armauthorization.NewRoleAssignmentsClient("", cred, clientOptions)
+ if err != nil {
+ return fmt.Errorf("failed to create role assignments client: %w", err)
+ }
+
+ // List all role assignments at root scope and filter by principal ID and role definition ID
+ log.Println("Listing role assignments at root scope (/) for principal " + principalID)
+ pager := roleAssignmentsClient.NewListForScopePager("/", &armauthorization.RoleAssignmentsClientListForScopeOptions{
+ Filter: to.Ptr("atScope()"),
+ })
+
+ for pager.More() {
+ page, err := pager.NextPage(ctx)
+ if err != nil {
+ return fmt.Errorf("failed to list role assignments at root scope: %w", err)
+ }
+ for _, ra := range page.Value {
+ if *ra.Properties.PrincipalID != principalID {
+ continue
+ }
+ if !strings.HasSuffix(*ra.Properties.RoleDefinitionID, userAccessAdminRoleDefinitionID) {
+ continue
+ }
+ log.Println("Found User Access Administrator role assignment at root scope, deleting it")
+ _, err := roleAssignmentsClient.DeleteByID(ctx, *ra.ID, nil)
+ if err != nil {
+ var respErr *azcore.ResponseError
+ if errors.As(err, &respErr) && respErr.StatusCode == 403 {
+ return fmt.Errorf("failed to delete role assignment - got 403 Forbidden. Your token may no longer reflect the elevated role assignment. Run 'az login' to refresh your credentials and try again: %w", err)
+ }
+ return fmt.Errorf("failed to delete role assignment %s: %w", *ra.ID, err)
+ }
+ log.Println("Successfully removed User Access Administrator role assignment at root scope")
+ return nil
+ }
+ }
+
+ return fmt.Errorf("user access administrator role assignment at root scope not found")
+}
+
+func getOIDFromToken(tokenString string) (string, error) {
+ parts := strings.Split(tokenString, ".")
+ if len(parts) != 3 {
+ return "", fmt.Errorf("invalid JWT token format: expected 3 parts, got %d", len(parts))
+ }
+
+ // JWT uses base64url encoding without padding - add padding as needed
+ payload := parts[1]
+ switch len(payload) % 4 {
+ case 2:
+ payload += "=="
+ case 3:
+ payload += "="
+ }
+
+ decoded, err := base64.URLEncoding.DecodeString(payload)
+ if err != nil {
+ return "", fmt.Errorf("failed to decode JWT payload: %w", err)
+ }
+
+ var claims struct {
+ OID string `json:"oid"`
+ }
+ if err := json.Unmarshal(decoded, &claims); err != nil {
+ return "", fmt.Errorf("failed to parse JWT claims: %w", err)
+ }
+
+ if claims.OID == "" {
+ return "", fmt.Errorf("oid claim not found in JWT token")
+ }
+
+ return claims.OID, nil
+}
diff --git a/v2/internal/attacktechniques/main.go b/v2/internal/attacktechniques/main.go
index 66134db43..68ecdf430 100644
--- a/v2/internal/attacktechniques/main.go
+++ b/v2/internal/attacktechniques/main.go
@@ -53,6 +53,7 @@ import (
_ "github.com/datadog/stratus-red-team/v2/internal/attacktechniques/azure/impact/blob-ransomware-individual-file-deletion"
_ "github.com/datadog/stratus-red-team/v2/internal/attacktechniques/azure/impact/resource-lock"
_ "github.com/datadog/stratus-red-team/v2/internal/attacktechniques/azure/persistence/create-bastion-shareable-link"
+ _ "github.com/datadog/stratus-red-team/v2/internal/attacktechniques/azure/privilege-escalation/root-user-access-administrator"
_ "github.com/datadog/stratus-red-team/v2/internal/attacktechniques/eks/lateral-movement/create-access-entry"
_ "github.com/datadog/stratus-red-team/v2/internal/attacktechniques/eks/persistence/backdoor-aws-auth-configmap"
_ "github.com/datadog/stratus-red-team/v2/internal/attacktechniques/entra-id/persistence/backdoor-application"