AWS Compromised IAM Key Quarantine


Description

Detects when an IAM user has the AWSCompromisedKeyQuarantineV2 policy attached to their account.

Query · python

IAM_ACTIONS = {
    "AttachUserPolicy",
    "AttachGroupPolicy",
    "AttachRolePolicy",
}

QUARANTINE_MANAGED_POLICY = "arn:aws:iam::aws:policy/AWSCompromisedKeyQuarantineV2"


def rule(event):
    return all(
        [
            event.get("eventSource", "") == "iam.amazonaws.com",
            event.get("eventName", "") in IAM_ACTIONS,
            event.deep_get("requestParameters", "policyArn", default="")
            == QUARANTINE_MANAGED_POLICY,
        ]
    )


def title(event):
    account_id = event.get("recipientAccountId", "<ACCOUNT_ID_NOT_FOUND>")
    user_name = event.deep_get("requestParameters", "userName", default="<USER_NAME_NOT_FOUND>")
    return f"Compromised Key quarantined for [{user_name}] in AWS Account [{account_id}]"

Analyst notes

Check the quarantined IAM entity's key usage for signs of compromise and follow the instructions outlined in the AWS support case opened regarding this event.

Raw source AWS Compromised IAM Key Quarantine · Panther Python
Esc
Published by panther-labs/panther-analysis ↗, licensed under Apache 2.0 ↗. Reproduced here unmodified.
AnalysisType: rule
LogTypes:
  - AWS.CloudTrail
Description: "Detects when an IAM user has the AWSCompromisedKeyQuarantineV2 policy attached to their account."
DisplayName: "AWS Compromised IAM Key Quarantine"
Enabled: true
RuleID: "AWS.CloudTrail.IAMCompromisedKeyQuarantine"
Filename: aws_iam_compromised_key_quarantine.py
Severity: High
Tags:
  - AWS
  - Identity and Access Management
  - Initial Access:Valid Accounts
  - Credential Access:Unsecured Credentials
Reports:
  MITRE ATT&CK:
    - TA0001:T1078.004
    - TA0006:T1552.001
Runbook: >
  Check the quarantined IAM entity's key usage for signs of compromise and follow the instructions outlined in the AWS support case opened regarding this event.
Reference: https://unit42.paloaltonetworks.com/malicious-operations-of-exposed-iam-keys-cryptojacking/
Threshold: 1
DedupPeriodMinutes: 60
Tests:
  - Name: AttachUserPolicy AWSCompromisedKeyQuarantineV2-true
    ExpectedResult: true
    Log:
      {
        "eventVersion": "1.08",
        "userIdentity":
          {
            "type": "AssumedRole",
            "principalId": "FAKE_PRINCIPAL:user.name",
            "arn": "arn:aws:sts::123456789012:assumed-role/a-role/user.name",
            "accountId": "123456789012",
            "accessKeyId": "FAKE_ACCESS_KEY",
            "sessionContext":
              {
                "sessionIssuer":
                  {
                    "type": "Role",
                    "principalId": "FAKE_PRINCIPAL",
                    "arn": "arn:aws:iam::123456789012:role/a-role",
                    "accountId": "123456789012",
                    "userName": "a-role",
                  },
                "webIdFederationData": {},
                "attributes":
                  {
                    "creationDate": "2023-11-21T22:28:31Z",
                    "mfaAuthenticated": "false",
                  },
              },
          },
        "eventTime": "2023-11-21T23:23:52Z",
        "eventSource": "iam.amazonaws.com",
        "eventName": "AttachUserPolicy",
        "awsRegion": "us-east-1",
        "sourceIPAddress": "1.2.3.4",
        "userAgent": "AWS Internal",
        "requestParameters":
          {
            "userName": "test-user",
            "policyArn": "arn:aws:iam::aws:policy/AWSCompromisedKeyQuarantineV2",
          },
        "responseElements": null,
        "requestID": "a2468e00-2b3c-4696-8056-327a624b5887",
        "eventID": "e7bb4b23-66e1-4656-b607-f575fde3b790",
        "readOnly": false,
        "eventType": "AwsApiCall",
        "managementEvent": true,
        "recipientAccountId": "123456789012",
        "eventCategory": "Management",
        "sessionCredentialFromConsole": "true",
      }
  - Name: PutUserPolicy-false
    ExpectedResult: false
    Log:
      {
        "eventVersion": "1.08",
        "userIdentity":
          {
            "type": "AssumedRole",
            "principalId": "FAKE_PRINCIPAL:evan.gibler",
            "arn": "arn:aws:sts::123456789012:assumed-role/a-role/user.name",
            "accountId": "123456789012",
            "accessKeyId": "FAKE_ACCESS_KEY",
            "sessionContext":
              {
                "sessionIssuer":
                  {
                    "type": "Role",
                    "principalId": "FAKE_PRINCIPAL",
                    "arn": "arn:aws:iam::123456789012:role/a-role",
                    "accountId": "123456789012",
                    "userName": "a-role",
                  },
                "webIdFederationData": {},
                "attributes":
                  {
                    "creationDate": "2023-11-21T22:28:31Z",
                    "mfaAuthenticated": "false",
                  },
              },
          },
        "eventTime": "2023-11-21T23:31:17Z",
        "eventSource": "iam.amazonaws.com",
        "eventName": "PutUserPolicy",
        "awsRegion": "us-east-1",
        "sourceIPAddress": "136.32.237.81",
        "userAgent": "AWS Internal",
        "requestParameters":
          {
            "userName": "test-user",
            "policyName": "TestUserDenyAll",
            "policyDocument": "{\n\t\"Version\": \"2012-10-17\",\n\t\"Statement\": [\n\t\t{\n\t\t\t\"Sid\": \"TestUserDenyAll\",\n\t\t\t\"Effect\": \"Deny\",\n\t\t\t\"Action\": [\"*\"],\n\t\t\t\"Resource\": [\"*\"]\n\t\t}\n\t]\n}",
          },
        "responseElements": null,
        "requestID": "2f59fa44-615c-40b7-a31f-01401e523663",
        "eventID": "7ee6ba6e-1943-417a-a6a3-3a2b0292cdac",
        "readOnly": false,
        "eventType": "AwsApiCall",
        "managementEvent": true,
        "recipientAccountId": "123456789012",
        "eventCategory": "Management",
        "sessionCredentialFromConsole": "true",
      }


# ------ paired body: aws_iam_compromised_key_quarantine.py ------

IAM_ACTIONS = {
    "AttachUserPolicy",
    "AttachGroupPolicy",
    "AttachRolePolicy",
}

QUARANTINE_MANAGED_POLICY = "arn:aws:iam::aws:policy/AWSCompromisedKeyQuarantineV2"


def rule(event):
    return all(
        [
            event.get("eventSource", "") == "iam.amazonaws.com",
            event.get("eventName", "") in IAM_ACTIONS,
            event.deep_get("requestParameters", "policyArn", default="")
            == QUARANTINE_MANAGED_POLICY,
        ]
    )


def title(event):
    account_id = event.get("recipientAccountId", "<ACCOUNT_ID_NOT_FOUND>")
    user_name = event.deep_get("requestParameters", "userName", default="<USER_NAME_NOT_FOUND>")
    return f"Compromised Key quarantined for [{user_name}] in AWS Account [{account_id}]"

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.