
Análisis educativo y exploit de prueba de concepto para CVE-2022-22965, una vulnerabilidad de ejecución remota de código en Spring MVC/WebFlux mediante el enlace de datos en JDK 9+ con despliegue de WAR en Tomcat.
Recientemente Spring ha publicado una vulnerabilidad CVE de gran repercusión. La información del CVE indica: "A Spring MVC or Spring WebFlux application running on JDK 9+ may be vulnerable to remote code execution (RCE) via data binding. The specific exploit requires the application to run on Tomcat as a WAR deployment. If the application is deployed as a Spring Boot executable jar, i.e. the default, it is not vulnerable to the exploit. However, the nature of the vulnerability is more general, and there may be other ways to exploit it.(una aplicación Spring MVC o Spring WebFlux que se ejecute en JDK 9+ puede ser vulnerable a la ejecución remota de código (RCE) mediante el enlace de datos. La explotación específica requiere que la aplicación se ejecute en Tomcat como un despliegue WAR. Si la aplicación se despliega como un jar ejecutable de Spring Boot, es decir, el valor predeterminado, no es vulnerable a esta explotación. Sin embargo, la naturaleza de la vulnerabilidad es más general y puede haber otras formas de explotarla)". Este análisis estudia el principio de la vulnerabilidad reproduciendo este CVE.
Antes de ver el principio del enlace de parámetros de Spring MVC, echemos un vistazo a algunas API relacionadas con Java Bean.
Declare la siguiente clase Java Bean:```java public class User { private String name;
public User() {
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public int getAge() {
return 18;
}
}
Usemos el siguiente código de prueba para ver la información obtenida por Introspector.getBeanInfo:```java
@Test
public void testIntrospector() throws IntrospectionException {
BeanInfo beanInfo = Introspector.getBeanInfo(User.class);
for (PropertyDescriptor pdesc:beanInfo.getPropertyDescriptors()){
System.out.println("Property: " + pdesc.getName() + ",Class:" + pdesc.getPropertyType());
}
// for (MethodDescriptor md:beanInfo.getMethodDescriptors()) {
// System.out.println("Method: " + md.getName());
// }
}
salida:```text Property: age,Class:int Property: class,Class:class java.lang.Class Property: name,Class:class java.lang.String
Además de age y name, que son de esperar, también hay una propiedad class cuyo nombre de clase es Class. Si se continúa llamando a Introspector.getBeanInfo(Class.class), se puede obtener más información, como classLoader:```text jdk11:
Property: annotatedInterfaces
Property: annotatedSuperclass
Property: annotation
Property: annotations
Property: anonymousClass
Property: array
Property: canonicalName
Property: class
Property: classLoader
Property: classes
Property: componentType
Property: constructors
Property: declaredAnnotations
Property: declaredClasses
Property: declaredConstructors
Property: declaredFields
Property: declaredMethods
Property: declaringClass
Property: enclosingClass
Property: enclosingConstructor
Property: enclosingMethod
Property: enum
Property: enumConstants
Property: fields
Property: genericInterfaces
Property: genericSuperclass
Property: interface
Property: interfaces
Property: localClass
Property: memberClass
Property: methods
Property: modifiers
Property: module
Property: name
Property: nestHost
Property: nestMembers
Property: package
Property: packageName
Property: primitive
Property: protectionDomain
Property: signers
Property: simpleName
Property: superclass
Property: synthetic
Property: typeName
Property: typeParameters
Además, comparemos las diferencias en la información obtenida por Introspector.getBeanInfo(Class.class) bajo diferentes versiones de JDK; arriba está la salida de jdk-11 y abajo la de JDK8:```text jdk8: Property: annotatedInterfaces Property: annotatedSuperclass Property: annotation Property: annotations Property: anonymousClass Property: array Property: canonicalName Property: class Property: classLoader Property: classes Property: componentType Property: constructors Property: declaredAnnotations Property: declaredClasses Property: declaredConstructors Property: declaredFields Property: declaredMethods Property: declaringClass Property: enclosingClass Property: enclosingConstructor Property: enclosingMethod Property: enum Property: enumConstants Property: fields Property: genericInterfaces Property: genericSuperclass Property: interface Property: interfaces Property: localClass Property: memberClass Property: methods Property: modifiers Property: name Property: package Property: primitive Property: protectionDomain Property: signers Property: simpleName Property: superclass Property: synthetic Property: typeName Property: typeParameters
I don't see any source text to translate. The INPUT section is empty. Please provide the Chinese (zh) Markdown content for chunk 11 so I can translate it into Spanish (es).```text
Property: annotatedInterfaces
Property: annotatedSuperclass
Property: annotation
Property: annotations
Property: anonymousClass
Property: array
Property: canonicalName
Property: class
Property: classLoader
Property: classes
Property: componentType
Property: constructors
Property: declaredAnnotations
Property: declaredClasses
Property: declaredConstructors
Property: declaredFields
Property: declaredMethods
Property: declaringClass
Property: enclosingClass
Property: enclosingConstructor
Property: enclosingMethod
Property: enum
Property: enumConstants
Property: fields
Property: genericInterfaces
Property: genericSuperclass
Property: interface
Property: interfaces
Property: localClass
Property: memberClass
Property: methods
Property: modifiers
Property: module
Property: name
Property: package
Property: packageName
Property: primitive
Property: protectionDomain
Property: signers
Property: simpleName
Property: superclass
Property: synthetic
Property: typeName
Property: typeParameters
En comparación con JDK8, jdk9 tiene dos atributos adicionales: module y packageName, mientras que JDK11, además de los atributos module y packageName, tiene otros dos: nestHost y nestMembers.