GitBook: [#2924] No subject

This commit is contained in:
CPol 2021-12-29 01:10:37 +00:00 committed by gitbook-bot
parent 62107f3d2f
commit 1a5e61658f
No known key found for this signature in database
GPG Key ID: 07D2180C7B12D0FF
14 changed files with 214 additions and 21 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 565 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 565 KiB

After

Width:  |  Height:  |  Size: 118 KiB

View File

@ -217,6 +217,7 @@
* [Kubernetes Role-Based Access Control (RBAC)](pentesting/pentesting-kubernetes/kubernetes-role-based-access-control-rbac.md)
* [Attacking Kubernetes from inside a Pod](pentesting/pentesting-kubernetes/attacking-kubernetes-from-inside-a-pod.md)
* [Kubernetes Basics](pentesting/pentesting-kubernetes/kubernetes-basics.md)
* [Exposing Services in Kubernetes](pentesting/pentesting-kubernetes/exposing-services-in-kubernetes.md)
* [7/tcp/udp - Pentesting Echo](pentesting/7-tcp-udp-pentesting-echo.md)
* [21 - Pentesting FTP](pentesting/pentesting-ftp/README.md)
* [FTP Bounce attack - Scan](pentesting/pentesting-ftp/ftp-bounce-attack.md)

View File

@ -275,6 +275,11 @@ If you have access to the docker socket or have access to a user in the **docker
[authz-and-authn-docker-access-authorization-plugin.md](authz-and-authn-docker-access-authorization-plugin.md)
{% endcontent-ref %}
## Hardening Docker
* The tool [**docker-bench-security**](https://github.com/docker/docker-bench-security) is a script that checks for dozens of common best-practices around deploying Docker containers in production. The tests are all automated, and are based on the [CIS Docker Benchmark v1.3.1](https://www.cisecurity.org/benchmark/docker/).\
You need to run the tool from the host running docker or from a container with enough privileges. Find out **how to run it in the README:** [**https://github.com/docker/docker-bench-security**](https://github.com/docker/docker-bench-security).
## References
* [https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/](https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/)

View File

@ -75,7 +75,7 @@ In case you can **make an app resolve a JNDI LDAP UR**L, you can control the LDA
#### Deserialization exploit
![](<../../.gitbook/assets/image (654).png>)
![](<../../.gitbook/assets/image (654) (1).png>)
The **exploit is serialized** and will be deserialized.\
In case `trustURLCodebase` is `true`, an attacker can provide his own classes in the codebase if not, he will need to abuse gadgets in the classpath.

View File

@ -14,7 +14,7 @@ HTTP/1.1 allows to ask for **different resources without needing to wait for pre
However, there is a problem desynchronising the responses queue. If an attacker send a HTTP Response smuggling attack and the responses to the **initial request and the smuggled one are responded immediately**, the smuggled response won't be inserted inside the queue of the victim response but will **just be discarded as an error**.
![](<../.gitbook/assets/image (635).png>)
![](<../.gitbook/assets/image (635) (1).png>)
Therefore, it's needed that the **smuggled** **request** **takes more time to be processed** inside the back-end server. Therefore, by the time the smuggled request is processed, the communication with the attacker will be over.
@ -80,7 +80,7 @@ Then, the **victim** will **receive** the **response** from the **HEAD** request
Following the previous example, knowing that you can **control the body** of the request whose response is going to receive the victim and that a **HEAD** **response** usually contains in its headers the **Content-Type and the Content-Length**, you can **send a request like the following** one to **cause XSS** in the victim without the page being vulnerable to XSS:
![](<../.gitbook/assets/image (654) (1).png>)
![](<../.gitbook/assets/image (654) (1) (1).png>)
### Cache Poisoning

View File

@ -52,3 +52,13 @@ Another important details about enumeration and Kubernetes permissions abuse is
* [https://securekubernetes.com/](https://securekubernetes.com)
* [https://madhuakula.com/kubernetes-goat/index.html](https://madhuakula.com/kubernetes-goat/index.html)
## Hardening Kubernetes
The tool [**kube-bench**](https://github.com/aquasecurity/kube-bench) is a tool that checks whether Kubernetes is deployed securely by running the checks documented in the [**CIS Kubernetes Benchmark**](https://www.cisecurity.org/benchmark/kubernetes/).\
You can choose to:
* run kube-bench from inside a container (sharing PID namespace with the host)
* run a container that installs kube-bench on the host, and then run kube-bench directly on the host
* install the latest binaries from the [Releases page](https://github.com/aquasecurity/kube-bench/releases),
* compile it from source.

View File

@ -0,0 +1,160 @@
# Exposing Services in Kubernetes
There are **different ways to expose services** in Kubernetes so both **internal** endpoints and **external** endpoints can access them. This Kubernetes configuration is pretty critical as the administrator could give access to **attackers to services they shouldn't be able to access**.
### ClusterIP
A **ClusterIP** service is the **default** Kubernetes **service**. It gives you a **service inside** your cluster that other apps inside your cluster can access. There is **no external access**.
However, this can be accessed using the Kubernetes Proxy:
```
kubectl proxy --port=8080
```
Now, you can navigate through the Kubernetes API to access services using this scheme:
`http://localhost:8080/api/v1/proxy/namespaces/<NAMESPACE>/services/<SERVICE-NAME>:<PORT-NAME>/`
For example you could use the following URL:
`http://localhost:8080/api/v1/proxy/namespaces/default/services/my-internal-service:http/`
to access this service:
```yaml
apiVersion: v1
kind: Service
metadata:
name: my-internal-service
spec:
selector:
app: my-app
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
```
_This method requires you to run `kubectl` as an **authenticated user**._
### NodePort
**NodePort opens a specific port on all the Nodes** (the VMs), and any **traffic** that is sent to this port is **forwarded to the service**. This is a really bad option usually.
![](<../../.gitbook/assets/image (635).png>)
An example of NodePort specification:
```yaml
apiVersion: v1
kind: Service
metadata:
name: my-nodeport-service
spec:
selector:
app: my-app
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30036
protocol: TCP
```
If you **don't specify** the **nodePort** in the yaml (it's the port that will be opened) a port in the **range 3000032767 will be used**.
### LoadBalancer <a href="#0d96" id="0d96"></a>
Exposes the Service externally **using a cloud provider's load balancer**. On GKE, this will spin up a [Network Load Balancer](https://cloud.google.com/compute/docs/load-balancing/network/) that will give you a single IP address that will forward all traffic to your service.
![](<../../.gitbook/assets/image (654).png>)
You have to pay for a LoadBalancer per exposed service, which can get expensive.
### ExternalName
Services of type ExternalName **map a Service to a DNS name**, not to a typical selector such as `my-service` or `cassandra`. You specify these Services with the `spec.externalName` parameter.
This Service definition, for example, maps the `my-service` Service in the `prod` namespace to `my.database.example.com`:
```yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: my.database.example.com
```
When looking up the host `my-service.prod.svc.cluster.local`, the cluster DNS Service returns a `CNAME` record with the value `my.database.example.com`. Accessing `my-service` works in the same way as other Services but with the crucial difference that **redirection happens at the DNS level** rather than via proxying or forwarding.
### External IPs <a href="#external-ips" id="external-ips"></a>
Traffic that ingresses into the cluster with the **external IP** (as **destination IP**), on the Service port, will be **routed to one of the Service endpoints**. `externalIPs` are not managed by Kubernetes and are the responsibility of the cluster administrator.
In the Service spec, `externalIPs` can be specified along with any of the `ServiceTypes`. In the example below, "`my-service`" can be accessed by clients on "`80.11.12.10:80`" (`externalIP:port`)
```yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 9376
externalIPs:
- 80.11.12.10
```
### Ingress
Unlike all the above examples, **Ingress is NOT a type of service**. Instead, it sits i**n front of multiple services and act as a “smart router”** or entrypoint into your cluster.
You can do a lot of different things with an Ingress, and there are **many types of Ingress controllers that have different capabilities**.
![](<../../.gitbook/assets/image (653).png>)
The default GKE ingress controller will spin up a [HTTP(S) Load Balancer](https://cloud.google.com/compute/docs/load-balancing/http/) for you. This will let you do both path based and subdomain based routing to backend services. For example, you can send everything on foo.yourdomain.com to the foo service, and everything under the yourdomain.com/bar/ path to the bar service.
The YAML for a Ingress object on GKE with a [L7 HTTP Load Balancer](https://cloud.google.com/compute/docs/load-balancing/http/) might look like this:
```yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
spec:
backend:
serviceName: other
servicePort: 8080
rules:
- host: foo.mydomain.com
http:
paths:
- backend:
serviceName: foo
servicePort: 8080
- host: mydomain.com
http:
paths:
- path: /bar/*
backend:
serviceName: bar
servicePort: 8080
```
### References
* [https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0](https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0)
* [https://kubernetes.io/docs/concepts/services-networking/service/](https://kubernetes.io/docs/concepts/services-networking/service/)

View File

@ -6,24 +6,33 @@ Kubernetes uses several **specific network services** that you might find **expo
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.
## How Kubernetes Exposes Services
It might be useful for you to understand how Kubernetes can **expose services publicly** in order to find them:
{% content-ref url="exposing-services-in-kubernetes.md" %}
[exposing-services-in-kubernetes.md](exposing-services-in-kubernetes.md)
{% endcontent-ref %}
## Finding Exposed pods via port scanning
The following ports might be open in a Kubernetes cluster:
| Port | Process | Description |
| ---------- | -------------- | ---------------------------------------------------------------------- |
| 443/TCP | kube-apiserver | Kubernetes API port |
| 2379/TCP | etcd | |
| 6666/TCP | etcd | etcd |
| 4194/TCP | cAdvisor | Container metrics |
| 6443/TCP | kube-apiserver | Kubernetes API port |
| 8443/TCP | kube-apiserver | Minikube API port |
| 8080/TCP | kube-apiserver | Insecure API port |
| 10250/TCP | kubelet | HTTPS API which allows full mode access |
| 10255/TCP | kubelet | Unauthenticated read-only HTTP port: pods, running pods and node state |
| 10256/TCP | kube-proxy | Kube Proxy health check server |
| 9099/TCP | calico-felix | Health check server for Calico |
| 6782-4/TCP | weave | Metrics and endpoints |
| Port | Process | Description |
| ----------- | -------------- | ---------------------------------------------------------------------- |
| 443/TCP | kube-apiserver | Kubernetes API port |
| 2379/TCP | etcd | |
| 6666/TCP | etcd | etcd |
| 4194/TCP | cAdvisor | Container metrics |
| 6443/TCP | kube-apiserver | Kubernetes API port |
| 8443/TCP | kube-apiserver | Minikube API port |
| 8080/TCP | kube-apiserver | Insecure API port |
| 10250/TCP | kubelet | HTTPS API which allows full mode access |
| 10255/TCP | kubelet | Unauthenticated read-only HTTP port: pods, running pods and node state |
| 10256/TCP | kube-proxy | Kube Proxy health check server |
| 9099/TCP | calico-felix | Health check server for Calico |
| 6782-4/TCP | weave | Metrics and endpoints |
| 30000-32767 | NodePort | Proxy to the servicen |
### Kube-apiserver
@ -64,6 +73,14 @@ curl -k https://<IP Address>:10255
http://<external-IP>:10255/pods
```
### etcd API
```
curl -k https://<IP address>:2379
curl -k https://<IP address>:2379/version
etcdctl --endpoints=http://<MASTER-IP>:2379 get / --prefix --keys-only
```
### cAdvisor
Service useful to gather metrics.
@ -72,12 +89,12 @@ Service useful to gather metrics.
curl -k https://<IP Address>:4194
```
#### etcd API
### 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 accesible through those ports.
```
curl -k https://<IP address>:2379
curl -k https://<IP address>:2379/version
etcdctl --endpoints=http://<MASTER-IP>:2379 get / --prefix --keys-only
sudo nmap -sS -p 30000-32767 <IP>
```
## Vulnerable Misconfigurations