Detection rules › Panther
Panther rules: push
| Rule | Severity |
|---|---|
| Push Security App Banner Acknowledged | low |
| Push Security Authorized IdP Login | informational |
| Push Security New App Detected | informational |
| Push Security New SaaS Account Created | informational |
| Push Security Open Security Finding | informational |
| Push Security Phishable MFA Method | informational |
| Push Security Phishing Attack | high |
| Push Security SaaS App MFA Method Changed | informational |
| Push Security Unauthorized IdP Login | high |
Push Security New App Detected
#Detection logic
def rule(event):
if event.get("object") != "APP":
return False
if event.get("type") == "CREATE":
return True
return False
def title(event):
new_type = event.deep_get("new", "type")
return f"New app in use: {new_type}"
Rule specification
AnalysisType: rule
Filename: push_security_new_app_detected.py
RuleID: "Push.Security.New.App.Detected"
DisplayName: "Push Security New App Detected"
Enabled: true
LogTypes:
- PushSecurity.Entities
Severity: Info
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on PushSecurity.Entities events when all of the conditions below hold.
Condition
objectisAPPtypeisCREATE
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
object | eq |
| field:"group.name" kind:eq value:"APP" |
type | eq |
| field:"type" kind:eq value:"CREATE" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
type | new.type |
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"id": "c478966c-f927-411c-b919-179832d3d50c",
"new": {
"approvalStatus": null,
"creationTimestamp": 1698064423.0,
"id": "2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0",
"notes": "",
"ownerId": null,
"sensitivityLevel": null,
"type": "ZAPIER"
},
"object": "APP",
"old": null,
"timestamp": 1698604061.0,
"type": "CREATE",
"version": "1"
}
Push Security New SaaS Account Created
#Detection logic
def rule(event):
if event.get("object") != "ACCOUNT":
return False
if event.get("type") == "CREATE":
return True
return False
def title(event):
app_type = event.deep_get("new", "appType")
new_email = event.deep_get("new", "email")
return f"New account on {app_type} created by {new_email}"
Rule specification
AnalysisType: rule
Filename: push_security_new_saas_account_created.py
RuleID: "Push.Security.New.SaaS.Account.Created"
DisplayName: "Push Security New SaaS Account Created"
Enabled: true
LogTypes:
- PushSecurity.Entities
Severity: Info
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on PushSecurity.Entities events when all of the conditions below hold.
Condition
objectisACCOUNTtypeisCREATE
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
object | eq |
| field:"group.name" kind:eq value:"ACCOUNT" |
type | eq |
| field:"type" kind:eq value:"CREATE" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
appType | new.appType |
email | new.email |
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"id": "c478966c-f927-411c-b919-179832d3d50c",
"new": {
"appId": "2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0",
"appType": "ATLASSIAN",
"creationTimestamp": 1698064423.0,
"email": "john.hill@example.com",
"employeeId": "72d0347a-2663-4ef5-b1c5-df39163f1603",
"id": "d6a32ba5-0532-4a66-8137-48cdf409c972",
"lastUsedTimestamp": 1698669168.0,
"loginMethods": {
"oidcLogin": "GOOGLE_WORKSPACE",
"oktaSwaLogin": true,
"passwordLogin": true,
"samlLogin": "OKTA",
"vendorSsoLogin": "GOOGLE_WORKSPACE"
},
"mfaMethods": [
"APP_TOTP",
"PUSH_NOTIFICATION",
"EMAIL_OTP",
"U2F",
"HARDWARE_TOTP",
"PHONE_CALL",
"SMS_OTP",
"APP_PASSWORD",
"GRID_CARD",
"EXTERNAL_PROVIDER",
"BACKUP_CODES",
"WEBAUTHN"
],
"mfaRegistered": true,
"passwordId": "4c13674f-e88a-4411-bfa2-53a70468a898"
},
"object": "ACCOUNT",
"old": null,
"timestamp": 1698604061.0,
"type": "CREATE",
"version": "1"
}
Push Security Open Security Finding
#Detection logic
def rule(event):
if event.get("object") != "FINDING":
return False
event_type = event.get("type")
if event_type == "CREATE":
return True
if event_type == "UPDATE" and event.deep_get("new", "state") == "OPEN":
return True
return False
def title(event):
new_type = event.deep_get("new", "type")
app_type = event.deep_get("new", "appType")
return f"Open finding {new_type} for app {app_type}"
Rule specification
AnalysisType: rule
Filename: push_security_open_security_finding.py
RuleID: "Push.Security.Open.Security.Finding"
DisplayName: "Push Security Open Security Finding"
Enabled: true
LogTypes:
- PushSecurity.Entities
Severity: Info
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on PushSecurity.Entities events when all of the conditions below hold.
Condition
objectisFINDINGany of:
typeisCREATEall of:
typeisUPDATEnew.stateisOPEN
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
new.state | eq |
| field:"new.state" kind:eq value:"OPEN" |
object | eq |
| field:"group.name" kind:eq value:"FINDING" |
type | eq |
| field:"type" kind:eq |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
type | new.type |
appType | new.appType |
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"id": "c478966c-f927-411c-b919-179832d3d50c",
"new": {
"accountId": null,
"appId": "2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0",
"appType": "PUSH_SECURITY",
"creationTimestamp": 1698064423.0,
"employeeId": "379ac7ea-ff2a-42ef-af37-06d2020dc46a",
"id": "d6a32ba5-0532-4a66-8137-48cdf409c972",
"passwordId": "c4a045a1-5331-4714-af83-6a361e98960d",
"state": "OPEN",
"type": "WEAK_PASSWORD"
},
"object": "FINDING",
"old": null,
"timestamp": 1698604061.0,
"type": "CREATE",
"version": "1"
}
Push Security Phishable MFA Method
#Detection logic
identity_providers = ("MICROSOFT_365", "GOOGLE_WORKSPACE", "OKTA", "JUMPCLOUD", "PING")
phishable_mfa = ("EMAIL_OTP", "PHONE_CALL", "SMS", "APP_PASSWORD")
def rule(event):
if event.get("object") != "ACCOUNT":
return False
mfa_methods = event.deep_get("new", "mfaMethods")
for method in mfa_methods:
if method in phishable_mfa:
return True
return False
def severity(event):
if event.deep_get("new", "appType") in identity_providers:
return "HIGH"
return "INFO"
def title(event):
mfa_methods = ", ".join(event.deep_get("new", "mfaMethods", default="No MFA"))
new_email = event.deep_get("new", "email")
app_type = event.deep_get("new", "appType", default=[])
return f"{new_email} using phishable MFA method with {app_type}. \
MFA methods enabled: {mfa_methods}"
Rule specification
AnalysisType: rule
Filename: push_security_phishable_mfa_method.py
RuleID: "Push.Security.Phishable.MFA.Method"
DisplayName: "Push Security Phishable MFA Method"
Enabled: true
LogTypes:
- PushSecurity.Entities
Severity: Info
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on PushSecurity.Entities events when all of the conditions below hold.
Condition
objectisACCOUNTany element of
new.mfaMethodsmatches:new.mfaMethodsis one ofEMAIL_OTP,PHONE_CALL,SMS,APP_PASSWORD
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
object | eq |
| field:"group.name" kind:eq value:"ACCOUNT" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
email | new.email |
appType | new.appType |
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"id": "d1e5794f-666d-4cba-abae-c6d889ca1903",
"new": {
"appId": "67ef5c13-b5e6-4945-af7b-c11ac98f630f",
"appType": "DROPBOX",
"creationTimestamp": 1707775048.0,
"email": "jet.black@issp.com",
"employeeId": "ca6cf7ce-90e6-4eb5-a262-7899bc48c39c",
"id": "5e15ce4c-6b93-4fbf-aed9-1890775efa90",
"lastUsedTimestamp": null,
"loginMethods": {
"oidcLogin": null,
"oktaSwaLogin": false,
"passwordLogin": false,
"samlLogin": null
},
"mfaMethods": [
"SMS",
"EMAIL_OTP"
],
"mfaRegistered": false,
"passwordId": null
},
"object": "ACCOUNT",
"old": null
}
Push Security Phishing Attack
#Detection logic
def rule(event):
if event.get("object") == "PASSWORD_PHISHING":
return True
return False
def severity(event):
if event.deep_get("new", "mode") != "BLOCK":
return "HIGH"
return "LOW"
def title(event):
app_type = event.deep_get("new", "appType")
employee_email = event.deep_get("new", "employee", "email")
new_mode = event.deep_get("new", "mode")
return f"Phishing attack on app {app_type} user {employee_email}. \
Attack detected in mode {new_mode}."
Rule specification
AnalysisType: rule
Filename: push_security_phishing_attack.py
RuleID: "Push.Security.Phishing.Attack"
DisplayName: "Push Security Phishing Attack"
Enabled: true
LogTypes:
- PushSecurity.Controls
Severity: High
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on PushSecurity.Controls events when the condition below holds.
Condition
objectisPASSWORD_PHISHING
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
object | eq |
| field:"group.name" kind:eq value:"PASSWORD_PHISHING" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
appType | new.appType |
email | new.employee.email |
mode | new.mode |
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"id": "c478966c-f927-411c-b919-179832d3d50c",
"new": {
"appType": "OKTA",
"browser": "CHROME",
"employee": {
"chatopsEnabled": true,
"creationTimestamp": 1698669223.0,
"department": "Security Engineering",
"email": "john.hill@example.com",
"firstName": "John",
"id": "2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0",
"lastName": "Hill",
"licensed": true,
"location": "New York"
},
"mode": "BLOCK",
"os": "WINDOWS",
"referrerUrl": "https://statics.teams.cdn.office.net/",
"sourceIpAddress": "8.158.25.38",
"url": "https://evil.com/okta.php",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299"
},
"object": "PASSWORD_PHISHING",
"timestamp": 1698604061.0,
"version": "1"
}
Push Security SaaS App MFA Method Changed
#MFA method on SaaS app changed
Detection logic
def rule(event):
if event.get("object") != "ACCOUNT":
return False
if event.get("old") is None:
return False
new_mfa_methods = set(event.deep_get("new", "mfaMethods"))
old_mfa_methods = set(event.deep_get("old", "mfaMethods", default=[]))
if new_mfa_methods != old_mfa_methods:
return True
return False
def severity(event):
if event.deep_get("new", "mfaMethods") == []:
return "HIGH"
return "LOW"
def title(event):
mfa_methods = ", ".join(event.deep_get("new", "mfaMethods", default="No MFA"))
new_email = event.deep_get("new", "email")
new_apptype = event.deep_get("new", "appType")
if mfa_methods == "":
return f"{new_email} removed all MFA methods on {new_apptype}"
return f"{new_email} changed MFA method to {mfa_methods} on {new_apptype}"
Rule specification
AnalysisType: rule
Filename: push_security_mfa_method_changed.py
RuleID: "Push.Security.MFA.Method.Changed"
DisplayName: "Push Security SaaS App MFA Method Changed"
Enabled: true
LogTypes:
- PushSecurity.Entities
Severity: Info
Description: MFA method on SaaS app changed
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on PushSecurity.Entities events when all of the conditions below hold.
Condition
objectisACCOUNToldis present
This rule also runs imperative logic the parser cannot express as a filter. The conditions above are the structured part it could extract.
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
object | eq |
| field:"group.name" kind:eq value:"ACCOUNT" |
old | is_not_null | field:"old" kind:is_not_null |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
email | new.email |
appType | new.appType |
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"id": "d1e5794f-666d-4cba-abae-c6d889ca1903",
"new": {
"appId": "67ef5c13-b5e6-4945-af7b-c11ac98f630f",
"appType": "CONTENTFUL",
"creationTimestamp": 1707775048.0,
"email": "jet.black@issp.com",
"employeeId": "ca6cf7ce-90e6-4eb5-a262-7899bc48c39c",
"id": "5e15ce4c-6b93-4fbf-aed9-1890775efa90",
"lastUsedTimestamp": null,
"loginMethods": {
"oidcLogin": null,
"oktaSwaLogin": false,
"passwordLogin": false,
"samlLogin": null
},
"mfaMethods": [],
"mfaRegistered": false,
"passwordId": null
},
"object": "ACCOUNT",
"old": {
"appId": "67ef5c13-b5e6-4945-af7b-c11ac98f630f",
"appType": "CONTENTFUL",
"creationTimestamp": 1707775048.0,
"email": "jet.black@issp.com",
"employeeId": "ca6cf7ce-90e6-4eb5-a262-7899bc48c39c",
"id": "5e15ce4c-6b93-4fbf-aed9-1890775efa90",
"lastUsedTimestamp": null,
"loginMethods": {
"oidcLogin": null,
"oktaSwaLogin": false,
"passwordLogin": false,
"samlLogin": null
},
"mfaMethods": [
"SMS"
],
"mfaRegistered": false,
"passwordId": null
},
"timestamp": 1707775049.0,
"type": "CREATE",
"version": "1"
}