Skip to content

Commit

Permalink
Merge branch 'develop' into ben/check-packs-action/fix-comments
Browse files Browse the repository at this point in the history
  • Loading branch information
arielkr256 authored Nov 13, 2024
2 parents ec30ea9 + 9098060 commit 6ca2d0f
Show file tree
Hide file tree
Showing 11 changed files with 1,607 additions and 598 deletions.
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
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
1 change: 1 addition & 0 deletions packs/standard_ruleset.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,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
30 changes: 0 additions & 30 deletions rules/aws_eks_rules/anonymous_api_access.py

This file was deleted.

132 changes: 0 additions & 132 deletions rules/aws_eks_rules/anonymous_api_access.yml

This file was deleted.

68 changes: 68 additions & 0 deletions rules/standard_rules/sign_in_from_rogue_state.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import panther_event_type_helpers as event_type
import pycountry

# Configuration Required:
# Configure the below list of rogue states according to your needs/experience
# Refer to the link below to find the alpha-2 code corresponding to your country
# https://www.iban.com/country-codes
ROGUE_STATES = {"CN", "IR", "RU"}


def rule(event):
# Only evaluate successful logins
if event.udm("event_type") != event_type.SUCCESSFUL_LOGIN:
return False

# Ignore events with no IP data
if not event.udm("source_ip"):
return False

# Get contry of request origin and compare to identified rogue state list
country = get_country(event)
if country is None:
# We weren't able to find a matching country, therefore we don't have enough information
# to alert on
return False
# Wrapping in 'bool' so that we can use mocking for 'is_rogue_state'
return bool(is_rogue_state(country.alpha_2))


def title(event):
log_type = event.get("p_log_type")
country = get_country(event)
account_name = get_account_name(event)
return f"{log_type}: Sign-In for account {account_name} from Rogue State '{country.name}'"


def alert_context(event):
return {
"source_ip": event.udm("source_ip"),
"country": get_country(event).name,
"account_name": get_account_name(event),
}


def get_country(event) -> str:
"""Returns the country code from an event's IPinfo data."""
location_data = event.deep_get("p_enrichment", "ipinfo_location", event.udm_path("source_ip"))
if not location_data:
return None # Ignore event if we have no enrichment to analyze
return pycountry.countries.get(alpha_2=location_data.get("country").upper())


def get_account_name(event) -> str:
"""Returns the account name."""
if account_name := event.deep_get("p_udm", "user", "email"):
return account_name
if account_name := event.deep_get("p_udm", "user", "name"):
return account_name
if account_name := event.udm("actor_user"):
return account_name
return "UNKNWON ACCOUNT"


def is_rogue_state(country_code: str) -> bool:
"""Returns whether the country code provided belongs to an identified rogue state."""
# This function makes it easy for us to use unit test mocks to ensure altering the ROGUE_STATES
# dict doesn't break our test suite.
return country_code in ROGUE_STATES
Loading

0 comments on commit 6ca2d0f

Please sign in to comment.