Detection rules › Panther

EKS Audit Log based single sourceIP is generating multiple 403s

Severity
informational
Entities
aws_account_ids, aws_arns, ip_addresses, usernames
Log types
Amazon.EKS.Audit
Tags
EKS
Reference
https://aws.github.io/aws-eks-best-practices/security/docs/detective/
Source
github.com/panther-labs/panther-analysis

This detection identifies if a public sourceIP is generating multiple 403s with the Kubernetes API server.

MITRE ATT&CK coverage

Rule body yaml

AnalysisType: rule
Filename: source_ip_multiple_403.py
RuleID: "Amazon.EKS.Audit.Multiple403"
DisplayName: "EKS Audit Log based single sourceIP is generating multiple 403s"
Enabled: true
LogTypes:
  - Amazon.EKS.Audit
Tags:
  - EKS
Reports:
  MITRE ATT&CK:
    - "TA0007:T1613"
Reference: https://aws.github.io/aws-eks-best-practices/security/docs/detective/
Severity: Info
Description: > # (Optional)
  This detection identifies if a public sourceIP is generating multiple 403s
  with the Kubernetes API server.
DedupPeriodMinutes: 30 # The amount of time in minutes for grouping alerts (Optional, defaults to 60)
Threshold: 10 # 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)
  - user:username
  - p_any_ip_addresses
  - p_source_label
Tests:
  - Name: Not 403
    ExpectedResult: false
    Log:
      {
        "annotations":
          {
            "authorization.k8s.io/decision": "allow",
            "authorization.k8s.io/reason": "",
          },
        "apiVersion": "audit.k8s.io/v1",
        "auditID": "35506555-dffc-4337-b2b1-c4af52b88e18",
        "kind": "Event",
        "level": "Request",
        "objectRef":
          {
            "apiVersion": "v1",
            "name": "kube-bench-drn4j",
            "namespace": "default",
            "resource": "pods",
            "subresource": "log",
          },
        "p_any_aws_account_ids": ["123412341234"],
        "p_any_aws_arns":
          [
            "arn:aws:iam::123412341234:role/DevAdministrator",
            "arn:aws:sts::123412341234:assumed-role/DevAdministrator/1669660343296132000",
          ],
        "p_any_ip_addresses": ["5.5.5.5"],
        "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/kube-bench-drn4j/log?container=kube-bench",
        "responseStatus": { "code": 200 },
        "sourceIPs": ["5.5.5.5"],
        "stage": "ResponseStarted",
        "stageTimestamp": "2022-11-29 00:09:04.392",
        "user":
          {
            "extra":
              {
                "accessKeyId": ["ASIARLIVEKVNN6Y6J5UW"],
                "arn":
                  [
                    "arn:aws:sts::123412341234:assumed-role/DevAdministrator/1669660343296132000",
                  ],
                "canonicalArn":
                  ["arn:aws:iam::123412341234:role/DevAdministrator"],
                "sessionName": ["1669660343296132000"],
              },
            "groups": ["system:masters", "system:authenticated"],
            "uid": "aws-iam-authenticator:123412341234:AROARLIVEKVNIRVGDLJWJ",
            "username": "kubernetes-admin",
          },
        "userAgent": "kubectl/v1.25.4 (darwin/arm64) kubernetes/872a965",
        "verb": "get",
      }
  - Name: 403 and Private IP
    ExpectedResult: false
    Log:
      {
        "annotations":
          {
            "authorization.k8s.io/decision": "allow",
            "authorization.k8s.io/reason": 'RBAC: allowed by ClusterRoleBinding "system:coredns" of ClusterRole "system:coredns" to ServiceAccount "coredns/kube-system"',
          },
        "apiVersion": "audit.k8s.io/v1",
        "auditID": "e2626946-90e1-4d0c-829e-ad5a78572926",
        "kind": "Event",
        "level": "Metadata",
        "objectRef":
          {
            "apiGroup": "discovery.k8s.io",
            "apiVersion": "v1",
            "resource": "endpointslices",
          },
        "p_any_ip_addresses": ["10.0.27.115"],
        "p_any_usernames": ["system:serviceaccount:kube-system:coredns"],
        "p_event_time": "2022-11-29 22:34:06.892",
        "p_log_type": "Amazon.EKS.Audit",
        "p_parse_time": "2022-11-29 22:45:25.024",
        "p_row_id": "c2a7d8dd7c858dcae0a1aaf314b2a207",
        "p_source_id": "4c859cd4-9406-469b-9e0e-c2dc1bee24fa",
        "p_source_label": "example-cluster-eks-logs",
        "requestReceivedTimestamp": "2022-11-29 22:34:06.892",
        "requestURI": "/apis/discovery.k8s.io/v1/endpointslices?allowWatchBookmarks=true&resourceVersion=2528212&timeout=5m56s&timeoutSeconds=356&watch=true",
        "responseStatus": { "code": 403 },
        "sourceIPs": ["10.0.27.115"],
        "stage": "ResponseComplete",
        "stageTimestamp": "2022-11-29 22:40:02.903",
        "user":
          {
            "extra":
              {
                "authentication_kubernetes_io_slash_pod-name":
                  ["coredns-57ff979f67-bl27n"],
                "authentication_kubernetes_io_slash_pod-uid":
                  ["5b9488ae-5563-42aa-850b-b0d82edb3e22"],
              },
            "groups":
              [
                "system:serviceaccounts",
                "system:serviceaccounts:kube-system",
                "system:authenticated",
              ],
            "uid": "5e4461f9-f529-4e66-9343-0b0cc9452284",
            "username": "system:serviceaccount:kube-system:coredns",
          },
        "userAgent": "Go-http-client/2.0",
        "verb": "watch",
      }
  - Name: 403 and Public IP
    ExpectedResult: true
    Log:
      {
        "annotations":
          {
            "authorization.k8s.io/decision": "allow",
            "authorization.k8s.io/reason": 'RBAC: allowed by ClusterRoleBinding "system:coredns" of ClusterRole "system:coredns" to ServiceAccount "coredns/kube-system"',
          },
        "apiVersion": "audit.k8s.io/v1",
        "auditID": "e2626946-90e1-4d0c-829e-ad5a78572926",
        "kind": "Event",
        "level": "Metadata",
        "objectRef":
          {
            "apiGroup": "discovery.k8s.io",
            "apiVersion": "v1",
            "resource": "endpointslices",
          },
        "p_any_ip_addresses": ["5.5.5.5"],
        "p_any_usernames": ["system:serviceaccount:kube-system:coredns"],
        "p_event_time": "2022-11-29 22:34:06.892",
        "p_log_type": "Amazon.EKS.Audit",
        "p_parse_time": "2022-11-29 22:45:25.024",
        "p_row_id": "c2a7d8dd7c858dcae0a1aaf314b2a207",
        "p_source_id": "4c859cd4-9406-469b-9e0e-c2dc1bee24fa",
        "p_source_label": "example-cluster-eks-logs",
        "requestReceivedTimestamp": "2022-11-29 22:34:06.892",
        "requestURI": "/apis/discovery.k8s.io/v1/endpointslices?allowWatchBookmarks=true&resourceVersion=2528212&timeout=5m56s&timeoutSeconds=356&watch=true",
        "responseStatus": { "code": 403 },
        "sourceIPs": ["5.5.5.5"],
        "stage": "ResponseComplete",
        "stageTimestamp": "2022-11-29 22:40:02.903",
        "user":
          {
            "extra":
              {
                "authentication_kubernetes_io_slash_pod-name":
                  ["coredns-57ff979f67-bl27n"],
                "authentication_kubernetes_io_slash_pod-uid":
                  ["5b9488ae-5563-42aa-850b-b0d82edb3e22"],
              },
            "groups":
              [
                "system:serviceaccounts",
                "system:serviceaccounts:kube-system",
                "system:authenticated",
              ],
            "uid": "5e4461f9-f529-4e66-9343-0b0cc9452284",
            "username": "system:serviceaccount:kube-system:coredns",
          },
        "userAgent": "Go-http-client/2.0",
        "verb": "watch",
      }

Detection logic

Condition

stage eq "ResponseComplete"
responseStatus.code eq "403"
requestURI starts_with "/api/" or requestURI starts_with "/apis/"

This rule also runs imperative logic the parser cannot express as a filter; the conditions above are the structured part it could extract.

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
requestURIstarts_with
  • /api/
  • /apis/
responseStatus.codeeq
  • 403
stageeq
  • ResponseComplete