Spring4Shell: explicación de la vulnerabilidad de ejecución remota de código de día cero en Spring Framework
1 de abril de 2022
0 minutos de lecturaEl 30 de marzo de 2022, se encontró una vulnerabilidad crítica de ejecución remota de código (RCE) en Spring Framework. Más específicamente, forma parte del paquete spring-beans, una dependencia transitiva tanto en spring-webmvc como en spring-webflux. Esta vulnerabilidad es otro ejemplo de por qué es importante proteger la cadena de suministro de software de código abierto.
Recursos de seguridad como Lunasec, Rapid7 y Praetorian confirmaron que la vulnerabilidad es real y, mientras tanto, Spring ya lanzó una nueva versión que mitiga este problema, por lo que recomendamos actualizar. Aunque Spring4Shell no parece tener el mismo impacto que la reciente vulnerabilidad Log4Shell, todas las organizaciones que usan Spring Framework deberían evaluarla y priorizarla. En esta publicación, exploraremos cómo funciona la RCE.
Explicación de Spring4Shell
Si tenemos un controlador con una asignación de solicitud cargada en la memoria, ya somos vulnerables a este problema. A continuación, puedes ver nuestro GreetingController con un PostMapping a /greeting. Cuando llamamos a nuestra aplicación, por ejemplo, en Tomcat en http://mydomain/myapp/greeting, intenta transformar la entrada en un POJO (Plain Old Java Object), que en nuestro caso es el objeto Greeting.
Sin embargo, como Spring usa serialización internamente para asignar estos valores al objeto Java, también es posible establecer otros valores. Después de explorar un poco, descubrimos que se pueden establecer propiedades de una clase. Esto es interesante si ejecutas la aplicación en Tomcat.
Para mostrarlo en acción, podemos usar el siguiente curl para crear un archivo rce.jsp mediante algunas propiedades de registro de la clase.
Todo lo que se establece en el patrón termina como contenido del archivo. Con un poco de ingenio para escapar caracteres y usando encabezados, nuestro equipo pudo crear un archivo JSP en el servidor Tomcat con el sencillo cuerpo <% out.println(“HACKED”); %>. Este archivo ahora estaba disponible en /myapp/rce.jsp.

La POC completa creada por Kirill Efimov y Aviad Hahami del equipo de investigación de seguridad de Snyk está disponible en GitHub
Si podemos evaluar un out.println sencillo, también podemos crear archivos JSP con comandos de terminal que generen acceso a un shell inverso usando Runtime.exec(). Como alternativa, podemos crear una práctica interfaz de web shell usando las capacidades de JSP.
Un exploit similar, mencionado en muchos otros blogs, consiste en crear un JSP capaz de ejecutar un comando. Este script de Python crea por ti la solicitud adecuada con los encabezados necesarios. Después de ejecutar este script en nuestra aplicación de demostración, podemos ejecutar el comando whoami de esta manera: [http://localhost:8080/tomcatwar.jsp?pwd=j&cmd=whoami](http://localhost:8080/tomcatwar.jsp?pwd=j&cmd=whoami).

¿Quiénes son vulnerables?
Como la situación evoluciona rápidamente, solo podemos decir lo que sabemos hasta ahora.
En las versiones afectadas de spring-beans, parece que esta vulnerabilidad solo funciona si usas JDK 9 o una versión posterior. La introducción de JDK 9 permitió superar en gran medida un problema antiguo, CVE-2010-1622.
Como muchos desarrolladores de Java ya migraron a versiones posteriores a Java 8 y Spring Framework se usa muchísimo, creemos que muchas aplicaciones Java podrían ser vulnerables a este problema.
Hay varias formas de resolver este problema. Los responsables de Spring lanzaron una nueva versión del framework. Por eso, la mejor recomendación es actualizar a la versión 5.3.18 o 5.2.20 de Spring Framework. Según nuestro equipo de seguridad, solo tienes que actualizar el paquete `spring-bean` a la versión más reciente, pero tiene más sentido actualizar todo el framework. Si usas Spring Boot, las versiones 2.6.6 o 2.5.12 incluyen la versión actualizada de Spring Framework.
Si no puedes actualizar a una versión más reciente de Spring, quizá sea viable bajar la versión de Java a Java 8.
Otra opción es crear un InitBinder en el controlador o como un ControllerAdvice independiente, como se muestra a continuación.
Ten en cuenta que esta no es una solución definitiva. Crear una lista de bloqueo como esta no se considera una buena práctica de seguridad, pero podría darte algo de tiempo. Los responsables de Spring Framework sugieren crear un RequestMappingHandlerAdapter para actualizar el WebDataBinder al final, después de toda la inicialización, en su publicación del blog.
Dependencia de frameworks y bibliotecas
Spring4Shell vuelve a demostrar que dependemos mucho de los frameworks y las bibliotecas de código abierto. Sin embargo, cuando aparece una vulnerabilidad de seguridad como esta o la reciente RCE de Log4Shell, es importante estar al tanto para poder mitigarla de inmediato.
Snyk puede ayudarte a mantenerte al tanto mediante el análisis periódico de tus aplicaciones. Snyk te avisa a ti y a tu equipo cuando detecta nuevas vulnerabilidades y les ofrece los siguientes pasos recomendados para mantener seguras sus aplicaciones.
Por último, vulnerabilidades de día cero como esta nos recuerdan por qué es importante mantener las bibliotecas actualizadas. Si estás al día, puedes aplicar actualizaciones, volver a compilar y lanzar una nueva versión más fácilmente y con rapidez.
Empieza con los desafíos de Capture the Flag
Aprende a resolver desafíos de captura la bandera con nuestro taller virtual introductorio a pedido.



