Skip to content

Commit

Permalink
Merge branch 'develop' into helper-reorg
Browse files Browse the repository at this point in the history
  • Loading branch information
arielkr256 authored Oct 17, 2024
2 parents f5d800d + 32305a2 commit 8b16cf9
Show file tree
Hide file tree
Showing 13 changed files with 207 additions and 68 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/check-deprecated.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ on:
pull_request:

permissions:
contents: read
contents: read

jobs:
check_removed_rules:
Expand All @@ -20,10 +20,10 @@ jobs:
pypi.org:443
- name: Checkout panther-analysis
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1

- name: Fetch Release
run: |
git fetch --depth=1 origin release
git fetch --depth=1 origin develop
- name: Set python version
uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 #v5.2.0
Expand All @@ -39,4 +39,4 @@ jobs:
- name: Check for Removed Rules
run: |
pipenv run make check-deprecated
4 changes: 2 additions & 2 deletions .github/workflows/check-packs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
panther_analysis_tool check-packs || echo "errors=`cat errors.txt`" >> $GITHUB_OUTPUT
- name: Comment PR
uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6
uses: thollander/actions-comment-pull-request@e2c37e53a7d2227b61585343765f73a9ca57eda9
if: ${{ steps.check-packs.outputs.errors }}
with:
mode: upsert
Expand All @@ -54,7 +54,7 @@ jobs:
```
comment_tag: check-packs
- name: Delete comment
uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6
uses: thollander/actions-comment-pull-request@e2c37e53a7d2227b61585343765f73a9ca57eda9
if: ${{ !steps.check-packs.outputs.errors }}
with:
mode: delete
Expand Down
15 changes: 6 additions & 9 deletions .scripts/deleted_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,21 @@

def get_deleted_ids() -> set[str]:
# Run git diff, get output
result = subprocess.run(['git', 'diff', 'origin/release', 'HEAD'], capture_output=True)
result = subprocess.run(["git", "diff", "origin/develop", "HEAD"], capture_output=True)
if result.stderr:
raise Exception(result.stderr.decode("utf-8"))

ids = set()
for line in result.stdout.decode("utf-8").split("\n"):
if m := diff_pattern.match(line):
# Add the ID to the list
ids.add(m.group(1))

return ids


def get_deprecated_ids() -> set[str]:
""" Returns all the IDs listed in `deprecated.txt`. """
"""Returns all the IDs listed in `deprecated.txt`."""
with open("deprecated.txt", "r") as f:
return set(f.read().split("\n"))

Expand All @@ -43,6 +43,7 @@ def check(_):
else:
print("✅ No unaccounted deletions found! You're in the clear! 👍")


def remove(args):
api_token = args.api_token or os.environ.get("PANTHER_API_TOKEN")
api_host = args.api_host or os.environ.get("PANTHER_API_HOST")
Expand All @@ -61,11 +62,7 @@ def remove(args):
ids = list(get_deprecated_ids())

pat_args = argparse.Namespace(
analysis_id = ids,
query_id = [],
confirm_bypass = True,
api_token = api_token,
api_host = api_host
analysis_id=ids, query_id=[], confirm_bypass=True, api_token=api_token, api_host=api_host
)

logging.basicConfig(
Expand Down
7 changes: 6 additions & 1 deletion .scripts/mitre_mapping_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,13 @@


def main(path: Path) -> bool:
# Ignore any schema test files
# Schema tests can't be loaded by panther_analysis_tool because each file contains multiple
# YAML documents.
ignore_files = list(path.glob("**/*_tests.y*ml"))

# Load Repo
analysis_items = load_analysis_specs([path], ignore_files=[])
analysis_items = load_analysis_specs([path], ignore_files=ignore_files)

items_with_invalid_mappings = [] # Record all items with bad tags
for analysis_item in analysis_items:
Expand Down
9 changes: 9 additions & 0 deletions .vscode/rule_jsonschema.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

"type": "object",
"properties": {
"AlertTitle": {
"$ref": "#/definitions/AlertTitle"
},
"AnalysisType": {
"$ref": "#/definitions/AnalysisType"
},
Expand Down Expand Up @@ -85,6 +88,12 @@
}
],
"definitions": {
"AlertTitle": {
"$comment": "https://docs.panther.com/detections/rules/writing-simple-detections#alerttitle",
"description": "Use AlertTitle to dynamically set the title of an alert generated by a match on this detection.",
"type": "string",
"default": "rule"
},
"AnalysisType": {
"description": "what kind of detection",
"type": "string",
Expand Down
4 changes: 3 additions & 1 deletion deprecated.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@ AWS.CloudTrail.RootFailedConsoleLogin
AWS.S3.GreyNoiseActivity
AWS.CloudTrail.RootConsoleLogin
Okta.GeographicallyImprobableAccess
Okta.BruteForceLogins
Okta.BruteForceLogins
Query.Snowflake.PublicRoleGrant
Snowflake.PublicRoleGrant
2 changes: 0 additions & 2 deletions packs/snowflake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ PackDefinition:
- Query.Snowflake.KeyUserPasswordLogin
- Query.Snowflake.MFALogin
- Query.Snowflake.Multiple.Logins.Followed.By.Success
- Query.Snowflake.PublicRoleGrant
- Query.Snowflake.SuspectedUserAccess
- Query.Snowflake.TempStageCreated
- Query.Snowflake.UserCreated
Expand All @@ -38,7 +37,6 @@ PackDefinition:
- Snowflake.KeyUserPasswordLogin
- Snowflake.LoginWithoutMFA
- Snowflake.Multiple.Failed.Logins.Followed.By.Success
- Snowflake.PublicRoleGrant
- Snowflake.TempStageCreated
- Snowflake.User.Access
- Snowflake.UserCreated
Expand Down
2 changes: 0 additions & 2 deletions queries/snowflake_queries/snowflake_public_role_grant.py

This file was deleted.

16 changes: 0 additions & 16 deletions queries/snowflake_queries/snowflake_public_role_grant.yml

This file was deleted.

29 changes: 0 additions & 29 deletions queries/snowflake_queries/snowflake_public_role_grant_query.yml

This file was deleted.

35 changes: 35 additions & 0 deletions rules/gcp_audit_rules/gcp_user_added_to_privileged_group.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from panther_base_helpers import key_value_list_to_dict

PRIVILEGED_GROUPS = {
# "[email protected]"
}

USER_EMAIL = ""
GROUP_EMAIL = ""


def rule(event):
events = event.deep_get("protoPayload", "metadata", "event", default=[])

for event_ in events:
if event_.get("eventname") != "ADD_GROUP_MEMBER":
continue
# Get the username
params = key_value_list_to_dict(event_.get("parameter", []), "name", "value")
global USER_EMAIL, GROUP_EMAIL # pylint: disable=global-statement
USER_EMAIL = params.get("USER_EMAIL")
GROUP_EMAIL = params.get("GROUP_EMAIL")
if GROUP_EMAIL in get_privileged_groups():
return True
return False


def title(event):
actor = event.deep_get("actor", "email", default="")
global USER_EMAIL, GROUP_EMAIL
return f"{actor} has added {USER_EMAIL} to the privileged group {GROUP_EMAIL}"


def get_privileged_groups():
# We make this a function, so we can mock it for unit tests
return PRIVILEGED_GROUPS
140 changes: 140 additions & 0 deletions rules/gcp_audit_rules/gcp_user_added_to_privileged_group.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
AnalysisType: rule
Filename: gcp_user_added_to_privileged_group.py
RuleID: "GCP.User.Added.To.Privileged.Group"
DisplayName: "GCP User Added to Privileged Group"
Enabled: false
LogTypes:
- GCP.AuditLog
Severity: Low
Tags:
- Configuration Required
Reports:
MITRE ATT&CK:
- TA0004:T1078.004 # Privilege Escalation: Valid Accounts: Cloud Accounts
- TA0004:T1484.001 # Privilege Escalation: Domain or Tenant Policy Modification: Group Policy Modification
Description: A user was added to a group with special previleges
DedupPeriodMinutes: 60
Threshold: 1
Reference:
https://github.com/GoogleCloudPlatform/security-analytics/blob/main/src/2.02/2.02.md
Runbook: Determine if the user had been added to the group for legitimate reasons.
Tests:
- Name: User Added to Privileged Group
ExpectedResult: true
Mocks:
- objectName: get_privileged_groups
returnValue: '["[email protected]"]'
Log:
{
"logName": "organizations/123/logs/cloudaudit.googleapis.com%2Factivity",
"severity": "NOTICE",
"insertId": "285djodxlmu",
"resource": {
"type": "audited_resource",
"labels": {
"method": "google.admin.AdminService.addGroupMember",
"service": "admin.googleapis.com"
}
},
"timestamp": "2022-03-22T22:12:58.916Z",
"receiveTimestamp": "2022-03-22T22:12:59.439766009Z",
"protoPayload": {
"@type": "type.googleapis.com/google.cloud.audit.AuditLog",
"serviceName": "admin.googleapis.com",
"methodName": "google.admin.AdminService.addGroupMember",
"resourceName": "organizations/123/groupSettings",
"authenticationInfo": {
"principalEmail": "[email protected]"
},
"requestMetadata": {
"callerIP": "11.22.33.44",
"requestAttributes": {},
"destinationAttributes": {}
},
"metadata": {
"@type": "type.googleapis.com/ccc_hosted_reporting.ActivityProto",
"activityId": {
"timeUsec": "1647987178916000",
"uniqQualifier": "-8614641986436885296"
},
"event": [
{
"eventName": "ADD_GROUP_MEMBER",
"eventType": "GROUP_SETTINGS",
"parameter": [
{
"label": "LABEL_OPTIONAL",
"value": "[email protected]",
"type": "TYPE_STRING",
"name": "USER_EMAIL"
},
{
"type": "TYPE_STRING",
"value": "[email protected]",
"label": "LABEL_OPTIONAL",
"name": "GROUP_EMAIL"
}
]
}
]
}
}
}
- Name: User Added to Non-Privileged Group
ExpectedResult: false
Log:
{
"logName": "organizations/123/logs/cloudaudit.googleapis.com%2Factivity",
"severity": "NOTICE",
"insertId": "285djodxlmu",
"resource": {
"type": "audited_resource",
"labels": {
"method": "google.admin.AdminService.addGroupMember",
"service": "admin.googleapis.com"
}
},
"timestamp": "2022-03-22T22:12:58.916Z",
"receiveTimestamp": "2022-03-22T22:12:59.439766009Z",
"protoPayload": {
"@type": "type.googleapis.com/google.cloud.audit.AuditLog",
"serviceName": "admin.googleapis.com",
"methodName": "google.admin.AdminService.addGroupMember",
"resourceName": "organizations/123/groupSettings",
"authenticationInfo": {
"principalEmail": "[email protected]"
},
"requestMetadata": {
"callerIP": "11.22.33.44",
"requestAttributes": {},
"destinationAttributes": {}
},
"metadata": {
"@type": "type.googleapis.com/ccc_hosted_reporting.ActivityProto",
"activityId": {
"timeUsec": "1647987178916000",
"uniqQualifier": "-8614641986436885296"
},
"event": [
{
"eventName": "ADD_GROUP_MEMBER",
"eventType": "GROUP_SETTINGS",
"parameter": [
{
"label": "LABEL_OPTIONAL",
"value": "[email protected]",
"type": "TYPE_STRING",
"name": "USER_EMAIL"
},
{
"type": "TYPE_STRING",
"value": "[email protected]",
"label": "LABEL_OPTIONAL",
"name": "GROUP_EMAIL"
}
]
}
]
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ def title(event):
return (
f"GSuite workspace setting for default calendar sharing was changed by "
f"[{event.deep_get('actor', 'email', default='<UNKNOWN_EMAIL>')}] "
f"from [{event.deep_get('parameters', 'OLD_VALUE', default='<NO_OLD_SETTING_FOUND>')}] "
f"to [{event.deep_get('parameters', 'NEW_VALUE', default='<NO_NEW_SETTING_FOUND>')}]"
+ f"from [{event.deep_get('parameters', 'OLD_VALUE', default='<NO_OLD_SETTING_FOUND>')}] "
+ "to [{event.deep_get('parameters', 'NEW_VALUE', default='<NO_NEW_SETTING_FOUND>')}]"
)

0 comments on commit 8b16cf9

Please sign in to comment.