反序列化漏洞匯總
1、概述
序列化是讓Java對象脫離Java運行環境的一種手段,可以有效的實現多平臺之間的通信、對象持久化存儲。

Java 序列化是指把 Java 對象轉換為字節序列的過程,便于保存在內存、文件、數據庫中,ObjectOutputStream類的 writeObject() 方法可以實現序列化。反序列化是指把字節序列恢復為 Java 對象的過程,ObjectInputStream 類的 readObject() 方法用于反序列化。
條件:
類必須實現反序列化接口,同時設置serialVersionUID以便適用不同jvm環境。
可通過SerializationDumper這個工具來查看其存儲格式,主要包括Magic頭:0xaced,TC_OBJECT:0x73,TC_CLASS:0x72,serialVersionUID,newHandle
示例:

代碼功能:
將String對象obj1序列化后寫入object文件,后反序列化得到對象obj2。
Object文件中的內容:

Ac ed 00 05是java序列化內容的特征,編碼后是rO0ABQ==
使用場景:
? http參數,cookie,sesion,存儲方式可能是base64(rO0),壓縮后的base64(H4sl),MII等
? Servlets HTTP,Sockets,Session管理器 包含的協議就包括JMX,RMI,JMS,JNDI等(\xac\xed)
? xml Xstream,XMLDecoder等(HTTP Body:Content-Type:application/xml)
? json(Jackson,fastjson) http請求中包含
2、漏洞成因
序列化和反序列化本身并不存在問題。但當輸入的反序列化的數據可被用戶控制,那么攻擊者即可通過構造惡意輸入,讓反序列化產生非預期的對象,在此過程中執行構造的任意代碼。
漏洞案例:

Test.class中MyObject類有一個共有屬性name,myObj實例化后將myObj.name賦值為了“hi”,然后序列話寫入object:

漏洞發生在反序列化過程,MyObject類實現了Serializable接口,并重寫了readObject()函數(從源輸入流中讀取字節序列,反序列化成對象),這里定制的行為是打開計算器:
攻擊時序圖:

3、Weblogic反序列化漏洞匯總
歷史漏洞:

3.1 CVE-2015-4852 Commons Collections
概述:
借用Java反序列化和Apache Commons Collections這一基礎類庫實現遠程命令執行。這個漏洞橫掃WebLogic、WebSphere、JBoss、Jenkins、OpenNMS的最新版。
漏洞出現在WLS Security組件,允許遠程攻擊者執行任意命令。攻擊者通過向TCP端口7001發送T3協議流量,其中包含精心構造的序列化Java對象利用此漏洞。
(T3 協議在 WebLogic Server 和其他 Java 程序,包括客戶端及其他 WebLogic Server 實例間傳輸數據)
漏洞分析:
Apache Commons Collections是一個擴展了Java標準庫里的Collection結構的第三方基礎庫,實現了一個TransformedMap類,該類是對Java標準數據結構Map接口的一個擴展。該類可以在一個元素被加入到集合內時,自動對該元素進行特定的修飾變換,具體的變換邏輯由Transformer類定義,Transformer在TransformedMap實例化時作為參數傳入。(可控變量)。

如果某個可序列化的類重寫了readObject()方法,并且在readObject()中對Map類型的變量進行了鍵值修改操作,并且這個Map變量是可控的,就可以實現我們的攻擊目標了。
于是找到了這個類:AnnotationInvocationHandler。該類的代碼如下(反序列化)
我們可以實例化一個AnnotationInvocationHandler類,將其成員變量memberValues賦值為精心構造的惡意TransformedMap對象。然后將其序列化,提交給未做安全檢測的Java應用。Java應用在進行反序列化操作時,則會觸發TransformedMap的變換函數,執行預設的命令。
分析:https://security.tencent.com/index.php/blog/msg/97
Poc:https://github.com/fjserna/CVE-2015-7547
修復辦法:

http://www.oracle.com/technetwork/topics/security/alert-cve-2015-4852-2763333.html
https://blogs.oracle.com/security/entry/security_alert_cve_2015_4852
3.2 CVE-2016-0638
漏洞位置,在readExternal位置:

補丁,加了一個FilteringObjectInputStream過濾接口:

3.3 CVE-2017-3248
根據JRMPListener來構造的,從補丁也可以看出,在resolveClass和resolveProxyClass都設置了黑名單。

3.4 CVE-2017-3506&CVE-2017-10271
概述:
CVE-2017-10271 是3506的繞過。
漏洞在WLS-WebServices這個組件中,基于WLS wsat模塊,核心就是XMLDecoder的反序列化漏洞,Java 調用XMLDecoder解析XML文件的時候,存在命令執行漏洞。
當前市面上挖礦主力軍。
案例:
xmldecoder.xml:

利用Java的XMLDecoder解析這個xml文件:

這段代碼執行后,直接刪除了本地的e:\1.txt文件,相當于在命令行調用了cmd /c del e:\1.txt命令。Jdk中的XmlDecoder反序列化能調用本地的應用,也能執行系統支持的命令。
漏洞分析:
漏洞出現在wls-wsat.war中,此組件使用了weblogic自帶的webservices處理程序來處理SOAP請求,在weblogic.wsee.jaxws.workcontext.WorkContextServerTube
類中獲取XML數據傳遞給XMLDecoder來解析。

實例化了WorkContextXmlInputAdapter類,并且將獲取到的XML格式的序列化數據傳遞到此類的構造方法中,最后通過XMLDecoder來進行反序列化操作。

漏洞復現:
抓包:

工具:
java -jar WebLogic_Wls-Wsat_RCE_Exp.jar http://192.168.43.100:7001 test.jsp

http://192.168.43.100:7001/bea_wls_internal/test.jsp?password=secfree&command=cat%20/etc/passwd

修復:
1、建議不要用JDK中的XmlDeocder類,尋求其它更安全的xml解析工具類,考慮是否刪除WLS-WebServices組件
2、官方修復:補丁限定了object,new,method,void,array等字段,限定了不能生成java 實例
參考:
https://github.com/Tom4t0/Tom4t0.github.io/blob/29314ca531f23e9e245bad9516c5d4e4c63756f2/_posts/2017-12-22-WebLogic%20WLS-WebServices%E7%BB%84%E4%BB%B6%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90.md
3.5 CVE-2018-2628
影響版本:
Oracle WebLogic Server10.3.6.0
Oracle WebLogic Server12.2.1.2
Oracle WebLogic Server12.2.1.3
Oracle WebLogic Server12.1.3.0

漏洞分析:
1.反射機制
JAVA反射機制是在運行狀態中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。
2.RMI
RMI是Remote Method Invocation的簡稱,是J2SE的一部分,能夠讓程序員開發出基于Java的分布式應用。一個RMI對象是一個遠程Java對象,可以從另一個Java虛擬機上(甚至跨過網絡)調用它的方法,可以像調用本地Java對象的方法一樣調用遠程對象的方法,使分布在不同的JVM中的對象的外表和行為都像本地對象一樣。
RMI傳輸過程都使用序列化和反序列化,如果RMI服務端端口對外開發,并且服務端使用了像Apache Commons Collections這類庫,那么會導致遠程命令執行。
RMI依賴于Java遠程消息交換協議JRMP(Java Remote Messaging Protocol),該協議為java定制,要求服務端與客戶端都為java編寫。
3.繞過黑名單
Weblogic 中InboundMsgAbbrev 的resolveProxyClass處理rmi接口類型,因為只判斷了java.rmi.registry.Registry ,找一個其他的rmi接口繞過,比如java.rmi.activation.Activator為 RMI 對象激活提供支持。
漏洞掃描:

復現過程:
首先服務端監聽ysoserial,上面的反射代碼被集成到了ysoserial工具中的CommonsCollections 的payload中,最終依然是sun.reflect.annotation.AnnotationInvocationHandler。
攻擊端生成payload,接口用java.rmi.registry.Registry
4、漏洞挖掘
基本手段:
從可控數據的反序列化或間接的反序列化接口入手,在此基礎上嘗試構造序列化對象。
先拿到一個Java應用,需要找到一個接受外部輸入的序列化對象的接收點,即反序列化漏洞的觸發點。我們可以通過審計源碼中對反序列化函數的調用(例如readObject())來尋找,也可以直接通過對應用交互流量進行抓包,查看流量中是否包含java序列化數據來判斷,java序列化數據的特征為以標記(ac ed 00 05)開頭。
確定了反序列化輸入點后,再考察應用的Class Path中是否包含Apache Commons Collections庫(ysoserial所支持的其他庫亦可),如果是,就可以使用ysoserial來生成反序列化的payload,指定庫名和想要執行的命令即可:
通過先前找到的傳入對象方式進行對象注入,數據中載入payload,觸發受影響應用中ObjectInputStream的反序列化操作,隨后通過反射調用Runtime.getRunTime.exec即可完成利用。
5、防御手段
5.1 weblogic防御
? 過濾T3協議,限定可連接的IP
? 設置Nginx反向代理,實現t3協議和http協議隔離
? JEP290(JDK8u121,7u131,6u141),這個機制主要是在每層反序列化過程中都加了一層黑名單處理
5.2 原生反序列化防御
? 不要反序列化不可信的數據
? 給反序列數據加密簽名,并確保解密在反序列之前
? 給反序列化接口添加認證授權
? 反序列化服務只允許監聽在本地或者開啟相應防火墻
? 升級第三方庫
? 升級JDK,JEP290
參考:
https://blog.chaitin.cn/2015-11-11_java_unserialize_rce/#h4.2_weblogic
http://xxlegend.com/2018/04/18/CVE-2018-2628%20%E7%AE%80%E5%8D%95%E5%A4%8D%E7%8E%B0%E5%92%8C%E5%88%86%E6%9E%90/
http://pirogue.org/2017/12/29/weblogic-XMLDecoder/
https://paper.seebug.org/333/(3248)