Query Details
AWSCloudTrail
| where EventName in ("CreatePolicy", "CreatePolicyVersion")
and isempty(ErrorCode)
and isempty(ErrorMessage)
| extend DynamicRequestParameters = todynamic(RequestParameters)
| extend Statement = case(
bag_keys(DynamicRequestParameters) has "policyDocument", todynamic(tostring(DynamicRequestParameters["policyDocument"]))["Statement"],
bag_keys(DynamicRequestParameters) has "content", todynamic(tostring(DynamicRequestParameters["content"]))["Statement"],
dynamic(null)
)
| mv-expand Statement = iff(isnotempty(bag_keys(Statement)), pack_array(Statement), Statement)
| extend
Effect = tostring(Statement["Effect"]),
Action = tostring(Statement["Action"]),
Resource = tostring(Statement["Resource"])
| where Effect == "Allow" and Resource has "*" and Action has "*"
| summarize take_any(*) by AwsEventId
| invoke AWSIdentityRole()
| extend PolicyArn = tostring(todynamic(ResponseElements)["policy"]["arn"])
| join kind=leftouter (
AWSCloudTrail
| where EventName in ("AttachUserPolicy","AttachRolePolicy","AttachGroupPolicy")
and isempty(ErrorCode)
and isempty(ErrorMessage)
| extend PolicyArn = tostring(todynamic(RequestParameters)["policyArn"])
| where isnotempty(PolicyArn)
| summarize AttachedEntities = make_list(RequestParameters, 200) by PolicyArn
) on PolicyArn
| project
TimeGenerated,
UserIdentityType,
Identity,
ActorRole,
TargetRole,
TargetRoleSessionName,
UserIdentityAccountId,
UserIdentityAccountName,
RecipientAccountId,
RecipientAccountName,
SessionCreationDate,
UserIdentityPrincipalid,
UserIdentityArn,
SourceIpAddress,
EventSource,
EventTypeName,
EventName,
ManagementEvent,
ReadOnly,
ErrorCode,
ErrorMessage,
PolicyArn,
Statement = iff(isnotempty(bag_keys(Statement)), pack_array(Statement), Statement),
AttachedEntities,
RequestParameters,
ResponseElements,
Resources,
SessionMfaAuthenticated,
UserAgent,
AwsEventId
This query is used to retrieve information from the AWSCloudTrail table. It filters events with the EventName "CreatePolicy" or "CreatePolicyVersion" and no error code or error message. It then extends the DynamicRequestParameters column to convert it into a dynamic type. The Statement column is extended to extract the "policyDocument" or "content" from the DynamicRequestParameters. The Statement column is then expanded to create separate rows for each statement. The query further filters rows where the Effect is "Allow", Resource contains "", and Action contains "". It then summarizes the data by taking any value for each AwsEventId. The AWSIdentityRole function is invoked to get additional information. The result is joined with the AWSCloudTrail table on the PolicyArn column. Finally, the query projects various columns from the result.

Jose Sebastián Canós
Released: October 25, 2023
Tables
Keywords
Operators