0x01 前言距離上一次更新JAVA安全的系列文章已經過去一段時間了,在上一篇文章中介紹了反序列化利用鏈基本知識,並闡述了Transform鏈的基本知識。 Transform鏈並不是一條完整的利用鏈,只是CommonsCollections利用鏈中的一部分。當然並不是所有的CC鏈都需要用Transform鏈。
為了更方便的理解CC鏈,我們並不會按照順序來闡述所有的鏈,而是按照鏈的難易程度,由易到難。
0x02CommonsCollections5鏈CommonsCollections5鍊是整個CC鏈中最簡單的一條鏈,通過BadAttributeValueExpException類的readObject方法觸發反序列化的過程,最終調用Transform鏈來達到命令執行的效果。
在ysoserial的環境中調試CommonsCollections5鏈的方式很簡單,如圖2.1所示。
圖2.1 使用ysoserial生成反序列化利用鏈
直接調用就會執行彈出計算器的命令,跟踪run方法可以查看代碼執行邏輯,如圖2.2所示。
圖2.2 在ysoserial中的序列化和反序列化過程
在ysoserial的run方法中既有序列化的過程,也有反序列化的過程。所以調用run方法因為反序列化的過程導致會執行對應的惡意代碼,彈出計算器。
在很多情況下需要保存反序列化對像到文件,可以通過在run方法中添加文件保存方法即可,如圖2.3所示。
圖2.3 保存序列化字節碼對像到文件
通過上面的方式可以直接把生成的序列化字節碼對象保存到文件cc.ser,查看文件內容,如圖2.4所示。文件中開頭的字符是aced0005,符合序列化文件的標準特徵。
圖2.4 通過xxd查看序列化文件保存的內容
通過上面的方式可以利用ysoserial生成標準的CommonsCollections5利用鏈對應的payload,下一步會繼續對CommonsCollections5利用鏈的調用過程進行分析。
通過debug的方式可以查看整個CommonsCollections5利用鏈的棧調用過程,如圖2.5所示。
圖2.5 CommonsCollections5利用鏈的棧調用過程
在圖2.5中,紅框2對應的過程階段是屬於Transform鏈的調用過程,在上一篇文章中已經進行詳述。紅框1對應的過程階段是屬於CommonsCollections5特有的調用過程,也是屬於本文的重點部分內容。
反序列化的起始點是javax.management.BadAttributeValueExpException類的readObject方法,如圖2.6所示。
圖2.6 調用BadAttributeValueExpException類的readObject方法
從圖2.6可以看出readObject方法首先獲取字節流類(也就是本類)對應的val字段,然後基於多個判斷,最終下一步操作是val字段對應的toString方法。這裡有一點需要注意的是判斷邏輯中要求System.getSecurityManager()為null,也就是不能開啟SecurityManager模式。
在下一步的調用棧中是調用了org.apache.commons.collections.keyvalue.TiedMapEntry的toString方法,也就是需要把上一步的val字段類型賦值為TiedMapEntry類。在TiedMapEntry類的toString方法中調用了getValue方法,如圖2.7所示。
圖2.7 TiedMapEntry類的toString方法
繼續跟踪getValue方法,如圖2.8所示。
圖2.8 調用map接口的get方法
從圖2.8可以看出,這裡調用了java.util.Map接口的get方法。所有隻要找到一個繼承自java.util.Map接口的類的get方法中存在惡意調用即可。在CommonsCollections5鏈中找到的惡意類是org.apache.commons.collections.map.LazyMap類,如圖2.9所示。
圖2.9 LazyMap類的get方法調用
從圖2.9可以看出LazyMap類的get方法會調用org.apache.commons.collections.Transformer類的transform方法。在上一篇文章的內容中已經講到在反序列化過程中如果可以調用transform方法,那麼就可以通過transform方法來執行系統命令,也就可以達到RCE的效果。
實際上要編寫真正可利用的EXP遠比基於棧調用來分析更加複雜,因為在編寫EXP的過程中,需要考慮每一步棧調用的過程中的邏輯判斷條件,這並不是一件簡單的事情。
一般來說反序列化利用鏈代碼的編寫是倒著來寫的,首先是transform鏈的構造,如果某個類可以調用transformChain的transform方法,則可以執行命令,如圖2.10所示
圖2.10 通過調用Transformer類的transform方法調用執行命令
註釋transform方法調用,繼續倒序編寫EXP。如果某個類可以調用LazyMap類的get方法,則可以執行系統命令,如圖2.11所示。
圖2.11 通過調用LazyMap類的get方法執行命令
註釋LazyMap的get方法調用,繼續倒序編寫EXP。如果某個類可以調用TiedMapEntry類的toString方法,則可以執行系統命令,如圖2.12所示。
圖2.12 通過調用TiedMapEntry類的toString方法執行系統命令
註釋TiedMapEntry的toString方法調用,繼續倒序編寫EXP。找到javax.management. BadAttributeValueExpException類的readObject方法中存在toString的方法調用,模擬反序列化過程,執行命令,如圖2.13所示。
圖2.13 模擬BadAttributeValueExpException類的反序列化過程執行命令
這樣就完整的複現和分析了CommonsCollections5利用鏈,從圖2.13的payload中可以看出CommonsCollections5利用鏈中沒有復雜的邏輯處理,適合新手入門java反序列化漏洞學習。
0x03CommonsCollections7鏈CommonsCollections7鍊是一條和CommonsCollections5鏈很像的利用鏈,最終的結果都是通過LazyMap的get方法調用Transform鏈來執行命令,調用棧如圖3.1所示。
圖3.1CommonsCollections7利用鏈
如圖3.1所示,其中紅框部分和CommonsCollections5鍊是完全一樣的,區別在於CommonsCollections7鍊是通過Hashtable類readObject方法一步步調用AbstractMap類的equals方法來調用的。
由於分析調用鏈的方式基本相同,所以不再對這條鏈進行分析。
0x04 結論CommonsCollections利用鏈中有多條利用鏈都涉及到Transform鏈,包括CC1、CC5、CC6、CC7,其中的調用過程都非常相似。但是並不是所有的CC鏈都是基於Transform實現的命令執行,在下一篇文章中會講到其他的利用鏈,會有更加複雜的應用方式。
往期推薦1
告別腳本小子系列丨JAVA安全(1)——JAVA本地調試和遠程調試技巧
2
告別腳本小子系列丨JAVA安全(2)——JAVA反編譯技巧
3
告別腳本小子系列丨JAVA安全(3)——JAVA反射機制
4
告別腳本小子系列丨JAVA安全(4)——ClassLoader機制與冰蠍Webshell分析
5
告別腳本小子系列丨JAVA安全(5)——序列化與反序列化
6
告別腳本小子系列丨JAVA安全(6)——反序列化利用鏈(上)