Detection rules › Panther

AWS Compromised IAM Key Quarantine

Severity
high
Log types
AWS.CloudTrail
Tags
AWS, Identity and Access Management, Initial Access:Valid Accounts, Credential Access:Unsecured Credentials
Reference
https://unit42.paloaltonetworks.com/malicious-operations-of-exposed-iam-keys-cryptojacking/
Source
github.com/panther-labs/panther-analysis

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

MITRE ATT&CK coverage

Rules detecting the same action

Other rules on this platform that filter on the same API call or operation.

Rule body yaml

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",
      }

Detection logic

Condition

eventSource eq "iam.amazonaws.com"
eventName in ["AttachUserPolicy", "AttachGroupPolicy", "AttachRolePolicy"]
requestParameters.policyArn eq "arn:aws:iam::aws:policy/AWSCompromisedKeyQuarantineV2"

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
eventNamein
  • AttachGroupPolicy
  • AttachRolePolicy
  • AttachUserPolicy
eventSourceeq
  • iam.amazonaws.com
requestParameters.policyArneq
  • arn:aws:iam::aws:policy/AWSCompromisedKeyQuarantineV2

Output fields

Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.

FieldSource
userNamerequestParameters.userName
recipientAccountId