↳ Source GitHubRègle analytiqueMedium

AWSCloudTrail - Full Admin policy created and then attached to Roles, Users or Groups

Description

Identifies creation of IAM policies that grant full administrative access and subsequent attachment to a role, user, or group. This sequence can be used to elevate a low-privilege identity to administrative access and should be investigated immediately. AWS IAM Policy Grammar: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_grammar.html and AWS IAM API at https://docs.aws.amazon.com/IAM/latest/APIReference/API_Operations.html
Type de règle
Scheduled
Version
1.0.5
Statut déclaré
Available
Fréquence
1d
Période analysée
14d
Déclenchement
gt 0

Couverture MITRE déclarée

Sources déclarées

Métadonnées du fichier source. Aucune dépendance déduite du KQL.

Connecteurs

Types de données

Requête KQL

Requête originale, sans modification.

let EventNameList = dynamic(["AttachUserPolicy","AttachRolePolicy","AttachGroupPolicy"]);
let createPolicy = dynamic(["CreatePolicy", "CreatePolicyVersion"]);
let timeframe = 1d;
let lookback = 14d;
// Creating Master table with all the events to use with materialize for better performance
let EventInfo = AWSCloudTrail
| where TimeGenerated >= ago(lookback)
| where EventName in (EventNameList) or EventName in (createPolicy)
| extend UserIdentityArn = iif(isempty(UserIdentityArn), tostring(parse_json(Resources)[0].ARN), UserIdentityArn)
| extend UserName = tostring(split(UserIdentityArn, '/')[-1])
| extend AccountName = case( UserIdentityPrincipalid == "Anonymous", "Anonymous", isempty(UserIdentityUserName), UserName, UserIdentityUserName)
| extend AccountName = iif(AccountName contains "@", tostring(split(AccountName, '@', 0)[0]), AccountName),
  AccountUPNSuffix = iif(AccountName contains "@", tostring(split(AccountName, '@', 1)[0]), "");
//Checking for Policy creation event with Full Admin Privileges since lookback period.
let FullAdminPolicyEvents =  materialize(  EventInfo
| where TimeGenerated >= ago(lookback)
| where EventName in (createPolicy)
| extend PolicyName = tostring(parse_json(RequestParameters).policyName)
| extend Statement = parse_json(tostring((parse_json(RequestParameters).policyDocument))).Statement
| mvexpand Statement
| extend Action = parse_json(Statement).Action , Effect = tostring(parse_json(Statement).Effect), Resource = tostring(parse_json(Statement).Resource)
| mvexpand Action
| extend Action = tostring(Action)
| where Effect =~ "Allow" and Action == "*" and Resource == "*"
| distinct TimeGenerated, EventName, PolicyName, SourceIpAddress, UserIdentityArn, UserIdentityUserName, RecipientAccountId, AccountName, AccountUPNSuffix
| extend UserIdentityUserName = iff(isnotempty(UserIdentityUserName), UserIdentityUserName, tostring(split(UserIdentityArn,'/')[-1]))
| project-rename StartTime = TimeGenerated  );
let PolicyAttach = materialize(  EventInfo
| where TimeGenerated >= ago(timeframe)
| where EventName in (EventNameList)
| extend PolicyName = tostring(split(tostring(parse_json(RequestParameters).policyArn),"/")[1])
| summarize AttachEventCount=count(), StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by EventSource, EventName,   UserIdentityType , UserIdentityArn, SourceIpAddress, RecipientAccountId, AccountName, AccountUPNSuffix, PolicyName
| extend AttachEvent = pack("StartTime", StartTime, "EndTime", EndTime, "EventName", EventName, "UserIdentityType",   UserIdentityType, "AccountName", AccountName, "AccountUPNSuffix", AccountUPNSuffix, "RecipientAccountId", RecipientAccountId, "UserIdentityArn", UserIdentityArn, "SourceIpAddress", SourceIpAddress)
| project EventSource, PolicyName, AttachEvent, RecipientAccountId, AccountName, AccountUPNSuffix, AttachEventCount
);
// Joining the list of PolicyNames and checking if it has been attached to any Roles/Users/Groups.
// These Roles/Users/Groups will be Privileged and can be used by adversaries as pivot point for privilege escalation via multiple ways.
FullAdminPolicyEvents
| join kind=leftouter
(
    PolicyAttach
)
on PolicyName
| project-away PolicyName1
| extend timestamp = StartTime

Entités déclarées

AccountIP

Contenus associés

Liens établis à partir des identifiants déclarés et des manifests des solutions.

Traçabilité de la source

GitHub

Les valeurs affichées proviennent des fichiers du dépôt Azure/Azure-Sentinel. Elles décrivent le modèle publié, pas la configuration de votre workspace.

Identifiant source
826bb2f8-7894-4785-9a6b-a8a855d8366f
Autres fichiers source 3Solutions/Amazon Web Services/Analytic Rules/AWS_FullAdminPolicyAttachedToRolesUsersGroups.yamlsource ↗Detections/AWSCloudTrail/AWS_FullAdminPolicyAttachedToRolesUsersGroups.yamlmigration-note ↗Solutions/Amazon Web Services/Data/Solution_AmazonWebServices.jsonsolution-membership ↗
GSTEP / SUIVI DU CATALOGUE

Ajouté au catalogue : 16 sept. 2026 · 05:49 UTC
Dernier changement observé : 16 sept. 2026 · 05:49 UTC

Dates de synchronisation GSTEP, distinctes des dates de publication du contenu source.