Skip to content

Commit

Permalink
THREAT-411 ZIA AdminAuditRules - Password, Log, Backup (#1425)
Browse files Browse the repository at this point in the history
Co-authored-by: Ariel Ropek <[email protected]>
  • Loading branch information
akozlovets098 and arielkr256 authored Nov 14, 2024
1 parent c9724bf commit 3439310
Show file tree
Hide file tree
Showing 11 changed files with 718 additions and 0 deletions.
5 changes: 5 additions & 0 deletions packs/zscaler_zia.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ PackDefinition:
IDs:
- ZIA.Account.Access.Removed
- ZIA.Additional.Cloud.Roles
- ZIA.Backup.Deleted
- ZIA.Cloud.Account.Created
- ZIA.Golden.Restore.Point.Dropped
- ZIA.Insecure.Password.Settings
- ZIA.Logs.Downloaded
- ZIA.Log.Streaming.Disabled
- ZIA.Password.Expiration
- ZIA.Trust.Modification
- panther_zscaler_helpers
Expand Down
22 changes: 22 additions & 0 deletions rules/zscaler_rules/zia/zia_backup_deleted.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from panther_zscaler_helpers import zia_alert_context, zia_success


def rule(event):
if not zia_success(event):
return False
action = event.deep_get("event", "action", default="ACTION_NOT_FOUND")
category = event.deep_get("event", "category", default="CATEGORY_NOT_FOUND")
if action == "DELETE" and category == "BACKUP_AND_RESTORE":
return True
return False


def title(event):
return (
f"[Zscaler.ZIA]: Backup was deleted by admin with id "
f"[{event.deep_get('event', 'adminid', default='<ADMIN_ID_NOT_FOUND>')}]"
)


def alert_context(event):
return zia_alert_context(event)
78 changes: 78 additions & 0 deletions rules/zscaler_rules/zia/zia_backup_deleted.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
AnalysisType: rule
RuleID: ZIA.Backup.Deleted
Description: This rule detects when ZIA backup data was deleted.
DisplayName: ZIA Backup Deleted
Runbook: Verify that this change was planned. If not, make sure to restore the backup.
Reference: https://help.zscaler.com/zia/about-backup-and-restore
Enabled: true
Filename: zia_backup_deleted.py
Severity: Medium
Reports:
MITRE ATT&CK:
- TA0005:T1562.008 # Disable or Modify Cloud Logs
LogTypes:
- Zscaler.ZIA.AdminAuditLog
DedupPeriodMinutes: 60
Threshold: 1
Tests:
- Name: Backup deleted
ExpectedResult: true
Log:
{
"event": {
"action": "DELETE",
"adminid": "[email protected]",
"auditlogtype": "ZIA",
"category": "BACKUP_AND_RESTORE",
"clientip": "1.2.3.4",
"errorcode": "None",
"interface": "UI",
"postaction": { },
"preaction": {
"adminLogin": "[email protected]",
"goldenRestorePoint": false,
"id": 163372,
"name": "test-restore-2",
"time": 1730737925000
},
"recordid": "366",
"resource": "test-restore-2",
"result": "SUCCESS",
"subcategory": "BACKUP_AND_RESTORE",
"time": "2024-11-04 16:32:18.000000000"
},
"sourcetype": "zscalernss-audit"
}
- Name: Backup created
ExpectedResult: false
Log:
{
"event": {
"action": "CREATE",
"adminid": "[email protected]",
"auditlogtype": "ZIA",
"category": "BACKUP_AND_RESTORE",
"clientip": "1.2.3.4",
"errorcode": "None",
"interface": "UI",
"postaction": {
"adminLogin": "[email protected]",
"goldenRestorePoint": false,
"id": 163372,
"name": "test-restore-2",
"time": 1730737925000
},
"preaction": {
"goldenRestorePoint": false,
"id": 0,
"name": "test-restore-2",
"time": 0
},
"recordid": "365",
"resource": "test-restore-2",
"result": "SUCCESS",
"subcategory": "BACKUP_AND_RESTORE",
"time": "2024-11-04 16:32:05.000000000"
},
"sourcetype": "zscalernss-audit"
}
39 changes: 39 additions & 0 deletions rules/zscaler_rules/zia/zia_golden_restore_point_dropped.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from panther_zscaler_helpers import zia_alert_context, zia_success


def rule(event):
if not zia_success(event):
return False
action = event.deep_get("event", "action", default="ACTION_NOT_FOUND")
category = event.deep_get("event", "category", default="CATEGORY_NOT_FOUND")
golden_restore_point_pre = event.deep_get(
"event",
"preaction",
"goldenRestorePoint",
default="<PRE_RESTORE_POINT_NOT_FOUND>",
)
golden_restore_point_post = event.deep_get(
"event",
"postaction",
"goldenRestorePoint",
default="<POPT_RESTORE_POINT_NOT_FOUND>",
)
if (
action == "UPDATE"
and category == "BACKUP_AND_RESTORE"
and golden_restore_point_pre is True
and golden_restore_point_post is False
):
return True
return False


def title(event):
return (
f"[Zscaler.ZIA]: goldenRestorePoint was dropped by admin with id "
f"[{event.deep_get('event', 'adminid', default='<ADMIN_ID_NOT_FOUND>')}]"
)


def alert_context(event):
return zia_alert_context(event)
85 changes: 85 additions & 0 deletions rules/zscaler_rules/zia/zia_golden_restore_point_dropped.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
AnalysisType: rule
RuleID: ZIA.Golden.Restore.Point.Dropped
Description: This rule detects when ZIA goldenRestorePoint was dropped.
It means that some piece of information that was impossible to delete before, now is deletable
DisplayName: ZIA Golden Restore Point Dropped
Runbook: Verify that this change was planned. If not, revert the change.
Reference: https://help.zscaler.com/zia/about-backup-and-restore
Enabled: true
Filename: zia_golden_restore_point_dropped.py
Severity: Medium
Reports:
MITRE ATT&CK:
- TA0005:T1562.008 # Disable or Modify Cloud Logs
LogTypes:
- Zscaler.ZIA.AdminAuditLog
DedupPeriodMinutes: 60
Threshold: 1
Tests:
- Name: goldenRestorePoint dropped
ExpectedResult: true
Log:
{
"event": {
"action": "UPDATE",
"adminid": "[email protected]",
"auditlogtype": "ZIA",
"category": "BACKUP_AND_RESTORE",
"clientip": "1.2.3.4",
"errorcode": "None",
"interface": "UI",
"postaction": {
"adminLogin": "[email protected]",
"goldenRestorePoint": false,
"id": 163371,
"name": "test-restore",
"time": 1730737915000
},
"preaction": {
"adminLogin": "[email protected]",
"goldenRestorePoint": true,
"id": 163371,
"name": "test-restore",
"time": 1730737915000
},
"recordid": "367",
"resource": "test-restore",
"result": "SUCCESS",
"subcategory": "BACKUP_AND_RESTORE",
"time": "2024-11-04 16:32:28.000000000"
},
"sourcetype": "zscalernss-audit"
}
- Name: Backup created
ExpectedResult: false
Log:
{
"event": {
"action": "CREATE",
"adminid": "[email protected]",
"auditlogtype": "ZIA",
"category": "BACKUP_AND_RESTORE",
"clientip": "1.2.3.4",
"errorcode": "None",
"interface": "UI",
"postaction": {
"adminLogin": "[email protected]",
"goldenRestorePoint": false,
"id": 163372,
"name": "test-restore-2",
"time": 1730737925000
},
"preaction": {
"goldenRestorePoint": false,
"id": 0,
"name": "test-restore-2",
"time": 0
},
"recordid": "365",
"resource": "test-restore-2",
"result": "SUCCESS",
"subcategory": "BACKUP_AND_RESTORE",
"time": "2024-11-04 16:32:05.000000000"
},
"sourcetype": "zscalernss-audit"
}
46 changes: 46 additions & 0 deletions rules/zscaler_rules/zia/zia_insecure_password_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from panther_zscaler_helpers import zia_alert_context, zia_success


def rule(event):
if not zia_success(event):
return False
auth_frequency = event.deep_get(
"event",
"postaction",
"authFrequency",
default="<AUTH_FREQUENCY_NOT_FOUND>",
)
password_expiry = event.deep_get(
"event",
"postaction",
"passwordExpiry",
default="<PASSWORD_EXPIRY_NOT_FOUND>",
)
password_strength = event.deep_get(
"event",
"postaction",
"passwordStrength",
default="<PASSWORD_STRENGTH_NOT_FOUND>",
)
if (
auth_frequency == "PERMANENT_COOKIE"
or password_expiry == "NEVER" # nosec bandit B105
or password_strength == "NONE" # nosec bandit B105
):
return True
return False


def dedup(event):
return event.deep_get("event", "adminid", default="<ADMIN_ID_NOT_FOUND>")


def title(event):
return (
f"[Zscaler.ZIA]: Password settings are insecure for admin with id "
f"[{event.deep_get('event', 'adminid', default='<ADMIN_ID_NOT_FOUND>')}]"
)


def alert_context(event):
return zia_alert_context(event)
Loading

0 comments on commit 3439310

Please sign in to comment.