-
Notifications
You must be signed in to change notification settings - Fork 176
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'develop' into THREAT-411-ZIA-AdminAuditRules---Password…
…,-Log,-Backup
- Loading branch information
Showing
34 changed files
with
2,393 additions
and
901 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
policies/aws_s3_policies/aws_s3_bucket_policy_confused_deputy.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import json | ||
|
||
REQUIRED_CONDITIONS = { | ||
"aws:SourceArn", | ||
"aws:SourceAccount", | ||
"aws:SourceOrgID", | ||
"aws:SourceOrgPaths", | ||
} | ||
|
||
|
||
def policy(resource): | ||
bucket_policy = resource.get("Policy") | ||
if bucket_policy is None: | ||
return True # Pass if there is no bucket policy | ||
|
||
policy_statements = json.loads(bucket_policy).get("Statement", []) | ||
for statement in policy_statements: | ||
# Check if the statement includes a service principal and allows access | ||
principal = statement.get("Principal", {}) | ||
if "Service" in principal and statement["Effect"] == "Allow": | ||
conditions = statement.get("Condition", {}) | ||
# Flatten nested condition keys (e.g., inside "StringEquals") | ||
flat_condition_keys = set() | ||
for condition in conditions.values(): | ||
if isinstance(condition, dict): | ||
flat_condition_keys.update(condition.keys()) | ||
# Check if any required condition key is present | ||
if not REQUIRED_CONDITIONS.intersection(flat_condition_keys): | ||
return False | ||
return True |
39 changes: 39 additions & 0 deletions
39
policies/aws_s3_policies/aws_s3_bucket_policy_confused_deputy.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
AnalysisType: policy | ||
Filename: aws_s3_bucket_policy_confused_deputy.py | ||
PolicyID: "AWS.S3.Bucket.PolicyConfusedDeputyProtection" | ||
DisplayName: "S3 Bucket Policy Confused Deputy Protection for Service Principals" | ||
Enabled: true | ||
ResourceTypes: | ||
- AWS.S3.Bucket | ||
Tags: | ||
- AWS | ||
- Security Control | ||
- Best Practices | ||
Severity: High | ||
Description: > | ||
Ensures that S3 bucket policies with service principals include conditions to prevent the confused deputy problem. | ||
Runbook: > | ||
Update the bucket policy to include conditions such as aws:SourceArn, aws:SourceAccount, | ||
aws:SourceOrgID, or aws:SourceOrgPaths when a service principal is specified. | ||
Reference: https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html | ||
Tests: | ||
- Name: Compliant Policy with Service Principal and Condition | ||
ExpectedResult: true | ||
Resource: | ||
{ | ||
"Policy": '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"cloudtrail.amazonaws.com"},"Action":"s3:PutObject","Resource":"arn:aws:s3:::my-example-bucket/*","Condition":{"StringEquals":{"aws:SourceAccount":"123456789012"}}}]}' | ||
} | ||
|
||
- Name: Non-Compliant Policy with Service Principal and No Condition | ||
ExpectedResult: false | ||
Resource: | ||
{ | ||
"Policy": '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"cloudtrail.amazonaws.com"},"Action":"s3:PutObject","Resource":"arn:aws:s3:::my-example-bucket/*"}]}' | ||
} | ||
|
||
- Name: Policy without Service Principal | ||
ExpectedResult: true | ||
Resource: | ||
{ | ||
"Policy": '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::123456789012:root"},"Action":"s3:GetObject","Resource":"arn:aws:s3:::my-example-bucket/*"}]}' | ||
} |
29 changes: 29 additions & 0 deletions
29
queries/notion_queries/notion_many_pages_deleted_query.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
AnalysisType: scheduled_query | ||
QueryName: Notion Many Pages Deleted Query | ||
Enabled: false | ||
Tags: | ||
- Notion | ||
- Data Security | ||
- Data Destruction | ||
Description: > | ||
A Notion User deleted multiple pages, which were not created or restored from the trash within the same hour. | ||
Query: | | ||
SELECT | ||
event:actor.person.email AS user | ||
,ARRAY_AGG(event:type) AS actions | ||
,event:details.page_name AS page_name | ||
,event:details.target.page_id AS id | ||
FROM | ||
panther_logs.public.notion_auditlogs | ||
WHERE | ||
p_occurs_since(1 hour) | ||
AND event:type IN ('page.deleted','page.created','page.restored_from_trash') | ||
AND event:details.target.type = 'page_id' | ||
AND page_name != '' | ||
AND event:actor.type = 'person' | ||
GROUP BY id, user, page_name | ||
HAVING | ||
actions = ARRAY_CONSTRUCT('page.deleted') | ||
Schedule: | ||
RateMinutes: 60 | ||
TimeoutMinutes: 2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
def rule(_): | ||
return True | ||
|
||
|
||
def title(event): | ||
user = event.get("user", "<NO_USER_FOUND>") | ||
return f"Notion User [{user}] deleted multiple pages." |
29 changes: 29 additions & 0 deletions
29
queries/notion_queries/notion_many_pages_deleted_sched.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
AnalysisType: scheduled_rule | ||
Filename: notion_many_pages_deleted_sched.py | ||
RuleID: "Notion.Many.Pages.Deleted.Sched" | ||
DisplayName: "Notion Many Pages Deleted" | ||
Enabled: true | ||
ScheduledQueries: | ||
- Notion Many Pages Deleted Query | ||
Tags: | ||
- Notion | ||
- Data Security | ||
- Data Destruction | ||
Severity: Medium | ||
Description: A Notion User deleted multiple pages, which were not created or restored from the trash within the same hour. | ||
DedupPeriodMinutes: 60 | ||
Threshold: 10 # Number of pages deleted; please change this value to suit your organization's needs. | ||
Runbook: Possible Data Destruction. Follow up with the Notion User to determine if this was done for a valid business reason. | ||
Reference: https://www.notion.so/help/duplicate-delete-and-restore-content | ||
Tests: | ||
- Name: query_result | ||
ExpectedResult: true | ||
Log: | ||
{ | ||
"actions": [ | ||
"page.deleted" | ||
], | ||
"id": "1360a5bb-da41-8177-bedb-d015d012392a", | ||
"page_name": "Newslette", | ||
"user": "[email protected]" | ||
} |
20 changes: 20 additions & 0 deletions
20
queries/okta_queries/okta_52_char_username_threat_hunt.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
AnalysisType: saved_query | ||
QueryName: "Okta Username Above 52 Characters Security Advisory" | ||
Description: > | ||
On October 30, 2024, a vulnerability was internally identified in generating the cache key for AD/LDAP DelAuth. The Bcrypt algorithm was used to generate the cache key where we hash a combined string of userId + username + password. Under a specific set of conditions, listed below, this could allow users to authenticate by providing the username with the stored cache key of a previous successful authentication. | ||
Customers meeting the pre-conditions should investigate their Okta System Log for unexpected authentications from usernames greater than 52 characters between the period of July 23rd, 2024 to October 30th, 2024. | ||
https://trust.okta.com/security-advisories/okta-ad-ldap-delegated-authentication-username/ | ||
Query: | | ||
SELECT | ||
p_event_time as p_timeline, | ||
* | ||
FROM | ||
panther_logs.public.okta_systemlog | ||
WHERE | ||
p_occurs_between('2024-07-22 00:00:00Z','2024-11-01 00:00:00Z') | ||
AND actor:type = 'User' | ||
AND eventType = 'user.session.start' | ||
AND outcome:result = 'SUCCESS' | ||
AND LEN(actor:alternateId) >= 52 | ||
ORDER by p_event_time ASC NULLS LAST | ||
LIMIT 100 |
12 changes: 12 additions & 0 deletions
12
queries/snowflake_queries/snowflake_attempted_login_by_disabled_user.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
def rule(_): | ||
return True | ||
|
||
|
||
def title(event): | ||
source = event.get("p_source_label", "<UNKNOWN SOURCE>") | ||
username = event.get("USER_NAME", "<UNKNOWN USER>") | ||
return f"{source}: Attempted signin by disabled user {username}" | ||
|
||
|
||
def alert_context(event): | ||
return event.get("user") |
42 changes: 42 additions & 0 deletions
42
queries/snowflake_queries/snowflake_attempted_login_by_disabled_user.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
AnalysisType: scheduled_rule | ||
Filename: snowflake_attempted_login_by_disabled_user.py | ||
RuleID: "Snowflake.Stream.AttemptedLoginByDisabledUser" | ||
Enabled: true | ||
ScheduledQueries: | ||
- Snowflake Attempted Login With Disabled User | ||
Severity: Low | ||
Reports: | ||
MITRE ATT&CK: | ||
- TA0001:T1078.004 | ||
Description: > | ||
Detects when a login is attempted by a disabled user account. | ||
Tags: | ||
- Snowflake | ||
- Behavior Analysis | ||
- Initial Access:Valid Accounts:Cloud Accounts | ||
Tests: | ||
- Name: Login by Disabled User | ||
ExpectedResult: true | ||
Log: | ||
{ | ||
"p_source_label": "SF-Prod", | ||
"user": { | ||
"CREATED_ON": "2024-10-09 19:43:05.083000000", | ||
"DEFAULT_ROLE": "PANTHER_AUDIT_VIEW_ROLE", | ||
"DISABLED": true, | ||
"DISPLAY_NAME": | ||
"FORMER_ADMIN", | ||
"EXT_AUTHN_DUO": false, | ||
"HAS_MFA": false, | ||
"HAS_PASSWORD": true, | ||
"HAS_RSA_PUBLIC_KEY": false, | ||
"LAST_SUCCESS_LOGIN": "2024-10-09 20:59:00.043000000", | ||
"LOGIN_NAME": "FORMER_ADMIN", | ||
"MUST_CHANGE_PASSWORD": false, | ||
"NAME": "FORMER_ADMIN", | ||
"OWNER": "ACCOUNTADMIN", | ||
"SNOWFLAKE_LOCK": false, | ||
"USER_ID": "51" | ||
}, | ||
"USER_NAME": "FORMER_ADMIN" | ||
} |
Oops, something went wrong.