-
Notifications
You must be signed in to change notification settings - Fork 618
[New/Tuning] General API Abuse D4C/K8s Rules #5591
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Rule: New - GuidelinesThese guidelines serve as a reminder set of considerations when proposing a new rule. Documentation and Context
Rule Metadata Checks
New BBR Rules
Testing and Validation
|
1 similar comment
Rule: New - GuidelinesThese guidelines serve as a reminder set of considerations when proposing a new rule. Documentation and Context
Rule Metadata Checks
New BBR Rules
Testing and Validation
|
…end for Containers
|
⛔️ Test failed Results
|
| any where host.os.type == "linux" and event.dataset == "kubernetes.audit_logs" and | ||
| kubernetes.audit.verb in ("get", "create") and kubernetes.audit.objectRef.subresource == "exec" and | ||
| kubernetes.audit.stage == "ResponseComplete" and `kubernetes.audit.annotations.authorization_k8s_io/decision` == "allow" | ||
| kubernetes.audit.stage in ("ResponseComplete", "ResponseStarted") and `kubernetes.audit.annotations.authorization_k8s_io/decision` == "allow" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Aegrah host.os.type == linux is not reported in AKS. Not to mention, I don't think we should limit exec'ing into Linux only. We should consider this for all K8s/D4C rules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I left this here because that update is added in #5577; I left it out because I will merge the other PR first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| kubernetes.audit.stage in ("ResponseComplete", "ResponseStarted") and `kubernetes.audit.annotations.authorization_k8s_io/decision` == "allow" | |
| kubernetes.audit.stage in ("ResponseComplete", "ResponseStarted") and `kubernetes.audit.annotations.authorization_k8s_io/decision` == "allow" | |
| and kubernetes.audit.level == "Request" |
When testing this rule I noticed duplicate alerts for audit level Request and RequestResponse. May want to consider only including Request level here.
|
⛔️ Test failed Results
|
|
⛔️ Test failed Results
|
|
⛔️ Test failed Results
|
|
⛔️ Test failed Results
|
| ) | ||
| ) and process.interactive == true and container.id like "*" | ||
| ] by orchestrator.resource.name | ||
| [any where event.dataset == "kubernetes.audit_logs" and kubernetes.audit.stage in ("ResponseComplete", "ResponseStarted")] by `kubernetes.audit.user.extra.authentication.kubernetes.io/pod-name` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| [any where event.dataset == "kubernetes.audit_logs" and kubernetes.audit.stage in ("ResponseComplete", "ResponseStarted")] by `kubernetes.audit.user.extra.authentication.kubernetes.io/pod-name` | |
| [any where event.dataset == "kubernetes.audit_logs" and kubernetes.audit.stage in ("ResponseComplete", "ResponseStarted") and event.outcome == "success"] by `kubernetes.audit.user.extra.authentication.kubernetes.io/pod-name` |
may want to filter out failed requests
| This rule leverages a combination of Defend for Containers and Kubernetes audit logs to detect the execution of direct | ||
| interactive Kubernetes API requests. An adversary may need to execute direct interactive Kubernetes API requests to gain | ||
| access to the Kubernetes API server or other resources within the cluster. These requests are often used to enumerate | ||
| the Kubernetes API server or other resources within the cluster, and may indicate an attempt to move laterally within | ||
| the cluster. Note that this rule may not trigger if the authorization token of the request is expanded within the process | ||
| argument list, as the length of the "process.args" field may lead to the field being ignored. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably should make this description a bit more distinct from the last rule, clearer that this is looking for forbidden calls and why that's relevant from a security perspective
| ) | ||
| ] by `kubernetes.audit.user.extra.authentication.kubernetes.io/pod-name` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| ) | |
| ] by `kubernetes.audit.user.extra.authentication.kubernetes.io/pod-name` | |
| ) | |
| and event.outcome == "success" | |
| ] by `kubernetes.audit.user.extra.authentication.kubernetes.io/pod-name` |
may want to consider excluding failed requests
| sequence with maxspan=60s | ||
| [file where host.os.type == "linux" and event.type == "change" and event.action == "open" and | ||
| file.path in ("/var/run/secrets/kubernetes.io/serviceaccount/token", "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt") and | ||
| process.interactive == true and container.id like "*"] by orchestrator.resource.name | ||
| [any where event.dataset == "kubernetes.audit_logs" and kubernetes.audit.stage in ("ResponseComplete", "ResponseStarted")] by `kubernetes.audit.user.extra.authentication.kubernetes.io/pod-name` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trying to figure out why this doesn't capture the following behavior I executed from inside a container, is it meant to?
# Get the service account token
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
# API server endpoint
API=https://kubernetes.default.svc
# === Make requests with unusual user agents (triggers detection) ===
# Custom attack tool user agent
curl -sk -H "Authorization: Bearer $TOKEN" \
-A 'hacker-tool/1.0' \
$API/api/v1/secrets
| file where host.os.type == "linux" and event.type == "change" and event.action == "open" and file.path in ( | ||
| "/var/run/secrets/kubernetes.io/serviceaccount/token", "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" | ||
| ) and | ||
| process.interactive == true and container.id like "*" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same question as above, is it because I'm adding token to env variables?
| query = ''' | ||
| file where host.os.type == "linux" and event.type == "change" and event.action == "open" and | ||
| file.path == "/var/run/secrets/kubernetes.io/serviceaccount/namespace" and | ||
| process.interactive == true and container.id like "*" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cat this file is showing up as a process event for me. As a file event it's showing as file.path /home/curl_user/.ash_history with no field to distinguish the specific file being read. Is this a known variation?
| (process.name == "ncat" and process.args like "--ssl*") or | ||
| (process.name == "kubectl" and process.args in ("get", "list", "watch", "create", "patch", "update")) | ||
| ) and | ||
| process.interactive == true and container.id like "*" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This rule captures the service token read I mentioned earlier 👍🏾
| any where host.os.type == "linux" and event.dataset == "kubernetes.audit_logs" and | ||
| kubernetes.audit.verb in ("get", "create") and kubernetes.audit.objectRef.subresource == "exec" and | ||
| kubernetes.audit.stage == "ResponseComplete" and `kubernetes.audit.annotations.authorization_k8s_io/decision` == "allow" | ||
| kubernetes.audit.stage in ("ResponseComplete", "ResponseStarted") and `kubernetes.audit.annotations.authorization_k8s_io/decision` == "allow" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| kubernetes.audit.stage in ("ResponseComplete", "ResponseStarted") and `kubernetes.audit.annotations.authorization_k8s_io/decision` == "allow" | |
| kubernetes.audit.stage in ("ResponseComplete", "ResponseStarted") and `kubernetes.audit.annotations.authorization_k8s_io/decision` == "allow" | |
| and kubernetes.audit.level == "Request" |
When testing this rule I noticed duplicate alerts for audit level Request and RequestResponse. May want to consider only including Request level here.
Summary
This PR introduces 11 new detection rules for detecting suspicious activity within containers, leveraging Elastic Defend for Containers (D4C) and Kubernetes audit logs.
Standalone D4C Rules (7 rules)
Process and file-based detection rules using Defend for Containers telemetry:
Credential Access & K8s API:
/var/run/secrets/kubernetes.io/serviceaccount/tokenorca.crtDiscovery:
kubernetes.default,*.svc.cluster.local)envandprintenvexecution to enumerate container environment variableswhichcommand probing for networking, container management, compilation, and scanning toolsExecution:
Multi-Data Source Correlation Rules (4 rules)
EQL sequence rules correlating D4C process/file events with Kubernetes audit logs:
forbidauthorization decisionsKey Details
Rule Summary
Kubernetes User Exec into Pod
Hit a FN where
ResponseCompletedid not log theexecevent, butResponseStarteddid. Adding theResponseStartedstage tokubernetes.audit.stageto address this FN.Environment Variable Enumeration Detected via Defend for Containers
This rule detects the execution of the "env" or "printenv" commands inside a container. The "env" command is used to display all the environment variables for the current shell, and the "printenv" command is used to print the values of environment variables. These commands are used to enumerate the environment variables of the container, which can be used by an adversary to gain information about the container and the services running inside it.
Tested this rule across telemetry, and over the last 365 days, only 37 hits returned. Once D4C is reintroduced, this will increase; however, I expect this behavior to be limited by interactive processes within a container.
DNS Enumeration Detected via Defend for Containers
This rule detects the execution of DNS enumeration tools inside a container. DNS enumeration tools are used to enumerate the DNS servers and domains of the container, which can be used by an adversary to gain information about the network configuration of the container and the services running inside it.
Across all of telemetry last 365 days only 9 hits on
Suspicious Network Tool Launched Inside A Container. However, this rule is very broad; the one proposed in this PR is way more specific. This may allow to further reduce the noise from theSuspicious Network Tool Launched Inside A Containerrule.Tool Enumeration Detected via Defend for Containers
This rule detects the enumeration of tools by the "which" command inside a container. The "which" command is used to list what tools are installed on a system, and may be used by an adversary to gain information about the container and the services running inside it.
0 hits in telemetry last 365 days when filtered on containers.
Tool Installation Detected via Defend for Containers
This rule detects the installation of tools inside a container. An adversary may need to install additional software to enumerate the container, its environment, and move laterally within the environment.
Last 365 days, 11 hits via
Unusual Interactive Process Launched in a Containerwere detected within Telemetry.Service Account Namespace Read Detected via Defend for Containers
This rule detects the reading of the service account namespace file inside a container. The service account namespace file is used to identify the namespace of the container in which it is running, and may be used by an adversary to get a better understanding of the container and the services running inside it.
0 hits in telemetry last 365 days.
Service Account Token or Certificate Read Detected via Defend for Containers
This rule detects the reading of the service account token or certificate inside a container. The service account token or certificate is used to authenticate the container to the Kubernetes API server, and may be used by an adversary to gain access to the Kubernetes API server or other resources within the cluster. These files are a common target for adversaries to gain access to the cluster.
0 hits in telemetry last 365 days.
Direct Interactive Kubernetes API Request Detected via Defend for Containers
This rule detects the execution of direct interactive Kubernetes API requests inside a container. An adversary may need to execute direct interactive Kubernetes API requests to gain access to the Kubernetes API server or other resources within the cluster. These requests are often used to enumerate the Kubernetes API server or other resources within the cluster, and may indicate an attempt to move laterally within the cluster. Note that this rule may not trigger if the token is expanded within the process argument list, as the length of the "process.args" field may lead to the field being ignored.
Last 365 days, quite a lot of hits in telemetry, however, this is expected. I created this as low severity, because this activity may also occur within benign infrastructure. I will create a similar rule to this, chaining K8s audit logs to this API hitting activity from an MDA perspective, which I will assign a higher severity.
Direct Interactive Kubernetes API Request by Common Utilities
This rule leverages a combination of Defend for Containers and Kubernetes audit logs to detect the execution of direct interactive Kubernetes API requests. An adversary may need to execute direct interactive Kubernetes API requests to gain access to the Kubernetes API server or other resources within the cluster. These requests are often used to enumerate the Kubernetes API server or other resources within the cluster, and may indicate an attempt to move laterally within the cluster. Note that this rule may not trigger if the authorization token of the request is expanded within the process argument list, as the length of the "process.args" field may lead to the field being ignored.
Forbidden Direct Interactive Kubernetes API Request
This rule leverages a combination of Defend for Containers and Kubernetes audit logs to detect the execution of direct interactive Kubernetes API requests, that are forbidden by the Kubernetes API. An adversary may need to execute direct interactive Kubernetes API requests to gain access to the Kubernetes API server or other resources within the cluster. These requests are often used to enumerate the Kubernetes API server or other resources within the cluster, and may indicate an attempt to move laterally within the cluster. Note that this rule may not trigger if the authorization token of the request is expanded within the process argument list, as the length of the "process.args" field may lead to the field being ignored.
Direct Interactive Kubernetes API Request by Unusual Utilities
This rule leverages a combination of Defend for Containers and Kubernetes audit logs to detect the execution of direct interactive Kubernetes API requests via unusual utilities. An adversary may need to execute direct interactive Kubernetes API requests to gain access to the Kubernetes API server or other resources within the cluster. These requests are often used to enumerate the Kubernetes API server or other resources within the cluster, and may indicate an attempt to move laterally within the cluster.
Service Account Token or Certificate Access Followed by Kubernetes API Request
This rule leverages a combination of Defend for Containers and Kubernetes audit logs to detect the access to the service account token or certificate followed by the execution of a direct interactive Kubernetes API request. An adversary may need to access the service account token or certificate to gain access to the Kubernetes API server or other resources within the cluster. These requests are often used to enumerate the Kubernetes API server or other resources within the cluster, and may indicate an attempt to move laterally within the cluster.