diff --git a/packs/aws.yml b/packs/aws.yml index e47135121..abec46f57 100644 --- a/packs/aws.yml +++ b/packs/aws.yml @@ -143,6 +143,7 @@ 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 diff --git a/rules/aws_eks_rules/anonymous_api_access.py b/rules/aws_eks_rules/anonymous_api_access.py new file mode 100644 index 000000000..b85f24fde --- /dev/null +++ b/rules/aws_eks_rules/anonymous_api_access.py @@ -0,0 +1,30 @@ +from panther_aws_helpers import eks_panther_obj_ref + + +def rule(event): + # Check if the username is set to "system:anonymous", which indicates anonymous access + p_eks = eks_panther_obj_ref(event) + if p_eks.get("actor") == "system:anonymous": + return True + return False + + +def title(event): + p_eks = eks_panther_obj_ref(event) + return ( + f"Anonymous API access detected on Kubernetes API server " + f"from [{p_eks.get('sourceIPs')[0]}] to [{p_eks.get('resource')}] " + f"in namespace [{p_eks.get('ns')}] on [{p_eks.get('p_source_label')}]" + ) + + +def dedup(event): + p_eks = eks_panther_obj_ref(event) + return f"anonymous_access_{p_eks.get('p_source_label')}_{p_eks.get('sourceIPs')[0]}" + + +def alert_context(event): + p_eks = eks_panther_obj_ref(event) + mutable_event = event.to_dict() + mutable_event["p_eks"] = p_eks + return dict(mutable_event) diff --git a/rules/aws_eks_rules/anonymous_api_access.yml b/rules/aws_eks_rules/anonymous_api_access.yml new file mode 100644 index 000000000..e8f2548fb --- /dev/null +++ b/rules/aws_eks_rules/anonymous_api_access.yml @@ -0,0 +1,132 @@ +AnalysisType: rule +Filename: anonymous_api_access.py +RuleID: "Amazon.EKS.AnonymousAPIAccess" +DisplayName: "EKS Anonymous API Access Detected" +Enabled: true +LogTypes: + - Amazon.EKS.Audit +Severity: Medium +Reports: + MITRE ATT&CK: + - "TA0001:T1190" # Initial Access: Exploit Public-Facing Application +Description: > + This rule detects anonymous API requests made to the Kubernetes API server. + In production environments, anonymous access should be disabled to prevent + unauthorized access to the API server. +DedupPeriodMinutes: 60 +Reference: + https://kubernetes.io/docs/reference/access-authn-authz/authentication/#anonymous-requests +Runbook: > + Check the EKS cluster configuration and ensure that anonymous access + to the Kubernetes API server is disabled. This can be done by verifying the API + server arguments and authentication webhook configuration. +SummaryAttributes: + - user:username + - p_any_ip_addresses + - p_source_label +Tags: + - EKS + - Security Control + - API + - Initial Access:Exploit Public-Facing Application +Tests: + - Name: Anonymous API Access + ExpectedResult: true + Log: + { + "annotations": { + "authorization.k8s.io/decision": "allow", + "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding system:public-info-viewer" + }, + "apiVersion": "audit.k8s.io/v1", + "auditID": "abcde12345", + "kind": "Event", + "level": "Request", + "objectRef": { + "apiVersion": "v1", + "name": "test-pod", + "namespace": "default", + "resource": "pods" + }, + "p_any_aws_account_ids": [ + "123412341234" + ], + "p_any_aws_arns": [ + "arn:aws:iam::123412341234:role/DevAdministrator" + ], + "p_any_ip_addresses": [ + "8.8.8.8" + ], + "p_any_usernames": [ + "system:anonymous" + ], + "p_event_time": "2022-11-29 00:09:04.38", + "p_log_type": "Amazon.EKS.Audit", + "p_parse_time": "2022-11-29 00:10:25.067", + "p_row_id": "2e4ab474b0f0f7a4a8fff4f014a9b32a", + "p_source_id": "4c859cd4-9406-469b-9e0e-c2dc1bee24fa", + "p_source_label": "example-cluster-eks-logs", + "requestReceivedTimestamp": "2022-11-29 00:09:04.38", + "requestURI": "/api/v1/namespaces/default/pods/test-pod", + "responseStatus": { + "code": 200 + }, + "sourceIPs": [ + "8.8.8.8" + ], + "stage": "ResponseComplete", + "user": { + "username": "system:anonymous" + }, + "userAgent": "kubectl/v1.25.4" + } + - Name: Non-Anonymous API Access + ExpectedResult: false + Log: + { + "annotations": { + "authorization.k8s.io/decision": "allow", + "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding system:public-info-viewer" + }, + "apiVersion": "audit.k8s.io/v1", + "auditID": "abcde12345", + "kind": "Event", + "level": "Request", + "objectRef": { + "apiVersion": "v1", + "name": "test-pod", + "namespace": "default", + "resource": "pods" + }, + "p_any_aws_account_ids": [ + "123412341234" + ], + "p_any_aws_arns": [ + "arn:aws:iam::123412341234:role/DevAdministrator" + ], + "p_any_ip_addresses": [ + "8.8.8.8" + ], + "p_any_usernames": [ + "kubernetes-admin" + ], + "p_event_time": "2022-11-29 00:09:04.38", + "p_log_type": "Amazon.EKS.Audit", + "p_parse_time": "2022-11-29 00:10:25.067", + "p_row_id": "2e4ab474b0f0f7a4a8fff4f014a9b32a", + "p_source_id": "4c859cd4-9406-469b-9e0e-c2dc1bee24fa", + "p_source_label": "example-cluster-eks-logs", + "requestReceivedTimestamp": "2022-11-29 00:09:04.38", + "requestURI": "/api/v1/namespaces/default/pods/test-pod", + "responseStatus": { + "code": 200 + }, + "sourceIPs": [ + "8.8.8.8" + ], + "stage": "ResponseComplete", + "user": { + "username": "kubernetes-admin" + }, + "userAgent": "kubectl/v1.25.4" + }