{"id":13561892,"url":"https://github.com/quarkslab/kdigger","last_synced_at":"2026-02-03T10:38:39.141Z","repository":{"id":37079693,"uuid":"403605621","full_name":"quarkslab/kdigger","owner":"quarkslab","description":"Kubernetes focused container assessment and context discovery tool for penetration testing","archived":false,"fork":false,"pushed_at":"2024-06-18T10:09:18.000Z","size":242,"stargazers_count":461,"open_issues_count":2,"forks_count":19,"subscribers_count":16,"default_branch":"main","last_synced_at":"2025-06-08T16:02:13.642Z","etag":null,"topics":["containers","kubernetes","pentest","security","tool"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/quarkslab.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-09-06T11:59:07.000Z","updated_at":"2025-05-31T15:52:58.000Z","dependencies_parsed_at":"2023-01-19T11:02:30.563Z","dependency_job_id":null,"html_url":"https://github.com/quarkslab/kdigger","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/quarkslab/kdigger","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quarkslab%2Fkdigger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quarkslab%2Fkdigger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quarkslab%2Fkdigger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quarkslab%2Fkdigger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/quarkslab","download_url":"https://codeload.github.com/quarkslab/kdigger/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quarkslab%2Fkdigger/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29041866,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-03T10:09:22.136Z","status":"ssl_error","status_checked_at":"2026-02-03T10:09:16.814Z","response_time":96,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["containers","kubernetes","pentest","security","tool"],"created_at":"2024-08-01T13:01:02.319Z","updated_at":"2026-02-03T10:38:39.125Z","avatar_url":"https://github.com/quarkslab.png","language":"Go","funding_links":[],"categories":["Go","1 Offensive","Point-of-use validations","Repositories / Tools","Tools","Open Source Projects"],"sub_categories":["1.9 Tools","Vulnerability information exchange","Attacking","Kubernetes"],"readme":"# kdigger\n\n`kdigger`, short for \"Kubernetes digger\", is a context discovery tool for\nKubernetes penetration testing. This tool is a compilation of various plugins\ncalled buckets to facilitate pentesting Kubernetes from inside a pod.\n\nHere is a demo showing `kdigger v1.3.0` in action, using only four buckets.\nPlease note that around twenty plugins exist and you can read more about all\nthe features in the following documentation.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://user-images.githubusercontent.com/11256051/183686558-0dd9dbaa-ac3d-4ea0-9bcf-81344b91ba3e.gif\" alt=\"Demonstration of kdigger v1.3.0 features\"/\u003e\n\u003c/p\u003e\n\nPlease note that this is not an ultimate pentest tool on Kubernetes. Some\nplugins perform really simple actions that could be performed manually by\ncalling the `mount` command or listing all devices present in dev with `ls\n/dev` for example. But some others automate scanning processes, such as the\nadmission controller scanner. In the end, this tool aims to humbly speed up the\npentesting process.\n\n## Table of content\n\n* [Installation](#installation)\n    * [Via releases](#via-releases)\n    * [Build from source](#build-from-source)\n    * [With Nix](#with-nix)\n    * [Via Go](#via-go)\n* [Usage](#usage)\n    * [Digging](#digging)\n    * [Generating](#generating)\n    * [Fuzzing](#fuzzing)\n* [Details](#details)\n    * [Updates](#updates)\n    * [Usage warning](#usage-warning)\n    * [Results warning](#results-warning)\n    * [Why another tool?](#why-another-tool)\n    * [How is this tool built?](#how-is-this-tool-built)\n    * [Areas for improvement](#areas-for-improvement)\n    * [How to experiment with this tool?](#how-to-experiment-with-this-tool)\n* [Buckets](#buckets)\n    * [Admission](#admission)\n    * [API Resources](#api-resources)\n    * [Authorization](#authorization)\n    * [Capabilities](#capabilities)\n    * [Cgroups](#cgroups)\n    * [CloudMetadata](#cloudmetadata)\n    * [ContainerDetect](#containerdetect)\n    * [Devices](#devices)\n    * [Environment](#environment)\n    * [Mount](#mount)\n    * [Node](#node)\n    * [PIDNamespace](#pidnamespace)\n    * [Processes](#processes)\n    * [Runtime](#runtime)\n    * [Services](#services)\n    * [Syscalls](#syscalls)\n    * [Token](#token)\n    * [UserID](#userid)\n    * [UserNamespace](#usernamespace)\n    * [Version](#version)\n* [Contributing](#contributing)\n* [License](#license)\n\n## Installation\n\n`kdigger` is available on Linux amd64, arm64 and macOS amd64.\n\n**Please note that `kdigger` should be mostly run inside of pods on not on your\nhost machine.**\n\n### Via releases\n\nFor installation instructions from binaries please visit the [releases\npage](https://github.com/quarkslab/kdigger/releases). \n\nPlease note that these are statically linked binaries (which is often\n**not** the case in Go on Linux by default, contrary to what one might think!).\n\n### Build from source\n\nJust type `make` to build with the\n[default build target](https://github.com/quarkslab/kdigger/blob/main/Makefile#L20).\n```bash\ngit clone https://github.com/quarkslab/kdigger\nmake\n```\n\nThen you can move the binary somewhere included in your PATH, for example:\n\n```bash\nsudo install kdigger /usr/local/bin\n```\n\nNote that you will need [`golangci-lint`](https://github.com/golangci/golangci-lint)\nto use the `release` target that will build for the supported architectures.\nYou can use `make install-linter` to install `golangci-lint` on the host.\n\n### With Nix\n\nYou can use Nix with a new shell environments thanks to [a contributor\nPR](https://github.com/quarkslab/kdigger/pull/2) that [added kdigger to\nnixpkgs](https://github.com/NixOS/nixpkgs/pull/177868).\n\n```bash\nnix-shell -p kdigger\n```\n\nYou can also create docker images with `kdigger` and other tools easily\nwith [nixery.dev](https://nixery.dev/):\n\n```bash\ndocker run -it nixery.dev/kubectl/kdigger/bash /bin/bash\n```\n\n### Via Go\n\n```bash\ngo install github.com/quarkslab/kdigger@main\n```\n\n## Usage\n\n### Digging\n\nWhat you generally want to do is running all the buckets with `dig all` or just\n`d a`:\n```bash\nkdigger dig all\n```\n\nHelp is provided by the CLI itself, just type `kdigger` to see the options:\n\n```console\n$ kdigger\nkdigger is an extensible CLI tool to dig around when you are in a Kubernetes\ncluster. For that you can use multiples buckets. Buckets are plugins that can\nscan specific aspects of a cluster or bring expertise to automate the Kubernetes\npentest process.\n\nUsage:\n  kdigger [command]\n\nAvailable Commands:\n  completion  Generate the autocompletion script for the specified shell\n  dig         Use all buckets or specific ones\n  gen         Generate template for pod with security features disabled\n  help        Help about any command\n  ls          List available buckets or describe specific ones\n  version     Print the version information\n\nFlags:\n  -h, --help            help for kdigger\n  -o, --output string   Output format. One of: human|json. (default \"human\")\n  -w, --width int       Width for the human output (default 140)\n\nUse \"kdigger [command] --help\" for more information about a command.\n\n```\n\nMake sure to check out the help on the ``dig`` command to see all the available\nflags:\n\n```console\n$ kdigger help dig\nThis command runs buckets, special keyword \"all\" or \"a\" runs all registered\nbuckets. You can find information about all buckets with the list command. To\nrun one or more specific buckets, just input their names or aliases as\narguments.\n\nUsage:\n  kdigger dig [buckets] [flags]\n\nAliases:\n  dig, d\n\nFlags:\n      --admission-create    Actually create pods to scan admission instead of using server dry run. (this flag is specific to the admission bucket)\n      --admission-force     Force creation of pods to scan admission even without cleaning rights. (this flag is specific to the admission bucket)\n  -c, --color               Enable color in output. (default true if output is human)\n  -h, --help                help for dig\n      --kubeconfig string   (optional) absolute path to the kubeconfig file (default \"/home/vagrant/.kube/config\")\n  -n, --namespace string    Kubernetes namespace to use. (default to the namespace in the context)\n  -s, --side-effects        Enable all buckets that might have side effect on environment.\n\nGlobal Flags:\n  -o, --output string   Output format. One of: human|json. (default \"human\")\n  -w, --width int       Width for the human output (default 140)\n```\n\n### Generating\n\nYou can also generate useful templates for pods with security features disabled\nto escalate privileges when you can create such a pod. See the help for this\nspecific command for more information.\n\n```console\n$ kdigger help gen\nThis command generates templates for pod with security features disabled.\nYou can customize the pods with some of the string flags and activate\nboolean flags to disabled security features. Examples:\n\n  # Generate a very simple template in json\n  kdigger gen -o json\n\n  # Create a very simple pod\n  kdigger gen | kubectl apply -f -\n\n  # Create a pod named mypod with most security features disabled\n  kdigger gen -all mypod | kubectl apply -f -\n\n  # Create a custom privileged pod\n  kdigger gen --privileged --image bash --command watch --command date | kubectl apply -f -\n\n  # Fuzz the API server admission\n  kdigger gen --fuzz-pod --fuzz-init --fuzz-container | kubectl apply --dry-run=server -f -\n\nUsage:\n  kdigger gen [name] [flags]\n\nAliases:\n  gen, generate\n\nFlags:\n      --all                   Enable everything\n      --command stringArray   Container command used (default [sleep,infinitely])\n      --fuzz-container        Generate a random container security context. (will override other options)\n      --fuzz-init             Generate a random init container security context.\n      --fuzz-pod              Generate a random pod security context.\n  -h, --help                  help for gen\n      --hostnetwork           Add the hostNetwork flag on the whole pod\n      --hostpath              Add a hostPath volume to the container\n      --hostpid               Add the hostPid flag on the whole pod\n      --image string          Container image used (default \"busybox\")\n  -n, --namespace string      Kubernetes namespace to use\n      --privileged            Add the security flag to the security context of the pod\n      --tolerations           Add tolerations to be schedulable on most nodes\n\nGlobal Flags:\n  -o, --output string   Output format. One of: human|json. (default \"human\")\n  -w, --width int       Width for the human output (default 140)\n```\n\n### Fuzzing\n\nYou can try to fuzz your API admission with `kdigger`, find\n[some information in this PR](https://github.com/quarkslab/kdigger/pull/11).\nIt can be interesting to see if your sets of custom policies are resistant\nagainst randomly generated pod manifest.\n\nSee how `kdigger` can generate random container securityContext:\n```console\n./kdigger gen --fuzz-container -o json | jq '.spec.containers[].securityContext'\n```\n\nOr generate a dozen:\n```bash\nfor _ in {1..12}; do ./kdigger gen --fuzz-container -o json | jq '.spec.containers[].securityContext'; done\n```\n\nFuzz your admission API with simple commands similar to:\n```bash\nwhile true; do ./kdigger gen --fuzz-pod --fuzz-init --fuzz-container | kubectl apply --dry-run=server -f -; done\n```\n\n## Details\n\n### Updates\n\nI updates this tool from time to time, when I have new ideas after reading a\nbook or doing CTF challenges, you can find information in the\n[changelog](https://github.com/quarkslab/kdigger/blob/master/CHANGELOG.md).\n\n### Usage warning\n\nBe careful when running this tool, some checks have side effects, like scanning\nyour available syscalls or trying to create pods to scan the admission control.\nBy default these checks will **not** run without adding the `--side-effects` or\n`-s` flag.\n\nFor example, syscalls scans may succeed to perform some syscalls with\nempty arguments, and it can alter your environment or configuration. For\ninstance, if the `hostname` syscall is successful, it will replace the\nhostname with the empty string. So please, **NEVER** run with\nsufficient permissions (as root for example) directly on your machine.\n\nThe admission scan will by default run as server dry-run but will generate API\nserver logs.\n\n### Results warning\n\nSome tests are based on details of implementation or side effects on the\nenvironment that might be subject to changes in the future. So be cautious with\nthe results. For example, CoreDNS is considering removing the wildcard feature,\nsee [CoreDNS issue 4984]( https://github.com/coredns/coredns/issues/4984).\n\nOn top of that, some results might need some experience to be understood and\nanalyzed. To take a specific example, if you are granted the ``CAP_SYS_ADMIN``\ncapability inside a Kubernetes container, there is a good chance that it is\nbecause you are running in a privileged container. But you should definitely\nconfirm that by looking at the number of devices available or the other\ncapabilities that you are granted. Indeed, it might be necessary to get\n``CAP_SYS_ADMIN`` to be privileged but it’s not sufficient and if it is your\ngoal, you can easily trick the results by crafting very specific pods that\nmight look confusing regarding this tool results.\n\nIt might not be the most sophisticated tool to pentest a Kubernetes cluster,\nbut you can see this as a *Kubernetes pentest 101 compilation*!\n\n### Why another tool?\n\nI started researching Kubernetes security a few months ago and participated in\nthe [2021 Europe KubeCon Cloud-Native Security Day\nCTF](https://controlplaneio.github.io/kubecon-2021-sig-security-day-ctf/). I\nlearned a lot by watching various security experts conferences and\ndemonstrations and this CTF was a really beginner-friendly entry point to\npractice what I learned in theory. During a live solving session, I had the\nopportunity to see how Kubernetes security experts were trying to solve the\nchallenge, how they were thinking, what they were looking for.\n\nSo I decided to create a tool that compiles most of the checks we usually do as\npentesters when in a Kubernetes pod to acquire information very quickly. There\nalready are various tools out there. For example, a lot of experts were using\n[amicontained](https://github.com/genuinetools/amicontained), a famous\ncontainer introspection tool by Jessie Frazelle. This tool is truly awesome,\nbut some features are outdated, like the PID namespace detection, and it is not\nspecialized in Kubernetes, it is only a container tool that can already give a\nlot of hints about your Kubernetes situation.\n\nThat is why, in kdigger, I included most of amicontained features. You can:\n\n- Try to guess your container runtime.\n- See your capabilities.\n- Scan for namespace activation and configuration.\n- Scan for the allowed syscalls.\n\nBut you can also do more Kubernetes specific operations:\n\n- Retrieve service account token.\n- Scan token permissions.\n- List interesting environment variables.\n- List available devices.\n- Retrieve all available services in a cluster.\n- Scan the admission controller chain!\n\nAnyway, this tool is obviously not an *automatically hack your Kubernetes\ncluster* application, it is mostly just a compilation of tedious tasks that can\nbe performed automatically very quickly. You still need a lot of expertise to\ninterpret the digest and understand what the various outputs mean. And also,\nduring pentest and challenges, you do not always have Internet access to pull\nyour favorite toolchain, so you can also see this compilation as a checklist\nthat you can somehow perform manually with a basic installation and a shell.\n\n### How is this tool built?\n\nIn addition to all the available features, this tool was built with a plugin\ndesign so that it can be easily extended by anyone that wants to bring some\nexpertise.\n\nFor example, you are a security researcher on Kubernetes, and when you are\ndoing CTFs or pentesting real infrastructure, you are often performing specific\nrepetitive actions that could be automated or at least compiled with others.\nYou can take a look at `/pkg/plugins/template/template.go` to bootstrap your\nown plugins and propose them to the project to extend the features! You only\nneed a name, optionally some aliases, a description and filling the `Run()`\nfunction with the actual logic.\n\n### Areas for improvement\n\nThe expertise proposed by the tool could be refined and more precise. For now\nit's mostly dumping raw data for most of the buckets and rely on the user to\nunderstand what it implies.\n\nGenerally, the output format is not the best and could be reworked. The human\nformat via array lines does not fit all the use cases perfectly but is simple to\ngeneralize without having each plugin to implement their format. The tool also\nproposes a JSON output format.\n\n### How to experiment with this tool?\n\nGood news! We created a mini Kubernetes CTF with basic steps to try the tool\nand resolve quick challenges. For more information go to the [minik8s-ctf\nrepository](https://github.com/quarkslab/minik8s-ctf).\n\n## Buckets\n\nYou can list and describe the available buckets (or plugins) with `kdigger\nlist` or `kdigger ls`:\n```console\n$ kdigger ls\n+-----------------+----------------------------+----------------------------------------+-------------+---------------+\n|       NAME      |           ALIASES          |               DESCRIPTION              | SIDEEFFECTS | REQUIRECLIENT |\n+-----------------+----------------------------+----------------------------------------+-------------+---------------+\n| admission       | [admissions adm]           | Admission scans the admission          | true        | true          |\n|                 |                            | controller chain by creating (by       |             |               |\n|                 |                            | default with dry run) specific pods to |             |               |\n|                 |                            | find what is prevented or not.         |             |               |\n| apiresources    | [api apiresource]          | APIResources discovers the available   | false       | true          |\n|                 |                            | APIs of the cluster.                   |             |               |\n| authorization   | [authorizations auth]      | Authorization checks your API          | false       | true          |\n|                 |                            | permissions with the current context   |             |               |\n|                 |                            | or the available token.                |             |               |\n| capabilities    | [capability cap]           | Capabilities lists all capabilities in | false       | false         |\n|                 |                            | all sets and displays dangerous        |             |               |\n|                 |                            | capabilities in red.                   |             |               |\n| cgroups         | [cgroup cg]                | Cgroups reads the /proc/self/cgroup    | false       | false         |\n|                 |                            | files that can leak information under  |             |               |\n|                 |                            | cgroups v1.                            |             |               |\n| cloudmetadata   | [cloud meta]               | Cloudmetadata scans the usual metadata | false       | false         |\n|                 |                            | endpoints in public clouds.            |             |               |\n| containerdetect | [container cdetect]        | ContainerDetect retrieves hints that   | false       | false         |\n|                 |                            | the process is running inside a        |             |               |\n|                 |                            | typical container.                     |             |               |\n| devices         | [device dev]               | Devices shows the list of devices      | false       | false         |\n|                 |                            | available in the container.            |             |               |\n| environment     | [environments environ env] | Environment checks the presence of     | false       | false         |\n|                 |                            | kubernetes related environment         |             |               |\n|                 |                            | variables and shows them.              |             |               |\n| mount           | [mounts mn]                | Mount shows all mounted devices in the | false       | false         |\n|                 |                            | container.                             |             |               |\n| node            | [nodes n]                  | Node retrieves various information in  | false       | false         |\n|                 |                            | /proc about the current host.          |             |               |\n| pidnamespace    | [pidnamespaces pidns]      | PIDnamespace analyses the PID          | false       | false         |\n|                 |                            | namespace of the container in the      |             |               |\n|                 |                            | context of Kubernetes.                 |             |               |\n| processes       | [process ps]               | Processes analyses the running         | false       | false         |\n|                 |                            | processes in your PID namespace        |             |               |\n| runtime         | [runtimes rt]              | Runtime finds clues to identify which  | false       | false         |\n|                 |                            | container runtime is running the       |             |               |\n|                 |                            | container.                             |             |               |\n| services        | [service svc]              | Services uses CoreDNS wildcards        | false       | false         |\n|                 |                            | feature to discover every service      |             |               |\n|                 |                            | available in the cluster.              |             |               |\n| syscalls        | [syscall sys]              | Syscalls scans most of the syscalls to | true        | false         |\n|                 |                            | detect which are blocked and allowed.  |             |               |\n| token           | [tokens tk]                | Token checks for the presence of a     | false       | false         |\n|                 |                            | service account token in the           |             |               |\n|                 |                            | filesystem.                            |             |               |\n| userid          | [userids id]               | UserID retrieves UID, GID and their    | false       | false         |\n|                 |                            | corresponding names.                   |             |               |\n| usernamespace   | [usernamespaces userns]    | UserNamespace analyses the user        | false       | false         |\n|                 |                            | namespace configuration.               |             |               |\n| version         | [versions v]               | Version dumps the API server version   | false       | true          |\n|                 |                            | informations.                          |             |               |\n+-----------------+----------------------------+----------------------------------------+-------------+---------------+\n```\n\n### Admission\n\nAdmission scans the admission controller chain by creating (by default with dry\nrun) specific pods to find what is prevented or not. The idea behind this bucket\nis to check, after you learned that you have `create pods` ability, if no\nadmission controller like a PodSecurityPolicy or another is blocking you to\ncreate node privilege escalation pods. Like mounting the host filesystem, or the\nhost PID namespace, or just a privileged container, for example.\n\nThis bucket currently automatically tries to create:\n- a privileged pod\n- a privilege escalation pod\n- a host network pod\n- a host path pod\n- a run as root pod\n- a host PID pod\n\nSo, if you are granted rights to `create pods`, you can check the presence of\nany admission controller that might restrict you.\n\nNote that it uses `--dry-run=server` by default but you can really create the\npods with the `--admission-create` admission plugin specific flag.\n\n### API Resources\n\nAPIResources discovers the available APIs of the cluster. These endpoints are\ninteresting because it only requires authentication and can leak some sensitive\ninformation. Indeed, you can learn about CRDs installed in the cluster, leaking\nfor example the presence of Prometheus using Prometheus Operator, or the\ninstallation of the Falco, etc. Generally, it can inform you on the stack used\nin the cluster if the components are installed using CRDs.\n\nThis is equivalent of running `kubectl api-resources`, the output is just\nabbreviated.\n\nPrior v1.14, [the endpoints used required not\nauthentication](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#discovery-roles).\nNow the API discovery (and version, health, ready) endpoints are grouped in the\n`system:discovery` ClusterRole (visible with `kubectl get clusterrole\nsystem:discovery -o yaml`). The rest is in `system:basic-user` for the self\nauthorization review with SelfSubjectAccessReviews and SelfSubjectSulesSeviews\nand `system:public-info-viewer`. The only part remaining for unauthenticated\nuser is version, health, ready, live endpoints (see with `kubectl get\nclusterrolebinding system:public-info-viewer -o yaml`).\n\n### Authorization\n\nAuthorization checks your API permissions with the current context or the\navailable token. If you use kdigger inside a pod as planned, it will check and\nuse the service account token that is normally mounted inside the pod. Then it\nwill basically operate exactly the same operation as if you do `kubectl auth\ncan-i --list` and display the result.\n\n### Capabilities\n\nCapabilities lists all capabilities in all sets and displays dangerous\ncapabilities in red.\n\nBasically, in a non-privileged container, the result might look like that:\n```text\n### CAPABILITIES ###\nComment: The bounding set contains 14 caps, it seems that you are running a non-privileged container.\n+-------------+----------------------------------------------------+\n|     SET     |                    CAPABILITIES                    |\n+-------------+----------------------------------------------------+\n| effective   | [chown dac_override fowner fsetid kill setgid      |\n|             | setuid setpcap net_bind_service net_raw sys_chroot |\n|             | mknod audit_write setfcap]                         |\n| permitted   | [chown dac_override fowner fsetid kill setgid      |\n|             | setuid setpcap net_bind_service net_raw sys_chroot |\n|             | mknod audit_write setfcap]                         |\n| inheritable | [chown dac_override fowner fsetid kill setgid      |\n|             | setuid setpcap net_bind_service net_raw sys_chroot |\n|             | mknod audit_write setfcap]                         |\n| bounding    | [chown dac_override fowner fsetid kill setgid      |\n|             | setuid setpcap net_bind_service net_raw sys_chroot |\n|             | mknod audit_write setfcap]                         |\n| ambient     | []                                                 |\n+-------------+----------------------------------------------------+\n```\n\nThis bucket might be especially useful to spot critical capabilities that can\nhelp you to escalate your privileges. This can be a good hint on whether you\nare running inside a privileged container or not.\n\nThis bucket also checks for the `NoNewPrivs` flag in `/proc/self/status` that\nwill be set to 1 if `allowPrivilegeEscalation` is set to false in the\n`SecurityContext` of the Pod. Note that `allowPrivilegeEscalation` is always\ntrue when the container:\n- is run as privileged, or\n- has `CAP_SYS_ADMIN`\n\n### Cgroups\n\nCgroups reads the /proc/self/cgroup files that can leak information under\ncgroups v1. The CgroupPath can leak many information, for example, you can see\nthese kinds of paths:\n\n```text\n/docker/744ba5524431986481406cfd13382cbeb7e59a4739dec5ff8b458bc821969662/kubelet/kubepods/besteffort/pod3716cd27-4591-40fc-9dae-3851142b1d51/e06769b086acea415152f733574033db4dc5e81c9a8f6563648fd5f3b60227af\n...\n/docker/744ba5524431986481406cfd13382cbeb7e59a4739dec5ff8b458bc821969662/system.slice/containerd.service\n```\n\nThese strings can give you information about the kind of container used, here\nthe `kubelet/kubepods` part can confirm we are in a Kubernetes pod's container.\nAlso you can learn about the container runtime used, here docker with\ncontainerd, also the container ID, the pod UID, the snapshot key, etc.\n\nKnowing the container ID and the container runtime can be interesting to\ndetermine where on the host will be stored the files written to the container\nfilesystem. This is for example useful when exploiting hooks that will be called\nin the context of the host, and thus escape the container, see these [kinds of\nescapes](http://blog.bofh.it/debian/id_413) for more information.\n\nFor kernels using cgroups v2, `/proc/self/mountinfo` can still leak information\nabout the container ID. See [this Stackoverflow\nthread](https://stackoverflow.com/a/69005753) and its related threads for more\ninformation.\n\n### CloudMetadata\n\nCloudmetadata scans the usual metadata endpoints in public clouds. It is usually\nquite simple to find at which service provider a VM come from, because of many\nleaks in the filesystems, the environment variables, etc. But from a containers\nin a VM, it can be harder, that's why this plugin performs a scan on the network\nvia the usual service running at `169.254.169.254` or alike. See the source code\nfor endpoints used and links to more endpoints.\n\nThis plugin only gives you the information of the availability of the main\nendpoints, which means that you might running in a specific public cloud. If\nthat's the case, further research, using available endpoints for that cloud, can\nbe conducted. You can potentially retrieve an authentication token or simply\nmore metadata to pivot within the cloud account.\n\n### ContainerDetect\n\nContainerDetect retrieves hints that the process is running inside a typical\ncontainer. This bucket follows a discussion on Twitter about detection technics\nhttps://twitter.com/g3rzi/status/1564594977220562945.\n\nFor now, it's composed of six hints:\n- systemd is not PID 1\n- kthreadd is not PID 2\n- inode number of root is not 2\n- root is an overlay fs\n- /etc/fstab is empty\n- /boot is empty\n\n### Devices\n\nDevices show the list of devices available in the container. This one is\nstraightforward, it's equivalent to just `ls /dev`. Nevertheless, the number of\navailable devices can also be a good hint on running in a privileged container\nor not.\n\n### Environment\n\nEnvironment checks the presence of Kubernetes related environment variables and\nshows them. Like always, it's not sufficient, but detecting Kubernetes related\nenvironment variables can give you a pretty good idea that you are running in a\nKubernetes cluster. That might be useful if you want to quickly find out where\nyou are. Of course, this one is easy to confuse, by just exporting some\nenvironment variable or removing some.\n\n### Mount\n\nMount show all mounted devices in the container. This is equivalent to use the\n`mount` command directly but the number of mounted devices and reading path can\nshow you mounted volumes, configmap or even secrets inside the pod.\n\n### Node\n\nNode retrieves various information in /proc about the current host. It seeks\ninformation in `/proc/cpuinfo`, `/proc/meminfo` and `/proc/version` to\nunderstand the context of execution of the containers. These files are not\nnamespaced and thus leak information about the reality of the underlying node.\n\nIt lists information about the CPU model, the number of cores, the total memory\navailable, the part that is used, the kernel version and some compilation\ndetails about it.\n\n### PIDNamespace\n\nPIDNamespace analyzes the PID namespace of the container in the context of\nKubernetes. Detecting the PID namespace is almost impossible so the idea of\nthis bucket is to scan the `/proc` folder to search for specific processes\nsuch as:\n* `pause`: it might signify that you are sharing the PID namespace between all\n  the containers composing the pod.\n* `kubelet`: it might signify that you are sharing the PID namespace with the\n  host.\n\nBy the way, the detection in\n[amicontained](https://github.com/genuinetools/amicontained) is based on the\ndevice number of the namespace file, a detail of implementation which is no\nlonger reliable and most of the time wrong. This is why I tried a different\napproach.\n\n### Processes\n\nProcesses analyzes the running processes in your PID namespace. It is similar\nto any `ps` command that list all processes like `ps -e` or `ps -A`. It gives\nyou the information of the number of running processes and if the first one is\nsystemd.\n\n### Runtime\n\nRuntime finds clues to identify which container runtime is running the\ncontainer. This one is calling exactly the same code that the one in\n[amicontained](https://github.com/genuinetools/amicontained). It is using a\npackage of the [genuinetools/bpfd](https://github.com/genuinetools/bpfd)\nproject to spot artifacts about container runtime that could betray their\npresence.\n\nPlease note that this is a 3-year-old part of that code and that it makes no\ndistinction between Docker and containerd.\n\n### Services\n\nServices uses CoreDNS wildcard feature to discover every service available in\nthe cluster. In fact, it appears that CoreDNS, that is now widely used in\nKubernetes cluster proposes a wildcard feature. You can learn more about it\n[~~here in the\ndocumentation~~](https://github.com/coredns/coredns/blob/master/plugin/kubernetes/README.md#wildcards).\n\nThis bucket is extremely useful to perform discovery really fast in a\nKubernetes cluster. The DNS will kindly give you every service domain present\nin the cluster.\n\nNote: [This feature was removed](https://github.com/coredns/coredns/pull/5019)\nstarting as of CoreDNS v1.9.0 because it was mostly used by bad actors (like\nthis tool). See the associated discussion on [the corresponding Github\nissue](https://github.com/coredns/coredns/issues/4984). Kubernetes v1.24 was\nstill using CoreDNS v1.8.6, but the v1.25 version updated CoreDNS to v1.9.3.\nThat's why this plugin no longer works on v1.25 and above.\n\n### Syscalls\n\nSyscalls scans most of the syscalls to detect which are blocked and allowed.\nThis one is also using a lot of the\n[amicontained](https://github.com/genuinetools/amicontained) code base except\nthat it also banned the `SYS_PTRACE` scan that causes a racing condition that\ncan hang the program forever.\n\nThis is one really nice way to see if you are in a privileged container with a\nlot of capabilities quickly: the list of blocked syscall might be almost empty.\n\nThis bucket also checks the `Seccomp` flag in `/proc/self/status`, it will\ndisplay if Seccomp is disabled, running in strict or in filter mode.\n\n### Token\n\nToken checks for the presence of a service account token in the filesystem.\nThen it dumps the stuff it finds in `/run/secrets/kubernetes.io/serviceaccount`\nwhich is composed of the service account token itself, the namespace and the CA\ncertificate of the kube API server.\n\nYou might want to use the `-o json` flag here and use `jq` to get that token\nfast!\n\n### UserID\n\nUserID retrieves UID, GID and their corresponding names. It also gives\n`homeDir` as a bonus! Unfortunately, we can list all group IDs without CGO\nenabled. This is almost (because `id` is better) equivalent to run the `id`\ncommand directly.\n\n### UserNamespace\n\nUserNamespace analyses the user namespace configuration. The user namespace is\ntransparent and can be easily detected. It is even possible to read the mapping\nbetween the current user namespace and the outer namespace. Unfortunately for\nnow, user namespaces cannot be used with Kubernetes.\n\n### Version\n\nVersion dumps the API server version information. It access the `/version`\npath that is accessible even by unauthenticated users. So even without a\nservice account token you can request this information. You can get more\ninformation on what you can access as an `system:unauthenticated` user with\n`kubectl describe clusterrolebinding | grep unauthenticated -B 9` for example.\nYou may encounter the `system:public-info-viewer` cluster role, you can\ndescribe it with `kubectl describe clusterrole system:public-info-viewer` and\ndisplay:\n\n```text\nName:         system:public-info-viewer\nLabels:       kubernetes.io/bootstrapping=rbac-defaults\nAnnotations:  rbac.authorization.kubernetes.io/autoupdate: true\nPolicyRule:\n  Resources  Non-Resource URLs  Resource Names  Verbs\n  ---------  -----------------  --------------  -----\n             [/healthz]         []              [get]\n             [/livez]           []              [get]\n             [/readyz]          []              [get]\n             [/version/]        []              [get]\n             [/version]         []              [get]\n```\n\n## Contributing\n\nAs kdigger is a security checklist when pentesting from inside a pod's\ncontainer, please consider adding a plugin if you have some checks that are not\ncovered by the tool. To do that, you can use the\n[template](https://github.com/quarkslab/kdigger/blob/master/pkg/plugins/template/template.go)\nand load your plugin into the project\n[here](https://github.com/quarkslab/kdigger/blob/master/commands/root.go#L71).\nI will be happy to see your PR!\n\nIf you have any other ideas or advice, consider opening an issue or directly\ncontact me @mtardy_ on twitter or by email.\n\n![A small digger trying to move the evergreen stuck cruise ship in the suez\ncanal](https://i.servimg.com/u/f41/11/93/81/35/digger10.jpg)\n\n## License\n\n[Apache License 2.0](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquarkslab%2Fkdigger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fquarkslab%2Fkdigger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquarkslab%2Fkdigger/lists"}