Spring4Shell : la vulnérabilité RCE zero-day dans Spring Framework expliquée
1 avril 2022
0 minutes de lectureLe 30 mars 2022, une vulnérabilité critique d’exécution de code à distance (RCE) a été découverte dans Spring Framework. Plus précisément, elle se trouve dans le package spring-beans, une dépendance transitive de spring-webmvc et spring-webflux. Cette vulnérabilité montre une fois de plus pourquoi sécuriser la chaîne d’approvisionnement logicielle est important dans l’open source.
Des ressources dédiées à la sécurité comme Lunasec, Rapid7 et Praetorian ont confirmé que la vulnérabilité était réelle. Entre-temps, Spring a déjà publié une nouvelle version qui corrige le problème. Nous recommandons donc de procéder à la mise à jour. Même si Spring4Shell ne semble pas avoir le même impact que la récente vulnérabilité Log4Shell, chaque organisation qui utilise Spring Framework devrait l’évaluer et la traiter en priorité. Dans cet article, nous allons voir comment fonctionne la RCE.
Explication de Spring4Shell
Si un contrôleur avec un mappage de requête est chargé en mémoire, nous sommes déjà vulnérables à ce problème. Ci-dessous, vous voyez notre GreetingController avec un PostMapping vers /greeting. Lorsque nous appelons notre application, par exemple dans Tomcat à l’adresse http://mydomain/myapp/greeting, elle tente de transformer l’entrée en POJO (Plain Old Java Object), qui correspond ici à l’objet Greeting.
Cependant, comme Spring utilise la sérialisation en interne pour mapper ces valeurs à l’objet Java, il est également possible de définir d’autres valeurs. Après quelques essais, il s’avère que vous pouvez définir les propriétés d’une classe. C’est intéressant si vous utilisez Tomcat.
Pour le montrer en action, nous pouvons utiliser la commande curl suivante pour créer un fichier rce.jsp à l’aide de certaines propriétés de journalisation de la classe.
Tout ce qui est défini dans le motif se retrouve dans le fichier. Grâce à quelques échappements ingénieux et à l’utilisation d’en-têtes, notre équipe a pu créer sur le serveur Tomcat un fichier JSP contenant le simple corps <% out.println(“HACKED”); %>. Ce fichier était alors accessible à l’adresse /myapp/rce.jsp.

La POC complète créée par Kirill Efimov et Aviad Haham)i de l’équipe de recherche en sécurité de Snyk est disponible sur GitHub
Si nous pouvons évaluer un simple out.println, nous pouvons également créer des fichiers JSP contenant des commandes de terminal qui permettent d’établir un accès par shell inversé avec Runtime.exec(). Nous pouvons aussi créer une interface web shell pratique à l’aide des fonctionnalités JSP.
Un exploit similaire, mentionné dans de nombreux autres blogs, consiste à créer un JSP capable d’exécuter une commande. Ce script Python génère pour vous la requête appropriée avec les en-têtes nécessaires. Après avoir exécuté ce script sur notre application de démonstration, nous pouvons exécuter la commande whoami comme suit : [http://localhost:8080/tomcatwar.jsp?pwd=j&cmd=whoami](http://localhost:8080/tomcatwar.jsp?pwd=j&cmd=whoami).

Qui est vulnérable ?
La situation évoluant actuellement très rapidement, nous ne pouvons parler que de ce que nous savons à l’heure actuelle.
Pour les versions concernées de spring-beans, cette vulnérabilité ne semble exploitable qu’avec JDK 9 ou une version ultérieure. L’introduction de JDK 9 a largement contourné un ancien problème, CVE-2010-1622.
Comme de nombreux développeurs Java ont déjà abandonné Java 8 au profit de versions ultérieures, et compte tenu de l’utilisation massive de Spring Framework, nous pensons que de nombreuses applications Java pourraient être vulnérables à ce problème.
Il existe plusieurs façons de résoudre ce problème. Les responsables de Spring ont publié une nouvelle version du framework. Le meilleur conseil est donc de passer à la version 5.3.18 ou 5.2.20 de Spring Framework. Selon notre équipe de sécurité, il suffit de mettre à jour le package `spring-bean` vers la dernière version, mais il est plus judicieux de mettre à jour l’ensemble du framework. Si vous utilisez Spring Boot, les versions 2.6.6 ou 2.5.12 intègrent la version mise à jour de Spring Framework.
Si vous ne pouvez pas passer à une version plus récente de Spring, vous pourriez envisager de revenir à Java 8.
Une autre option consiste à créer un InitBinder, dans le contrôleur ou sous la forme d’un ControllerAdvice distinct, comme ci-dessous.
Attention toutefois : il ne s’agit pas d’une solution définitive. Créer une liste de blocage comme celle-ci n’est pas considéré comme une bonne pratique de sécurité, mais cela peut vous faire gagner du temps. Les responsables du framework Spring suggèrent de créer un RequestMappingHandlerAdapter pour mettre à jour le WebDataBinder à la fin, une fois toutes les autres initialisations terminées, comme indiqué dans leur article de blog.
Tout dépend des frameworks et des bibliothèques
Spring4Shell montre une fois de plus à quel point nous dépendons des frameworks et bibliothèques open source. Toutefois, lorsqu’une vulnérabilité de sécurité comme celle-ci ou la récente RCE Log4Shell survient, vous devez en être informé pour pouvoir la corriger immédiatement.
Snyk vous aide à garder une longueur d’avance en analysant régulièrement vos applications. Snyk vous avertit, vous et votre équipe, lorsque de nouvelles vulnérabilités sont détectées et vous recommande les prochaines étapes à suivre pour sécuriser vos applications.
Enfin, les vulnérabilités zero-day comme celle-ci nous rappellent pourquoi il est important d’utiliser les dernières versions des bibliothèques. En restant à jour, vous pouvez appliquer les mises à jour, reconstruire et redéployer plus rapidement.
Lancez-vous dans les compétitions Capture The Flag
Apprenez à résoudre des défis de capture du drapeau en regardant à la demande notre atelier virtuel d’initiation.
