Skip to content

Commit

Permalink
Merge branch 'main' into egibs-sync-74
Browse files Browse the repository at this point in the history
  • Loading branch information
Evan Gibler authored Feb 8, 2024
2 parents 5ca4f1d + f689228 commit cf1becc
Show file tree
Hide file tree
Showing 17 changed files with 61 additions and 33 deletions.
1 change: 1 addition & 0 deletions rules/aws_cloudtrail_rules/aws_ecr_crud.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ LogTypes:
Tags:
- AWS
- Security Control
- Configuration Required
Reports:
CIS:
- 3.12
Expand Down
1 change: 1 addition & 0 deletions rules/aws_cloudtrail_rules/aws_ecr_events.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from panther_base_helpers import aws_rule_context, deep_get

# CONFIGURATION REQUIRED: Update with your expected AWS Accounts/Regions
AWS_ACCOUNTS_AND_REGIONS = {
"123456789012": {"us-west-1", "us-west-2"},
"103456789012": {"us-east-1", "us-east-2"},
Expand Down
3 changes: 2 additions & 1 deletion rules/aws_cloudtrail_rules/aws_ecr_events.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ LogTypes:
Tags:
- AWS
- Security Control
- Configuration Required
Reports:
MITRE ATT&CK:
- TA0005:T1535
Severity: High
Severity: Medium
Description: An ECR event occurred outside of an expected account or region
Runbook: https://docs.aws.amazon.com/AmazonECR/latest/userguide/logging-using-cloudtrail.html
Reference: https://aws.amazon.com/blogs/containers/amazon-ecr-in-multi-account-and-multi-region-architectures/
Expand Down
4 changes: 4 additions & 0 deletions rules/aws_cloudtrail_rules/aws_software_discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,9 @@ def title(event):
)


def dedup(event):
return deep_get(event, "userIdentity", "principalId")


def alert_context(event):
return aws_rule_context(event)
4 changes: 2 additions & 2 deletions rules/aws_cloudtrail_rules/aws_software_discovery.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ Tests:
eventVersion: "1.08"
managementEvent: false
Name: Non Discovery Event Names
DedupPeriodMinutes: 15
DedupPeriodMinutes: 360 # 6 hours
LogTypes:
- AWS.CloudTrail
RuleID: "AWS.Software.Discovery"
Threshold: 5
Threshold: 50
4 changes: 2 additions & 2 deletions rules/aws_cloudtrail_rules/aws_unauthorized_api_call.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Filename: aws_unauthorized_api_call.py
RuleID: "AWS.CloudTrail.UnauthorizedAPICall"
DisplayName: "Monitor Unauthorized API Calls"
Enabled: true
DedupPeriodMinutes: 720 # 12 hours
DedupPeriodMinutes: 1440 # 24 hours
LogTypes:
- AWS.CloudTrail
Tags:
Expand All @@ -24,7 +24,7 @@ SummaryAttributes:
- sourceIpAddress
- recipientAccountId
- p_any_aws_arns
Threshold: 10
Threshold: 20
Tests:
-
Name: Unauthorized API Call from Within AWS (IP)
Expand Down
2 changes: 1 addition & 1 deletion rules/aws_eks_rules/system_namespace_public_ip.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def title(event):

def dedup(event):
p_eks = eks_panther_obj_ref(event)
return f"{p_eks.get('p_source_label')}_eks_system_namespace_{p_eks.get('actor')}"
return f"{p_eks.get('p_source_label')}_eks_system_namespace_{p_eks.get('sourceIPs')[0]}"


def alert_context(event):
Expand Down
14 changes: 7 additions & 7 deletions rules/aws_eks_rules/system_namespace_public_ip.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ LogTypes:
- Amazon.EKS.Audit
Tags:
- EKS
#Reports: # (Optional)
# MITRE ATT&CK:
# - 'TA0027:T1475' # Tactic ID:Technique ID (https://attack.mitre.org/tactics/enterprise/)
Reports:
MITRE ATT&CK:
- 'TA0027:T1475' # Tactic ID:Technique ID (https://attack.mitre.org/tactics/enterprise/)
Reference: https://docs.aws.amazon.com/eks/latest/userguide/network_reqs.html
Severity: Info
Description: > # (Optional)
Description: >
This detection identifies if an activity is recorded in the Kubernetes audit log where
the user:username attribute begins with "system:" or "eks:" and the requests originating
IP Address is a Public IP Address
DedupPeriodMinutes: 15 # The amount of time in minutes for grouping alerts (Optional, defaults to 60)
Threshold: 1 # The minimum number of event matches prior to an alert sending (Optional, defaults to 1)
SummaryAttributes: # A list of fields in the event to create top 5 summaries for (Optional)
DedupPeriodMinutes: 1440 # 24 hours
Threshold: 1
SummaryAttributes:
- user:username
- p_source_label
Tests:
Expand Down
8 changes: 4 additions & 4 deletions rules/gsuite_reports_rules/gsuite_drive_overly_visible.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ def rule(event):


def dedup(event):
details = details_lookup("access", RESOURCE_CHANGE_EVENTS, event)
if param_lookup(details.get("parameters", {}), "doc_title"):
return param_lookup(details.get("parameters", {}), "doc_title")
return "<UNKNOWN_DOC_TITLE>"
user = deep_get(event, "actor", "email")
if user is None:
user = deep_get(event, "actor", "profileId", default="<UNKNOWN_PROFILEID>")
return user


def title(event):
Expand Down
1 change: 1 addition & 0 deletions rules/gsuite_reports_rules/gsuite_drive_overly_visible.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Runbook: >
Investigate whether the drive document is appropriate to be this visible.
SummaryAttributes:
- actor:email
DedupPeriodMinutes: 360 # 6 hours
Tests:
-
Name: Access Event
Expand Down
10 changes: 4 additions & 6 deletions rules/gsuite_reports_rules/gsuite_drive_visibility_change.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,7 @@ def alert_context(event):


def dedup(event):
log = event.get("p_row_id")
return ALERT_DETAILS[log]["DOC_TITLE"]
return deep_get(event, "actor", "email", default="<UNKNOWN_USER>")


def title(event):
Expand All @@ -193,12 +192,11 @@ def title(event):
elif ALERT_DETAILS[log]["NEW_VISIBILITY"] == "public_in_the_domain":
sharing_scope += f" (anyone in {ALERT_DETAILS[log]['TARGET_DOMAIN']})"

alert_access_scope = ALERT_DETAILS[log]["ACCESS_SCOPE"][0].replace("can_", "")
# alert_access_scope = ALERT_DETAILS[log]["ACCESS_SCOPE"][0].replace("can_", "")

return (
f"User [{deep_get(event, 'actor', 'email', default='<UNKNOWN_USER>')}] made the document "
f"[{ALERT_DETAILS[log]['DOC_TITLE']}] externally visible to [{sharing_scope}] with "
f"[{alert_access_scope}] access"
f"User [{deep_get(event, 'actor', 'email', default='<UNKNOWN_USER>')}] made documents "
f"externally visible"
)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Runbook: >
Investigate whether the drive document is appropriate to be publicly accessible.
SummaryAttributes:
- actor:email
DedupPeriodMinutes: 360 # 6 hours
Tests:
-
Name: Access Event
Expand Down
4 changes: 2 additions & 2 deletions rules/okta_rules/okta_anonymizing_vpn_login.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ LogTypes:
Reports:
MITRE ATT&CK:
- TA0006:T1556 # Modify Authentication Process
Severity: High
Severity: Medium
Description: >
A user is attempting to sign-in to Okta from a known VPN anonymizer. The threat actor would access the compromised account using anonymizing proxy services.
Runbook: >
Restrict this access to trusted Network Zones and deny access from anonymizing proxies in policy using a Dynamic Network Zone.
Reference: >
https://sec.okta.com/articles/2023/08/cross-tenant-impersonation-prevention-and-detection
DedupPeriodMinutes: 30
DedupPeriodMinutes: 360 # 6 hours
Threshold: 1
Tests:
- Name: Other Event
Expand Down
15 changes: 12 additions & 3 deletions rules/okta_rules/okta_potentially_stolen_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def rule(event):
global PREVIOUS_SESSION

session_id = deep_get(event, "authenticationContext", "externalSessionId", default="unknown")
dt_hash = deep_get(event, "debugContext", "debugData", "dtHash", default="unknown")

# Some events by Okta admins may appear to have changed IPs
# and user agents due to internal Okta behavior:
Expand All @@ -30,7 +31,9 @@ def rule(event):
return False

# Filter only on app access and session start events
if event.get("eventType") not in EVENT_TYPES or session_id == "unknown":
if event.get("eventType") not in EVENT_TYPES or (
session_id == "unknown" or dt_hash == "unknown"
):
return False

# lookup if we've previously stored the session cookie
Expand All @@ -41,8 +44,8 @@ def rule(event):
PREVIOUS_SESSION = set(json.loads(PREVIOUS_SESSION))

# If the sessionID has not been seen before, store information about it
if len(PREVIOUS_SESSION) == 0:
key = session_id
if not PREVIOUS_SESSION:
key = session_id + "-" + dt_hash
put_string_set(
key,
[
Expand All @@ -53,6 +56,12 @@ def rule(event):
deep_get(event, "client", "userAgent", "browser"),
deep_get(event, "client", "userAgent", "os"),
event.get("p_event_time"),
"sign_on_mode:"
+ deep_get(event, "debugContext", "debugData", "signOnMode", default="unknown"),
"threat_suspected:"
+ deep_get(
event, "debugContext", "debugData", "threat_suspected", default="unknown"
),
],
epoch_seconds=event.event_time_epoch() + SESSION_TIMEOUT,
)
Expand Down
7 changes: 5 additions & 2 deletions rules/okta_rules/okta_potentially_stolen_session.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ Tests:
"requestId": "redacted",
"requestUri": "redacted",
"threatSuspected": "false",
"url": "redacted"
"url": "redacted",
"dtHash": "kzpx58a99d2oam082rlu588wgy1mb0zfi1e1l63f9cjx4uxc455k4t6xdiwbxian"
}
},
"displayMessage": "User login to Okta",
Expand Down Expand Up @@ -176,6 +177,7 @@ Tests:
},
"debugContext": {
"debugData": {
"dtHash": "kzpx58a99d2oam082rlu588wgy1mb0zfi1e1l63f9cjx4uxc455k4t6xdiwbxian",
"loginResult": "VERIFICATION_ERROR",
"requestId": "redacted",
"requestUri": "redacted",
Expand Down Expand Up @@ -288,7 +290,8 @@ Tests:
"requestId": "redacted",
"requestUri": "redacted",
"threatSuspected": "false",
"url": "redacted"
"url": "redacted",
"dtHash": "kzpx58a99d2oam082rlu588wgy1mb0zfi1e1l63f9cjx4uxc455k4t6xdiwbxian"
}
},
"displayMessage": "User login to Okta",
Expand Down
11 changes: 10 additions & 1 deletion rules/okta_rules/okta_rate_limits.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
DETECTION_EVENTS = [
"app.oauth2.client_id_rate_limit_warning",
"application.integration.rate_limit_exceeded",
"system.client.concurrency_rate_limit.notification",
"system.client.rate_limit.*",
"system.client.concurrency_rate_limit.*",
"system.operation.rate_limit.*",
"system.org.rate_limit.*",
"core.concurrency.org.limit.violation",
]


Expand All @@ -29,6 +31,13 @@ def title(event):
def severity(event):
if event.get("severity", "") == "INFO":
return "INFO"
eventtype = event.get("eventtype", "")
if "notification" in eventtype:
return "LOW"
if "warning" in eventtype:
return "MEDIUM"
if "violation" in eventtype:
return "HIGH"
return "DEFAULT"


Expand Down
4 changes: 2 additions & 2 deletions rules/okta_rules/okta_rate_limits.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Reports:
MITRE ATT&CK:
- TA0006:T1110
- TA0040:T1498
Reference: https://help.okta.com/en-us/content/topics/security/api-rate-limits.htm
Reference: https://developer.okta.com/docs/reference/rl-system-log-events/
Tests:
- ExpectedResult: true
Log:
Expand Down Expand Up @@ -236,7 +236,7 @@ Tests:
uuid: aa-11-22-33-44-bb
version: "0"
Name: Non event
DedupPeriodMinutes: 60
DedupPeriodMinutes: 360 # 6 hours
LogTypes:
- Okta.SystemLog
RuleID: "Okta.Rate.Limits"
Expand Down

0 comments on commit cf1becc

Please sign in to comment.