Summary
| Forestall ACL Alias | AWS_ATTACH_USER_POLICY |
| Edge Type | Attack Path |
| Affected Object Types | IAM Users, IAM Roles |
| Exploitation Certainty | High |
| AWS IAM Action | iam:AttachUserPolicy on the target user |
Description
iam:AttachUserPolicy lets a principal attach any managed policy to an IAM user. That includes AWS-managed ones like AdministratorAccess.
An attacker with this permission attaches an admin policy to a user they already control. That user becomes admin on the next call. If the target user is someone else, the attacker can escalate that account instead and use it later.
The edge is (Attacker:AWSUser|AWSRole) -[AWS_ATTACH_USER_POLICY]-> (TargetUser:AWSUser).
Identification
List who holds iam:AttachUserPolicy:
aws iam get-account-authorization-details \ --filter User Role Group LocalManagedPolicy AWSManagedPolicy \ --query "UserDetailList[?contains(AttachedManagedPolicies[*].PolicyName, 'AttachUserPolicy')]"Check a specific principal with the policy simulator:
aws iam simulate-principal-policy \ --policy-source-arn <attacker-user-arn> \ --action-names iam:AttachUserPolicy \ --resource-arns "arn:aws:iam::*:user/*"PowerShell (AWS Tools):
Get-IAMAccountAuthorizationDetail -Filter User | ForEach-Object { $_.AttachedManagedPolicies | Where-Object { $_.PolicyName -match "AttachUserPolicy" }}Exploitation
Attach an admin policy to a user you control:
aws iam attach-user-policy \ --user-name attacker-user \ --policy-arn arn:aws:iam::aws:policy/AdministratorAccessConfirm it landed:
aws iam list-attached-user-policies --user-name attacker-userNow use that user’s credentials. It has full admin. If you can’t sign in as the user yet, create an access key or set a login profile on the same user first.
Mitigation
- Keep
iam:AttachUserPolicyinside a small admin group. It is a direct route to admin. - Scope the permission to specific user ARNs instead of
*. - Put a permissions boundary on your users so an attached policy can’t exceed a ceiling.
- Alert whenever
AdministratorAccessor another high-privilege managed policy gets attached.
Detection
CloudTrail logs every attach call.
| Event | Description | Key Fields |
|---|---|---|
AttachUserPolicy |
Managed policy attached to a user | requestParameters.userName, requestParameters.policyArn, userIdentity.arn |
aws cloudtrail lookup-events \ --lookup-attributes AttributeKey=EventName,AttributeValue=AttachUserPolicy \ --query 'Events[*].{Time:EventTime,Actor:Username}'Worth a look:
- Any attach of
AdministratorAccessto a user that isn’t an admin. - An attach where the actor and the target user are different identities.