Analytic rule catalog
AWSCloudTrail - Privilege escalation via CRUD IAM policy
Back
| Id | e20d35a3-4fec-4c8b-81b1-fc33b41990b0 |
| Rulename | AWSCloudTrail - Privilege escalation via CRUD IAM policy |
| Description | Detects creation of inline IAM policies that grant broad IAM create, read, update, and delete capabilities. This behavior can establish or expand privileged control paths in the account and should be reviewed as potential privilege escalation. |
| Severity | Medium |
| Tactics | PrivilegeEscalation |
| Techniques | T1098.003 |
| Required data connectors | AWS |
| Kind | Scheduled |
| Query frequency | 1d |
| Query period | 1d |
| Trigger threshold | 0 |
| Trigger operator | gt |
| Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Amazon%20Web%20Services/Analytic%20Rules/AWS_PrivilegeEscalationViaCRUDIAMPolicy.yaml |
| Version | 1.0.2 |
| Arm template | e20d35a3-4fec-4c8b-81b1-fc33b41990b0.json |
AWSCloudTrail
| where EventName in ("PutUserPolicy","PutRolePolicy","PutGroupPolicy") and isempty(ErrorCode) and isempty(ErrorMessage)
| 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 contains "iam:Create" and (Action contains "iam:Get" or Action contains "iam:List") and Action contains "iam:Update" and Action contains "iam:Delete") and Resource == "*" and Condition == ""
| 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]), "")
| distinct TimeGenerated, EventName, PolicyName, SourceIpAddress, RecipientAccountId, AccountName, AccountUPNSuffix, UserIdentityArn, UserIdentityUserName
relevantTechniques:
- T1098.003
triggerThreshold: 0
id: e20d35a3-4fec-4c8b-81b1-fc33b41990b0
queryPeriod: 1d
triggerOperator: gt
alertDetailsOverride:
alertDisplayNameFormat: AWS IAM privilege escalation policy update by {{AccountName}}
alertDescriptionFormat: Detected {{EventName}} Event, updating inline IAM escalation policy {{PolicyName}} in account {{RecipientAccountId}}.
status: Available
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Amazon%20Web%20Services/Analytic%20Rules/AWS_PrivilegeEscalationViaCRUDIAMPolicy.yaml
queryFrequency: 1d
requiredDataConnectors:
- dataTypes:
- AWSCloudTrail
connectorId: AWS
version: 1.0.2
tactics:
- PrivilegeEscalation
query: |
AWSCloudTrail
| where EventName in ("PutUserPolicy","PutRolePolicy","PutGroupPolicy") and isempty(ErrorCode) and isempty(ErrorMessage)
| 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 contains "iam:Create" and (Action contains "iam:Get" or Action contains "iam:List") and Action contains "iam:Update" and Action contains "iam:Delete") and Resource == "*" and Condition == ""
| 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]), "")
| distinct TimeGenerated, EventName, PolicyName, SourceIpAddress, RecipientAccountId, AccountName, AccountUPNSuffix, UserIdentityArn, UserIdentityUserName
name: AWSCloudTrail - Privilege escalation via CRUD IAM policy
severity: Medium
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: AccountName
- identifier: UPNSuffix
columnName: AccountUPNSuffix
- identifier: CloudAppAccountId
columnName: RecipientAccountId
- entityType: IP
fieldMappings:
- identifier: Address
columnName: SourceIpAddress
customDetails:
EventName: EventName
RecipientAccountId: RecipientAccountId
PolicyName: PolicyName
UserIdentityArn: UserIdentityArn
description: |
Detects creation of inline IAM policies that grant broad IAM create, read, update, and delete capabilities.
This behavior can establish or expand privileged control paths in the account and should be reviewed as potential
privilege escalation.
kind: Scheduled
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"workspace": {
"type": "String"
}
},
"resources": [
{
"apiVersion": "2024-01-01-preview",
"id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/e20d35a3-4fec-4c8b-81b1-fc33b41990b0')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/e20d35a3-4fec-4c8b-81b1-fc33b41990b0')]",
"properties": {
"alertDetailsOverride": {
"alertDescriptionFormat": "Detected {{EventName}} Event, updating inline IAM escalation policy {{PolicyName}} in account {{RecipientAccountId}}.",
"alertDisplayNameFormat": "AWS IAM privilege escalation policy update by {{AccountName}}"
},
"alertRuleTemplateName": "e20d35a3-4fec-4c8b-81b1-fc33b41990b0",
"customDetails": {
"EventName": "EventName",
"PolicyName": "PolicyName",
"RecipientAccountId": "RecipientAccountId",
"UserIdentityArn": "UserIdentityArn"
},
"description": "Detects creation of inline IAM policies that grant broad IAM create, read, update, and delete capabilities.\nThis behavior can establish or expand privileged control paths in the account and should be reviewed as potential\nprivilege escalation.\n",
"displayName": "AWSCloudTrail - Privilege escalation via CRUD IAM policy",
"enabled": true,
"entityMappings": [
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "AccountName",
"identifier": "Name"
},
{
"columnName": "AccountUPNSuffix",
"identifier": "UPNSuffix"
},
{
"columnName": "RecipientAccountId",
"identifier": "CloudAppAccountId"
}
]
},
{
"entityType": "IP",
"fieldMappings": [
{
"columnName": "SourceIpAddress",
"identifier": "Address"
}
]
}
],
"OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Amazon%20Web%20Services/Analytic%20Rules/AWS_PrivilegeEscalationViaCRUDIAMPolicy.yaml",
"query": "AWSCloudTrail\n | where EventName in (\"PutUserPolicy\",\"PutRolePolicy\",\"PutGroupPolicy\") and isempty(ErrorCode) and isempty(ErrorMessage)\n | extend PolicyName = tostring(parse_json(RequestParameters).policyName)\n | extend Statement = parse_json(tostring((parse_json(RequestParameters).policyDocument))).Statement\n | mvexpand Statement\n | extend Action = parse_json(Statement).Action , Effect = tostring(parse_json(Statement).Effect), Resource = tostring(parse_json(Statement).Resource), Condition = tostring(parse_json(Statement).Condition)\n | extend Action = tostring(Action)\n | where Effect =~ \"Allow\" and (Action contains \"iam:Create\" and (Action contains \"iam:Get\" or Action contains \"iam:List\") and Action contains \"iam:Update\" and Action contains \"iam:Delete\") and Resource == \"*\" and Condition == \"\"\n | extend UserIdentityArn = iif(isempty(UserIdentityArn), tostring(parse_json(Resources)[0].ARN), UserIdentityArn)\n | extend UserName = tostring(split(UserIdentityArn, '/')[-1])\n | extend AccountName = case( UserIdentityPrincipalid == \"Anonymous\", \"Anonymous\", isempty(UserIdentityUserName), UserName, UserIdentityUserName)\n | extend AccountName = iif(AccountName contains \"@\", tostring(split(AccountName, '@', 0)[0]), AccountName),\n AccountUPNSuffix = iif(AccountName contains \"@\", tostring(split(AccountName, '@', 1)[0]), \"\")\n | distinct TimeGenerated, EventName, PolicyName, SourceIpAddress, RecipientAccountId, AccountName, AccountUPNSuffix, UserIdentityArn, UserIdentityUserName\n",
"queryFrequency": "P1D",
"queryPeriod": "P1D",
"severity": "Medium",
"status": "Available",
"subTechniques": [
"T1098.003"
],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"PrivilegeEscalation"
],
"techniques": [
"T1098"
],
"templateVersion": "1.0.2",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}