Post

No Single Pane of Glass Anatomy of an Azure Permission Takeover

No Single Pane of Glass Anatomy of an Azure Permission Takeover

No Single Pane of Glass: Anatomy of an Azure Permission Takeover

The Sysdig Threat Research Team (TRT) recently observed an alarming incident where an attacker exploited a single leaked service-principal credential and gained complete control over an Azure tenant by the next morning. This attacker achieved Global Administrator (GA) ownership of the directory and root-level access over every resource. They established persistence across numerous identities and seized control of the telemetry pipeline that was meant to monitor their activities. 🚨

In Azure, the question of “who and what can actually touch this tenant?” lacks a straightforward answer. Permissions exist in at least five disjointed systems that Azure does not unify. These systems do not share identifiers, and they have different logs and data models. An attacker can navigate between them without detection, as defenders typically focus on only one at a time. The entry point was unremarkable yet extremely common: a leaked service-principal client secret, which was exposed for about two weeks before the attacker discovered it. During this time, it was replayed from various anonymization infrastructures across the US, Germany, Sweden, Hong Kong, and the Netherlands. Most of these sessions were merely reconnaissance, until one session transitioned from reconnaissance to escalation. 🔍

The Sysdig TRT noted a rapid escalation of privileges. At 03:27 UTC, the first valid sign-in occurred. By 03:29:57, just two and a half minutes later, the attacker added a member to a role outside of Privileged Identity Management (PIM), becoming the Global Administrator at the directory root. Between 03:29 and 03:50, attacker-controlled client secrets were added to 26 application registrations. In Phase 2, starting at 04:32:37, the attacker utilized Microsoft.Authorization/elevateAccess/action to become User Access Administrator at the root level over Azure resources, followed by roleAssignments/write at the subscription scope. At 04:33, the attacker executed storageAccounts/listKeys on four storage accounts, and at 04:33:37-38, listKeys was performed on rootmanagesharedaccesskey for both Event Hub namespaces—those carrying the tenant’s own audit telemetry. This was followed by modifications to Key Vault access policies and data-plane secret reads. 🔑

From the initial login to owning the directory, every subscription resource, storage keys, Event Hub keys, and Key Vault access took the attacker about an hour of active effort, spread across one morning. There was no malware, no exploits, and no zero-days—just permissions that were granted, escalated, and harvested through entirely legitimate Azure APIs. After the incident, to identify everything the attacker controlled, one would need to reference at least five different locations. The connection between Entra directory roles and Azure RBAC (the resource control plane) is elevateAccess. A GA can invoke Microsoft.Authorization/elevateAccess/action and instantly grant themselves User Access Administrator at the root scope (/) over every subscription. This maneuver, which bridges two permission systems, is invisible in both systems’ “normal” views, as it appears in directory Activity logs (Entra audit log) but not in the subscription’s RBAC blade or exported AzureActivity log. Furthermore, shared keys and Shared Access Signatures (SAS) completely disrupt the “single pane of glass” concept. If you possess the key, you are authorized, period. The attacker executed listKeys on four storage accounts and on both Event Hub namespaces, obtaining bearer credentials to the data and telemetry transport. The act of generating the key is visible for just a moment in the activity log. Every subsequent use of it is anonymous and, by default, unlogged; data-plane use of the resulting key is only logged if per-resource data-plane diagnostics have been explicitly enabled, which are typically off by default for storage, Event Hubs, and most resource types. In this case, the Event Hub namespaces had no diagnostic settings at all, meaning the use of the stolen root keys would have left no trace whatsoever.

To read the complete article see: Read full article

This post is licensed under CC BY 4.0 by the author.