Skip to content

Commit

Permalink
new rule: GCP.User.Added.To.Privileged.Group
Browse files Browse the repository at this point in the history
  • Loading branch information
ben-githubs committed Oct 3, 2024
1 parent 38d0ce8 commit a42c190
Show file tree
Hide file tree
Showing 3 changed files with 234 additions and 0 deletions.
31 changes: 31 additions & 0 deletions global_helpers/panther_base_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -538,3 +538,34 @@ def key_value_list_to_dict(list_objects: List[dict], key: str, value: str) -> di
# example: [{'key': 'a', 'value': 1}, {'key': 'b', 'value': 2}]
# becomes: {'a': 1, 'b': 2}
return {item[key]: item[value] for item in list_objects}


def array_to_dict(array: List[dict], key: str, error_on_duplicate: bool = False) -> dict:
"""Take a list of dictionaries and convert them into a dictionary based on a unique key.
Args:
array (list of dicts): Array containing the dictionaries to itemize
key (str): Specified which value of each listed dict to use as key in the returned dict
For each dictionary 'D' in 'array', the corresponding key in the returned dict R is the
value D[key], so R[D[key]] = D.
error_on_duplicate (bool, optional): Raise KeyError if 2 dicts share the same value for key.
If False, previous entries are overridden by later entries of 'array' with the same key
value. (Default: False)
Returns:
out (dict): dictionary mapping for each dictionary in 'array'.
Raises:
KeyError: If any of the following occurs:
- a dictionary in 'array' does not have an entry for 'key'
- if 'error_on_duplicate' is True and multiple dictionaries in 'array' have the same
key value
"""
out = {}
for dict_ in array:
keyval = dict_[key]
if error_on_duplicate and keyval in out:
raise KeyError(f"Multiple entries in array share the same value for '{key}': {keyval}")
out[keyval] = dict_

return out
37 changes: 37 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,37 @@
from panther_base_helpers import array_to_dict, deep_get

PRIVILEGED_GROUPS = {
# "[email protected]"
}

USER_EMAIL = ""
GROUP_EMAIL = ""


def rule(event):
events = event.deep_get("protoPayload", "metadata", "event")
if len(events) != 1:
return False

event_ = events[0]
if event_.get("eventname") != "ADD_GROUP_MEMBER":
return False

# Get the username
params = array_to_dict(event_.get("parameter", []), "name")
global USER_EMAIL, GROUP_EMAIL # pylint: disable=global-statement
USER_EMAIL = deep_get(params, "USER_EMAIL", "value", default="<UNKNOWN USER>")
GROUP_EMAIL = deep_get(params, "GROUP_EMAIL", "value", default="<UNKNOWN GROUP")

return GROUP_EMAIL in get_privileged_groups()


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
166 changes: 166 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,166 @@
AnalysisType: rule
Filename: gcp_user_added_to_privileged_group.py
RuleID: "GCP.User.Added.To.Privileged.Group"
DisplayName: "GCP VPC Flow Logs Disabled"
Enabled: true
LogTypes:
- GCP.AuditLog
Severity: Low
Reports:
MITRA 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": "203.0.113.255",
"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"
}
]
}
]
}
},
"p_log_type": "GCP.AuditLog",
"p_row_id": "82d46669e6e2d9e985b8f7912201",
"p_schema_version": 0,
"p_event_time": "2022-03-22T22:12:58.916Z",
"p_parse_time": "2024-10-03T20:15:59.396527Z",
"p_any_ip_addresses": [
"203.0.113.255"
],
"p_any_emails": [
"[email protected]"
],
"p_any_usernames": [
"admin"
]
}
- 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": "203.0.113.255",
"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"
}
]
}
]
}
},
"p_log_type": "GCP.AuditLog",
"p_row_id": "82d46669e6e2d9e985b8f7912201",
"p_schema_version": 0,
"p_event_time": "2022-03-22T22:12:58.916Z",
"p_parse_time": "2024-10-03T20:15:59.396527Z",
"p_any_ip_addresses": [
"203.0.113.255"
],
"p_any_emails": [
"[email protected]"
],
"p_any_usernames": [
"admin"
]
}

0 comments on commit a42c190

Please sign in to comment.