Spring4Shell CVE-2022-22965 : tout savoir sur la vulnérabilité liée à Java Spring

Comprendre et neutraliser CVE-2022-22965 Spring4Shell
Maxime ALAY-EDDINE
mars 31, 2022

Cet article traite de Spring4Shell, vulnérabilité de type RCE (exécution de code à distance) découverte sur des technologies Java Spring.

Spring4Shell : un mot-clé pour définir une série de vulnérabilités qui affectent des technologies liées à Java Spring

Le 29 mars 2022, VMWare a déclaré une vulnérabilité référencée CVE-2022-22963 sur le produit Spring Cloud Function (technologie qui permet de mettre en place des services sous forme serverless).

Le même jour, une deuxième vulnérabilité de type Exécution de code à distance a été déclarée sur le produit Spring Framework (technologie cadricielle ou framework qui facilite le développement de projets Java).

Le 31/03/2022, après de nombreux débats sur les forums de discussion, cette deuxième vulnérabilité a reçu le code CVE-2022-22965.

Ces deux vulnérabilités sont mentionnées sur les réseaux sociaux sous le nom de Spring4Shell, en raison de leur lien avec les technologies de Spring, et du fait que ces technologies sont souvent des bibliothèques Java à déployer comme Log4J (bibliothèque Java qui a été ciblée par Log4Shell en décembre 2021).

Au moment de la rédaction de cet article, le NVD n’a pas encore créé de fiche officielle sur ces vulnérabilités.

L’Agence Nationale de la Sécurité des Systèmes d’Information (ANSSI) a quant à elle publié l’avis CERTFR-2022-AVI-297.

Spring4Shell décrit la vulnérabilité CVE-2022-22965

La communauté a utilisé le nom Spring4Shell pour décrire le tout, parfois avec un peu de confusion, et en souvenir de la vulnérabilité Log4Shell.

Néanmoins, le consensus veut que Spring4Shell soit plus précisément lié à la CVE-2022-22965, dont l’impact est bien moins grave que la vulnérabilité Log4Shell.

Spring4Shell est moins grave que Log4Shell et n'a de commun qu'une partie de son nom

En effet, Log4J était une technologie embarquée dans de très nombreux composants, dont la configuration par défaut permettait très souvent l’exploitation de la vulnérabilité CVE-2021-44228.

Ici, Spring Framework a une configuration par défaut qui limite fortement les capacités d’exploitation de CVE-2022-22965.

Cyberwatch recommande ainsi de mettre à jour les technologies vulnérables dans les meilleurs délais, mais de ne pas mobiliser les cellules de crise sans preuve apparente d’attaque.

Quelles sont les configurations vulnérables ?

CVE-2022-22963 affecte les composants Spring Cloud Function jusqu’à 3.1.6 et 3.2.2

La vulnérabilité CVE-2022-22963 affecte la bibliothèque Spring Cloud Function dans les versions suivantes :

  • Toute version jusqu’à 3.1.6 incluse ;
  • Toute version 3.2.X jusqu’à 3.2.2 incluse.

CVE-2022-22965 affecte les composants Spring Framework et Spring Boot jusqu’à 5.2.19 et 5.3.17

La vulnérabilité CVE-2022-22965 affecte les bibliothèques Spring Framework dans les versions suivantes sur Java 9 ou supérieur :

  • Toute version 5.0.X, 5.1.X, 5.2.X, jusqu’à 5.2.19 incluse ;
  • Toute version 5.3.X jusqu’à 5.3.17 incluse.

Elle affecte aussi les composants qui l’embarquent, comme la bibliothèque Spring Boot dans les versions suivantes sur Java 9 ou supérieur :

  • Toute version 2.0.X, 2.1.X, 2.2.X, 2.3.X, 2.4.X, jusqu’à 2.5.11 ;
  • Toute version 2.6.X jusqu’à 2.6.5 incluse.

D’après l’éditeur, les déploiements vulnérables sont exclusivement ceux qui respectent les spécificités suivantes :

  • déploiement de l’application Java sous forme de fichier WAR ;
  • exécution de l’application Java avec Apache Tomcat ;
  • présence d’une des dépendances spring-webmvc ou spring-webflux.

D’où le fait que cette CVE soit plus difficile à exploiter que Log4Shell, et donc bien moins grave.

Comment détecter la présence de Spring4Shell sur mon système d’information ?

Deux approches permettent de rechercher Spring4Shell sur votre système d’information : par parcours du disque dur, ou par tentatives d’injections sur les applications web.

Approche par parcours du disque dur

Une approche par parcours du disque dur permet d’identifier les bibliothèques JAR / WAR / EAR, et d’y rechercher la présence de bibliothèques Spring Boot ou Spring Framework.

Deux exemples basiques sont disponibles dans les scripts ci-dessous, pour Linux et Windows., et sont mis à disposition de la communauté sous licence GPLv3.

Exemple de script de recherche pour Linux

#!/bin/bash

###################################################################################
# ======================== Spring4Shell scanning scripts ==========================
#
# VERSION 1.0.0
#
# AUTHOR  Cyberwatch SAS
#
# PROJECTURI https://cyberwatch.fr
#
# DESCRIPTION
# Scans filesystem for war files that contains the Spring core lib.
# Provides the list of fetched files in the CPE format for Cyberwatch.
#
# SYNOPSIS
# Find Spring files and provide the results in the CPE format for Cyberwatch scans.
###################################################################################

toplevel='/'

# Run find with the sudo command if available, without the sudo command otherwise (can lead to permission issues)
sudo=''
sudo -n find -version > /dev/null && sudo='sudo -n'

# Le script est compatible à la fois Python 2 et Python 3. Prenons ce qui est disponible.
python='python'
if command -v python3 > /dev/null ; then
    python='python3'
elif command -v python2 > /dev/null ; then
    python='python2'
fi

pyscript=$(mktemp --tmpdir cyberwatch-XXXXXX.py)
cat > "$pyscript" <<PYTHON

import io
import os.path
import re
import sys
import zipfile

spring_re = re.compile('^spring-core.*-(?P<version>[0-9][0-9.]*[0-9]).*jar$')

def process_archive(archive_file, archive_path):
    try:
        with zipfile.ZipFile(archive_file) as archive:
            for member_path in archive.namelist():
                full_path = os.path.join(archive_path, member_path)
                m = spring_re.match(os.path.basename(archive_path))
                if m:
                    print('# WAR file found with vulnerable Spring Framework lib')
                    print('# ' + full_path)
                    print('CPE:cpe:2.3:a:vmware:spring_framework:' + m.group('version') + ':*:*:*:*:*:*:*')
                    return
                if os.path.splitext(member_path)[1].lower() in ['.jar', '.war', '.ear', '.zip']:
                    process_archive(io.BytesIO(archive.read(member_path)), full_path)
    except Exception as e:
      print("# Error reading " + archive_path + ": " + str(e))

for line in sys.stdin:
    path = line.rstrip()
    process_archive(path, path)

PYTHON

$sudo find "$toplevel" -xdev -type f \( -iname '*.war' \) |
    $sudo $python -- "$pyscript"

rm -- "$pyscript"

Exemple de script de recherche pour Windows

<#PSScriptInfo

.VERSION 1.0.0

.GUID cee16958-1b73-41c0-a6f2-a94e4ef5295b

.AUTHOR Cyberwatch SAS

.PROJECTURI https://cyberwatch.fr

.Description
Scans filesystem for war files that contains the Spring core lib.
Provides the list of fetched files in the CPE format for Cyberwatch.
WARNING: This script requires PowerShell v3 or higher!

.SYNOPSIS
Find Spring Framework files and provide the results in the CPE format for Cyberwatch analysis.
#>

Add-Type -Assembly 'System.IO.Compression'

function Invoke-Archive {
    param (
        [System.IO.Stream] $archiveStream,
        [string] $archivePath
    )

    try {
        $archive = New-Object System.IO.Compression.ZipArchive $archiveStream
    } catch {
        "# Warning: Unable to open archive $($archivePath): $($_.FullyQualifiedErrorID)"
        return
    }

    foreach ($entry in $archive.Entries) {
        $fullPath = "$archivePath/$($entry.FullName)"

        if ([System.IO.Path]::GetFileName($archivePath) -match '^spring-core.*-(\d[\d.]*\d).*jar$') {
            '# WAR file found with vulnerable Spring Framework lib'
            "# $fullPath"
            "CPE:cpe:2.3:a:vmware:spring_framework:$($Matches.1):*:*:*:*:*:*:*"
            return
        }

        if ([System.IO.Path]::GetExtension($entry.Name) -in ".jar", ".war", ".ear", ".zip") {
            $subarchive = $entry.Open()
            Invoke-Archive $subarchive $fullPath
        }
    }
}

foreach ($drive in Get-PSDrive -PSProvider FileSystem) {
    "# Browsing $($drive.Root)"
    foreach ($path in Get-ChildItem -Path $drive.Root -File -Recurse -Include "*.war" -ErrorAction SilentlyContinue -ErrorVariable UnscannablePaths) {
        $file = [System.IO.File]::OpenRead($path)
        Invoke-Archive $file $path
    }
    foreach ($Exception in $UnscannablePaths) {
        "# Warning: Unable to scan $($Exception.TargetObject): $($Exception.FullyQualifiedErrorID)"
    }
    ""
}

# END

Vous obtiendrez alors une ligne par fichier WAR qui contient une bibliothèque vulnérable, avec les versions installées. Une comparaison avec les versions indiquées dans cet article vous permettra alors de vérifier si votre système est vulnérable ou non.

Exemple de détection de Spring version 5.3.15, vulnérable

Approche par tentatives d’injection

L’injection passe par la création de requêtes web spécifiques, qui utilisent des entêtes et données POST spécialement construites pour déclencher la vulnérabilité.

Un exemple de script d’attaque est disponible sur un projet GitHub de Lunasec.

L’exécution de ce script sur la cible à tester vous permettra de vérifier si celle-ci est vulnérable ou non.

Cyberwatch met également à disposition de la communauté un module gratuit de scan de site web via son scanner Open Source Wapiti et la PR 275 https://github.com/wapiti-scanner/wapiti/pull/275.

Résultat de l'exécution de Wapiti avec le module Spring4Shell sur un site vulnérable
Résultat de l'exécution de Wapiti avec le module Spring4Shell sur un site vulnérable

Comment corriger les CVE-2022-22963 et CVE-2022-22965 Spring4Shell ?

L’approche la plus sûre consiste à mettre à jour les bibliothèques vulnérables, conformément à la liste ci-dessous.

Recommandations pour corriger CVE-2022-22963

  • Installer Spring Cloud Function version 3.1.7 pour les branches 3.1.X ou inférieures ;
  • Installer Spring Cloud Function version 3.2.3 pour la branche 3.2.X.

Recommandations pour corriger CVE-2022-22965 Spring4Shell

Cas de Spring Boot :

  • Installer Spring Boot version 2.5.12 pour les branches 2.5.X ou inférieures ;
  • Installer Spring Boot version 2.6.6 pour la branche 2.6.X.

Cas de Spring Core :

  • Installer Spring Framework 5.2.20 pour les branches 5.2.X ou inférieures ;
  • Installer Spring Framework 5.3.18 pour la branche 5.3.X.

De plus, Apache Tomcat a sorti des mises à jour qui permettent de neutraliser la CVE :

  • Installer Apache Tomcat 8.5.78 pour les branches 8.X ou inférieures ;
  • Installer Apache Tomcat 9.0.62 pour les branches 9.0.X ;
  • Installer Apache Tomcat 10.0.20 pour les branches 10.0.X.

Découvrez également Cyberwatch Vulnerability Manager, notre solution de gestion des vulnérabilités

Cyberwatch Vulnerability Manager est une solution de gestion des vulnérabilités, avec détection, priorisation, et correction.

Cyberwatch Vulnerability Manager est notamment capable de détecter Spring4Shell sur votre système d’information, via des analyses locales ou web, et de vous aider à prendre les bonnes décisions.

N’hésitez pas à demander une démonstration via le formulaire dédié.

Historique des mises à jour de cet article

Cet article concerne une vulnérabilité récemment découverte, dont l’actualité évolue régulièrement. Il subit donc régulièrement des modifications et sera enrichi en fonction de l’évolution des avis de la communauté.

31/03/2022 18h40 : première rédaction de l’article suite à la publication de la CVE-2022-22965.

31/03/2022 21h22 : mise à jour des scripts gratuits pour cibler uniquement les configurations avec WAR.

01/04/2022 16h55 : ajout des recommandations liées aux correctifs Apache Tomcat.

Vous avez des questions ?

Vous souhaitez une démonstration ?

Contactez-nous et nos experts reviendront vers vous sous 24h.

Votre demande