Translated ['.github/pull_request_template.md', 'src/pentesting-cloud/az

This commit is contained in:
Translator
2024-12-31 19:02:02 +00:00
parent 7770a50092
commit 2753c75e8b
244 changed files with 8471 additions and 11302 deletions

View File

@@ -2,15 +2,15 @@
{{#include ../../../banners/hacktricks-training.md}}
Kubernetes uses several **specific network services** that you might find **exposed to the Internet** or in an **internal network once you have compromised one pod**.
Kubernetes gebruik verskeie **spesifieke netwerkdienste** wat jy mag vind **blootgestel aan die Internet** of in 'n **interne netwerk sodra jy een pod gekompromitteer het**.
## Finding exposed pods with OSINT
One way could be searching for `Identity LIKE "k8s.%.com"` in [crt.sh](https://crt.sh) to find subdomains related to kubernetes. Another way might be to search `"k8s.%.com"` in github and search for **YAML files** containing the string.
Een manier kan wees om te soek na `Identity LIKE "k8s.%.com"` in [crt.sh](https://crt.sh) om subdomeine te vind wat met kubernetes verband hou. 'n Ander manier kan wees om te soek na `"k8s.%.com"` in github en te soek na **YAML-lêers** wat die string bevat.
## How Kubernetes Exposes Services
It might be useful for you to understand how Kubernetes can **expose services publicly** in order to find them:
Dit mag nuttig wees vir jou om te verstaan hoe Kubernetes **dienste publiek kan blootstel** om hulle te vind:
{{#ref}}
../exposing-services-in-kubernetes.md
@@ -18,7 +18,7 @@ It might be useful for you to understand how Kubernetes can **expose services pu
## Finding Exposed pods via port scanning
The following ports might be open in a Kubernetes cluster:
Die volgende poorte mag oop wees in 'n Kubernetes-kluster:
| Port | Process | Description |
| --------------- | -------------- | ---------------------------------------------------------------------- |
@@ -38,24 +38,20 @@ The following ports might be open in a Kubernetes cluster:
| 44134/TCP | Tiller | Helm service listening |
### Nmap
```bash
nmap -n -T4 -p 443,2379,6666,4194,6443,8443,8080,10250,10255,10256,9099,6782-6784,30000-32767,44134 <pod_ipaddress>/16
```
### Kube-apiserver
This is the **API Kubernetes service** the administrators talks with usually using the tool **`kubectl`**.
**Common ports: 6443 and 443**, but also 8443 in minikube and 8080 as insecure.
Dit is die **API Kubernetes diens** waarmee die administrateurs gewoonlik praat deur die hulpmiddel **`kubectl`** te gebruik.
**Gewone poorte: 6443 en 443**, maar ook 8443 in minikube en 8080 as onveilig.
```bash
curl -k https://<IP Address>:(8|6)443/swaggerapi
curl -k https://<IP Address>:(8|6)443/healthz
curl -k https://<IP Address>:(8|6)443/api/v1
```
**Check the following page to learn how to obtain sensitive data and perform sensitive actions talking to this service:**
**Kyk na die volgende bladsy om te leer hoe om sensitiewe data te verkry en sensitiewe aksies uit te voer deur met hierdie diens te praat:**
{{#ref}}
../kubernetes-enumeration.md
@@ -63,101 +59,84 @@ curl -k https://<IP Address>:(8|6)443/api/v1
### Kubelet API
This service **run in every node of the cluster**. It's the service that will **control** the pods inside the **node**. It talks with the **kube-apiserver**.
Hierdie diens **loop in elke knoop van die kluster**. Dit is die diens wat die **pods** binne die **knoop** sal **beheer**. Dit praat met die **kube-apiserver**.
If you find this service exposed you might have found an **unauthenticated RCE**.
As jy hierdie diens blootgestel vind, het jy dalk 'n **onaangekondigde RCE** gevind.
#### Kubelet API
```bash
curl -k https://<IP address>:10250/metrics
curl -k https://<IP address>:10250/pods
```
As die antwoord `Unauthorized` is, benodig dit verifikasie.
If the response is `Unauthorized` then it requires authentication.
If you can list nodes you can get a list of kubelets endpoints with:
As jy knope kan lys, kan jy 'n lys van kubelets eindpunte kry met:
```bash
kubectl get nodes -o custom-columns='IP:.status.addresses[0].address,KUBELET_PORT:.status.daemonEndpoints.kubeletEndpoint.Port' | grep -v KUBELET_PORT | while IFS='' read -r node; do
ip=$(echo $node | awk '{print $1}')
port=$(echo $node | awk '{print $2}')
echo "curl -k --max-time 30 https://$ip:$port/pods"
echo "curl -k --max-time 30 https://$ip:2379/version" #Check also for etcd
ip=$(echo $node | awk '{print $1}')
port=$(echo $node | awk '{print $2}')
echo "curl -k --max-time 30 https://$ip:$port/pods"
echo "curl -k --max-time 30 https://$ip:2379/version" #Check also for etcd
done
```
#### kubelet (Read only)
#### kubelet (Slegs lees)
```bash
curl -k https://<IP Address>:10255
http://<external-IP>:10255/pods
```
### etcd API
```bash
curl -k https://<IP address>:2379
curl -k https://<IP address>:2379/version
etcdctl --endpoints=http://<MASTER-IP>:2379 get / --prefix --keys-only
```
### Tiller
```bash
helm --host tiller-deploy.kube-system:44134 version
```
You could abuse this service to escalate privileges inside Kubernetes:
### cAdvisor
Service useful to gather metrics.
Diens nuttig om metrieks te versamel.
```bash
curl -k https://<IP Address>:4194
```
### NodePort
When a port is exposed in all the nodes via a **NodePort**, the same port is opened in all the nodes proxifying the traffic into the declared **Service**. By default this port will be in in the **range 30000-32767**. So new unchecked services might be accessible through those ports.
Wanneer 'n poort in al die nodes blootgestel word via 'n **NodePort**, word dieselfde poort in al die nodes oopgemaak wat die verkeer na die verklaarde **Service** proxify. Standaard sal hierdie poort in die **reeks 30000-32767** wees. So nuwe ongekontroleerde dienste mag deur daardie poorte toeganklik wees.
```bash
sudo nmap -sS -p 30000-32767 <IP>
```
## Kwetsbare Misconfigurasies
## Vulnerable Misconfigurations
### Kube-apiserver Anonieme Toegang
### Kube-apiserver Anonymous Access
Anonymous access to **kube-apiserver API endpoints is not allowed**. But you could check some endpoints:
Anonieme toegang tot **kube-apiserver API eindpunte is nie toegelaat nie**. Maar jy kan sommige eindpunte nagaan:
![](https://www.cyberark.com/wp-content/uploads/2019/09/Kube-Pen-2-fig-5.png)
### **Checking for ETCD Anonymous Access**
### **Kontroleer vir ETCD Anonieme Toegang**
The ETCD stores the cluster secrets, configuration files and more **sensitive data**. By **default**, the ETCD **cannot** be accessed **anonymously**, but it always good to check.
If the ETCD can be accessed anonymously, you may need to **use the** [**etcdctl**](https://github.com/etcd-io/etcd/blob/master/etcdctl/READMEv2.md) **tool**. The following command will get all the keys stored:
Die ETCD stoor die kluster geheime, konfigurasie lêers en meer **sensitiewe data**. **Standaard** kan die ETCD **nie** **anoniem** toeganklik wees nie, maar dit is altyd goed om te kontroleer.
As die ETCD anoniem toeganklik is, moet jy dalk die **[etcdctl](https://github.com/etcd-io/etcd/blob/master/etcdctl/READMEv2.md)** **instrument** gebruik. Die volgende opdrag sal al die sleutels wat gestoor is, kry:
```bash
etcdctl --endpoints=http://<MASTER-IP>:2379 get / --prefix --keys-only
```
### **Kubelet RCE**
The [**Kubelet documentation**](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/) explains that by **default anonymous acce**ss to the service is **allowed:**
Die [**Kubelet dokumentasie**](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/) verduidelik dat **anonieme toegang** tot die diens **standaard toegelaat** word:
> Enables anonymous requests to the Kubelet server. Requests that are not rejected by another authentication method are treated as anonymous requests. Anonymous requests have a username of `system:anonymous`, and a group name of `system:unauthenticated`
> Stel anonieme versoeke aan die Kubelet-bediener in staat. Versoeke wat nie deur 'n ander outentikasie metode verwerp word nie, word as anonieme versoeke behandel. Anonieme versoeke het 'n gebruikersnaam van `system:anonymous`, en 'n groepnaam van `system:unauthenticated`
To understand better how the **authentication and authorization of the Kubelet API works** check this page:
Om beter te verstaan hoe die **outentikasie en magtiging van die Kubelet API werk**, kyk na hierdie bladsy:
{{#ref}}
kubelet-authentication-and-authorization.md
{{#endref}}
The **Kubelet** service **API is not documented**, but the source code can be found here and finding the exposed endpoints is as easy as **running**:
Die **Kubelet** diens **API is nie gedokumenteer** nie, maar die bronkode kan hier gevind word en om die blootgestelde eindpunte te vind is so maklik soos **om te hardloop**:
```bash
curl -s https://raw.githubusercontent.com/kubernetes/kubernetes/master/pkg/kubelet/server/server.go | grep 'Path("/'
@@ -169,39 +148,34 @@ Path("/portForward")
Path("/containerLogs")
Path("/runningpods/").
```
Almal klink interessant.
All of them sound interesting.
You can use the [**Kubeletctl**](https://github.com/cyberark/kubeletctl) tool to interact with Kubelets and their endpoints.
Jy kan die [**Kubeletctl**](https://github.com/cyberark/kubeletctl) hulpmiddel gebruik om met Kubelets en hul eindpunte te kommunikeer.
#### /pods
This endpoint list pods and their containers:
Hierdie eindpunt lys pods en hul houers:
```bash
kubeletctl pods
```
#### /exec
This endpoint allows to execute code inside any container very easily:
Hierdie eindpunt maak dit baie maklik om kode binne enige houer uit te voer:
```bash
kubeletctl exec [command]
```
> [!NOTE]
> To avoid this attack the _**kubelet**_ service should be run with `--anonymous-auth false` and the service should be segregated at the network level.
> Om hierdie aanval te vermy, moet die _**kubelet**_ diens met `--anonymous-auth false` gedraai word en die diens moet op netwerkvlak gesegregeer word.
### **Checking Kubelet (Read Only Port) Information Exposure**
### **Kontroleer Kubelet (Slegs Lees Poort) Inligting Blootstelling**
When a **kubelet read-only port** is exposed, it becomes possible for information to be retrieved from the API by unauthorized parties. The exposure of this port may lead to the disclosure of various **cluster configuration elements**. Although the information, including **pod names, locations of internal files, and other configurations**, may not be critical, its exposure still poses a security risk and should be avoided.
Wanneer 'n **kubelet slegs lees poort** blootgestel word, word dit moontlik vir ongeregistreerde partye om inligting van die API te verkry. Die blootstelling van hierdie poort kan lei tot die bekendmaking van verskeie **kluster konfigurasie elemente**. Alhoewel die inligting, insluitend **pod name, plekke van interne lêers, en ander konfigurasies**, dalk nie krities is nie, bly die blootstelling 'n sekuriteitsrisiko en moet vermy word.
An example of how this vulnerability can be exploited involves a remote attacker accessing a specific URL. By navigating to `http://<external-IP>:10255/pods`, the attacker can potentially retrieve sensitive information from the kubelet:
'n Voorbeeld van hoe hierdie kwesbaarheid uitgebuit kan word, behels 'n afstandaanvaller wat toegang tot 'n spesifieke URL verkry. Deur na `http://<external-IP>:10255/pods` te navigeer, kan die aanvaller moontlik sensitiewe inligting van die kubelet verkry:
![https://www.cyberark.com/wp-content/uploads/2019/09/KUbe-Pen-2-fig-6.png](https://www.cyberark.com/wp-content/uploads/2019/09/KUbe-Pen-2-fig-6.png)
## References
## Verwysings
{{#ref}}
https://www.cyberark.com/resources/threat-research-blog/kubernetes-pentest-methodology-part-2
@@ -212,7 +186,3 @@ https://labs.f-secure.com/blog/attacking-kubernetes-through-kubelet
{{#endref}}
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -4,110 +4,96 @@
## Kubelet Authentication <a href="#kubelet-authentication" id="kubelet-authentication"></a>
[**From the docss:**](https://kubernetes.io/docs/reference/access-authn-authz/kubelet-authn-authz/)
[**Uit die dokumentasie:**](https://kubernetes.io/docs/reference/access-authn-authz/kubelet-authn-authz/)
By default, requests to the kubelet's HTTPS endpoint that are not rejected by other configured authentication methods are treated as anonymous requests, and given a **username of `system:anonymous`** and a **group of `system:unauthenticated`**.
Standaard word versoeke na die kubelet se HTTPS-eindpunt wat nie deur ander geconfigureerde autentikasie-metodes verwerp word nie, as anonieme versoeke behandel, en ontvang 'n **gebruikersnaam van `system:anonymous`** en 'n **groep van `system:unauthenticated`**.
The **3** authentication **methods** are:
- **Anonymous** (default): Use set setting the param **`--anonymous-auth=true` or the config:**
Die **3** autentikasie **metodes** is:
- **Anoniem** (standaard): Gebruik die instelling van die parameter **`--anonymous-auth=true` of die konfigurasie:**
```json
"authentication": {
"anonymous": {
"enabled": true
},
```
- **Webhook**: This will **enable** the kubectl **API bearer tokens** as authorization (any valid token will be valid). Allow it with:
- ensure the `authentication.k8s.io/v1beta1` API group is enabled in the API server
- start the kubelet with the **`--authentication-token-webhook`** and **`--kubeconfig`** flags or use the following setting:
```json
"authentication": {
"webhook": {
"cacheTTL": "2m0s",
"enabled": true
},
```
> [!NOTE]
> The kubelet calls the **`TokenReview` API** on the configured API server to **determine user information** from bearer tokens
- **X509 client certificates:** Allow to authenticate via X509 client certs
- see the [apiserver authentication documentation](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#x509-client-certs) for more details
- start the kubelet with the `--client-ca-file` flag, providing a CA bundle to verify client certificates with. Or with the config:
```json
"authentication": {
"x509": {
"clientCAFile": "/etc/kubernetes/pki/ca.crt"
}
}
```
## Kubelet Authorization <a href="#kubelet-authentication" id="kubelet-authentication"></a>
Any request that is successfully authenticated (including an anonymous request) **is then authorized**. The **default** authorization mode is **`AlwaysAllow`**, which **allows all requests**.
However, the other possible value is **`webhook`** (which is what you will be **mostly finding out there**). This mode will **check the permissions of the authenticated user** to allow or disallow an action.
> [!WARNING]
> Note that even if the **anonymous authentication is enabled** the **anonymous access** might **not have any permissions** to perform any action.
The authorization via webhook can be configured using the **param `--authorization-mode=Webhook`** or via the config file with:
```json
"authorization": {
"mode": "Webhook",
"webhook": {
"cacheAuthorizedTTL": "5m0s",
"cacheUnauthorizedTTL": "30s"
}
"anonymous": {
"enabled": true
},
```
- **Webhook**: Dit sal die kubectl **API bearer tokens** as outorisering **aktiveer** (enige geldige token sal geldig wees). Laat dit toe met:
- verseker dat die `authentication.k8s.io/v1beta1` API-groep geaktiveer is in die API-bediener
- begin die kubelet met die **`--authentication-token-webhook`** en **`--kubeconfig`** vlae of gebruik die volgende instelling:
```json
"authentication": {
"webhook": {
"cacheTTL": "2m0s",
"enabled": true
},
```
> [!NOTE]
> Die kubelet roep die **`TokenReview` API** op die geconfigureerde API-bediener om **gebruikersinligting** uit draer tokens te bepaal
The kubelet calls the **`SubjectAccessReview`** API on the configured API server to **determine** whether each request is **authorized.**
- **X509 kliënt sertifikate:** Laat toe om te autentiseer via X509 kliënt sertifikate
- sien die [apiserver autentisering dokumentasie](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#x509-client-certs) vir meer besonderhede
- begin die kubelet met die `--client-ca-file` vlag, wat 'n CA-bundel verskaf om kliënt sertifikate mee te verifieer. Of met die konfigurasie:
```json
"authentication": {
"x509": {
"clientCAFile": "/etc/kubernetes/pki/ca.crt"
}
}
```
## Kubelet Outeurstelling <a href="#kubelet-authentication" id="kubelet-authentication"></a>
The kubelet authorizes API requests using the same [request attributes](https://kubernetes.io/docs/reference/access-authn-authz/authorization/#review-your-request-attributes) approach as the apiserver:
Enige versoek wat suksesvol geverifieer is (insluitend 'n anonieme versoek) **word dan geoutoriseer**. Die **verstek** outeurstellingsmodus is **`AlwaysAllow`**, wat **alle versoeke toelaat**.
- **Action**
Die ander moontlike waarde is **`webhook`** (wat jy **meestal daar buite sal vind**). Hierdie modus sal **die regte van die geverifieerde gebruiker nagaan** om 'n aksie toe te laat of te weier.
| HTTP verb | request verb |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| POST | create |
| GET, HEAD | get (for individual resources), list (for collections, including full object content), watch (for watching an individual resource or collection of resources) |
| PUT | update |
| PATCH | patch |
| DELETE | delete (for individual resources), deletecollection (for collections) |
> [!WARNING]
> Let daarop dat selfs al is die **anonieme verifikasie geaktiveer** die **anonieme toegang** dalk **nie enige regte** het om enige aksie uit te voer nie.
- The **resource** talking to the Kubelet api is **always** **nodes** and **subresource** is **determined** from the incoming request's path:
Die outeurstelling via webhook kan gekonfigureer word met die **param `--authorization-mode=Webhook`** of via die konfigurasie lêer met:
```json
"authorization": {
"mode": "Webhook",
"webhook": {
"cacheAuthorizedTTL": "5m0s",
"cacheUnauthorizedTTL": "30s"
}
},
```
Die kubelet roep die **`SubjectAccessReview`** API op die geconfigureerde API-bediener om te **bepaal** of elke versoek **geoutoriseer** is.
| Kubelet API | resource | subresource |
| ------------ | -------- | ----------- |
| /stats/\* | nodes | stats |
| /metrics/\* | nodes | metrics |
| /logs/\* | nodes | log |
| /spec/\* | nodes | spec |
| _all others_ | nodes | proxy |
Die kubelet autoriseer API versoeke met dieselfde [versoek eienskappe](https://kubernetes.io/docs/reference/access-authn-authz/authorization/#review-your-request-attributes) benadering as die apiserver:
For example, the following request tried to access the pods info of kubelet without permission:
- **Aksie**
| HTTP werkwoord | versoek werkwoord |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| POST | skep |
| GET, HEAD | kry (vir individuele hulpbronne), lys (vir versamelings, insluitend volle objekinhoud), kyk (vir die monitering van 'n individuele hulpbron of versameling hulpbronne) |
| PUT | opdateer |
| PATCH | patch |
| DELETE | verwyder (vir individuele hulpbronne), verwyderversameling (vir versamelings) |
- Die **hulpbron** wat met die Kubelet API praat, is **altyd** **nodes** en **subhulpbron** word **bepaal** uit die inkomende versoek se pad:
| Kubelet API | hulpbron | subhulpbron |
| ------------- | -------- | ----------- |
| /stats/\* | nodes | stats |
| /metrics/\* | nodes | metrics |
| /logs/\* | nodes | log |
| /spec/\* | nodes | spec |
| _alle ander_ | nodes | proxy |
Byvoorbeeld, die volgende versoek het probeer om toegang te verkry tot die pods inligting van kubelet sonder toestemming:
```bash
curl -k --header "Authorization: Bearer ${TOKEN}" 'https://172.31.28.172:10250/pods'
Forbidden (user=system:node:ip-172-31-28-172.ec2.internal, verb=get, resource=nodes, subresource=proxy)
```
- We got a **Forbidden**, so the request **passed the Authentication check**. If not, we would have got just an `Unauthorised` message.
- We can see the **username** (in this case from the token)
- Check how the **resource** was **nodes** and the **subresource** **proxy** (which makes sense with the previous information)
- Ons het 'n **Verbode** gekry, so die versoek **het die Verifikasie-toets geslaag**. As dit nie was nie, sou ons net 'n `Onbevoeg` boodskap gekry het.
- Ons kan die **gebruikersnaam** sien (in hierdie geval van die token)
- Kyk hoe die **hulpbron** **nodes** was en die **subhulpbron** **proxy** (wat sin maak met die vorige inligting)
## References
- [https://kubernetes.io/docs/reference/access-authn-authz/kubelet-authn-authz/](https://kubernetes.io/docs/reference/access-authn-authz/kubelet-authn-authz/)
{{#include ../../../banners/hacktricks-training.md}}