Skip to content

Commit

Permalink
Merge branch 'develop' into ben/deprecate-notion-many-pages-deleted
Browse files Browse the repository at this point in the history
  • Loading branch information
arielkr256 authored Nov 13, 2024
2 parents 1dac0d4 + fe0038e commit eadf307
Show file tree
Hide file tree
Showing 24 changed files with 1,936 additions and 613 deletions.
23 changes: 10 additions & 13 deletions .github/workflows/check-packs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,19 @@ jobs:
run: pip install panther_analysis_tool

- name: Check packs
continue-on-error: true
id: check-packs
run: |
# Get the output for the PR comment body
panther_analysis_tool check-packs 2> errors.txt || true
echo ::set-output name=errors::`cat errors.txt`
# run again to get exit code
panther_analysis_tool check-packs || echo "errors=`cat errors.txt`" >> $GITHUB_OUTPUT
- name: Check packs (Exit Code)
run: |
exit $(panther_analysis_tool check-packs)
- name: Comment PR
uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b
if: ${{ steps.check-packs.outputs.errors }}
uses: thollander/actions-comment-pull-request@v3
if: failure()
with:
mode: upsert
message: |
Expand All @@ -56,15 +58,10 @@ jobs:
${{ steps.check-packs.outputs.errors }}
```
comment-tag: check-packs

- name: Delete comment
uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b
if: ${{ !steps.check-packs.outputs.errors }}
uses: thollander/actions-comment-pull-request@v3
if: success()
with:
mode: delete
message: |
:scream:
looks like some things could be wrong with the packs
```diff
${{ steps.check-packs.outputs.errors }}
```
comment-tag: check-packs
1 change: 1 addition & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ policyuniverse = "==1.5.1.20230817"
requests = "==2.31.0"
panther-analysis-tool = "~=0.54.0"
panther-detection-helpers = "==0.4.0"
pycountry = "==24.6.1"

[requires]
python_version = "3.11"
869 changes: 440 additions & 429 deletions Pipfile.lock

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions data_models/onelogin_data_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@

def get_event_type(event):
# currently, only tracking a handful of event types
if event.get("event_type_id") == 72 and event.get("privilege_name") == "Super user":
event_type_id = str(event.get("event_type_id"))
if event_type_id == "72" and event.get("privilege_name") == "Super user":
return event_type.ADMIN_ROLE_ASSIGNED
if event.get("event_type_id") == 6:
if event_type_id == "6":
return event_type.FAILED_LOGIN
if event.get("event_type_id") == 5:
if event_type_id == "5":
return event_type.SUCCESSFUL_LOGIN
if event.get("event_type_id") == 13:
if event_type_id == "13":
return event_type.USER_ACCOUNT_CREATED
return None
9 changes: 7 additions & 2 deletions global_helpers/panther_azuresignin_helpers.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
from panther_base_helpers import deep_get


def actor_user(event):
# 'event' could be a PantherEvent or an ImmutableCaseInsensitiveDict, so we have to use the
# imported deep_get method.
category = event.get("category", "")
if category in {"ServicePrincipalSignInLogs"}:
return event.deep_get("properties", "servicePrincipalName")
return deep_get(event, "properties", "servicePrincipalName")
if category in {"SignInLogs", "NonInteractiveUserSignInLogs"}:
return event.deep_get("properties", "userPrincipalName")
return deep_get(event, "properties", "userPrincipalName")
return None


Expand Down
1 change: 0 additions & 1 deletion packs/aws.yml
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ PackDefinition:
- AWS.CMK.KeyRotation
- AWS.DynamoDB.TableTTLEnabled
- AWS.EC2.Vulnerable.XZ.Image.Launched
- Amazon.EKS.AnonymousAPIAccess
- AWS.IAM.Policy.DoesNotGrantAdminAccess
- AWS.IAM.Policy.DoesNotGrantNetworkAdminAccess
- AWS.IAM.Resource.DoesNotHaveInlinePolicy
Expand Down
3 changes: 1 addition & 2 deletions packs/azure_signin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ PackDefinition:
# Globals used in these detections
- global_filter_azuresignin
- panther_azuresignin_helpers


- panther_base_helpers
- panther_event_type_helpers
# Data Models
- Standard.Azure.Audit.SignIn
Expand Down
8 changes: 8 additions & 0 deletions packs/snowflake_streaming.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,24 @@ PackDefinition:
- Snowflake.PotentialBruteForceSuccess
# Helpers
- panther_snowflake_helpers
# Queries
- Snowflake Attempted Login With Disabled User
- Snowflake User Daily Query Volume Spike
- Snowflake User Daily Query Volume Spike - Threat Hunting
- Suspicious Snowflake Sessions - Unusual Application
# Rules
- Snowflake.Stream.AccountAdminGranted
- Snowflake.Stream.AttemptedLoginByDisabledUser
- Snowflake.Stream.BruteForceByIp
- Snowflake.Stream.BruteForceByUsername
- Snowflake.Stream.ExternalShares
- Snowflake.Stream.FileDownloaded
- Snowflake.Stream.LoginSuccess
- Snowflake.Stream.LoginWithoutMFA
- Snowflake.Stream.PublicRoleGrant
- Snowflake.Stream.SuspiciousSession.UnusualApp
- Snowflake.Stream.TableCopiedIntoStage
- Snowflake.Stream.TempStageCreated
- Snowflake.Stream.UserCreated
- Snowflake.Stream.UserDailyQueryVolumeSpike
- Snowflake.Stream.UserEnabled
3 changes: 3 additions & 0 deletions packs/standard_ruleset.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ PackDefinition:
- Standard.Asana.Audit
- Standard.Atlassian.Audit
- Standard.AWS.CloudTrail
- Standard.Azure.Audit.SignIn
- Standard.Box.Event
- Standard.GCP.AuditLog
- Standard.Github.Audit
Expand All @@ -18,6 +19,7 @@ PackDefinition:
- Standard.OnePassword.ItemUsage
- Standard.OnePassword.SignInAttempt
- Standard.Zendesk.AuditLog
- Standard.Zoom.Activity
- Standard.Zoom.Operation
# Standard Detections
- Standard.AdminRoleAssigned
Expand All @@ -26,6 +28,7 @@ PackDefinition:
- Standard.MFADisabled
- Standard.NewAWSAccountCreated
- Standard.NewUserAccountCreated
- Standard.SignInFromRogueState
# Global Helpers
- panther_base_helpers
- panther_aws_helpers
Expand Down
20 changes: 20 additions & 0 deletions queries/okta_queries/okta_52_char_username_threat_hunt.yml
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
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")
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"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
AnalysisType: scheduled_query
QueryName: Snowflake Attempted Login With Disabled User
Enabled: false
Description: >
Returns instances where a disabled user's login credentials were used in a login
attempt.
Tags:
- Snowflake
Query: |
with disabled_users as (
select DATA as USER from panther_logs.public.snowflake_users_variant
where USER:DISABLED = true
),
logins as (
select * from
panther_logs.public.snowflake_loginhistory
where p_occurs_since('24h', , p_parse_time)
)
select * from logins join disabled_users
on logins.USER_NAME = disabled_users.USER:NAME
Schedule:
RateMinutes: 1440
TimeoutMinutes: 2
16 changes: 16 additions & 0 deletions queries/snowflake_queries/snowflake_suspicious_session.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
def rule(_):
return True


def title(event):
return f"{event.get('p_source_label', '<UNKNOWN SOURCE>')}: Suspicious Application Session"


def dedup(event):
return "-".join(
(
event.get("client_application", "<UNKNOWN APP>"),
event.get("client_os", "<UNKNOWN OS>"),
event.get("client_os_version", "<UNKNOWN VERSION>"),
)
)
30 changes: 30 additions & 0 deletions queries/snowflake_queries/snowflake_suspicious_session.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
AnalysisType: scheduled_rule
Filename: snowflake_suspicious_session.py
RuleID: "Snowflake.Stream.SuspiciousSession.UnusualApp"
DisplayName: Suspicious Snowflake Sessions - Unusual Application
Enabled: true
ScheduledQueries:
- "Suspicious Snowflake Sessions - Unusual Application"
Severity: Low
Reports:
MITRE ATT&CK:
- TA0001:T1078.004
Description: Detects unusual (non-common) applications and client characteristics
that have been used to connect to a Snowflake account
DedupPeriodMinutes: 1440
Tags:
- Snowflake
- Behavior Analysis
- Initial Access:Valid Accounts:Cloud Accounts
Tests:
- Name: New Session
ExpectedResult: true
Log:
{
"p_source_id": "26c3f2be-005e-443a-90cb-f623522f37a2",
"p_source_label": "SF Prod",
"client_application": "Snowflake Web App",
"first_seen": "2024-10-09 14:48:33.284",
"last_seen": "2024-10-09 15:01:13.492",
"n_sessions": 83
}
33 changes: 33 additions & 0 deletions queries/snowflake_queries/snowflake_suspicious_session_query.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
AnalysisType: scheduled_query
QueryName: Suspicious Snowflake Sessions - Unusual Application
Enabled: false
Description: This query can be used for the detection of unusual, non-common applications
and client characteristics that had been used to connect to the Snowflake account,
using a comparison to the previous usage baseline.
Schedule:
RateMinutes: 1320
TimeoutMinutes: 2
Tags:
- Snowflake
- Configuration Required
Query: |
-- Adjustments as follows:
-- adjust n_sessions threshold on line 18 as needed
-- adjust baseline lookback period on line 16 as desired
-- adust recent lookpack period on line 19 as desired
-- adjust scheduled query period to be 2 hrs shorter than the lookback window on line 19
select
CLIENT_ENVIRONMENT:APPLICATION as client_application,
CLIENT_ENVIRONMENT:OS as client_os,
CLIENT_ENVIRONMENT:OS_VERSION as client_os_version,
min(CREATED_ON) as first_seen,
max(CREATED_ON) as last_seen,
count(*) as n_sessions,
p_source_id,
p_source_label
from panther_logs.public.snowflake_sessions
where p_occurs_since(90d)
group by client_application, client_os, client_os_version, p_source_id, p_source_label
having n_sessions > 50
and first_seen > timeadd('day', -10, p_current_timestamp())
order by n_sessions desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
def rule(_):
return True


def title(event):
username = event.get("user_name", "<UNKNOWN USER>")
source = event.get("p_source_label", "<UNKNOWN SOURCE>")
return f"{source}: Abnormally large query volume from user {username}"
36 changes: 36 additions & 0 deletions queries/snowflake_queries/snowflake_user_query_volume_spike.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
AnalysisType: scheduled_rule
Filename: snowflake_user_query_volume_spike.py
RuleID: "Snowflake.Stream.UserDailyQueryVolumeSpike"
DisplayName: "Snowflake User Daily Query Volume Spike"
Enabled: true
ScheduledQueries:
- "Snowflake User Daily Query Volume Spike"
Severity: Low
Reports:
MITRE ATT&CK:
- TA0010:T1567
Description: >
Returns instances where a user's cumulative daily query volume is much larger than
normal. Could indicate exfiltration attempts.
Runbook: >
Review the user's query history for the past day. Identify any large queries
and determine if any data was accessed that shouldn't be.
Tags:
- Snowflake
- Behavior Analysis
- Exfiltration:Exfiltration Over Web Service
Tests:
- Name: High Query Volume
ExpectedResult: true
Log:
{
"p_source_id": "26c3f2be-005e-443a-90cb-f623522f37a2",
"p_source_label": "SF Prod",
"daily_bytes": 1376806.35210866,
"mean": 729289.7142857143,
"std_dev": 206110.99016770572,
"tend": "2024-10-21 22:09:13.47Z",
"tstart": "2024-10-20 22:09:13.47Z",
"USER_NAME": "ZEEBLE_BROMBUS",
"zscore": 3.141592,
}
Loading

0 comments on commit eadf307

Please sign in to comment.