Detection rules › Panther
Panther rules: wiz
Wiz Alert Passthrough Rule
#This is a third-party alert feed, not a detection over modeled telemetry. Another security product raised the finding; this rule forwards or reshapes it into the SIEM. It is searchable for reference but is excluded from the detection-rule browse and the ATT&CK coverage matrix.
This rule enriches and contextualizes security alerts generated by Wiz.
Detection logic
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
Rule specification
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
Stages and Predicates
Fires on Wiz.Issues events when all of the conditions below hold.
Condition
statusisOPENseverityis notINFORMATIONAL
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
severity | ne |
| field:"severity" kind:ne value:"INFORMATIONAL" |
status | eq |
| field:"status" kind:eq value:"OPEN" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
id | |
type | |
entity_snapshot | entitySnapshot |
name | sourceRule.name |
Response runbook
Review the Wiz alert details to determine what malicious behavior was detected, and whether or not it was blocked.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"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"
}
Wiz CICD Scan Policy Updated Or Deleted
#This rule detects updates and deletions of CICD scan policies.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Defense Impairment |
Detection logic
from panther_wiz_helpers import wiz_actor, wiz_alert_context, wiz_success
SUSPICIOUS_ACTIONS = ["DeleteCICDScanPolicy", "UpdateCICDScanPolicy"]
def rule(event):
if not wiz_success(event):
return False
return event.get("action", "ACTION_NOT_FOUND") in SUSPICIOUS_ACTIONS
def title(event):
actor = wiz_actor(event)
return (
f"[Wiz]: [{event.get('action', 'ACTION_NOT_FOUND')}] action "
f"performed by {actor.get('type')} [{actor.get('name')}]"
)
def dedup(event):
return event.get("id")
def alert_context(event):
return wiz_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Wiz.CICD.Scan.Policy.Updated.Or.Deleted
Description: This rule detects updates and deletions of CICD scan policies.
DisplayName: Wiz CICD Scan Policy Updated Or Deleted
Runbook: Verify that this change was planned. If not, revert the change and ensure this doesn't happen again.
Reference: https://www.wiz.io/academy/ci-cd-security-best-practices
Enabled: true
Filename: wiz_cicd_scan_policy_updated_or_deleted.py
Severity: Medium
Reports:
MITRE ATT&CK:
- TA0005:T1562.001 # Impair Defenses: Disable or Modify Tools
LogTypes:
- Wiz.Audit
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on Wiz.Audit events when all of the conditions below hold.
Condition
statusisSUCCESSactionis one ofDeleteCICDScanPolicy,UpdateCICDScanPolicy
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
action | in |
| field:"action" kind:in |
status | eq |
| field:"status" kind:eq value:"SUCCESS" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
action | |
source_ip | sourceip |
event_id | id |
action_parameters | actionparameters |
Response runbook
Verify that this change was planned. If not, revert the change and ensure this doesn't happen again.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"action": "DeleteCICDScanPolicy",
"actionparameters": {
"input": {
"id": "12345-cd1f-4a4b-b3e4-12345"
}
},
"id": "12345-de20-4e00-b958-12345",
"log_type": null,
"requestid": "12345-284b-4166-aea7-12345",
"serviceaccount": null,
"sourceip": "8.8.8.8",
"status": "SUCCESS",
"timestamp": "2023-09-01 14:27:42.694",
"user": {
"id": "test@company.com",
"name": "test@company.com"
}
}
Wiz Connector Updated Or Deleted
#This rule detects updates and deletions of connectors.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Defense Impairment |
Detection logic
from panther_wiz_helpers import wiz_actor, wiz_alert_context, wiz_success
SUSPICIOUS_ACTIONS = ["DeleteConnector", "UpdateConnector"]
def rule(event):
if not wiz_success(event):
return False
return event.get("action", "ACTION_NOT_FOUND") in SUSPICIOUS_ACTIONS
def title(event):
actor = wiz_actor(event)
return (
f"[Wiz]: [{event.get('action', 'ACTION_NOT_FOUND')}] action "
f"performed by {actor.get('type')} [{actor.get('name')}]"
)
def dedup(event):
return event.get("id")
def alert_context(event):
return wiz_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Wiz.Connector.Updated.Or.Deleted
Description: This rule detects updates and deletions of connectors.
DisplayName: Wiz Connector Updated Or Deleted
Runbook: Verify that this change was planned. If not, revert the change and ensure this doesn't happen again.
Reference: https://help.vulcancyber.com/en/articles/6735270-wiz-connector # article about integration with Vulcan
Enabled: true
Filename: wiz_connector_updated_or_deleted.py
Severity: Medium
Reports:
MITRE ATT&CK:
- TA0005:T1562.001 # Impair Defenses: Disable or Modify Tools
LogTypes:
- Wiz.Audit
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on Wiz.Audit events when all of the conditions below hold.
Condition
statusisSUCCESSactionis one ofDeleteConnector,UpdateConnector
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
action | in |
| field:"action" kind:in |
status | eq |
| field:"status" kind:eq value:"SUCCESS" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
action | |
source_ip | sourceip |
event_id | id |
action_parameters | actionparameters |
Response runbook
Verify that this change was planned. If not, revert the change and ensure this doesn't happen again.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"action": "DeleteConnector",
"actionParameters": {
"input": {
"id": "7a55031b-98f4-4a64-b77c-ad0bc9d7b54b"
},
"selection": [
"__typename",
"_stub"
]
},
"id": "c4fe1656-23a3-4b60-a689-d59a337c5551",
"requestId": "471b9148-887a-49ff-ad83-162d7e38cf4e",
"serviceAccount": null,
"sourceIP": "12.34.56.78",
"status": "SUCCESS",
"timestamp": "2024-07-09T08:03:09.825336Z",
"user": {
"id": "test.user@company.com",
"name": "user@company.com"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"
}
Wiz Data Classifier Updated Or Deleted
#This rule detects updates and deletions of data classifiers.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Defense Impairment |
Detection logic
from panther_wiz_helpers import wiz_actor, wiz_alert_context, wiz_success
SUSPICIOUS_ACTIONS = ["DeleteDataClassifier", "UpdateDataClassifier"]
def rule(event):
if not wiz_success(event):
return False
return event.get("action", "ACTION_NOT_FOUND") in SUSPICIOUS_ACTIONS
def title(event):
actor = wiz_actor(event)
return (
f"[Wiz]: [{event.get('action', 'ACTION_NOT_FOUND')}] action "
f"performed by {actor.get('type')} [{actor.get('name')}]"
)
def dedup(event):
return event.get("id")
def alert_context(event):
return wiz_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Wiz.Data.Classifier.Updated.Or.Deleted
Description: This rule detects updates and deletions of data classifiers.
DisplayName: Wiz Data Classifier Updated Or Deleted
Runbook: Verify that this change was planned. If not, revert the change and ensure this doesn't happen again.
Reference: https://www.wiz.io/solutions/dspm
Enabled: true
Filename: wiz_data_classifier_updated_or_deleted.py
Severity: Medium
Reports:
MITRE ATT&CK:
- TA0005:T1562.001 # Impair Defenses: Disable or Modify Tools
LogTypes:
- Wiz.Audit
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on Wiz.Audit events when all of the conditions below hold.
Condition
statusisSUCCESSactionis one ofDeleteDataClassifier,UpdateDataClassifier
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
action | in |
| field:"action" kind:in |
status | eq |
| field:"status" kind:eq value:"SUCCESS" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
action | |
source_ip | sourceip |
event_id | id |
action_parameters | actionparameters |
Response runbook
Verify that this change was planned. If not, revert the change and ensure this doesn't happen again.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"action": "DeleteDataClassifier",
"actionparameters": {
"input": {
"id": "CUSTOM-12345-c697-4c0f-9689-12345"
},
"selection": [
"__typename",
"_stub"
]
},
"id": "12345-2df6-4c45-838f-12345",
"log_type": "auditLogEntries",
"requestid": "12435-b44f-4216-ad13-12345",
"serviceaccount": null,
"sourceip": "8.8.8.8",
"status": "SUCCESS",
"timestamp": "2024-07-31 18:10:36.936",
"user": {
"id": "test@company.com",
"name": "test@company.com"
},
"useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
}
Wiz Defend Alert Passthrough Rule
#This rule enriches and contextualizes security alerts generated by Wiz.
Detection logic
def rule(event):
return event.get("severity") != "INFORMATIONAL"
def title(event):
return f"[Wiz Alert]: " f"{event.get('tdrId')}"
def severity(event):
sev = (event.get("severity", "") or "").upper()
if sev == "INFORMATIONAL":
return "INFO"
if sev in ("INFO", "LOW", "MEDIUM", "HIGH", "CRITICAL"):
return sev
return "DEFAULT"
def dedup(event):
# For lower-severity events, dedup based on specific source rule to reduce overall alert volume
if event.get("severity") in ("INFO", "INFORMATIONAL", "LOW"):
dedup_str = str(event.get("tdrId"))
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.get("threatId") + "_" + event.get("severity", "<SEVERITY_NOT_FOUND>")
def description(event):
return event.get("description")
def alert_context(event):
return {
"machine_id": event.deep_get("primaryResource", "externalId", default="<ID_NOT_FOUND>"),
"machine_type": event.deep_get("primaryResource", "type", default="<TYPE_NOT_FOUND>"),
"native_type": event.deep_get("primaryResource", "nativeType", default="<TYPE_NOT_FOUND>"),
"machine_name": event.deep_get("primaryResource", "name", default="<NAME_NOT_FOUND>"),
"mitre_attack_techniques": event.get("mitreTechniques"),
}
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 reference(event):
return get_issue_url(event) or "DEFAULT"
Rule specification
AnalysisType: rule
RuleID: Wiz.Defend.Alert.Passthrough
Description: This rule enriches and contextualizes security alerts generated by Wiz.
DisplayName: Wiz Defend 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_defend_passthrough.py
Severity: Medium
LogTypes:
- Wiz.Detections
DedupPeriodMinutes: 720
Threshold: 1
Stages and Predicates
Fires on Wiz.Detections events when the condition below holds.
Condition
severityis notINFORMATIONAL
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
severity | ne |
| field:"severity" kind:ne value:"INFORMATIONAL" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
machine_id | primaryResource.externalId |
machine_type | primaryResource.type |
native_type | primaryResource.nativeType |
machine_name | primaryResource.name |
mitre_attack_techniques | mitreTechniques |
tdrId |
Response runbook
Review the Wiz alert details to determine what malicious behavior was detected, and whether or not it was blocked.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"actors": [
{
"externalId": "1.1.1.1",
"id": "d16d839c-e1ea-5a8f-ac34-01750288bb6f",
"name": "1.1.1.1",
"type": "NETWORK_ADDRESS"
}
],
"cloudAccounts": [
{
"cloudPlatform": "AWS",
"externalId": 123456789,
"id": "12345-6de7-581a-9263-24f9d2172a05",
"name": "Your-Account"
}
],
"createdAt": "2025-10-23 23:15:59.818948801",
"description": "An EC2 instance has an unprotected port 1433 that is being probed by a known malicious host. This rule's final severity is assigned dynamically according to the severity assigned by GuardDuty.",
"id": "3a65eac1-b8ff-5eb8-8727-5e6cde9c39f3",
"mitreTactics": [
"TA0043",
"TA0007",
"TA0007"
],
"mitreTechniques": [
"TA0043-T1595",
"TA0007-T1046",
"TA0007-T1046"
],
"p_any_actor_ids": [
"d16d839c-e1ea-5a8f-ac34-01750288bb6f"
],
"p_any_domain_names": [
"app.wiz.io",
"console.aws.amazon.com"
],
"p_any_ip_addresses": [
"1.1.1.1"
],
"p_event_time": "2025-10-23 23:15:59.818948801",
"p_log_type": "Wiz.Detections",
"p_parse_time": "2025-10-23 23:24:46.965519396",
"p_row_id": "0000000000fa6bce74e7bf1b819f4e4c",
"p_schema_version": 0,
"p_source_id": "26c0c4b6-781c-40fa-9bc4-5bd16f8e5dda",
"p_source_label": "your-wiz-webhook",
"p_udm": {},
"primaryActor": {
"externalId": "1.1.1.1",
"id": "d16d839c-e1ea-5a8f-ac34-01750288bb6f",
"name": "1.1.1.1",
"type": "NETWORK_ADDRESS"
},
"primaryResource": {
"cloudAccount": {
"cloudPlatform": "AWS",
"externalId": 123456789,
"id": "12345678-1ab2-111a-1234-1234f9d123a01"
},
"externalId": "i-ABCDEF1234567890A",
"id": "12ab345c-678d-9efg-123h-45678a1a1111",
"name": "Your-EC2-Instance",
"nativeType": "EC2 Instance",
"region": "eu-central-1",
"type": "VIRTUAL_MACHINE"
},
"resources": [
{
"cloudAccount": {
"cloudPlatform": "AWS",
"externalId": 123456789,
"id": "12345678-1ab2-111a-1234-1234f9d123a01",
"name": "Your-Account"
},
"externalId": "i-ABCDEF1234567890A",
"id": "12ab345c-678d-9efg-123h-45678a1a1111",
"name": "Your-EC2-Instance",
"nativeType": "EC2 Instance",
"region": "eu-central-1",
"status": "Active",
"type": "VIRTUAL_MACHINE"
}
],
"severity": "HIGH",
"tdrId": "cer-awsguardduty-recon-ec2-portprobeunprotectedport",
"tdrSource": "GUARD_DUTY",
"threatId": "9a3032dc-4697-5d6d-b0f0-905668f63781",
"threatURL": "https://app.wiz.io/issues#~(issue~'9a3032dc-4697-5d6d-b0f0-905668f63781)",
"timeframe": {
"end": "2025-10-23 22:53:23.795000000",
"start": "2025-10-23 22:53:23.795000000"
},
"title": "Recon:EC2/PortProbeUnprotectedPort",
"trigger": {
"ruleId": "73ef6bc5-556b-4317-b0bf-6f5f0aa9605b",
"ruleName": "wiz-defend-detections",
"source": "DETECTIONS",
"type": "Created"
},
"triggeringEvents": [
{
"actor": {
"externalId": "1.1.1.1",
"id": "d16d839c-e1ea-5a8f-ac34-01750288bb6f",
"name": "1.1.1.1",
"type": "NETWORK_ADDRESS"
},
"actorIP": "1.1.1.1",
"actorIPMeta": {
"autonomousSystemNumber": 12555,
"autonomousSystemOrganization": "Data-center IMAQLIQ Ltd.",
"country": "Russia",
"customIPRanges": [],
"isForeign": true,
"relatedAttackGroupNames": [],
"reputation": "Suspicious",
"reputationSource": "Recorded Future"
},
"category": "Detection",
"cloudPlatform": "AWS",
"cloudProviderUrl": "https://console.aws.amazon.com/cloudtrail/home?region=eu-central-1#/events/arn:aws:guardduty:eu-central-1:111111111111:detector/12345678910/finding/12345678910",
"description": "An EC2 instance has an unprotected port which is being probed by a known malicious host.",
"eventTime": "2025-10-23 22:53:23.795000000",
"externalId": "arn:aws:guardduty:eu-central-1:111111111111:detector/12345678910/finding/12345678910",
"id": "0068fab1-e301-8ec1-a4e2-9e708323f373",
"name": "GuardDuty: Recon:EC2/PortProbeUnprotectedPort",
"origin": "AWS_GUARD_DUTY",
"resources": [
{
"externalId": "i-ABCDEF1234567890A",
"id": "12ab345c-678d-9efg-123h-45678a1a1111",
"name": "Your-Machine",
"nativeType": "virtualMachine",
"region": "eu-central-1",
"type": "VIRTUAL_MACHINE"
}
],
"source": "guardduty",
"status": "Success"
}
],
"triggeringEventsCount": 1
}
Wiz Image Integrity Validator Updated Or Deleted
#This rule detects updates and deletions of image integrity validators.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Defense Impairment |
Detection logic
from panther_wiz_helpers import wiz_actor, wiz_alert_context, wiz_success
SUSPICIOUS_ACTIONS = ["DeleteImageIntegrityValidator", "UpdateImageIntegrityValidator"]
def rule(event):
if not wiz_success(event):
return False
return event.get("action", "ACTION_NOT_FOUND") in SUSPICIOUS_ACTIONS
def title(event):
actor = wiz_actor(event)
return (
f"[Wiz]: [{event.get('action', 'ACTION_NOT_FOUND')}] action "
f"performed by {actor.get('type')} [{actor.get('name')}]"
)
def dedup(event):
return event.get("id")
def alert_context(event):
return wiz_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Wiz.Image.Integrity.Validator.Updated.Or.Deleted
Description: This rule detects updates and deletions of image integrity validators.
DisplayName: Wiz Image Integrity Validator Updated Or Deleted
Runbook: Verify that this change was planned. If not, revert the change and ensure this doesn't happen again.
Reference: https://www.wiz.io/blog/ensuring-supply-chain-security-verify-container-image-integrity-with-the-wiz-admi
Enabled: true
Filename: wiz_image_integrity_validator_updated_or_deleted.py
Severity: Medium
Reports:
MITRE ATT&CK:
- TA0005:T1562.001 # Impair Defenses: Disable or Modify Tools
LogTypes:
- Wiz.Audit
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on Wiz.Audit events when all of the conditions below hold.
Condition
statusisSUCCESSactionis one ofDeleteImageIntegrityValidator,UpdateImageIntegrityValidator
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
action | in |
| field:"action" kind:in |
status | eq |
| field:"status" kind:eq value:"SUCCESS" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
action | |
source_ip | sourceip |
event_id | id |
action_parameters | actionparameters |
Response runbook
Verify that this change was planned. If not, revert the change and ensure this doesn't happen again.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"action": "DeleteImageIntegrityValidator",
"actionparameters": {
"input": {
"id": "12345-5273-4bcb-9bd6-12345"
},
"selection": [
"_stub"
]
},
"id": "12345-362c-494a-b601-12345",
"log_type": "auditLogEntries",
"requestid": "12345-6532-4130-bb3a-12345",
"serviceaccount": {
"id": "test",
"name": "test1"
},
"sourceip": "8.8.8.8",
"status": "SUCCESS",
"timestamp": "2024-04-16 21:45:03.392",
"user": null,
"useragent": "Terraform-Provider/1.10.2360"
}
Wiz Integration Updated Or Deleted
#This rule detects updates and deletions of Wiz integrations.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Defense Impairment |
Detection logic
from panther_wiz_helpers import wiz_actor, wiz_alert_context, wiz_success
SUSPICIOUS_ACTIONS = ["DeleteIntegration", "UpdateIntegration"]
def rule(event):
if not wiz_success(event):
return False
return event.get("action", "ACTION_NOT_FOUND") in SUSPICIOUS_ACTIONS
def title(event):
actor = wiz_actor(event)
return (
f"[Wiz]: [{event.get('action', 'ACTION_NOT_FOUND')}] action "
f"performed by {actor.get('type')} [{actor.get('name')}]"
)
def dedup(event):
return event.get("id")
def alert_context(event):
return wiz_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Wiz.Integration.Updated.Or.Deleted
Description: This rule detects updates and deletions of Wiz integrations.
DisplayName: Wiz Integration Updated Or Deleted
Runbook: Verify that this change was planned. If not, revert the change and ensure this doesn't happen again.
Reference: https://www.wiz.io/integrations
Enabled: true
Filename: wiz_integration_updated_or_deleted.py
Severity: Medium
Reports:
MITRE ATT&CK:
- TA0005:T1562.001 # Impair Defenses: Disable or Modify Tools
LogTypes:
- Wiz.Audit
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on Wiz.Audit events when all of the conditions below hold.
Condition
statusisSUCCESSactionis one ofDeleteIntegration,UpdateIntegration
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
action | in |
| field:"action" kind:in |
status | eq |
| field:"status" kind:eq value:"SUCCESS" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
action | |
source_ip | sourceip |
event_id | id |
action_parameters | actionparameters |
Response runbook
Verify that this change was planned. If not, revert the change and ensure this doesn't happen again.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"action": "DeleteIntegration",
"actionParameters": {
"input": {
"id": "ab4ab152-509c-425b-aa1f-601b386dfe3f"
},
"selection": [
"__typename",
"_stub"
]
},
"id": "62e490d5-484c-4c21-a2ed-b6ebcaaa5aad",
"log_type": "auditLogEntries",
"requestId": "bc968f65-060c-40a0-85de-3d74d02d6a54",
"sourceIP": "12.34.56.78",
"status": "SUCCESS",
"timestamp": "2024-06-27 09:19:08.731355000",
"user": {
"id": "test.user@company.com",
"name": "user@company.com"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"
}
Wiz Issue Alert Passthrough Rule
#This is a third-party alert feed, not a detection over modeled telemetry. Another security product raised the finding; this rule forwards or reshapes it into the SIEM. It is searchable for reference but is excluded from the detection-rule browse and the ATT&CK coverage matrix.
This rule enriches and contextualizes security alerts generated by Wiz.
Detection logic
def rule(event):
return (
event.deep_get("issue", "status") == "OPEN"
and event.deep_get("issue", "severity") != "INFORMATIONAL"
)
def title(event):
return f"[Wiz Alert]: " f"{event.deep_get('control', 'name', default='ALERT_NAME_NOT_FOUND')}"
def severity(event):
return event.deep_get("issue", "severity")
def dedup(event):
if event.deep_get("issue", "severity") in ("INFO", "LOW"):
# If Wiz's severity is INFO or LOW, dedup on rule ID
dedup_str = event.deep_get("control", "id", default="<NO_ID_FOUND>")
if dedup_str:
return dedup_str
# If higher severity, dedup on the issue ID
return (
event.deep_get("issue", "id", default="<ISSUE_ID_NOT_FOUND>")
+ "_"
+ event.deep_get("issue", "severity", default="<SEVERITY_NOT_FOUND>")
)
def description(event):
return event.deep_get("control", "description", default="<DESCRIPTION_NOT_FOUND>")
def reference(event):
return get_issue_url(event) or "DEFAULT"
def alert_context(event):
return {
"id": event.deep_get("resource", "id") or "<ID_NOT_FOUND>",
"type": event.deep_get("resource", "type") or "<TYPE_NOT_FOUND>",
"name": event.deep_get("resource", "name") or "<NAME_NOT_FOUND>",
}
def get_issue_url(event):
if issue_id := event.deep_get("issue", "id"):
return f"https://app.wiz.io/issues#~(issue~'{issue_id})"
return None # Return None if there's no issue ID
Rule specification
AnalysisType: rule
RuleID: Wiz.Issue.Alert.Passthrough
Description: This rule enriches and contextualizes security alerts generated by Wiz.
DisplayName: Wiz Issue 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_issue_alert_passthrough.py
Severity: Medium
LogTypes:
- Wiz.IssuesWebhook
DedupPeriodMinutes: 720
Threshold: 1
Stages and Predicates
Fires on Wiz.IssuesWebhook events when all of the conditions below hold.
Condition
issue.statusisOPENissue.severityis notINFORMATIONAL
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
issue.severity | ne |
| field:"issue.severity" kind:ne value:"INFORMATIONAL" |
issue.status | eq |
| field:"issue.status" kind:eq value:"OPEN" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
id | resource.id |
type | resource.type |
name | resource.name |
name | control.name |
Response runbook
Review the Wiz alert details to determine what malicious behavior was detected, and whether or not it was blocked.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"control": {
"description": "An EC2 instance has an unprotected port that is being probed by a known malicious host. This rule's final severity is assigned dynamically according to the severity assigned by GuardDuty.",
"id": "cer-awsguardduty-recon-ec2-portprobeunprotectedport",
"name": "Recon:EC2/PortProbeUnprotectedPort",
"risks": [],
"severity": "HIGH"
},
"issue": {
"created": "2025-07-25 13:09:25.306109000",
"id": "e3188a71-794c-5ee8-b97c-eb794aa5b752",
"projects": "",
"severity": "HIGH",
"status": "OPEN"
},
"p_event_time": "2025-07-25 13:09:25.306109000",
"p_log_type": "Wiz.IssuesWebhook",
"p_parse_time": "2025-10-24 05:04:47.058502203",
"p_row_id": "eac735a1259bfda5e5fbf9da29a504",
"p_schema_version": 0,
"p_source_id": "26c0c4b6-781c-40fa-9bc4-5bd16f8e5dda",
"p_source_label": "wiz-issue-webhook",
"p_udm": {},
"resource": {
"cloudPlatform": "AWS",
"cloudProviderURL": "",
"id": "",
"name": "jenkins-aws",
"region": "us-east-2",
"status": "",
"subscriptionId": "111111111111",
"subscriptionName": "My-Subscription",
"type": "virtualMachine"
},
"trigger": {
"ruleId": "710a481b-3066-439f-9612-3f103afce604",
"ruleName": "issue-updates",
"source": "ISSUE",
"type": "Open"
}
}
Wiz Issue WITH SSH to EC2 Instance
#Wiz detected a security issue with an EC2 instance followed by an SSH connection to the instance. This sequence could indicate a potential security breach.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Lateral Movement |
Rule specification
AnalysisType: correlation_rule
RuleID: "Wiz.Issue.WITH.SSH"
DisplayName: "Wiz Issue WITH SSH to EC2 Instance"
Enabled: false
Severity: High
Tags:
- Configuration Required
Description: Wiz detected a security issue with an EC2 instance followed by an SSH connection to the instance. This sequence could indicate a potential security breach.
Reports:
MITRE ATT&CK:
- TA0008:T1021.004 # Lateral Movement: Remote Services: SSH
- TA0001:T1133 # Initial Access: External Remote Services
Detection:
- Group:
- ID: WizIssue
RuleID: Wiz.Alert.Passthrough
- ID: SSH Access
RuleID: AWS.VPC.SSHAllowedSignal
MatchCriteria:
field_name:
- GroupID: WizIssue
Match: entitySnapshot.externalId
- GroupID: SSH Access
Match: instanceId
LookbackWindowMinutes: 1800
Schedule:
RateMinutes: 1440
TimeoutMinutes: 5
Stages and Predicates
Fires when the steps below all occur within 30h, correlated by entitySnapshot.externalId, instanceId. Each step needs one match unless a higher minimum is shown.
Stage 1: step WizIssue
References detection Wiz Alert Passthrough Rule.
Stage 2: step SSH Access
References detection Signal - VPC Flow Logs Allowed SSH.
Wiz Revoke User Sessions
#This rule detects user sessions revoked.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Impact |
Detection logic
from panther_wiz_helpers import wiz_actor, wiz_alert_context, wiz_success
def rule(event):
if not wiz_success(event):
return False
return event.get("action", "ACTION_NOT_FOUND") == "RevokeUserSessions"
def title(event):
actor = wiz_actor(event)
return (
f"[Wiz]: [{event.get('action', 'ACTION_NOT_FOUND')}] action "
f"performed by {actor.get('type')} [{actor.get('name')}]"
)
def dedup(event):
return event.get("id")
def alert_context(event):
return wiz_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Wiz.Revoke.User.Sessions
Description: This rule detects user sessions revoked.
DisplayName: Wiz Revoke User Sessions
Runbook: Verify that this change was planned. If not, revoke all the sessions of the account and change its credentials
Reference: https://www.wiz.io/blog/storm-0558-compromised-microsoft-key-enables-authentication-of-countless-micr
Enabled: true
Filename: wiz_revoke_user_sessions.py
Severity: Medium
Reports:
MITRE ATT&CK:
- TA0040:T1531 # Account Access Removal
LogTypes:
- Wiz.Audit
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on Wiz.Audit events when all of the conditions below hold.
Condition
statusisSUCCESSactionisRevokeUserSessions
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
action | eq |
| field:"action" kind:eq value:"RevokeUserSessions" |
status | eq |
| field:"status" kind:eq value:"SUCCESS" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
action | |
source_ip | sourceip |
event_id | id |
action_parameters | actionparameters |
Response runbook
Verify that this change was planned. If not, revoke all the sessions of the account and change its credentials
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"action": "RevokeUserSessions",
"actionParameters": {
"input": {
"id": "<redacted>"
},
"selection": [
"__typename",
"_stub"
]
},
"id": "07fdb41e-e83d-46e2-814a-6cebc47acf97",
"requestId": "5fa96b8f-2c85-4c2d-b0f9-d4a4307ea8a7",
"serviceAccount": null,
"sourceIP": "12.34.56.78",
"status": "SUCCESS",
"timestamp": "2024-07-31T17:55:29.239928Z",
"user": {
"id": "test.user@company.com",
"name": "user@company.com"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"
}
Wiz Rotate Service Account Secret
#This rule detects service account secrets rotations.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Initial Access |
Detection logic
from panther_wiz_helpers import wiz_actor, wiz_alert_context, wiz_success
def rule(event):
if not wiz_success(event):
return False
return event.get("action", "ACTION_NOT_FOUND") == "RotateServiceAccountSecret"
def title(event):
actor = wiz_actor(event)
return (
f"[Wiz]: [{event.get('action', 'ACTION_NOT_FOUND')}] action "
f"performed by {actor.get('type')} [{actor.get('name')}]"
)
def dedup(event):
return event.get("id")
def alert_context(event):
return wiz_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Wiz.Rotate.Service.Account.Secret
Description: This rule detects service account secrets rotations.
DisplayName: Wiz Rotate Service Account Secret
Runbook: Verify the action was planned.
Reference: https://www.wiz.io/academy/kubernetes-secrets
Enabled: true
Filename: wiz_rotate_service_account_secret.py
Severity: Medium
Reports:
MITRE ATT&CK:
- TA0001:T1078.004 # Valid Accounts: Cloud Accounts
LogTypes:
- Wiz.Audit
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on Wiz.Audit events when all of the conditions below hold.
Condition
statusisSUCCESSactionisRotateServiceAccountSecret
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
action | eq |
| field:"action" kind:eq value:"RotateServiceAccountSecret" |
status | eq |
| field:"status" kind:eq value:"SUCCESS" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
action | |
source_ip | sourceip |
event_id | id |
action_parameters | actionparameters |
Response runbook
Verify the action was planned.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"action": "RotateServiceAccountSecret",
"actionParameters": {
"ID": "rsao...<redacted>",
"selection": [
"__typename",
{
"serviceAccount": [
"__typename",
"id",
"enabled",
"name",
"clientId",
"scopes",
"lastRotatedAt",
"expiresAt",
"description",
{
"integration": [
"__typename",
"id"
]
},
"clientSecret"
]
}
]
},
"id": "d78f5ef1-3814-4d47-b789-0e43d4cc0ef2",
"requestId": "2303f545-a219-4c6d-b217-b76bb5e06a20",
"serviceAccount": null,
"sourceIP": "12.34.56.78",
"status": "SUCCESS",
"timestamp": "2024-07-16T10:47:43.562393Z",
"user": {
"id": "test.user@company.com",
"name": "user@company.com"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"
}
Wiz Rule Change
#This rule detects creations, updates and deletions of Wiz rules.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Defense Impairment |
Detection logic
from panther_wiz_helpers import wiz_actor, wiz_alert_context, wiz_success
SUSPICIOUS_ACTIONS = [
"DeleteAutomationRule",
"UpdateAutomationRule",
"DeleteCloudEventRule",
"UpdateCloudEventRule",
"DeleteCloudConfigurationRule",
"UpdateCloudConfigurationRule",
"DeleteHostConfigurationRule",
"UpdateHostConfigurationRule",
"CreateIgnoreRule",
"DeleteIgnoreRule", # we have no sample log for such event, but I suppose there should be one
"UpdateIgnoreRule",
"CreateMalwareExclusion",
"UpdateMalwareExclusion",
]
def rule(event):
if not wiz_success(event):
return False
return event.get("action", "ACTION_NOT_FOUND") in SUSPICIOUS_ACTIONS
def title(event):
actor = wiz_actor(event)
return (
f"[Wiz]: [{event.get('action', 'ACTION_NOT_FOUND')}] action "
f"performed by {actor.get('type')} [{actor.get('name')}]"
)
def dedup(event):
return event.get("id")
def alert_context(event):
return wiz_alert_context(event)
def severity(event):
action = event.get("action", "ACTION_NOT_FOUND")
if "Delete" in action:
return "High"
if "Create" in action:
return "Low"
return "Default"
Rule specification
AnalysisType: rule
RuleID: Wiz.Rule.Change
Description: This rule detects creations, updates and deletions of Wiz rules.
DisplayName: Wiz Rule Change
Runbook: Verify that this change was planned. If not, revert the change and ensure this doesn't happen again. If needed, review the privileges of existing accounts.
Reference: https://www.wiz.io/blog/custom-runtime-rules-and-response-policies
Enabled: true
Filename: wiz_rule_change.py
Severity: Medium
Reports:
MITRE ATT&CK:
- TA0005:T1562.001 # Impair Defenses: Disable or Modify Tools
LogTypes:
- Wiz.Audit
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on Wiz.Audit events when all of the conditions below hold.
Condition
statusisSUCCESSactionis one ofDeleteAutomationRule,UpdateAutomationRule,DeleteCloudEventRule,UpdateCloudEventRule,DeleteCloudConfigurationRule
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
action | in |
| field:"action" kind:in |
status | eq |
| field:"status" kind:eq value:"SUCCESS" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
action | |
source_ip | sourceip |
event_id | id |
action_parameters | actionparameters |
Response runbook
Verify that this change was planned. If not, revert the change and ensure this doesn't happen again. If needed, review the privileges of existing accounts.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"action": "DeleteCloudConfigurationRule",
"actionparameters": {
"input": {
"id": "12345-3fd7-4063-8e06-12345"
},
"selection": [
"__typename",
"_stub"
]
},
"id": "12345-0301-491d-9fe6-12345",
"log_type": "auditLogEntries",
"requestid": "12345-c18f-4ce0-9288-12345",
"serviceaccount": null,
"sourceip": "8.8.8.8",
"status": "SUCCESS",
"timestamp": "2024-03-24 10:58:31.347",
"user": {
"id": "testy@company.com",
"name": "testy@company.com"
},
"useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36"
}
Wiz SAML Identity Provider Change
#This rule detects creations, updates and deletions of SAML identity providers.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Privilege Escalation |
Detection logic
from panther_wiz_helpers import wiz_actor, wiz_alert_context, wiz_success
SUSPICIOUS_ACTIONS = [
"UpdateSAMLIdentityProvider",
"DeleteSAMLIdentityProvider",
"CreateSAMLIdentityProvider",
"ModifySAMLIdentityProviderGroupMappings",
]
def rule(event):
if not wiz_success(event):
return False
return event.get("action", "ACTION_NOT_FOUND") in SUSPICIOUS_ACTIONS
def title(event):
actor = wiz_actor(event)
return (
f"[Wiz]: [{event.get('action', 'ACTION_NOT_FOUND')}] action "
f"performed by {actor.get('type')} [{actor.get('name')}]"
)
def dedup(event):
return event.get("id")
def alert_context(event):
return wiz_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Wiz.SAML.Identity.Provider.Change
Description: This rule detects creations, updates and deletions of SAML identity providers.
DisplayName: Wiz SAML Identity Provider Change
Runbook: Verify that this change was planned. If not, revert the change and ensure this doesn't happen again.
Reference: https://support.wiz.io/hc/en-us/articles/5644029716380-Single-Sign-on-SSO-Overview
Enabled: true
Filename: wiz_saml_identity_provider_change.py
Severity: High
Reports:
MITRE ATT&CK:
- TA0004:T1484.002 # Domain or Tenant Policy Modification: Trust Modification
LogTypes:
- Wiz.Audit
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on Wiz.Audit events when all of the conditions below hold.
Condition
statusisSUCCESSactionis one ofUpdateSAMLIdentityProvider,DeleteSAMLIdentityProvider,CreateSAMLIdentityProvider,ModifySAMLIdentityProviderGroupMappings
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
action | in |
| field:"action" kind:in |
status | eq |
| field:"status" kind:eq value:"SUCCESS" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
action | |
source_ip | sourceip |
event_id | id |
action_parameters | actionparameters |
Response runbook
Verify that this change was planned. If not, revert the change and ensure this doesn't happen again.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"action": "DeleteSAMLIdentityProvider",
"actionParameters": {
"input": {
"id": "<redacted>"
},
"selection": [
"_stub"
]
},
"id": "0fc891d1-c2e3-4db2-b896-7af27964c71b",
"requestId": "eec733c5-175c-4d0c-8b65-b9344f223a36",
"serviceAccount": {
"id": "<redacted>",
"name": "test-graphql-api"
},
"sourceIP": "12.34.56.78",
"status": "SUCCESS",
"timestamp": "2024-07-12T08:59:33.946633Z",
"user": null,
"userAgent": "Wiz-Terraform-Provider/1.13.3433"
}
Wiz Service Account Change
#This rule detects creations, updates and deletions of service accounts.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Initial Access |
Detection logic
from panther_wiz_helpers import wiz_actor, wiz_alert_context, wiz_success
SUSPICIOUS_ACTIONS = [
"CreateServiceAccount",
"DeleteServiceAccount",
"UpdateServiceAccount",
]
def rule(event):
if not wiz_success(event):
return False
return event.get("action", "ACTION_NOT_FOUND") in SUSPICIOUS_ACTIONS
def title(event):
actor = wiz_actor(event)
return (
f"[Wiz]: [{event.get('action', 'ACTION_NOT_FOUND')}] action "
f"performed by {actor.get('type')} [{actor.get('name')}]"
)
def dedup(event):
return event.get("id")
def alert_context(event):
return wiz_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Wiz.Service.Account.Change
Description: This rule detects creations, updates and deletions of service accounts.
DisplayName: Wiz Service Account Change
Runbook: Confirm this user acted with valid business intent and determine whether this activity was authorized.
Reference: https://www.wiz.io/blog/non-human-identities-dashboard
Enabled: true
Filename: wiz_service_account_change.py
Severity: High
Reports:
MITRE ATT&CK:
- TA0001:T1078.004 # Valid Accounts: Cloud Accounts
LogTypes:
- Wiz.Audit
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on Wiz.Audit events when all of the conditions below hold.
Condition
statusisSUCCESSactionis one ofCreateServiceAccount,DeleteServiceAccount,UpdateServiceAccount
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
action | in |
| field:"action" kind:in |
status | eq |
| field:"status" kind:eq value:"SUCCESS" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
action | |
source_ip | sourceip |
event_id | id |
action_parameters | actionparameters |
Response runbook
Confirm this user acted with valid business intent and determine whether this activity was authorized.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"action": "DeleteServiceAccount",
"actionParameters": {
"input": {
"id": "rsao...<redacted>"
},
"selection": [
"__typename",
"_stub"
]
},
"id": "ac5630ca-2dd9-40a5-8137-140443cd8087",
"requestId": "a9291dc4-a17c-4af7-bb9e-17905082221f",
"serviceAccount": null,
"sourceIP": "12.34.56.78",
"status": "SUCCESS",
"timestamp": "2024-07-09T14:16:02.836387Z",
"user": {
"__typename": "User",
"id": "test.user@company.com",
"name": "user@company.com"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"
}
Wiz Update IP Restrictions
#This rule detects updates of IP restrictions.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Persistence |
Detection logic
from panther_wiz_helpers import wiz_actor, wiz_alert_context, wiz_success
def rule(event):
if not wiz_success(event):
return False
return event.get("action", "ACTION_NOT_FOUND") == "UpdateIPRestrictions"
def title(event):
actor = wiz_actor(event)
return (
f"[Wiz]: [{event.get('action', 'ACTION_NOT_FOUND')}] action "
f"performed by {actor.get('type')} [{actor.get('name')}]"
)
def dedup(event):
return event.get("id")
def alert_context(event):
return wiz_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Wiz.Update.IP.Restrictions
Description: This rule detects updates of IP restrictions.
DisplayName: Wiz Update IP Restrictions
Runbook: Verify that this change was planned. If not, revert the change and ensure this doesn't happen again.
Reference: https://docs.wiz.io/docs/portal-security-settings#ip-restrictions
Enabled: true
Filename: wiz_update_ip_restrictions.py
Severity: High
Reports:
MITRE ATT&CK:
- TA0003:T1556.009 # Modify Authentication Process: Conditional Access Policies
LogTypes:
- Wiz.Audit
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on Wiz.Audit events when all of the conditions below hold.
Condition
statusisSUCCESSactionisUpdateIPRestrictions
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
action | eq |
| field:"action" kind:eq value:"UpdateIPRestrictions" |
status | eq |
| field:"status" kind:eq value:"SUCCESS" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
action | |
source_ip | sourceip |
event_id | id |
action_parameters | actionparameters |
Response runbook
Verify that this change was planned. If not, revert the change and ensure this doesn't happen again.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"action": "UpdateIPRestrictions",
"actionParameters": {
"input": {
"serviceAccountAccessAllowedIPs": [
"0.0.0.0/0"
],
"userAccessAllowedIPs": []
},
"selection": [
"__typename",
{
"ipRestrictions": [
"__typename",
"userAccessAllowedIPs",
"serviceAccountAccessAllowedIPs"
]
}
]
},
"id": "66aa29d4-7a2e-4b09-a46c-ff72b2c55425",
"requestId": "22681d26-0ba0-4730-8f05-0b2c3adefe1b",
"serviceAccount": null,
"sourceIP": "12.34.56.78",
"status": "SUCCESS",
"timestamp": "2024-07-31T18:10:33.436381Z",
"user": {
"id": "test.user@company.com",
"name": "user@company.com"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"
}
Wiz Update Login Settings
#This rule detects updates of Wiz login settings.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Detection logic
from panther_wiz_helpers import wiz_actor, wiz_alert_context, wiz_success
def rule(event):
if not wiz_success(event):
return False
return event.get("action", "ACTION_NOT_FOUND") == "UpdateLoginSettings"
def title(event):
actor = wiz_actor(event)
return (
f"[Wiz]: [{event.get('action', 'ACTION_NOT_FOUND')}] action "
f"performed by {actor.get('type')} [{actor.get('name')}]"
)
def dedup(event):
return event.get("id")
def alert_context(event):
return wiz_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Wiz.Update.Login.Settings
Description: This rule detects updates of Wiz login settings.
DisplayName: Wiz Update Login Settings
Runbook: Verify that this change was planned. If not, revert the change and ensure this doesn't happen again.
Reference: https://support.wiz.io/hc/en-us/categories/5311977085340-User-Management
Enabled: true
Filename: wiz_update_login_settings.py
Severity: Medium
Reports:
MITRE ATT&CK:
- TA0006:T1556 # Modify Authentication Process
LogTypes:
- Wiz.Audit
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on Wiz.Audit events when all of the conditions below hold.
Condition
statusisSUCCESSactionisUpdateLoginSettings
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
action | eq |
| field:"action" kind:eq value:"UpdateLoginSettings" |
status | eq |
| field:"status" kind:eq value:"SUCCESS" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
action | |
source_ip | sourceip |
event_id | id |
action_parameters | actionparameters |
Response runbook
Verify that this change was planned. If not, revert the change and ensure this doesn't happen again.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"action": "UpdateLoginSettings",
"actionParameters": {
"input": {
"patch": {
"approvedUserDomains": [
"abc.com"
]
}
},
"selection": [
"__typename",
{
"loginSettings": [
"__typename",
"approvedUserDomains"
]
}
]
},
"id": "f77a8e1e-5674-42d1-9f1e-8a259dc736cd",
"requestId": "417f1751-bcc1-4d38-86aa-eb781790bdd6",
"serviceAccount": null,
"sourceIP": "12.34.56.78",
"status": "SUCCESS",
"timestamp": "2024-06-16T13:14:22.291227Z",
"user": {
"id": "<redacted>",
"name": "user@company.com"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"
}
Wiz Update Scanner Settings
#This rule detects updates of Wiz scanner settings.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Defense Impairment |
Detection logic
from panther_wiz_helpers import wiz_actor, wiz_alert_context, wiz_success
def rule(event):
if not wiz_success(event):
return False
return event.get("action", "ACTION_NOT_FOUND") == "UpdateScannerSettings"
def title(event):
actor = wiz_actor(event)
return (
f"[Wiz]: [{event.get('action', 'ACTION_NOT_FOUND')}] action "
f"performed by {actor.get('type')} [{actor.get('name')}]"
)
def dedup(event):
return event.get("id")
def alert_context(event):
return wiz_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Wiz.Update.Scanner.Settings
Description: This rule detects updates of Wiz scanner settings.
DisplayName: Wiz Update Scanner Settings
Runbook: Verify that this change was planned. If not, revert the change and ensure this doesn't happen again.
Reference: https://www.wiz.io/academy/secret-scanning
Enabled: true
Filename: wiz_update_scanner_settings.py
Severity: Medium
Reports:
MITRE ATT&CK:
- TA0005:T1562.001 # Impair Defenses: Disable or Modify Tools
LogTypes:
- Wiz.Audit
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on Wiz.Audit events when all of the conditions below hold.
Condition
statusisSUCCESSactionisUpdateScannerSettings
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
action | eq |
| field:"action" kind:eq value:"UpdateScannerSettings" |
status | eq |
| field:"status" kind:eq value:"SUCCESS" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
action | |
source_ip | sourceip |
event_id | id |
action_parameters | actionparameters |
Response runbook
Verify that this change was planned. If not, revert the change and ensure this doesn't happen again.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"action": "UpdateScannerSettings",
"actionParameters": {
"input": {
"patch": {
"computeResourceGroupMemberScanSamplingEnabled": true,
"maxComputeResourceGroupMemberScanCount": 2,
"prioritizeActiveComputeResourceGroupMembers": true
}
},
"selection": [
"__typename",
{
"scannerSettings": [
"__typename",
"computeResourceGroupMemberScanSamplingEnabled",
"maxComputeResourceGroupMemberScanCount",
{
"customFileDetectionList": [
"__typename",
"id",
"url",
"fileDetectionCount"
]
}
]
}
]
},
"id": "dd48b7fe-576d-453d-a0d0-1f61425b1bb7",
"requestId": "d5c55350-0d54-46eb-88ee-4942f80e700c",
"serviceAccount": null,
"sourceIP": "12.34.56.78",
"status": "SUCCESS",
"timestamp": "2024-06-18T12:09:33.985762Z",
"user": {
"id": "test.user@company.com",
"name": "user@company.com"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
}
Wiz Update Support Contact List
#This rule detects updates of Wiz support contact list.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Collection |
Detection logic
from panther_wiz_helpers import wiz_actor, wiz_alert_context, wiz_success
def rule(event):
if not wiz_success(event):
return False
return event.get("action", "ACTION_NOT_FOUND") == "UpdateSupportContactList"
def title(event):
actor = wiz_actor(event)
return (
f"[Wiz]: [{event.get('action', 'ACTION_NOT_FOUND')}] action "
f"performed by {actor.get('type')} [{actor.get('name')}]"
)
def dedup(event):
return event.get("id")
def alert_context(event):
return wiz_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Wiz.Update.Support.Contact.List
Description: This rule detects updates of Wiz support contact list.
DisplayName: Wiz Update Support Contact List
Runbook: Verify that this change was planned. If not, revert the change and ensure this doesn't happen again.
Reference: https://www.wiz.io/
Enabled: true
Filename: wiz_update_support_contact_list.py
Severity: Low
Reports:
MITRE ATT&CK:
- TA0035:T1636.003 # Protected User Data: Contact List
LogTypes:
- Wiz.Audit
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on Wiz.Audit events when all of the conditions below hold.
Condition
statusisSUCCESSactionisUpdateSupportContactList
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
action | eq |
| field:"action" kind:eq value:"UpdateSupportContactList" |
status | eq |
| field:"status" kind:eq value:"SUCCESS" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
action | |
source_ip | sourceip |
event_id | id |
action_parameters | actionparameters |
Response runbook
Verify that this change was planned. If not, revert the change and ensure this doesn't happen again.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"action": "UpdateSupportContactList",
"actionParameters": {
"input": {
"patch": {
"contacts": [
"test.user@company.com"
]
}
},
"selection": [
"__typename",
{
"supportContactList": [
"__typename",
{
"contacts": [
"__typename",
"id"
]
}
]
}
]
},
"id": "3a9d0fc8-8466-4e79-a2cd-014a068b985c",
"requestId": "fddf46ff-c69a-4f5b-a06d-c05ec95dbb21",
"serviceAccount": null,
"sourceIP": "12.34.56.78",
"status": "SUCCESS",
"timestamp": "2024-07-23T10:16:54.517212Z",
"user": {
"id": "test.user@company.com",
"name": "user@company.com"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"
}
Wiz User Created Or Deleted
#This rule detects creations and deletions of Wiz users.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Stealth |
Detection logic
from panther_wiz_helpers import wiz_actor, wiz_alert_context, wiz_success
SUSPICIOUS_ACTIONS = ["CreateUser", "DeleteUser"]
def rule(event):
if not wiz_success(event):
return False
return event.get("action", "ACTION_NOT_FOUND") in SUSPICIOUS_ACTIONS
def title(event):
actor = wiz_actor(event)
return (
f"[Wiz]: [{event.get('action', 'ACTION_NOT_FOUND')}] action "
f"performed by {actor.get('type')} [{actor.get('name')}]"
)
def dedup(event):
return event.get("id")
def alert_context(event):
return wiz_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Wiz.User.Created.Or.Deleted
Description: This rule detects creations and deletions of Wiz users.
DisplayName: Wiz User Created Or Deleted
Runbook: Verify that this change was planned.
Reference: https://support.wiz.io/hc/en-us/categories/5311977085340-User-Management
Enabled: true
Filename: wiz_user_created_or_deleted.py
Severity: Low
Reports:
MITRE ATT&CK:
- TA0003:T1136.003 # Create Account
- TA0005:T1070.009 # Indicator Removal
LogTypes:
- Wiz.Audit
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on Wiz.Audit events when all of the conditions below hold.
Condition
statusisSUCCESSactionis one ofCreateUser,DeleteUser
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
action | in |
| field:"action" kind:in |
status | eq |
| field:"status" kind:eq value:"SUCCESS" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
action | |
source_ip | sourceip |
event_id | id |
action_parameters | actionparameters |
Response runbook
Verify that this change was planned.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"action": "CreateUser",
"actionParameters": {
"input": {
"assignedProjectIds": null,
"email": "testy@company.com",
"expiresAt": null,
"name": "Test User",
"role": "GLOBAL_ADMIN"
},
"selection": [
"__typename",
{
"user": [
"__typename",
"id"
]
}
]
},
"id": "220d23be-f07c-4d97-b4a6-87ad04eddb14",
"requestId": "0d9521b2-c3f8-4a73-bf7c-20257788752e",
"serviceAccount": null,
"sourceIP": "8.8.8.8",
"status": "SUCCESS",
"timestamp": "2024-07-29T09:40:15.66643Z",
"user": {
"id": "someuser@company.com",
"name": "someuser@company.com"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"
}
Wiz User Role Updated Or Deleted
#This rule detects updates and deletions of Wiz user roles.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Persistence |
Detection logic
from panther_wiz_helpers import wiz_actor, wiz_alert_context, wiz_success
SUSPICIOUS_ACTIONS = ["DeleteUserRole", "UpdateUserRole"]
def rule(event):
if not wiz_success(event):
return False
return event.get("action", "ACTION_NOT_FOUND") in SUSPICIOUS_ACTIONS
def title(event):
actor = wiz_actor(event)
return (
f"[Wiz]: [{event.get('action', 'ACTION_NOT_FOUND')}] action "
f"performed by {actor.get('type')} [{actor.get('name')}]"
)
def dedup(event):
return event.get("id")
def alert_context(event):
return wiz_alert_context(event)
def severity(event):
action = event.get("action", "ACTION_NOT_FOUND")
if "Delete" in action:
return "High"
return "Default"
Rule specification
AnalysisType: rule
RuleID: Wiz.User.Role.Updated.Or.Deleted
Description: This rule detects updates and deletions of Wiz user roles.
DisplayName: Wiz User Role Updated Or Deleted
Runbook: Verify that this change was planned. If not, revert the change and ensure this doesn't happen again. Review privileges given to accounts to ensure the principle of minimal privilege
Reference: https://www.wiz.io/blog/cloud-security-custom-roles-democratization
Enabled: true
Filename: wiz_user_role_updated_or_deleted.py
Severity: Medium
Reports:
MITRE ATT&CK:
- TA0003:T1098.001 # Account Manipulation
LogTypes:
- Wiz.Audit
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on Wiz.Audit events when all of the conditions below hold.
Condition
statusisSUCCESSactionis one ofDeleteUserRole,UpdateUserRole
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
action | in |
| field:"action" kind:in |
status | eq |
| field:"status" kind:eq value:"SUCCESS" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
action | |
source_ip | sourceip |
event_id | id |
action_parameters | actionparameters |
Response runbook
Verify that this change was planned. If not, revert the change and ensure this doesn't happen again. Review privileges given to accounts to ensure the principle of minimal privilege
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"action": "DeleteUserRole",
"actionParameters": {
"input": {
"id": "b92c4032-9af8-4e2d-b6dc-3bf2005bb7ad"
},
"selection": [
"__typename",
"_stub"
]
},
"id": "671d8e2d-1ca8-47eb-bf1c-d46cd3f0d737",
"requestId": "a83aba82-c707-4a2f-9761-fe9ee723b703",
"serviceAccount": null,
"sourceIP": "12.34.56.78",
"status": "SUCCESS",
"timestamp": "2024-07-31T18:09:28.790129Z",
"user": {
"id": "test.user@company.com",
"name": "user@company.com"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"
}