Wiz Alert Passthrough Rule


Description

This rule enriches and contextualizes security alerts generated by Wiz.

Query · python

from panther_base_helpers import deep_get


def rule(event):
    return event.get("status") == "OPEN" and event.get("severity") != "INFORMATIONAL"


def title(event):
    return (
        f"[Wiz Alert]: "
        f"{event.deep_get('sourceRule', 'name', default='ALERT_DESCRIPTION_NOT_FOUND')}"
    )


def severity(event):
    return event.get("severity")


def dedup(event):
    # For lower-severity events, dedup based on specific source rule to reduce overall alert volume
    if event.get("severity") in ("INFO", "LOW"):
        dedup_str = str(event.deep_get("sourceRule", "id"))
        if dedup_str:
            return dedup_str
    # If the severity is higher, or for some reason we couldn't generate a dedup string based on
    #   the source rule, then use the alert severity + the resource ID itself.
    return event.deep_get(
        "entitySnapshot", "externalId", default="<RESOURCE_NOT_FOUND>"
    ) + event.get("severity", "<SEVERITY_NOT_FOUND>")


def description(event):
    return event.deep_get("sourceRule", "controlDescription", default="<DESCRIPTION_NOT_FOUND>")


def reference(event):
    return get_issue_url(event) or "DEFAULT"


def runbook(event):
    return event.deep_get(
        "sourceRule", "resolutionRecommendation", default="<RECOMMENDATION_NOT_FOUND>"
    )


def alert_context(event):
    security_subcategories = event.deep_get("sourceRule", "securitySubCategories", default=[{}])
    return {
        "id": event.get("id", "<ID_NOT_FOUND>"),
        "type": event.get("type", "<TYPE_NOT_FOUND>"),
        "entity_snapshot": event.get("entitySnapshot", {}),
        "entity_url": get_entity_url(event),
        "mitre_attack_categories": [
            subcategory
            for subcategory in security_subcategories
            if deep_get(subcategory, "category", "framework", "name") == "MITRE ATT&CK Matrix"
        ],
    }


def get_issue_url(event):
    if issue_id := event.get("id"):
        return f"https://app.wiz.io/issues#~(issue~'{issue_id})"
    return None  # Return None if there's no issue ID


def get_entity_url(event):
    entity_id = event.deep_get("entitySnapshot", "id")
    entity_type = event.deep_get("entitySnapshot", "type")
    if entity_id and entity_type:
        return f"https://app.wiz.io/issues#~(entity~(~'{entity_id}*2c{entity_type}))"
    return None  # Return None if we're missing the ID or type

Analyst notes

Review the Wiz alert details to determine what malicious behavior was detected, and whether or not it was blocked.

Raw source Wiz Alert Passthrough Rule · Panther Python
Esc
Published by panther-labs/panther-analysis ↗, licensed under Apache 2.0 ↗. Reproduced here unmodified.
AnalysisType: rule
RuleID: Wiz.Alert.Passthrough
Description: This rule enriches and contextualizes security alerts generated by Wiz.
DisplayName: Wiz Alert Passthrough Rule
Runbook: Review the Wiz alert details to determine what malicious behavior was detected, and whether or not it was blocked.
Reference: https://www.wiz.io/product
Enabled: true
Filename: wiz_alert_passthrough.py
Severity: Medium
LogTypes:
  - Wiz.Issues
DedupPeriodMinutes: 720
Threshold: 1
Tests:
  - Name: Open Alert
    ExpectedResult: true
    Log:
      {
          "createdAt": "2024-06-04 02:28:06.763277000",
          "entitySnapshot": {
              "cloudProviderURL": "",
              "externalId": "someExternalId",
              "id": "12345",
              "name": "someName",
              "nativeType": "",
              "providerId": "someProviderId",
              "region": "",
              "resourceGroupExternalId": "",
              "subscriptionExternalId": "",
              "subscriptionName": "",
              "tags": { },
              "type": "DATA_FINDING"
          },
          "id": "54321",
          "notes": [ ],
          "projects": [
              {
                  "businessUnit": "",
                  "id": "45678",
                  "name": "Project 2",
                  "riskProfile": {
                      "businessImpact": "MBI"
                  },
                  "slug": "project-2"
              },
          ],
          "serviceTickets": [ ],
          "severity": "HIGH",
          "sourceRule": {
              "__typename": "Control",
              "controlDescription": "Alert Description",
              "id": "12345",
              "name": "Alert Name",
              "resolutionRecommendation": "Alert Resolution Recommendation",
              "securitySubCategories": [
                {
                  "category": {
                    "framework": {
                      "name": "Wiz for Risk Assessment"
                    },
                    "name": "High Profile Threats"
                  },
                  "title": "High-profile vulnerability exploited in the wild"
                },
                {
                  "category": {
                    "framework": {
                      "name": "MITRE ATT&CK Matrix"
                    },
                    "name": "TA0001 Initial Access"
                  },
                  "title": "T1190 Exploit Public-Facing Application"
                },
              ]
          },
          "status": "OPEN",
          "statusChangedAt": "2024-06-04 02:28:06.597355000",
          "type": "TOXIC_COMBINATION",
          "updatedAt": "2024-06-04 02:28:06.763277000"
      }
  - Name: Low-Severity Open Alert
    ExpectedResult: true
    Log:
      {
          "createdAt": "2024-06-04 02:28:06.763277000",
          "entitySnapshot": {
              "cloudProviderURL": "",
              "externalId": "someExternalId",
              "id": "12345",
              "name": "someName",
              "nativeType": "",
              "providerId": "someProviderId",
              "region": "",
              "resourceGroupExternalId": "",
              "subscriptionExternalId": "",
              "subscriptionName": "",
              "tags": { },
              "type": "DATA_FINDING"
          },
          "id": "54321",
          "notes": [ ],
          "projects": [
              {
                  "businessUnit": "",
                  "id": "45678",
                  "name": "Project 2",
                  "riskProfile": {
                      "businessImpact": "MBI"
                  },
                  "slug": "project-2"
              },
          ],
          "serviceTickets": [ ],
          "severity": "LOW",
          "sourceRule": {
              "__typename": "Control",
              "controlDescription": "Alert Description",
              "id": "12345",
              "name": "Alert Name",
              "resolutionRecommendation": "Alert Resolution Recommendation",
              "securitySubCategories": [
                {
                  "category": {
                    "framework": {
                      "name": "Wiz for Risk Assessment"
                    },
                    "name": "High Profile Threats"
                  },
                  "title": "High-profile vulnerability exploited in the wild"
                },
                {
                  "category": {
                    "framework": {
                      "name": "MITRE ATT&CK Matrix"
                    },
                    "name": "TA0001 Initial Access"
                  },
                  "title": "T1190 Exploit Public-Facing Application"
                },
              ]
          },
          "status": "OPEN",
          "statusChangedAt": "2024-06-04 02:28:06.597355000",
          "type": "TOXIC_COMBINATION",
          "updatedAt": "2024-06-04 02:28:06.763277000"
      }
  - Name: Resolved Alert
    ExpectedResult: false
    Log:
      {
          "createdAt": "2024-06-04 02:28:06.763277000",
          "entitySnapshot": {
              "cloudProviderURL": "",
              "externalId": "someExternalId",
              "id": "12345",
              "name": "someName",
              "nativeType": "",
              "providerId": "someProviderId",
              "region": "",
              "resourceGroupExternalId": "",
              "subscriptionExternalId": "",
              "subscriptionName": "",
              "tags": { },
              "type": "DATA_FINDING"
          },
          "id": "54321",
          "notes": [ ],
          "projects": [
              {
                  "businessUnit": "",
                  "id": "45678",
                  "name": "Project 2",
                  "riskProfile": {
                      "businessImpact": "MBI"
                  },
                  "slug": "project-2"
              },
          ],
          "serviceTickets": [ ],
          "severity": "HIGH",
          "sourceRule": {
              "__typename": "Control",
              "controlDescription": "Alert Description",
              "id": "12345",
              "name": "Alert Name",
              "resolutionRecommendation": "Alert Resolution Recommendation"
          },
          "status": "RESOLVED",
          "statusChangedAt": "2024-06-04 02:28:06.597355000",
          "type": "TOXIC_COMBINATION",
          "updatedAt": "2024-06-04 02:28:06.763277000"
      }


# ------ paired body: wiz_alert_passthrough.py ------

from panther_base_helpers import deep_get


def rule(event):
    return event.get("status") == "OPEN" and event.get("severity") != "INFORMATIONAL"


def title(event):
    return (
        f"[Wiz Alert]: "
        f"{event.deep_get('sourceRule', 'name', default='ALERT_DESCRIPTION_NOT_FOUND')}"
    )


def severity(event):
    return event.get("severity")


def dedup(event):
    # For lower-severity events, dedup based on specific source rule to reduce overall alert volume
    if event.get("severity") in ("INFO", "LOW"):
        dedup_str = str(event.deep_get("sourceRule", "id"))
        if dedup_str:
            return dedup_str
    # If the severity is higher, or for some reason we couldn't generate a dedup string based on
    #   the source rule, then use the alert severity + the resource ID itself.
    return event.deep_get(
        "entitySnapshot", "externalId", default="<RESOURCE_NOT_FOUND>"
    ) + event.get("severity", "<SEVERITY_NOT_FOUND>")


def description(event):
    return event.deep_get("sourceRule", "controlDescription", default="<DESCRIPTION_NOT_FOUND>")


def reference(event):
    return get_issue_url(event) or "DEFAULT"


def runbook(event):
    return event.deep_get(
        "sourceRule", "resolutionRecommendation", default="<RECOMMENDATION_NOT_FOUND>"
    )


def alert_context(event):
    security_subcategories = event.deep_get("sourceRule", "securitySubCategories", default=[{}])
    return {
        "id": event.get("id", "<ID_NOT_FOUND>"),
        "type": event.get("type", "<TYPE_NOT_FOUND>"),
        "entity_snapshot": event.get("entitySnapshot", {}),
        "entity_url": get_entity_url(event),
        "mitre_attack_categories": [
            subcategory
            for subcategory in security_subcategories
            if deep_get(subcategory, "category", "framework", "name") == "MITRE ATT&CK Matrix"
        ],
    }


def get_issue_url(event):
    if issue_id := event.get("id"):
        return f"https://app.wiz.io/issues#~(issue~'{issue_id})"
    return None  # Return None if there's no issue ID


def get_entity_url(event):
    entity_id = event.deep_get("entitySnapshot", "id")
    entity_type = event.deep_get("entitySnapshot", "type")
    if entity_id and entity_type:
        return f"https://app.wiz.io/issues#~(entity~(~'{entity_id}*2c{entity_type}))"
    return None  # Return None if we're missing the ID or type

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.