↳ Source GitHubRègle analytiqueHigh
AWSCloudTrail - CloudFormation policy created then used for privilege escalation
Description
Identifies creation of IAM policies that grant CloudFormation and IAM permissions commonly used for privilege
escalation, followed by attachment activity to a user, role, or group. Review whether the new policy and any
subsequent attachment were authorized because this pattern can enable an attacker to create or elevate access.
- Type de règle
- Scheduled
- Version
- 1.0.4
- Statut déclaré
- Available
- Fréquence
- 1d
- Période analysée
- 1d
- 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), Condition = tostring(parse_json(Statement).Condition)
| extend Action = tostring(Action)
| where Effect =~ "Allow" and (((Action has "iam:*" or Action has "iam:PassRole") and Action has "cloudformation:*") or ((Action has "iam:*" or Action has "iam:PassRole") and Action contains "cloudformation:DescribeStacks" and Action contains "cloudformation:CreateStack") or ((Action contains "iam:*" or Action contains "iam:PassRole") and Action contains "cloudformation:Describe*" and Action contains "cloudformation:Create*")) and Resource == "*" and Condition == ""
| distinct TimeGenerated, EventName, PolicyName, SourceIpAddress, UserIdentityArn, RecipientAccountId, AccountName, AccountUPNSuffix
| project-rename StartTime = TimeGenerated );
let PolicyAttach = materialize( EventInfo
| where TimeGenerated >= ago(timeframe)
| where EventName in (EventNameList) and isempty(ErrorCode) and isempty(ErrorMessage)
| extend PolicyName = tostring(split(tostring(parse_json(RequestParameters).policyArn),"/")[1])
| summarize AttachEventCount=count(), StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by EventSource, EventName, RecipientAccountId, AccountName, AccountUPNSuffix, UserIdentityType , UserIdentityArn, SourceIpAddress, PolicyName
| extend AttachEvent = pack("StartTime", StartTime, "EndTime", EndTime, "EventName", EventName, "UserIdentityType", UserIdentityType, "SourceIpAddress", SourceIpAddress, "AccountName", AccountName, "AccountUPNSuffix", AccountUPNSuffix, "RecipientAccountId", RecipientAccountId, "UserIdentityArn", UserIdentityArn)
| project EventSource, PolicyName, AttachEvent, AttachEventCount, RecipientAccountId, AccountName, AccountUPNSuffix
);
// 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
Entités déclarées
Contenus associés
Liens établis à partir des identifiants déclarés et des manifests des solutions.
Traçabilité de la source
GitHubLes 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.
- Commit
7ca9800↗- Identifiant source
efdc3cff-f006-426f-97fd-4657862f7b9a
GSTEP / SUIVI DU CATALOGUE
Ajouté au catalogue : 16 sept. 2026 · 05:49 UTC
Dernier changement observé : 16 sept. 2026 · 05:49 UTC