IAM Entity Created Without CloudFormation


Description

An IAM Entity (Group, Policy, Role, or User) was created manually. IAM entities should be created in code to ensure that permissions are tracked and managed correctly.

Query · python

import re

from panther_aws_helpers import aws_cloudtrail_success, aws_rule_context

# The role dedicated for IAM administration
IAM_ADMIN_ROLES = {
    "arn:aws:iam::123456789012:role/IdentityCFNServiceRole",
}

# The role patterns dedicated for IAM Service Roles
IAM_ADMIN_ROLE_PATTERNS = {"arn:aws:iam::[0-9]+:role/IdentityCFNServiceRole"}

# API calls that are indicative of IAM entity creation
IAM_ENTITY_CREATION_EVENTS = {
    "BatchCreateUser",
    "CreateGroup",
    "CreateInstanceProfile",
    "CreatePolicy",
    "CreatePolicyVersion",
    "CreateRole",
    "CreateServiceLinkedRole",
    "CreateUser",
}


def rule(event):
    # Check if this event is in scope
    if (
        not aws_cloudtrail_success(event)
        or event.get("eventName") not in IAM_ENTITY_CREATION_EVENTS
    ):
        return False

    # All IAM changes MUST go through CloudFormation
    if event.deep_get("userIdentity", "invokedBy") != "cloudformation.amazonaws.com":
        return True

    # Only approved IAM Roles can make IAM Changes
    for admin_role_pattern in IAM_ADMIN_ROLE_PATTERNS:
        # Check if the arn matches any role patterns, return False if there is a match
        if (
            len(
                re.findall(
                    admin_role_pattern,
                    event.deep_get("userIdentity", "sessionContext", "sessionIssuer", "arn"),
                )
            )
            > 0
        ):
            return False

    return (
        event.deep_get("userIdentity", "sessionContext", "sessionIssuer", "arn")
        not in IAM_ADMIN_ROLES
    )


def alert_context(event):
    return aws_rule_context(event)

Analyst notes

Verify whether IAM entity needs to exist. If so, re-create it in an appropriate CloudFormation, Terraform, or other template. Delete the original manually created entity.

Raw source IAM Entity Created Without CloudFormation · Panther Python
Esc
Published by panther-labs/panther-analysis ↗, licensed under Apache 2.0 ↗. Reproduced here unmodified.
AnalysisType: rule
Filename: aws_iam_entity_created_without_cloudformation.py
RuleID: "AWS.CloudTrail.IAMEntityCreatedWithoutCloudFormation"
DisplayName: "IAM Entity Created Without CloudFormation"
Enabled: false
LogTypes:
  - AWS.CloudTrail
Reports:
  MITRE ATT&CK:
    - TA0003:T1136
Tags:
  - AWS
  - Configuration Required
  - Identity and Access Management
  - Persistence:Create Account
Severity: Medium
Description: >
  An IAM Entity (Group, Policy, Role, or User) was created manually. IAM entities should be created in code to ensure that permissions are tracked and managed correctly.
Runbook: >
  Verify whether IAM entity needs to exist. If so, re-create it in an appropriate CloudFormation, Terraform, or other template. Delete the original manually created entity.
Reference: https://blog.awsfundamentals.com/aws-iam-roles-with-aws-cloudformation
SummaryAttributes:
  - userAgent
  - sourceIpAddress
  - recipientAccountId
  - p_any_aws_arns
Tests:
  - Name: IAM Entity Created Automatically
    ExpectedResult: false
    Log:
      {
        "eventVersion": "1.05",
        "userIdentity":
          {
            "type": "AssumedRole",
            "principalId": "1111:tester",
            "arn": "arn:aws:sts::123456789012:assumed-role/tester",
            "accountId": "123456789012",
            "accessKeyId": "1",
            "invokedBy": "cloudformation.amazonaws.com",
            "sessionContext":
              {
                "attributes":
                  {
                    "mfaAuthenticated": "true",
                    "creationDate": "2019-01-01T00:00:00Z",
                  },
                "sessionIssuer":
                  {
                    "type": "Role",
                    "principalId": "1111",
                    "arn": "arn:aws:iam::123456789012:role/IdentityCFNServiceRole",
                    "accountId": "123456789012",
                    "userName": "tester",
                  },
              },
          },
        "eventTime": "2019-01-01T00:00:00Z",
        "eventSource": "iam.amazonaws.com",
        "eventName": "CreateUser",
        "awsRegion": "us-east-1",
        "sourceIPAddress": "111.111.111.111",
        "userAgent": "console.amazonaws.com",
        "requestParameters": { "userName": "user", "path": "/" },
        "responseElements": null,
        "requestID": "1",
        "eventID": "1",
        "eventType": "AwsApiCall",
        "recipientAccountId": "123456789012",
      }
  - Name: IAM Entity Created Manually With Approved Role
    ExpectedResult: true
    Log:
      {
        "eventVersion": "1.05",
        "userIdentity":
          {
            "type": "AssumedRole",
            "principalId": "1111:tester",
            "arn": "arn:aws:sts::123456789012:assumed-role/tester",
            "accountId": "123456789012",
            "accessKeyId": "1",
            "sessionContext":
              {
                "attributes":
                  {
                    "mfaAuthenticated": "true",
                    "creationDate": "2019-01-01T00:00:00Z",
                  },
                "sessionIssuer":
                  {
                    "type": "Role",
                    "principalId": "1111",
                    "arn": "arn:aws:iam::123456789012:role/IdentityCFNServiceRole",
                    "accountId": "123456789012",
                    "userName": "tester",
                  },
              },
          },
        "eventTime": "2019-01-01T00:00:00Z",
        "eventSource": "iam.amazonaws.com",
        "eventName": "CreateUser",
        "awsRegion": "us-east-1",
        "sourceIPAddress": "111.111.111.111",
        "userAgent": "console.amazonaws.com",
        "requestParameters": { "userName": "user", "path": "/" },
        "responseElements": null,
        "requestID": "1",
        "eventID": "1",
        "eventType": "AwsApiCall",
        "recipientAccountId": "123456789012",
      }
  - Name: IAM Entity Created Manually With Approved Role Pattern
    ExpectedResult: false
    Log:
      {
        "eventVersion": "1.05",
        "userIdentity":
          {
            "type": "AssumedRole",
            "principalId": "1111:tester",
            "arn": "arn:aws:sts::123456789012:assumed-role/tester",
            "accountId": "123456789012",
            "accessKeyId": "1",
            "invokedBy": "cloudformation.amazonaws.com",
            "sessionContext":
              {
                "attributes":
                  {
                    "mfaAuthenticated": "true",
                    "creationDate": "2019-01-01T00:00:00Z",
                  },
                "sessionIssuer":
                  {
                    "type": "Role",
                    "principalId": "1111",
                    "arn": "arn:aws:iam::210987654321:role/IdentityCFNServiceRole",
                    "accountId": "123456789012",
                    "userName": "tester",
                  },
              },
          },
        "eventTime": "2019-01-01T00:00:00Z",
        "eventSource": "iam.amazonaws.com",
        "eventName": "CreateUser",
        "awsRegion": "us-east-1",
        "sourceIPAddress": "111.111.111.111",
        "userAgent": "console.amazonaws.com",
        "requestParameters": { "userName": "user", "path": "/" },
        "responseElements": null,
        "requestID": "1",
        "eventID": "1",
        "eventType": "AwsApiCall",
        "recipientAccountId": "123456789012",
      }
  - Name: IAM Entity Created Manually
    ExpectedResult: true
    Log:
      {
        "eventVersion": "1.05",
        "userIdentity":
          {
            "type": "AssumedRole",
            "principalId": "1111:tester",
            "arn": "arn:aws:sts::123456789012:assumed-role/tester",
            "accountId": "123456789012",
            "accessKeyId": "1",
            "sessionContext":
              {
                "attributes":
                  {
                    "mfaAuthenticated": "true",
                    "creationDate": "2019-01-01T00:00:00Z",
                  },
                "sessionIssuer":
                  {
                    "type": "Role",
                    "principalId": "1111",
                    "arn": "arn:aws:iam::123456789012:role/OtherRole",
                    "accountId": "123456789012",
                    "userName": "tester",
                  },
              },
          },
        "eventTime": "2019-01-01T00:00:00Z",
        "eventSource": "iam.amazonaws.com",
        "eventName": "CreateUser",
        "awsRegion": "us-east-1",
        "sourceIPAddress": "111.111.111.111",
        "userAgent": "console.amazonaws.com",
        "requestParameters": { "userName": "user", "path": "/" },
        "responseElements": null,
        "requestID": "1",
        "eventID": "1",
        "eventType": "AwsApiCall",
        "recipientAccountId": "123456789012",
      }
  - Name: Non IAM Entity Creation Event
    ExpectedResult: false
    Log:
      {
        "eventVersion": "1.05",
        "userIdentity":
          {
            "type": "AssumedRole",
            "principalId": "1111:tester",
            "arn": "arn:aws:sts::123456789012:assumed-role/tester",
            "accountId": "123456789012",
            "accessKeyId": "1",
            "sessionContext":
              {
                "attributes":
                  {
                    "mfaAuthenticated": "true",
                    "creationDate": "2019-01-01T00:00:00Z",
                  },
                "sessionIssuer":
                  {
                    "type": "Role",
                    "principalId": "1111",
                    "arn": "arn:aws:iam::123456789012:role/OtherRole",
                    "accountId": "123456789012",
                    "userName": "tester",
                  },
              },
          },
        "eventTime": "2019-01-01T00:00:00Z",
        "eventSource": "iam.amazonaws.com",
        "eventName": "NotCreateUser",
        "awsRegion": "us-east-1",
        "sourceIPAddress": "111.111.111.111",
        "userAgent": "console.amazonaws.com",
        "requestParameters": { "userName": "user", "path": "/" },
        "responseElements": null,
        "requestID": "1",
        "eventID": "1",
        "eventType": "AwsApiCall",
        "recipientAccountId": "123456789012",
      }
  - Name: Error Manually Creating IAM Entity
    ExpectedResult: false
    Log:
      {
        "eventVersion": "1.05",
        "errorCode": "EntityAlreadyExists",
        "userIdentity":
          {
            "type": "AssumedRole",
            "principalId": "1111:tester",
            "arn": "arn:aws:sts::123456789012:assumed-role/tester",
            "accountId": "123456789012",
            "accessKeyId": "1",
            "sessionContext":
              {
                "attributes":
                  {
                    "mfaAuthenticated": "true",
                    "creationDate": "2019-01-01T00:00:00Z",
                  },
                "sessionIssuer":
                  {
                    "type": "Role",
                    "principalId": "1111",
                    "arn": "arn:aws:iam::123456789012:role/OtherRole",
                    "accountId": "123456789012",
                    "userName": "tester",
                  },
              },
          },
        "eventTime": "2019-01-01T00:00:00Z",
        "eventSource": "iam.amazonaws.com",
        "eventName": "CreateUser",
        "awsRegion": "us-east-1",
        "sourceIPAddress": "111.111.111.111",
        "userAgent": "console.amazonaws.com",
        "requestParameters": { "userName": "user", "path": "/" },
        "responseElements": null,
        "requestID": "1",
        "eventID": "1",
        "eventType": "AwsApiCall",
        "recipientAccountId": "123456789012",
      }


# ------ paired body: aws_iam_entity_created_without_cloudformation.py ------

import re

from panther_aws_helpers import aws_cloudtrail_success, aws_rule_context

# The role dedicated for IAM administration
IAM_ADMIN_ROLES = {
    "arn:aws:iam::123456789012:role/IdentityCFNServiceRole",
}

# The role patterns dedicated for IAM Service Roles
IAM_ADMIN_ROLE_PATTERNS = {"arn:aws:iam::[0-9]+:role/IdentityCFNServiceRole"}

# API calls that are indicative of IAM entity creation
IAM_ENTITY_CREATION_EVENTS = {
    "BatchCreateUser",
    "CreateGroup",
    "CreateInstanceProfile",
    "CreatePolicy",
    "CreatePolicyVersion",
    "CreateRole",
    "CreateServiceLinkedRole",
    "CreateUser",
}


def rule(event):
    # Check if this event is in scope
    if (
        not aws_cloudtrail_success(event)
        or event.get("eventName") not in IAM_ENTITY_CREATION_EVENTS
    ):
        return False

    # All IAM changes MUST go through CloudFormation
    if event.deep_get("userIdentity", "invokedBy") != "cloudformation.amazonaws.com":
        return True

    # Only approved IAM Roles can make IAM Changes
    for admin_role_pattern in IAM_ADMIN_ROLE_PATTERNS:
        # Check if the arn matches any role patterns, return False if there is a match
        if (
            len(
                re.findall(
                    admin_role_pattern,
                    event.deep_get("userIdentity", "sessionContext", "sessionIssuer", "arn"),
                )
            )
            > 0
        ):
            return False

    return (
        event.deep_get("userIdentity", "sessionContext", "sessionIssuer", "arn")
        not in IAM_ADMIN_ROLES
    )


def alert_context(event):
    return aws_rule_context(event)

Detection rules belong to the projects that publish them and remain under their own licenses. This site indexes and links to them; it claims no rights in them.