JAVA反序列化中的反射鏈

從反射鏈的構(gòu)造看JAVA反序列化

http://www.freebuf.com/news/150872.html

構(gòu)造反射鏈:Transformer類(lèi),源碼解釋為從一個(gè)類(lèi)轉(zhuǎn)化為另一個(gè)類(lèi)。其中的transform()為執(zhí)行轉(zhuǎn)換方法。

ConstantTransformer,invokerTransformer,ChainedTransformer和TransformedMap繼承了Transformer類(lèi)。利用它們來(lái)構(gòu)造反序列化payload,原理為:

ConstantTransformer類(lèi)通過(guò)transform轉(zhuǎn)換得到內(nèi)部類(lèi)的對(duì)象類(lèi)型,如參數(shù)是Runtime.class時(shí),經(jīng)ConstantTransformer類(lèi)執(zhí)行后返回java.lang.Runtime

invokerTransformer類(lèi),通過(guò)反射創(chuàng)建新的對(duì)象實(shí)例。其中transform方法定義為:

這個(gè)transform(Object input) 中使用Java反射機(jī)制調(diào)用了input對(duì)象的一個(gè)方法,而該方法名是實(shí)例化InvokerTransformer類(lèi)時(shí)傳入的iMethodName成員變量:

也就是說(shuō)這段反射代碼中的調(diào)用的方法名和Class對(duì)象均可控。于是,我們可以構(gòu)造一個(gè)惡意的Transformer鏈,借用InvokerTransformer.transform()執(zhí)行任意命令。

method.invoke(input,iargs)意思是,執(zhí)行input對(duì)象的method方法,參數(shù)是iargs。

舉例:構(gòu)造一個(gè)對(duì)象,并且調(diào)用transform對(duì)象,如下圖所示:

查看method變量的值如下圖所示:

cls變量獲取到的是傳遞進(jìn)來(lái)的input的對(duì)象值,此處input傳遞的是Runtime的對(duì)象,下面兩行代碼要反射Runtime的getRuntime方法,iMethodName表示要得到的方法名稱(chēng),iParamTypes表示方法中所使用的參數(shù)類(lèi)型的數(shù)組。

執(zhí)行invoke方法,因?yàn)槭欠瓷鋑etRuntime()方法,參數(shù)為空,所以iArgs的值可以為空。成功的反射出了Runtime.getRuntime()的方法,然而如果要執(zhí)行任意代碼的化,還需要有exec代碼段,全部應(yīng)該是Runtime.getRuntime().exec(“calc.exe”)。

構(gòu)造payload

此時(shí)已經(jīng)獲得了GetRuntime()的Method對(duì)象,如果要執(zhí)行exec(“calc.exe”),還需要進(jìn)行一次invoke反射的過(guò)程,將GetRuntime()反射成對(duì)象,因?yàn)橹挥袑?duì)象才能調(diào)用exec函數(shù)。因此我們根據(jù)上面構(gòu)造出下面的代碼段,如下圖:

上圖中,構(gòu)造出tran2的方法,配置invoke的參數(shù)都為null,利用tran2.transform(run),反射invoke方法,過(guò)程與上文中一樣,此處直接看輸出了:

此處已經(jīng)是Runtime類(lèi)了,繼續(xù)構(gòu)造exec(“calc.exe”)代碼段,如下圖所示:

由此構(gòu)造成功payload。

以上是構(gòu)造反射鏈,執(zhí)行反射鏈用到ChainedTransformer。

利用for循環(huán),對(duì)傳入的transformers[i]運(yùn)行transform方法,就是把上文的步驟利用一個(gè)for循環(huán)整合在了一起。

現(xiàn)在我構(gòu)造一個(gè)以數(shù)組為主的反射鏈進(jìn)行彈窗,代碼段如下圖所示:

構(gòu)造出了chain方法之后,還需要調(diào)用transform方法,至于傳入的對(duì)象會(huì)被很快覆蓋掉,所以input的類(lèi)型可以任意。

TransformedMap類(lèi)

這個(gè)類(lèi)調(diào)用了ChainedTransformer類(lèi)中的transform方法。transform函數(shù)調(diào)用在TransformedMap類(lèi)的setvalue方法中。

只要我們控制valueTransformer的值為ChainTransformer對(duì)象就可以執(zhí)行反射鏈了,找到他的賦值地點(diǎn),如下圖所示:

當(dāng)TransformedMap內(nèi)的key 或者value發(fā)生變化時(shí),就會(huì)觸發(fā)相應(yīng)的Transformer的transform()方法。另外,還可以使用Transformer數(shù)組構(gòu)造成ChainedTransformer。當(dāng)觸發(fā)時(shí),ChainedTransformer可以按順序調(diào)用一系列的變換。

payload測(cè)試代碼:

InvokerTransformer.transform()執(zhí)行任意命令,測(cè)試代碼如下:

這樣,這段惡意代碼本質(zhì)上就是利用反射調(diào)用Runtime() 執(zhí)行了一段系統(tǒng)命令,作用等同于:

也就是說(shuō),一個(gè)精心構(gòu)造的TransformedMap,在其任意鍵值被修改時(shí),可以觸發(fā)變換,從而執(zhí)行任意命令。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類(lèi)相關(guān)的語(yǔ)法,內(nèi)部類(lèi)的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 34,692評(píng)論 18 399
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,554評(píng)論 19 139
  • 小編費(fèi)力收集:給你想要的面試集合 1.C++或Java中的異常處理機(jī)制的簡(jiǎn)單原理和應(yīng)用。 當(dāng)JAVA程序違反了JA...
    八爺君閱讀 5,206評(píng)論 1 114
  • 最近公司要做停車(chē)自動(dòng)標(biāo)記車(chē)輛位置的功能,這是室內(nèi)定位反向?qū)ぼ?chē)系統(tǒng)的前提條件,也是室內(nèi)定位技術(shù)剛需! 解決思...
    Ran_戈閱讀 4,272評(píng)論 0 2
  • 暢想一下未來(lái)20年,會(huì)是什么樣的生活?未來(lái)50年是什么樣的生活?未來(lái)100年呢?我們吃什么,用什么,怎么出門(mén),我們...
    蒼松月影閱讀 566評(píng)論 2 1

友情鏈接更多精彩內(nèi)容