LoFP LoFP / an administrator may need to exec into a pod for a legitimate reason like debugging purposes. containers built from linux and windows os images, tend to include debugging utilities. in this case, an admin may choose to run commands inside a specific container with kubectl exec ${pod_name} -c ${container_name} -- ${cmd} ${arg1} ${arg2} ... ${argn}. for example, the following command can be used to look at logs from a running cassandra pod: kubectl exec cassandra --cat /var/log/cassandra/system.log . additionally, the -i and -t arguments might be used to run a shell connected to the terminal: kubectl exec -i -t cassandra -- sh

Techniques

Sample rules

Kubernetes User Exec into Pod

Description

This rule detects a user attempt to establish a shell session into a pod using the ’exec’ command. Using the ’exec' command in a pod allows a user to establish a temporary shell session and execute any process/commands in the pod. An adversary may call bash to gain a persistent interactive shell which will allow access to any data the pod has permissions to, including secrets.

Detection logic

any where event.dataset == "kubernetes.audit_logs" and kubernetes.audit.verb in ("get", "create") and
kubernetes.audit.objectRef.subresource == "exec" and kubernetes.audit.stage in ("ResponseComplete", "ResponseStarted") and
kubernetes.audit.level == "Request" and `kubernetes.audit.annotations.authorization_k8s_io/decision` == "allow" and
not (
  (kubernetes.audit.objectRef.namespace == "trident" and kubernetes.audit.objectRef.name like "trident-controller-*") or
  (kubernetes.audit.objectRef.namespace == "vuls" and kubernetes.audit.requestURI like "/api/v1/namespaces/vuls/pods/vuls-*/exec?command=sh&command=-c&command=*+%2Fvuls%2Fresults*") or
  (kubernetes.audit.objectRef.namespace == "git-runners" and kubernetes.audit.requestURI like (
     "/api/v1/namespaces/git-runners/pods/runner-*/exec?command=sh&command=-c&command=if+%5B+-x+%2Fusr%2Flocal%2Fbin%2Fbash+%5D%3B+then%0A%09exec+%2Fusr%2Flocal%2Fbin%2Fbash+%0Aelif+%5B+-x+%2Fusr%2Fbin%2Fbash+%5D%3B+then%0A%09exec+%2Fusr%2Fbin%2Fbash+%0Aelif+%5B+-x+%2Fbin%2Fbash+%5D%3B+then%0A%09exec+%2Fbin%2Fbash+%0Aelif+%5B+-x+%2Fusr%2Flocal%2Fbin%2Fsh+%5D%3B+then%0A%09exec+%2Fusr%2Flocal%2Fbin%2Fsh+%0Aelif+%5B+-x+%2Fusr%2Fbin%2Fsh+%5D%3B+then%0A%09exec+%2Fusr%2Fbin%2Fsh+%0Aelif+%5B+-x+%2Fbin%2Fsh+%5D%3B+then%0A%09exec+%2Fbin%2Fsh+%0Aelif+%5B+-x+%2Fbusybox%2Fsh+%5D%3B+then%0A%09exec+%2Fbusybox%2Fsh+%0Aelse%0A%09echo+shell+not+found%0A%09exit+1%0Afi%0A%0A&container=*&container=*&stderr=true&stdin=true&stdout=true",
     "/api/v1/namespaces/git-runners/pods/runner-*/exec?command=gitlab-runner-helper&command=read-logs&command=--path&command=%2Flogs-*%2Foutput.log&command=--offset&command=0&command=--wait-file-timeout&command=1m0s&container=*&container=*&stderr=true&stdout=true"
  )) or
  (kubernetes.audit.objectRef.namespace == "elasticsearch-cluster" and kubernetes.audit.requestURI like (
    "/api/v1/namespaces/elasticsearch-cluster/pods/*/exec?command=df&command=-h&container=elasticsearch&stdin=true&stdout=true&tty=true",
    "/api/v1/namespaces/elasticsearch-cluster/pods/*/exec?command=df&command=-h&container=elasticsearch&stderr=true&stdout=true",
    "/api/v1/namespaces/elasticsearch-cluster/pods/*/exec?command=df&command=-h&container=kibana&stderr=true&stdout=true"
  )) or
  (kubernetes.audit.objectRef.namespace == "kube-system" and kubernetes.audit.requestURI like (
    "/api/v1/namespaces/kube-system/pods/*/exec?command=%2Fproxy-agent&command=--help&container=konnectivity-agent&stderr=true&stdout=true",
    "api/v1/namespaces/kube-system/pods/*/exec?command=cilium&command=endpoint&command=list&command=-o&command=json&container=cilium-agent&stderr=true&stdout=true",
    "/api/v1/namespaces/kube-system/pods/*/exec?command=cilium&command=status&command=-o&command=json&container=cilium-agent&stderr=true&stdout=true",
    "/api/v1/namespaces/kube-system/pods/*/exec?command=sh&command=-c&command=clear%3B+%28bash+%7C%7C+ash+%7C%7C+sh%29&container=*&stdin=true&stdout=true&tty=true"
  ))
)

Interactive Exec Into Container Detected via Defend for Containers

Description

This rule detects interactive ’exec’ events launched against a container using the ’exec’ command. Using the ’exec' command in a pod allows a user to establish a temporary shell session and execute any process/command inside the container. This rule specifically targets higher-risk interactive commands that allow real-time interaction with a container’s shell. A malicious actor could use this level of access to further compromise the container environment or attempt a container breakout.

Detection logic

process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and
process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox") and
process.entry_leader.entry_meta.type == "container" and

/* process is the inital process run in a container */
process.entry_leader.same_as_process == true and

/* interactive process */
process.interactive == true and container.id like "*"