Detection rules › Panther

GCP Org or Folder Policy Was Changed Manually

Severity
high
Compliance
GCP_CIS_1.3 1.8
Log types
GCP.AuditLog
Tags
GCP, Identity & Access Management, Persistence, Modify Authentication Process - Conditional Access Policies
Reference
https://cloud.google.com/iam/docs/granting-changing-revoking-access
Source
github.com/panther-labs/panther-analysis

Alert if a GCP Org or Folder Policy Was Changed Manually.

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
Filename: gcp_iam_org_folder_changes.py
RuleID: "GCP.IAM.OrgFolderIAMChanges"
DisplayName: "GCP Org or Folder Policy Was Changed Manually"
Enabled: true
DedupPeriodMinutes: 1440 # 24 hours
LogTypes:
  - GCP.AuditLog
Tags:
  - GCP
  - Identity & Access Management
  - Persistence
  - Modify Authentication Process - Conditional Access Policies 
Reports:
  GCP_CIS_1.3:
    - 1.8
  MITRE ATT&CK:
    - TA0003:T1556.009
Severity: High
Description: >
  Alert if a GCP Org or Folder Policy Was Changed Manually.
Runbook: |
  Contact the party that made the change.
  If it was intended to be temporary, ask for a window for rollback (< 24 hours).
  If it must be permanent, ask for change-management doc explaining why it was needed.
  Direct them to make the change in Terraform to avoid automated rollback.
  Grep for google_org and google_folder in terraform repos for places to
  put your new policy bindings.
Reference: https://cloud.google.com/iam/docs/granting-changing-revoking-access
SummaryAttributes:
  - severity
  - p_any_ip_addresses
Tests:
  - Name: Terraform User Agent
    ExpectedResult: true
    Log:
      {
        "insertId": "-lmjke7dbt7y",
        "logName": "organizations/888888888888/logs/cloudaudit.googleapis.com%2Factivity",
        "p_log_type": "GCP.AuditLog",
        "protoPayload":
          {
            "at_sign_type": "type.googleapis.com/google.cloud.audit.AuditLog",
            "authenticationInfo":
              {
                "principalEmail": "terraform@platform.iam.gserviceaccount.com",
                "principalSubject": "serviceAccount:terraform@platform.iam.gserviceaccount.com",
                "serviceAccountKeyName": "//iam.googleapis.com/projects/platform/serviceAccounts/terraform@platform.iam.gserviceaccount.com/keys/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
              },
            "authorizationInfo":
              [
                {
                  "granted": true,
                  "permission": "resourcemanager.organizations.setIamPolicy",
                  "resource": "organizations/888888888888",
                  "resourceAttributes":
                    {
                      "name": "organizations/888888888888",
                      "service": "cloudresourcemanager.googleapis.com",
                      "type": "cloudresourcemanager.googleapis.com/Organization",
                    },
                },
              ],
            "methodName": "SetIamPolicy",
            "request":
              {
                "@type": "type.googleapis.com/google.iam.v1.SetIamPolicyRequest",
                "policy":
                  {
                    "bindings":
                      [
                        {
                          "members":
                            [
                              "joey.jojo@example.com",
                              "serviceAccount:terraform@platform.iam.gserviceaccount.com",
                            ],
                          "role": "roles/owner",
                        },
                      ],
                    "etag": "BwXcRFUAtX4=",
                  },
                "resource": "organizations/888888888888",
                "updateMask": "bindings,etag,auditConfigs",
              },
            "requestMetadata":
              {
                "callerIP": "100.100.100.100",
                "callerSuppliedUserAgent": "Terraform/0.13.2 terraform-provider-google/3.90.1",
                "destinationAttributes": {},
                "requestAttributes": {},
              },
            "resourceName": "organizations/888888888888",
            "response":
              {
                "@type": "type.googleapis.com/google.iam.v1.Policy",
                "bindings":
                  [
                    {
                      "members":
                        [
                          "joey.jojo@example.com",
                          "serviceAccount:terraform@platform.iam.gserviceaccount.com",
                        ],
                      "role": "roles/owner",
                    },
                  ],
                "etag": "BwXeRCtKxCw=",
              },
            "serviceData":
              {
                "@type": "type.googleapis.com/google.iam.v1.logging.AuditData",
                "policyDelta":
                  {
                    "bindingDeltas":
                      [
                        {
                          "action": "ADD",
                          "member": "user:backdoor@example.com",
                          "role": "roles/owner",
                        },
                      ],
                  },
              },
            "serviceName": "cloudresourcemanager.googleapis.com",
            "status": {},
          },
        "receiveTimestamp": "2022-05-05 14:00:49.450798551",
        "resource":
          {
            "labels": { "organization_id": "888888888888" },
            "type": "organization",
          },
        "severity": "NOTICE",
        "timestamp": "2022-05-05 14:00:48.814294000",
      }
  - Name: Manual Change
    ExpectedResult: true
    Log:
      {
        "insertId": "-yoga2udnx8s",
        "logName": "organizations/888888888888/logs/cloudaudit.googleapis.com%2Factivity",
        "p_log_type": "GCP.AuditLog",
        "protoPayload":
          {
            "@type": "type.googleapis.com/google.cloud.audit.AuditLog",
            "authenticationInfo": { "principalEmail": "chris@example.com" },
            "authorizationInfo":
              [
                {
                  "granted": true,
                  "permission": "resourcemanager.organizations.setIamPolicy",
                  "resource": "organizations/888888888888",
                  "resourceAttributes":
                    {
                      "name": "organizations/888888888888",
                      "service": "cloudresourcemanager.googleapis.com",
                      "type": "cloudresourcemanager.googleapis.com/Organization",
                    },
                },
              ],
            "methodName": "SetIamPolicy",
            "request":
              {
                "@type": "type.googleapis.com/google.iam.v1.SetIamPolicyRequest",
                "etag": "BwXYPRNtbqo=",
                "policy":
                  {
                    "bindings":
                      [
                        {
                          "members":
                            [
                              "user:chris@example.com",
                              "serviceAccount:diana@platform.iam.gserviceaccount.com",
                            ],
                          "role": "roles/owner",
                        },
                      ],
                  },
              },
            "receiveTimestamp": "2022-02-17T22:52:03.190032712Z",
            "requestMetadata":
              {
                "callerIp": "38.38.38.38",
                "callerSuppliedUserAgent": "Mozilla/5.0 Chrome/98.0.4758.102",
                "destinationAttributes": {},
                "requestAttributes": {},
              },
            "resource":
              {
                "labels": { "organization_id": "888888888888" },
                "type": "organization",
              },
            "resourceName": "organizations/888888888888",
            "response":
              {
                "@type": "type.googleapis.com/google.iam.v1.Policy",
                "bindings":
                  [
                    {
                      "members": ["user:chris@example.com"],
                      "role": "roles/owner",
                    },
                  ],
                "etag": "BwXYPp1Xs/Y=",
              },
            "serviceData":
              {
                "@type": "type.googleapis.com/google.iam.v1.logging.AuditData",
                "policyDelta":
                  {
                    "bindingDeltas":
                      [
                        {
                          "action": "REMOVE",
                          "member": "serviceAccount:diana@platform.iam.gserviceaccount.com",
                          "role": "roles/owner",
                        },
                      ],
                  },
              },
          },
        "serviceName": "cloudresourcemanager.googleapis.com",
        "severity": "NOTICE",
        "status": {},
        "timestamp": "2022-02-17T22:52:02.692083Z",
      }

Detection logic

Condition

protoPayload.methodName eq "SetIamPolicy"
logName starts_with "organizations" or logName starts_with "folder"
logName ends_with "/logs/cloudaudit.googleapis.com%2Factivity"

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
logNameends_with
  • /logs/cloudaudit.googleapis.com%2Factivity
logNamestarts_with
  • folder
  • organizations
protoPayload.methodNameeq
  • SetIamPolicy

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
actoractor_user
policy_changeprotoPayload.serviceData.policyDelta
caller_ipprotoPayload.requestMetadata.callerIP
user_agentprotoPayload.requestMetadata.callerSuppliedUserAgent
p_log_type