Account Security Configuration Changed


Description

An account wide security configuration was changed.

Query · python

import json
from fnmatch import fnmatch
from unittest.mock import MagicMock

from panther_aws_helpers import aws_cloudtrail_success, aws_rule_context

SECURITY_CONFIG_ACTIONS = {
    "DeleteAccountPublicAccessBlock",
    "DeleteDeliveryChannel",
    "DeleteDetector",
    "DeleteFlowLogs",
    "DeleteRule",
    "DeleteTrail",
    "DisableEbsEncryptionByDefault",
    "DisableRule",
    "StopConfigurationRecorder",
    "StopLogging",
}

ALLOW_LIST = [
    # Add expected events and users here to suppress alerts
    # {"userName": "ExampleUser", "eventName": "DeleteRule"},
]


def rule(event):
    global ALLOW_LIST  # pylint: disable=global-statement
    if isinstance(ALLOW_LIST, MagicMock):
        ALLOW_LIST = json.loads(ALLOW_LIST())  # pylint: disable=not-callable

    if not aws_cloudtrail_success(event):
        return False

    for entry in ALLOW_LIST:
        if fnmatch(
            event.deep_get(
                "userIdentity",
                "sessionContext",
                "sessionIssuer",
                "userName",
                default="",
            ),
            entry["userName"],
        ):
            if fnmatch(event.get("eventName"), entry["eventName"]):
                return False

    if event.get("eventName") == "UpdateDetector":
        return not event.deep_get("requestParameters", "enable", default=True)

    return event.get("eventName") in SECURITY_CONFIG_ACTIONS


def title(event):
    return f"Sensitive AWS API call {event.get('eventName')} made by {event.udm('actor_user')}"


def alert_context(event):
    return aws_rule_context(event)

Analyst notes

Verify that this change was planned. If not, revert the change and update the access control policies to ensure this doesn't happen again.

Raw source Account Security Configuration Changed · Panther Python
Esc
Published by panther-labs/panther-analysis ↗, licensed under Apache 2.0 ↗. Reproduced here unmodified.
AnalysisType: rule
Filename: aws_security_configuration_change.py
RuleID: "AWS.CloudTrail.SecurityConfigurationChange"
DisplayName: "Account Security Configuration Changed"
Enabled: true
LogTypes:
  - AWS.CloudTrail
Tags:
  - AWS
  - Defense Evasion:Impair Defenses
Severity: Medium
Reports:
  MITRE ATT&CK:
    - TA0005:T1562

  Stratus Red Team:
    - aws.defense-evasion.cloudtrail-delete
    - aws.defense-evasion.cloudtrail-stop
    - aws.defense-evasion.vpc-remove-flow-logs
Description: An account wide security configuration was changed.
Runbook: >
  Verify that this change was planned. If not, revert the change and update the access control policies to ensure this doesn't happen again.
Reference: https://docs.aws.amazon.com/prescriptive-guidance/latest/aws-startup-security-baseline/controls-acct.html
SummaryAttributes:
  - eventName
  - userAgent
  - sourceIpAddress
  - recipientAccountId
  - p_any_aws_arns
Tests:
  - Name: Security Configuration Changed
    ExpectedResult: true
    Log:
      {
        "awsRegion": "us-west-2",
        "eventID": "1111",
        "eventName": "DeleteTrail",
        "eventSource": "cloudtrail.amazonaws.com",
        "eventTime": "2019-01-01T00:00:00Z",
        "eventType": "AwsApiCall",
        "eventVersion": "1.05",
        "readOnly": false,
        "recipientAccountId": "123456789012",
        "requestID": "1111",
        "requestParameters": { "name": "example-trail" },
        "responseElements": null,
        "sourceIPAddress": "111.111.111.111",
        "userAgent": "Mozilla/2.0 (compatible; NEWT ActiveX; Win32)",
        "userIdentity":
          {
            "accessKeyId": "1111",
            "accountId": "123456789012",
            "arn": "arn:aws:sts::123456789012:assumed-role/example-role/example-user",
            "invokedBy": "cloudformation.amazonaws.com",
            "principalId": "1111",
            "sessionContext":
              {
                "attributes":
                  {
                    "creationDate": "2019-01-01T00:00:00Z",
                    "mfaAuthenticated": "true",
                  },
                "sessionIssuer":
                  {
                    "accountId": "123456789012",
                    "arn": "arn:aws:iam::123456789012:role/example-role",
                    "principalId": "1111",
                    "type": "Role",
                    "userName": "example-role",
                  },
                "webIdFederationData": {},
              },
            "type": "AssumedRole",
          },
      }
  - Name: Security Configuration Not Changed
    ExpectedResult: false
    Log:
      {
        "awsRegion": "us-west-2",
        "eventID": "1111",
        "eventName": "DescribeTrail",
        "eventSource": "cloudtrail.amazonaws.com",
        "eventTime": "2019-01-01T00:00:00Z",
        "eventType": "AwsApiCall",
        "eventVersion": "1.05",
        "readOnly": false,
        "recipientAccountId": "123456789012",
        "requestID": "1111",
        "requestParameters": { "name": "example-trail" },
        "responseElements": null,
        "sourceIPAddress": "111.111.111.111",
        "userAgent": "Mozilla/2.0 (compatible; NEWT ActiveX; Win32)",
        "userIdentity":
          {
            "accessKeyId": "1111",
            "accountId": "123456789012",
            "arn": "arn:aws:sts::123456789012:assumed-role/example-role/example-user",
            "invokedBy": "cloudformation.amazonaws.com",
            "principalId": "1111",
            "sessionContext":
              {
                "attributes":
                  {
                    "creationDate": "2019-01-01T00:00:00Z",
                    "mfaAuthenticated": "true",
                  },
                "sessionIssuer":
                  {
                    "accountId": "123456789012",
                    "arn": "arn:aws:iam::123456789012:role/example-role",
                    "principalId": "1111",
                    "type": "Role",
                    "userName": "example-role",
                  },
                "webIdFederationData": {},
              },
            "type": "AssumedRole",
          },
      }
  - Name: Non Security Configuration Change
    ExpectedResult: false
    Log:
      {
        "awsRegion": "us-west-2",
        "eventID": "1111",
        "eventName": "PutPolicy",
        "eventSource": "iam.amazonaws.com",
        "eventTime": "2019-01-01T00:00:00Z",
        "eventType": "AwsApiCall",
        "eventVersion": "1.05",
        "readOnly": false,
        "recipientAccountId": "123456789012",
        "requestID": "1111",
        "requestParameters": { "name": "example-trail" },
        "responseElements": null,
        "sourceIPAddress": "111.111.111.111",
        "userAgent": "Mozilla/2.0 (compatible; NEWT ActiveX; Win32)",
        "userIdentity":
          {
            "accessKeyId": "1111",
            "accountId": "123456789012",
            "arn": "arn:aws:sts::123456789012:assumed-role/example-role/example-user",
            "invokedBy": "cloudformation.amazonaws.com",
            "principalId": "1111",
            "sessionContext":
              {
                "attributes":
                  {
                    "creationDate": "2019-01-01T00:00:00Z",
                    "mfaAuthenticated": "true",
                  },
                "sessionIssuer":
                  {
                    "accountId": "123456789012",
                    "arn": "arn:aws:iam::123456789012:role/example-role",
                    "principalId": "1111",
                    "type": "Role",
                    "userName": "example-role",
                  },
                "webIdFederationData": {},
              },
            "type": "AssumedRole",
          },
      }
  - Name: Security Configuration Not Changed - Error
    ExpectedResult: false
    Log:
      {
        "awsRegion": "us-west-2",
        "errorCode": "ConflictException",
        "eventID": "1111",
        "eventName": "DeleteTrail",
        "eventSource": "cloudtrail.amazonaws.com",
        "eventTime": "2019-01-01T00:00:00Z",
        "eventType": "AwsApiCall",
        "eventVersion": "1.05",
        "readOnly": false,
        "recipientAccountId": "123456789012",
        "requestID": "1111",
        "requestParameters": { "name": "example-trail" },
        "responseElements": null,
        "sourceIPAddress": "111.111.111.111",
        "userAgent": "Mozilla/2.0 (compatible; NEWT ActiveX; Win32)",
        "userIdentity":
          {
            "accessKeyId": "1111",
            "accountId": "123456789012",
            "arn": "arn:aws:sts::123456789012:assumed-role/example-role/example-user",
            "invokedBy": "cloudformation.amazonaws.com",
            "principalId": "1111",
            "sessionContext":
              {
                "attributes":
                  {
                    "creationDate": "2019-01-01T00:00:00Z",
                    "mfaAuthenticated": "true",
                  },
                "sessionIssuer":
                  {
                    "accountId": "123456789012",
                    "arn": "arn:aws:iam::123456789012:role/example-role",
                    "principalId": "1111",
                    "type": "Role",
                    "userName": "example-role",
                  },
                "webIdFederationData": {},
              },
            "type": "AssumedRole",
          },
      }
  - Name: Security Configuration Changed - Allowlisted User
    ExpectedResult: false
    Mocks:
      - {
          "objectName": "ALLOW_LIST",
          "returnValue": '[{"userName": "ExampleUser", "eventName": "DeleteRule"}]',
        }
    Log:
      {
        "awsRegion": "us-west-2",
        "eventID": "1111",
        "eventName": "DeleteRule",
        "eventSource": "cloudtrail.amazonaws.com",
        "eventTime": "2019-01-01T00:00:00Z",
        "eventType": "AwsApiCall",
        "eventVersion": "1.05",
        "readOnly": false,
        "recipientAccountId": "123456789012",
        "requestID": "1111",
        "requestParameters": { "name": "example-trail" },
        "responseElements": null,
        "sourceIPAddress": "111.111.111.111",
        "userAgent": "Mozilla/2.0 (compatible; NEWT ActiveX; Win32)",
        "userIdentity":
          {
            "accessKeyId": "1111",
            "accountId": "123456789012",
            "arn": "arn:aws:sts::123456789012:assumed-role/example-role/example-user",
            "invokedBy": "cloudformation.amazonaws.com",
            "principalId": "1111",
            "sessionContext":
              {
                "attributes":
                  {
                    "creationDate": "2019-01-01T00:00:00Z",
                    "mfaAuthenticated": "true",
                  },
                "sessionIssuer":
                  {
                    "accountId": "123456789012",
                    "arn": "arn:aws:iam::123456789012:role/example-role",
                    "principalId": "1111",
                    "type": "Role",
                    "userName": "ExampleUser",
                  },
                "webIdFederationData": {},
              },
            "type": "AssumedRole",
          },
      }


# ------ paired body: aws_security_configuration_change.py ------

import json
from fnmatch import fnmatch
from unittest.mock import MagicMock

from panther_aws_helpers import aws_cloudtrail_success, aws_rule_context

SECURITY_CONFIG_ACTIONS = {
    "DeleteAccountPublicAccessBlock",
    "DeleteDeliveryChannel",
    "DeleteDetector",
    "DeleteFlowLogs",
    "DeleteRule",
    "DeleteTrail",
    "DisableEbsEncryptionByDefault",
    "DisableRule",
    "StopConfigurationRecorder",
    "StopLogging",
}

ALLOW_LIST = [
    # Add expected events and users here to suppress alerts
    # {"userName": "ExampleUser", "eventName": "DeleteRule"},
]


def rule(event):
    global ALLOW_LIST  # pylint: disable=global-statement
    if isinstance(ALLOW_LIST, MagicMock):
        ALLOW_LIST = json.loads(ALLOW_LIST())  # pylint: disable=not-callable

    if not aws_cloudtrail_success(event):
        return False

    for entry in ALLOW_LIST:
        if fnmatch(
            event.deep_get(
                "userIdentity",
                "sessionContext",
                "sessionIssuer",
                "userName",
                default="",
            ),
            entry["userName"],
        ):
            if fnmatch(event.get("eventName"), entry["eventName"]):
                return False

    if event.get("eventName") == "UpdateDetector":
        return not event.deep_get("requestParameters", "enable", default=True)

    return event.get("eventName") in SECURITY_CONFIG_ACTIONS


def title(event):
    return f"Sensitive AWS API call {event.get('eventName')} made by {event.udm('actor_user')}"


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.