GitBook: [#2905] No subject

This commit is contained in:
CPol 2021-12-21 21:58:59 +00:00 committed by gitbook-bot
parent b1f71a3344
commit b9a919bf04
No known key found for this signature in database
GPG Key ID: 07D2180C7B12D0FF
3 changed files with 78 additions and 38 deletions

View File

@ -211,7 +211,7 @@
* [Scanner and Fax](pentesting/pentesting-printers/scanner-and-fax.md)
* [Pentesting SAP](pentesting/pentesting-sap.md)
* [Pentesting Kubernetes](pentesting/pentesting-kubernetes/README.md)
* [Enumeration from a Pod](pentesting/pentesting-kubernetes/enumeration-from-a-pod.md)
* [Kubernetes Enumeration](pentesting/pentesting-kubernetes/enumeration-from-a-pod.md)
* [Hardening Roles/ClusterRoles](pentesting/pentesting-kubernetes/hardening-roles-clusterroles.md)
* [Pentesting Kubernetes from the outside](pentesting/pentesting-kubernetes/pentesting-kubernetes-from-the-outside.md)
* [7/tcp/udp - Pentesting Echo](pentesting/7-tcp-udp-pentesting-echo.md)

View File

@ -17,6 +17,14 @@ Organization
A virtual machine (called a Compute Instance) is a resource. A resource resides in a project, probably alongside other Compute Instances, storage buckets, etc.
### **IAM Policies, Bindings and Memberships**
In GCP there are different ways to grant a principal access over a resource:
* **Memberships**: You set **principals as members of roles** **without restrictions** over the role or the principals. You can put a user as a member of a role and then put a group as a member of the same role and also set those principals (user and group) as member of other roles.
* **Bindings**: Several **principals can be binded to a role**. Those **principals can still be binded or be members of other roles**. However, if a principal which isnt binded to the role is set as **member of a binded role**, the next time the **binding is applied, the membership will disappear**.
* **Policies**: A policy is **authoritative**, it indicates roles and principals and then, **those principals cannot have more roles and those roles cannot have more principals** unless that policy is modified (not even in other policies, bindings or memberships). Therefore, when a role or principal is specified in policy all its privileges are **limited by that policy**. Obviously, this can be bypassed in case the principal is given the option to modify the policy or privilege escalation permissions (like create a new principal and bind him a new role).
### **IAM Roles**
There are **three types** of roles in IAM:
@ -70,14 +78,6 @@ gcloud compute instances get-iam-policy [INSTANCE] --zone [ZONE]
The IAM policies indicates the permissions principals has over resources via roles which ara assigned granular permissions. Organization policies **restrict how those service can be used or which features are enabled disabled**. This helps in order to improve the least privilege of each resource in the gcp environment.
### **Terraform IAM Policies, Bindings and Memberships**
As defined by terraform in [https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google\_project\_iam](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google\_project\_iam) using terraform with GCP there are different ways to grant a principal access over a resource:
* **Memberships**: You set **principals as members of roles** **without restrictions** over the role or the principals. You can put a user as a member of a role and then put a group as a member of the same role and also set those principals (user and group) as member of other roles.
* **Bindings**: Several **principals can be binded to a role**. Those **principals can still be binded or be members of other roles**. However, if a principal which isnt binded to the role is set as **member of a binded role**, the next time the **binding is applied, the membership will disappear**.
* **Policies**: A policy is **authoritative**, it indicates roles and principals and then, **those principals cannot have more roles and those roles cannot have more principals** unless that policy is modified (not even in other policies, bindings or memberships). Therefore, when a role or principal is specified in policy all its privileges are **limited by that policy**. Obviously, this can be bypassed in case the principal is given the option to modify the policy or privilege escalation permissions (like create a new principal and bind him a new role).
### **Service accounts**
Virtual machine instances are usually **assigned a service account**. Every GCP project has a [default service account](https://cloud.google.com/compute/docs/access/service-accounts#default\_service\_account), and this will be assigned to new Compute Instances unless otherwise specified. Administrators can choose to use either a custom account or no account at all. This service account **can be used by any user or application on the machine** to communicate with the Google APIs. You can run the following command to see what accounts are available to you:

View File

@ -1,20 +1,38 @@
# Enumeration from a Pod
# Kubernetes Enumeration
In a situation where you have managed to break into a Kubernetes Pod you could start enumerating the kubernetes environment from within.
## Kubernetes Tokens
## Service Account Tokens
If you have compromised access to a machine the user may have access to some Kubernetes platform. The token is usually located in a file pointed by the **env var `KUBECONFIG`** or **inside `~/.kube`**.
In this folder you might find config files with **tokens and configurations to connect to the API server**. In this folder you can also find a cache folder with information previously retrieved.
If you have compromised a pod inside a kubernetes environment, there are other places where you can find tokens and information about the current K8 env:
### Service Account Tokens
Before continuing, if you don't know what is a service in Kubernetes I would suggest you to [**follow this link and read at least the information about Kubernetes architecture**](./#architecture)**.**
Taken from the Kubernetes [documentation](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#use-the-default-service-account-to-access-the-api-server):
_“When you create a pod, if you do not specify a service account, it is automatically assigned the_ default _service account in the same namespace.”_
**ServiceAccount** is an object managed by Kubernetes and used to provide an identity for processes that run in a pod.\
Every service account has a secret related to it and this secret contains a bearer token. This is a JSON Web Token (JWT), a method for representing claims securely between two parties.
Usually in the directory `/run/secrets/kubernetes.io/serviceaccount` or `/var/run/secrets/kubernetes.io/serviceaccount` you can find the files:
Usually **one** of the directories:
* `/run/secrets/kubernetes.io/serviceaccount`
* `/var/run/secrets/kubernetes.io/serviceaccount`
* `/secrets/kubernetes.io/serviceaccount` 
contain the files:
* **ca.crt**: It's the ca certificate to check kubernetes communications
* **namespace**: It indicates the current namespace
* **token**: It contains the **service token** of the current pod.
Now that you have the token, you can find the API server inside the environment variable **`KUBECONFIG`**. For more info run `(env | set) | grep -i "kuber|kube`**`"`**
The service account token is being signed by the key residing in the file **sa.key** and validated by **sa.pub**.
Default location on **Kubernetes**:
@ -25,10 +43,6 @@ Default location on **Minikube**:
* /var/lib/localkube/certs
Taken from the Kubernetes [documentation](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#use-the-default-service-account-to-access-the-api-server):
_“When you create a pod, if you do not specify a service account, it is automatically assigned the_ default _service account in the same namespace.”_
### Hot Pods
_**Hot pods are**_ pods containing a privileged service account token. A privileged service account token is a token that has permission to do privileged tasks such as listing secrets, creating pods, etc.
@ -39,18 +53,25 @@ If you don't know what is **RBAC**, [**read this section**](./#cluster-hardening
## Enumeration CheatSheet
To enumerate the environment you can upload the [**kubectl**](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/#install-kubectl-binary-with-curl-on-linux) binary and use it. Also, using the **service** **token** obtained before you can manually access some endpoints of the **API Server**.\
In order to find the the IP of the API service check the environment for a variable called `KUBERNETES_SERVICE_HOST`.
In order to enumerate a K8s environment you need a couple of this:
* A **valid authentication token**. In the previous section we saw where to search for a user token and for a service account token.
* The **address (**_**https://host:port**_**) of the Kubernetes API**. This can be usually found in the environment variables and/or in the kube config file.
* **Optional**: The **ca.crt to verify the API server**. This can be found in the same places the token can be found. This is useful to verify the API server certificate, but using `--insecure-skip-tls-verify` with `kubectl` or `-k` with `curl` you won't need this.
With those details you can **enumerate kubernetes**. If the **API** for some reason is **accessible** through the **Internet**, you can just download that info and enumerate the platform from your host.
However, usually the **API server is inside an internal network**, therefore you will need to **create a tunnel** through the compromised machine to access it from your machine, or you can **upload the** [**kubectl**](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/#install-kubectl-binary-with-curl-on-linux) binary, or use **`curl/wget/anything`** to perform raw HTTP requests to the API server. 
### Differences between `list` and `get` verbs
With **`get`** permissions you can access the API:
With **`get`** permissions you can access information of specific assets (_`describe` option in `kubectl`_) API:
```
GET /apis/apps/v1/namespaces/{namespace}/deployments/{name}
```
If you have the **`list`** permission, you are allowed to execute these API requests:
If you have the **`list`** permission, you are allowed to execute API requests to list a type of asset (_`get` option in `kubectl`_):
```bash
#In a namespace
@ -59,7 +80,7 @@ GET /apis/apps/v1/namespaces/{namespace}/deployments
GET /apis/apps/v1/deployments
```
If you have the **`watch`** permission, you are allowed to execute these API requests:
If you have the **`watch`** permission, you are allowed to execute API requests to monitor assets:
```
GET /apis/apps/v1/deployments?watch=true
@ -77,16 +98,35 @@ The following `kubectl` commands indicates just how to list the objects. If you
### Using kubectl
when using kubectl it might come in handy to define a temporary alias, if the token used is different to the one defined in `/run/secrets/kubernetes.io/serviceaccount` or `/var/run/secrets/kubernetes.io/serviceaccount`.
Having the token and the address of the API server you use kubectl or curl to access it as indicated here:
```bash
alias kubectl='kubectl --token=<jwt_token>'
alias kubectl='kubectl --token=<jwt_token> --server=https://host:port --insecure-skip-tls-verify'
```
[kubectl cheatsheet](https://kubernetes.io/docs/reference/kubectl/cheatsheet/)
You can find an [**official kubectl cheatsheet here**](https://kubernetes.io/docs/reference/kubectl/cheatsheet/). The goal of the following sections is to present in ordered manner different options to enumerate and understand the new K8s you have obtained access to:
### Get Current Privileges
{% tabs %}
{% tab title="kubectl" %}
```bash
./kubectl auth can-i --list #Get privileges in general
./kubectl auth can-i --list -n custnamespace #Get privileves in custnamespace
```
{% endtab %}
{% endtabs %}
**Once you know which privileges** you have, check the following page to figure out **if you can abuse them** to escalate privileges:
{% content-ref url="hardening-roles-clusterroles.md" %}
[hardening-roles-clusterroles.md](hardening-roles-clusterroles.md)
{% endcontent-ref %}
### Get namespaces
Kubernetes supports **multiple virtual clusters** backed by the same physical cluster. These virtual clusters are called **namespaces**.
{% tabs %}
{% tab title="kubectl" %}
```bash
@ -96,8 +136,8 @@ alias kubectl='kubectl --token=<jwt_token>'
{% tab title="API" %}
```bash
curl -v -H "Authorization: Bearer <jwt_token>" \
https://<Kubernetes_API_IP>:<port>/api/v1/namespaces/
curl -k -v -H "Authorization: Bearer $TOKEN" \
https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT_HTTPS/api/v1/namespaces/
```
{% endtab %}
{% endtabs %}
@ -129,23 +169,23 @@ If you can read secrets you can use the following lines to get the privileges re
for token in `./kubectl describe secrets -n kube-system | grep "token:" | cut -d " " -f 7`; do echo $token; ./kubectl --token $token auth can-i --list; echo; done
```
### Get Current Privileges
### Get Service Accounts
{% tabs %}
{% tab title="kubectl" %}
```bash
./kubectl auth can-i --list #Get privileges in general
./kubectl auth can-i --list -n custnamespace #Get privileves in custnamespace
./kubectl get serviceaccounts
```
{% endtab %}
{% tab title="API" %}
```bash
curl -k -v -H "Authorization: Bearer $TOKEN" \
https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT_HTTPS/api/v1/namespaces/{namespace}/serviceaccounts/api/v1/namespaces/
```
{% endtab %}
{% endtabs %}
**Once you know which privileges** you have, check the following page to figure out **if you can abuse them** to escalate privileges:
{% content-ref url="hardening-roles-clusterroles.md" %}
[hardening-roles-clusterroles.md](hardening-roles-clusterroles.md)
{% endcontent-ref %}
### Get Current Context
{% tabs %}
@ -332,7 +372,7 @@ Information obtained from: [Kubernetes Namespace Breakout using Insecure Host Pa
By default there isn't any encryption in the communication between pods .Mutual authentication, two-way, pod to pod.
#### Create a sidecar proxy app <a href="create-a-sidecar-proxy-app" id="create-a-sidecar-proxy-app"></a>
#### Create a sidecar proxy app <a href="#create-a-sidecar-proxy-app" id="create-a-sidecar-proxy-app"></a>
Create your .yaml
@ -393,7 +433,7 @@ kubectl get svc --all-namespaces
### Scanning
The following Bash script (taken from a [Kubernetes workshop](https://github.com/calinah/learn-by-hacking-kccn/blob/master/k8s_cheatsheet.md)) will install and scan the IP ranges of the kubernetes cluster:
The following Bash script (taken from a [Kubernetes workshop](https://github.com/calinah/learn-by-hacking-kccn/blob/master/k8s\_cheatsheet.md)) will install and scan the IP ranges of the kubernetes cluster:
```bash
sudo apt-get update