Microsoft Sentinel Analytic Rules
cloudbrothers.infoAzure Sentinel RepoToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

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

Back
Id826bb2f8-7894-4785-9a6b-a8a855d8366f
RulenameFull Admin policy created and then attached to Roles, Users or Groups
DescriptionIdentity and Access Management (IAM) securely manages access to AWS services and resources.

Identifies when a policy is created with Full Administrators Access (Allow-Action:*,Resource:*).

This policy can be attached to role,user or group and may be used by an adversary to escalate a normal user privileges to an adminsitrative level.

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
SeverityMedium
TacticsPrivilegeEscalation
Required data connectorsAWS
AWSS3
KindScheduled
Query frequency1d
Query period14d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Amazon Web Services/Analytic Rules/AWS_FullAdminPolicyAttachedToRolesUsersGroups.yaml
Version1.0.1
Arm template826bb2f8-7894-4785-9a6b-a8a855d8366f.json
Deploy To Azure
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);
//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
| 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, UserIdentityUserName = iff(isnotempty(UserIdentityUserName),   UserIdentityUserName, tostring(split(UserIdentityArn,'/')[-1])), PolicyName
| extend AttachEvent = pack("StartTime", StartTime, "EndTime", EndTime, "EventName", EventName, "UserIdentityType",   UserIdentityType, "UserIdentityArn", UserIdentityArn, "SourceIpAddress", SourceIpAddress, "UserIdentityUserName", UserIdentityUserName)
| project EventSource, PolicyName, AttachEvent, 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, IPCustomEntity = SourceIpAddress, AccountCustomEntity = UserIdentityUserName
kind: Scheduled
triggerOperator: gt
queryFrequency: 1d
name: Full Admin policy created and then attached to Roles, Users or Groups
status: Available
queryPeriod: 14d
id: 826bb2f8-7894-4785-9a6b-a8a855d8366f
description: |
  'Identity and Access Management (IAM) securely manages access to AWS services and resources. 
  Identifies when a policy is created with Full Administrators Access (Allow-Action:*,Resource:*). 
  This policy can be attached to role,user or group and may be used by an adversary to escalate a normal user privileges to an adminsitrative level.
  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'  
severity: Medium
query: |
  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);
  //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
  | 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, UserIdentityUserName = iff(isnotempty(UserIdentityUserName),   UserIdentityUserName, tostring(split(UserIdentityArn,'/')[-1])), PolicyName
  | extend AttachEvent = pack("StartTime", StartTime, "EndTime", EndTime, "EventName", EventName, "UserIdentityType",   UserIdentityType, "UserIdentityArn", UserIdentityArn, "SourceIpAddress", SourceIpAddress, "UserIdentityUserName", UserIdentityUserName)
  | project EventSource, PolicyName, AttachEvent, 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, IPCustomEntity = SourceIpAddress, AccountCustomEntity = UserIdentityUserName  
version: 1.0.1
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Amazon Web Services/Analytic Rules/AWS_FullAdminPolicyAttachedToRolesUsersGroups.yaml
entityMappings:
- entityType: Account
  fieldMappings:
  - identifier: FullName
    columnName: AccountCustomEntity
- entityType: IP
  fieldMappings:
  - identifier: Address
    columnName: IPCustomEntity
requiredDataConnectors:
- connectorId: AWS
  dataTypes:
  - AWSCloudTrail
- connectorId: AWSS3
  dataTypes:
  - AWSCloudTrail
tactics:
- PrivilegeEscalation
triggerThreshold: 0
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/826bb2f8-7894-4785-9a6b-a8a855d8366f')]",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/826bb2f8-7894-4785-9a6b-a8a855d8366f')]",
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules",
      "kind": "Scheduled",
      "apiVersion": "2022-11-01-preview",
      "properties": {
        "displayName": "Full Admin policy created and then attached to Roles, Users or Groups",
        "description": "'Identity and Access Management (IAM) securely manages access to AWS services and resources. \nIdentifies when a policy is created with Full Administrators Access (Allow-Action:*,Resource:*). \nThis policy can be attached to role,user or group and may be used by an adversary to escalate a normal user privileges to an adminsitrative level.\nAWS IAM Policy Grammar: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_grammar.html\nand AWS IAM API at https://docs.aws.amazon.com/IAM/latest/APIReference/API_Operations.html'\n",
        "severity": "Medium",
        "enabled": true,
        "query": "let EventNameList = dynamic([\"AttachUserPolicy\",\"AttachRolePolicy\",\"AttachGroupPolicy\"]);\nlet createPolicy = dynamic([\"CreatePolicy\", \"CreatePolicyVersion\"]);\nlet timeframe = 1d;\nlet lookback = 14d;\n// Creating Master table with all the events to use with materialize for better performance\nlet EventInfo = AWSCloudTrail\n| where TimeGenerated >= ago(lookback)\n| where EventName in (EventNameList) or EventName in (createPolicy);\n//Checking for Policy creation event with Full Admin Privileges since lookback period.\nlet FullAdminPolicyEvents =  materialize(  EventInfo\n| where TimeGenerated >= ago(lookback)\n| where EventName in (createPolicy)\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)\n| mvexpand Action\n| extend Action = tostring(Action)\n| where Effect =~ \"Allow\" and Action == \"*\" and Resource == \"*\"\n| distinct TimeGenerated, EventName, PolicyName, SourceIpAddress, UserIdentityArn, UserIdentityUserName\n| extend UserIdentityUserName = iff(isnotempty(UserIdentityUserName), UserIdentityUserName, tostring(split(UserIdentityArn,'/')[-1]))\n| project-rename StartTime = TimeGenerated  );\nlet PolicyAttach = materialize(  EventInfo\n| where TimeGenerated >= ago(timeframe)\n| where EventName in (EventNameList)\n| extend PolicyName = tostring(split(tostring(parse_json(RequestParameters).policyArn),\"/\")[1])\n| summarize AttachEventCount=count(), StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by EventSource, EventName,   UserIdentityType , UserIdentityArn, SourceIpAddress, UserIdentityUserName = iff(isnotempty(UserIdentityUserName),   UserIdentityUserName, tostring(split(UserIdentityArn,'/')[-1])), PolicyName\n| extend AttachEvent = pack(\"StartTime\", StartTime, \"EndTime\", EndTime, \"EventName\", EventName, \"UserIdentityType\",   UserIdentityType, \"UserIdentityArn\", UserIdentityArn, \"SourceIpAddress\", SourceIpAddress, \"UserIdentityUserName\", UserIdentityUserName)\n| project EventSource, PolicyName, AttachEvent, AttachEventCount\n);\n// Joining the list of PolicyNames and checking if it has been attached to any Roles/Users/Groups.\n// These Roles/Users/Groups will be Privileged and can be used by adversaries as pivot point for privilege escalation via multiple ways.\nFullAdminPolicyEvents\n| join kind=leftouter\n(\n    PolicyAttach\n)\non PolicyName\n| project-away PolicyName1\n| extend timestamp = StartTime, IPCustomEntity = SourceIpAddress, AccountCustomEntity = UserIdentityUserName\n",
        "queryFrequency": "P1D",
        "queryPeriod": "P14D",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0,
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "PrivilegeEscalation"
        ],
        "alertRuleTemplateName": "826bb2f8-7894-4785-9a6b-a8a855d8366f",
        "customDetails": null,
        "entityMappings": [
          {
            "fieldMappings": [
              {
                "identifier": "FullName",
                "columnName": "AccountCustomEntity"
              }
            ],
            "entityType": "Account"
          },
          {
            "fieldMappings": [
              {
                "identifier": "Address",
                "columnName": "IPCustomEntity"
              }
            ],
            "entityType": "IP"
          }
        ],
        "templateVersion": "1.0.1",
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Amazon Web Services/Analytic Rules/AWS_FullAdminPolicyAttachedToRolesUsersGroups.yaml",
        "status": "Available"
      }
    }
  ]
}