Trouver les images vulnérables à la faille log4j avec bash et trivy dans k8s
Sommaire
Il y a quelques jours, le 10 décembre 2021, une vulnérabilité critique a été découverte sur Apache Log4j 2, une librairie Java pour la gestion des logs. Cette faille permettant l'exécution de code à distance est surnommée Log4Shell.
C'est une bonne opportunité pour jouer avec bash, pour trouver au sein de cluster Kubernetes quelles images de pods sont impactés.
Lister les images du cluster
Lister les pods est assez facile, mais lister les images est un tout petit peu plus compliqué. Nous devons jouer avec l'option jsonpath
pour sélectionner l'image.
La commande suivante permet de lister toutes les images de pods s'exécutant dans un namespace:
1$ kubectl get pods -o jsonpath=’{range .items[*]}{.spec.containers[*].image}{“ “}’
Ajoutons à cela quelque lignes magiques de bash pour classer, avoir les images des sidecars et dédupliquer la sortie, cela donne le résultat suivant :
1$ kubectl get pods -o jsonpath='{range .items[*]}{.spec.containers[*].image}{" "}' | tr " " "\n" | sort -u
2consul:1.3.0
3elasticsearch:5.6.13
4grafana/grafana:5.1.0
5jboss/keycloak:4.5.0.Final
6jhipster/consul-config-loader:v0.3.0
7jhipster/jhipster-console:v4.0.0
8jhipster/jhipster-elasticsearch:v4.0.0
9jhipster/jhipster-logstash:v4.0.0
10jhipster/jhipster-zipkin:v4.0.0
11mariadb:10.5
12mongo:4.0.2
13nextcloud:20.0.6-apache
14postgres:10.4
Maintenant que nous pouvons récupérer les images, utilisons trivy.
Trivy
Trivy est un scanner de sécurité open source développé par la société Aquasecurity. Il scanne vos images, pour y trouver toutes les vulnérabilités "CVE". Ce logiciel est embarqué dans d'autres outils "DevSecOps", comme VMware Harbor, GitLab, et d'autres.
Pour l'installer sur votre OS favori, cela se passe par la : https://aquasecurity.github.io/trivy/v0.21.2/getting-started/installation/.
L'utilisation de trivy est très simple. Par exemple, pour voir les vulnérabilités d'une image lancez la commande suivante :
1$ trivy image — severity CRITICAL elasticsearch:5.6.13
Le résultat parle de lui-même:
1$ trivy image --severity CRITICAL elasticsearch:5.6.13
22021-12-12T21:20:06.322+0100 INFO Detected OS: debian
32021-12-12T21:20:06.322+0100 INFO Detecting Debian vulnerabilities...
42021-12-12T21:20:06.350+0100 INFO Number of language-specific files: 1
52021-12-12T21:20:06.350+0100 INFO Detecting jar vulnerabilities...
6
7Java (jar)
8==========
9Total: 6 (CRITICAL: 6)
10
11+-------------------------------------+------------------+----------+-------------------+---------------+---------------------------------------+
12| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
13+-------------------------------------+------------------+----------+-------------------+---------------+---------------------------------------+
14| io.netty:netty | CVE-2019-20444 | CRITICAL | 3.10.6.Final | 4.1.44.Final | netty: HTTP request smuggling |
15| | | | | | -->avd.aquasec.com/nvd/cve-2019-20444 |
16+ +------------------+ + + +---------------------------------------+
17| | CVE-2019-20445 | | | | netty: HttpObjectDecoder.java allows |
18| | | | | | Content-Length header to accompanied |
19| | | | | | by second Content-Length header |
20| | | | | | -->avd.aquasec.com/nvd/cve-2019-20445 |
21+-------------------------------------+------------------+ +-------------------+---------------+---------------------------------------+
22| io.netty:netty-handler | CVE-2019-20444 | | 4.1.13.Final | 4.1.44 | netty: HTTP request smuggling |
23| | | | | | -->avd.aquasec.com/nvd/cve-2019-20444 |
24+ +------------------+ + +---------------+---------------------------------------+
25| | CVE-2019-20445 | | | 4.1.45 | netty: HttpObjectDecoder.java allows |
26| | | | | | Content-Length header to accompanied |
27| | | | | | by second Content-Length header |
28| | | | | | -->avd.aquasec.com/nvd/cve-2019-20445 |
29+-------------------------------------+------------------+ +-------------------+---------------+---------------------------------------+
30| org.apache.logging.log4j:log4j-api | CVE-2021-44228 | | 2.11.1 | 2.15.0 | log4j-core: Remote code execution |
31| | | | | | in Log4j 2.x when logs contain |
32| | | | | | an attacker-controlled... |
33| | | | | | -->avd.aquasec.com/nvd/cve-2021-44228 |
34+-------------------------------------+ + + + + +
35| org.apache.logging.log4j:log4j-core | | | | | |
36| | | | | | |
37| | | | | | |
38| | | | | | |
39+-------------------------------------+------------------+----------+-------------------+---------------+---------------------------------------+
On voit que la vulnérabilité CVE-2021–44228 est présente, nous devons patcher ou mettre à jour dès que possible !
Bash & Trivy
Edit (15/12/2021) : Il existe un plug-in tout fait pour cela ! Voir ici: https://github.com/aquasecurity/trivy-plugin-kubectl
Ok, maintenant que nous avons la liste des images dans notre cluster, que nous savons scanner une image, allons plus loin, et bouclons !
Voici un script bash permettant cela juste ci-dessous. Amusez-vous avec ! Notez que dans l'exemple nous listons les images du namespace courant. Vous pouvez l'améliorer au besoin.
1#!/usr/bin/env bash
2RED='\033[0;31m'
3NC='\033[0m'
4
5OLDIFS="$IFS"
6IFS=$'\n'
7VULN=$1
8
9# $1 arg is the CVE number to check
10if [ -z $1 ]; then
11 echo -e "usage: $0 CVE-NUMBER (i.e: './k8s_vuln.sh CVE-2021-44228')"
12 exit
13fi
14
15# Check command existence before using it
16if ! command -v trivy &> /dev/null; then
17 echo "trivy not found, please install it"
18 exit
19fi
20if ! command -v kubectl &> /dev/null; then
21 echo "kubectl not found, please install it"
22 exit
23fi
24
25# CVE-2021-44228
26echo "Scanning $1..."
27
28namespaces=`kubectl get ns | cut -d' ' -f 1 | tail -n+2`
29for ns in ${namespaces}; do
30 echo "- scanning in namespace ${ns}"
31 imgs=`kubectl get pods,deployments,daemonsets,statefulsets,jobs,cronjobs -n ${ns} -o jsonpath='{range .items[*]}{.spec.containers[*].image}{" "}' | tr " " "\n" | sort -u`
32 for img in ${imgs}; do
33 echo " scanning ${img}"
34 result=`trivy -q image --light --no-progress --severity CRITICAL ${img}`
35 if echo ${result} | grep -q "$1" ; then
36 echo -e " ${RED}${img} is vulnerable, please patch!${NC}"
37 fi
38 done
39done
40
41IFS="$OLDIFS"
Etapes suivantes
Ceci était un rapide exemple d'utilisation bash, mais vous pouvez utiliser des outils de sécurité plus avancé pour être alerté de telles failles, comme Sysdig Secure, Snyk ou d'autres !
References
- Docker blog post: https://www.docker.com/blog/apache-log4j-2-cve-2021-44228/
- Apache Log4j : https://logging.apache.org/log4j/2.x/security.html