1. 前言
2016年發在烏雲知識庫,重新發出來紀念一下。
以下分析如何利用JAVA反序列化漏洞控制開放HTTPS服務的weblogic服務器,以及相應的防護方法。
# 2. HTTPS服務的架構分析
如果某服務器需要對公網用戶提供HTTPS服務,可以在不同的層次實現。
2.1. 使用SSL網關提供HTTPS服務
當使用SSL網關提供HTTPS服務時,網絡架構如下圖所示(無關的設備已省略,下同)。
SSL網關只會向後轉發HTTP協議的數據,不會將T3協議數據轉發至weblogic服務器,因此在該場景中,無法通過公網利用weblogic的JAVA反序列化漏洞。
2.2. 使用負載均衡提供HTTPS服務
當使用負載均衡提供HTTPS服務時,網絡架構如下圖所示。
安全起見,負載均衡應選擇轉發HTTP協議而不是TCP協議,因此在該場景中,也無法通過公網利用weblogic的JAVA反序列化漏洞。
2.3. 使用web代理提供HTTPS服務
當使用web代理(如apache、nginx等)提供HTTPS服務時,網絡架構如下圖所示。
web代理只會向後轉發HTTP協議的數據,因此在該場景中,也無法通過公網利用weblogic的JAVA反序列化漏洞。
2.4. 使用weblogic提供HTTPS服務
當使用weblogic提供HTTPS服務時,網絡架構如下圖所示。
weblogic能夠接收到利用SSL加密後的T3協議數據,因此在該場景中,通過公網能夠利用weblogic的JAVA反序列化漏洞。
根據上述分析,僅當HTTPS服務由weblogic提供時,才能夠利用其JAVA反序列化漏洞。
# 3. weblogic開放SSL服務時的T3協議格式分析
利用weblogic的JAVA反序列化漏洞時,必須向weblogic發送T3協議頭。爲了能夠利用提供SSL服務的weblogic的JAVA反序列化漏洞,需要首先分析當weblogic提供SSL服務時的T3協議格式。
SSL數據包爲加密的形式,無法直接進行分析,需要進行解密。當已知SSL私鑰時,可以利用Wireshark對SSL通信數據進行解密。
weblogic可以使用演示SSL證書提供SSL服務,也可以使用指定SSL證書提供SSL服務。
可以使用兩種方法進行分析,一是使用weblogic提供的演示SSL證書進行分析,二是使用自己生成的SSL證書進行分析。
3.1. 使用weblogic演示證書進行分析(方法一)
3.1.1. 使用weblogic演示證書開放SSL服務
登錄weblogic控制檯,將AdminServer的“啓用SSL監聽端口”鉤選,並填入SSL監聽端口號。
查看AdminServer的密鑰庫配置,確認爲“演示標識和演示信任”(Demo Identity and Demo Trust),可以看到演示密鑰庫的文件名爲“DemoIdentity.jks”,演示信任密鑰庫文件名爲“DemoTrust.jks”。
查看AdminServer的SSL配置,可以看到演示密鑰庫的私鑰別名爲“DemoIdentity”。
使用HTTPS方式登錄weblogic控制檯,確認可以正常登錄。
3.1.2. 生成weblogic演示證書的私鑰文件
以下爲weblogic演示密鑰庫的密碼信息。
Property | Value |
Trust store location | DemoTrust.jks文件,可在控制檯查看 |
Trust store password | DemoTrustKeyStorePassPhrase |
Key store location | DemoIdentity.jks文件,可在控制檯查看 |
Key store password | DemoIdentityKeyStorePassPhrase |
Private key password | DemoIdentityPassPhrase |
Private Key Alias | DemoIdentity,可在控制檯查看 |
使用以下命令生成weblogic演示密鑰庫的私鑰文件。
set keystore=DemoIdentity.jks
set tmp_p12=tmp.p12
set storepass=DemoIdentityKeyStorePassPhrase
set keypass=DemoIdentityPassPhrase
set alias=DemoIdentity
set pwd_new=123456
keytool -importkeystore -srckeystore %keystore% -destkeystore %tmp_p12% -srcstoretype JKS -deststoretype PKCS12 -srcstorepass %storepass% -deststorepass %pwd_new% -srcalias %alias% -destalias %alias% -srckeypass %keypass% -destkeypass %pwd_new%
set out_pem=tmp.rsa.pem
set final_pem=final.key
openssl pkcs12 -in %tmp_p12% -nodes -out %out_pem% -passin pass:%pwd_new%
openssl rsa -in %out_pem% -check > %final_pem%
最終生成的final.key即爲weblogic演示密鑰庫的私鑰文件。final.key的密鑰格式爲
-----BEGIN RSA PRIVATE KEY-----
…
-----END RSA PRIVATE KEY-----
3.1.3. 修改weblogic停止腳本
需要修改weblogic的停止腳本“stopWebLogic.xx”,將ADMIN_URL字段的“t3”改爲“t3s”,並在java調用weblogic.WLST類的JVM啓動參數中加入“-Dweblogic.security.TrustKeyStore=DemoTrust”,使weblogic在調用停止腳本時使用演示證書,否則會出現證書不被信任的錯誤。
3.2. 使用自定義證書進行分析(方法二)
3.2.1. 生成自定義密鑰庫
使用以下命令生成自定義密鑰庫。
set keystore=keystore.jks
set alias=server
set pwd=123456
set url=url-test
set validity=7300
keytool -genkey -alias %alias% -keyalg RSA -keysize 2048 -keystore %keystore% -storetype jks -storepass %pwd% -keypass %pwd% -dname "CN=%url%, OU=companyName, O=companyName, L=cityName, ST=provinceName, C=CN" -validity %validity%
生成的密鑰庫名稱爲keystore.jks,密鑰庫密碼與私鑰密碼均爲“123456”。
3.2.2. 使weblogic使用指定的密鑰庫
將上述步驟生成的密鑰庫文件keystore.jks複製到weblogic的domain目錄中。
登錄weblogic控制檯,在AdminServer的密鑰庫界面,選擇密鑰庫類型爲“定製標識和 Java 標準信任”(Custom Identity and Java Standard Trust),定製標識密鑰庫輸入“keystore.jks”,定製標識密鑰庫類型輸入“JKS”,定製標識密鑰庫密碼短語與確認定製標識密鑰庫密碼短語輸入“123456”,保存上述修改。
在AdminServer的SSL界面,私有密鑰別名輸入“server”,私有密鑰密碼短語與確認私有密鑰密碼短語輸入“123456”。
使用HTTPS對應的URL打開weblogic控制檯,確保可以正常登錄,查看證書信息如下。
3.2.3. 將自定義證書導入java信任密鑰庫中
在上一步驟中可以看到Java標準信任密鑰庫對應的文件爲weblogic的JDK目錄中的“jdk\jre\lib\security\cacerts”文件,密鑰類型也是JKS。
當weblogic作爲SSL客戶端連接服務器時,會檢查服務器的證書鏈是否與weblogic的JDK目錄中的cacerts文件匹配。
需要將自定義證書的公鑰導入weblogic的JDK目錄中的cacerts文件中,否則在調用weblogic停止腳本時,會由於證書不受信任而失敗。
使用以下命令導出自定義證書的公鑰。
set keystore=keystore.jks
set alias=server
set pwd=123456
set exportcert=export.cer
keytool -export -alias %alias% -keystore %keystore% -file %exportcert% -storepass %pwd%
導出的公鑰文件爲export.cert。
使用以下命令將公鑰導入weblogic的JDK目錄的cacerts文件中,在導入前需要備份cacerts。cacerts密鑰庫的默認密碼爲changeit,可進行修改。
set keystore=cacerts
set alias=server
set pwd=changeit
set cert=export.cer
keytool -import -alias %alias% -keystore %keystore% -trustcacerts -storepass %pwd% -file %cert%
3.2.4. 生成自定義證書的私鑰文件
使用以下命令生成自定義證書的私鑰文件。
set keystore=keystore.jks
set tmp_p12=tmp.p12
set storepass=123456
set keypass=123456
set alias=server
set pwd_new=123456
keytool -importkeystore -srckeystore %keystore% -destkeystore %tmp_p12% -srcstoretype JKS -deststoretype PKCS12 -srcstorepass %storepass% -deststorepass %pwd_new% -srcalias %alias% -destalias %alias% -srckeypass %keypass% -destkeypass %pwd_new%
set out_pem=tmp.rsa.pem
set final_pem=final.key
openssl pkcs12 -in %tmp_p12% -nodes -out %out_pem% -passin pass:%pwd_new%
openssl rsa -in %out_pem% -check > %final_pem%
最終生成的final.key即爲自定義證書的私鑰文件。
3.2.5. 修改weblogic停止腳本
需要修改weblogic的停止腳本“stopWebLogic.xx”,將ADMIN_URL字段的“t3”改爲“t3s”,並在java調用weblogic.WLST類的JVM啓動參數中加入“-Dweblogic.security.TrustKeyStore=DemoTrust”。
除了以上修改外,還需在停止腳本的JVM啓動參數中加入“-Dweblogic.security.SSL.ignoreHostnameVerification=true”,避免因自定義證書中的地址與停止腳本實際訪問的ssl服務的地址不一致而出現錯誤。
3.3. 調用weblogic停止腳本並抓包
前文中已將weblogic的停止腳本“stopWebLogic.xx”中的訪問鏈接改爲t3s協議,會使用SSL協議進行通信。
需要調用weblogic的停止腳本並進行抓包。由於停止腳本會與同一臺機器的weblogic通信,在Linux環境中抓包較爲方便,需要使用tcpdump對Loopback對應的網卡進行抓包。
3.4. 使用Wireshark解密SSL通信數據
前文已生成了weblogic的私鑰文件,並對weblogic停止腳本調用過程進行了抓包,可以使用Wireshark解密對應的SSL通信數據。
首先在Wireshark中設置需要使用的私鑰文件,打開Wireshark菜單的“Edit->Preferences”,打開“Protocols->SSL”,點擊“RSA keys list”旁的“Edit”按鈕,如下圖。
添加一行配置,IP爲weblogic服務器的IP,Port爲weblogic的SSL監聽端口,Protocol爲tcp,Key File爲之前已生成的weblogic的SSL證書的私鑰文件。
使用Wireshark打開抓包文件,可以看到原本爲加密形式的通信數據有部分已被解密,找到T3協議頭相關數據,可以看到停止腳本向weblogic發送的T3協議頭以“t3s”開頭。
服務器返回的數據如下。
費了老大的勁,才發現原來weblogic開放HTTPS服務後,t3協議頭的前幾個字節由“t3”變成了“t3s”。
以上步驟在Linux環境的weblogic 10.3.4測試成功。
3.5. JAVA反序列化漏洞調用過程
當weblogic開放HTTPS服務時,JAVA反序列化漏洞的調用過程如下。
at org.apache.commons.collections.functors.InvokerTransformer.transform(InvokerTransformer.java:132)
at org.apache.commons.collections.functors.ChainedTransformer.transform(ChainedTransformer.java:122)
at org.apache.commons.collections.map.TransformedMap.checkSetValue(TransformedMap.java:203)
at org.apache.commons.collections.map.AbstractInputCheckedMapDecorator$MapEntry.setValue(AbstractInputCheckedMapDecorator.java:191)
at sun.reflect.annotation.AnnotationInvocationHandler.readObject(AnnotationInvocationHandler.java:334)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:974)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1849)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at weblogic.rjvm.InboundMsgAbbrev.readObject(InboundMsgAbbrev.java:65)
at weblogic.rjvm.InboundMsgAbbrev.read(InboundMsgAbbrev.java:37)
at weblogic.rjvm.MsgAbbrevJVMConnection.readMsgAbbrevs(MsgAbbrevJVMConnection.java:283)
at weblogic.rjvm.MsgAbbrevInputStream.init(MsgAbbrevInputStream.java:210)
at weblogic.rjvm.MsgAbbrevJVMConnection.dispatch(MsgAbbrevJVMConnection.java:498)
at weblogic.rjvm.t3.MuxableSocketT3.dispatch(MuxableSocketT3.java:330)
at weblogic.socket.BaseAbstractMuxableSocket.dispatch(BaseAbstractMuxableSocket.java:298)
at weblogic.socket.SSLFilterImpl.dispatch(SSLFilterImpl.java:258)
at weblogic.socket.SocketMuxer.readReadySocketOnce(SocketMuxer.java:950)
at weblogic.socket.SocketMuxer.readReadySocket(SocketMuxer.java:898)
at weblogic.socket.PosixSocketMuxer.processSockets(PosixSocketMuxer.java:130)
at weblogic.socket.SocketReaderRequest.run(SocketReaderRequest.java:29)
at weblogic.socket.SocketReaderRequest.execute(SocketReaderRequest.java:42)
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:145)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:117)
# 4. 如何控制開放HTTPS服務的weblogic服務器
4.1. 如何發送T3協議數據
利用weblogic的JAVA反序列化漏洞時,必須向weblogic發送T3協議頭。當weblogic開放HTTPS服務時,向其發送的T3協議頭應以“t3s”開頭。向weblogic發送數據時應使用SSL協議,且不應對服務器的證書進行驗證。
無論weblogic開放HTTP服務還是HTTPS服務,在向weblogic發送利用JAVA反序列化漏洞的序列化數據時,數據內容不需要改變。
4.2. 如何調用weblogic的RMI服務
可以利用weblogic的JAVA反序列化數據使weblogic在服務器生成指定的jar文件並加載,在jar文件中開啓weblogic的RMI服務,可以從公網直接調用,能夠控制服務器。
當weblogic開放HTTPS服務時,調用weblogic的RMI服務時有幾點需要進行修改。
在調用weblogic的RMI服務時,使用的URL應改爲以“t3s”開頭;
在調用weblogic的RMI服務時,客戶端需要引入weblogic.jar。使用t3s協議時,weblobic.jar會嘗試從當前目錄讀取weblogic授權文件license.bea,需要保證weblogic.jar能正確地讀取該文件;
weblogic.jar中會對服務器證書進行驗證,判斷其是否爲可信證書。由於可能遇到服務器的證書未經過CA認證,因此需要修改證書驗證的相關代碼,忽略證書未經認證的問題;
JVM啓動參數需要增加“-Dweblogic.security.SSL.ignoreHostnameVerification=true”,避免因自定義證書中的地址與停止腳本實際訪問的ssl服務的地址不一致而出現錯誤。
# 5. 可行的漏洞修復方法
5.1. 將SSL服務轉移至其他設備
將SSL服務轉移至weblogic服務器外層的設備實現,如SSL網關、負載均衡、單獨部署的web代理等,將HTTP請求轉發至weblogic,可以修復JAVA反序列化漏洞。
優點 | 缺點 |
對系統影響小,不需測試對現有系統功能的影響 | 需要對SSL證書進行格式轉換;需要購買設備;無法防護從內網發起的JAVA反序列化漏洞攻擊 |
5.2. 將SSL服務轉移至weblogic服務器的web代理
在weblogic所在服務器安裝web代理應用,如apache、nginx等,將SSL服務轉移至web代理應用,使web代理監聽原有的weblogic監聽端口,並將HTTP請求轉發給本機的weblogic,可以修復JAVA反序列化漏洞。
優點 | 缺點 |
對系統影響小,不需測試對現有系統功能的影響;不需要購買設備 | 需要對SSL證書進行格式轉換;無法防護從內網發起的JAVA反序列化漏洞攻擊;會增加服務器的性能開銷 |
5.3. 將SSL服務轉移至weblogic服務器的web代理並修改weblogic的監聽IP
將weblogic的監聽地址修改爲“127.0.0.1”或“localhost”,只允許本機訪問weblogic服務。
在weblogic所在服務器安裝web代理應用,如apache、nginx等,將SSL服務轉移至web代理應用,使web代理監聽原有的weblogic監聽端口,並將HTTP請求轉發給本機的weblogic,可以修復JAVA反序列化漏洞。web代理的監聽IP需設置爲“0.0.0.0”,否則其他服務器無法訪問。
需要將weblogic停止腳本中的ADMIN_URL參數中的IP修改爲“127.0.0.1”或“localhost”,否則停止腳本將不可用。
優點 | 缺點 |
對系統影響小,不需測試對現有系統功能的影響;不需要購買設備;能夠防護從內網發起的JAVA反序列化漏洞攻擊 | 需要對SSL證書進行格式轉換;會增加服務器的性能開銷 |
5.4. 修改weblogic的代碼
weblogic處理T3S協議的類爲“weblogic.rjvm.t3.MuxableSocketT3S”,繼承自“weblogic.rjvm.t3.MuxableSocketT3”類,且MuxableSocketT3S類中沒有對dispatch方法進行重寫,因此可以採用與"修復weblogic的JAVA反序列化漏洞的多種方法")中“修改weblogic的代碼”部分相同的修復方法。具體步驟略。
優點 | 缺點 |
不需要對SSL證書進行格式轉換;對系統影響小,不需測試對現有系統功能的影響;不需要購買設備;能夠防護從內網發起的JAVA反序列化漏洞攻擊;不會增加服務器的性能開銷 | 存在商業風險,可能給oracle的維保帶來影響 |
6. 結束
3.MuxableSocketT3S”,繼承自“weblogic.rjvm.t3.MuxableSocketT3”類,且MuxableSocketT3S類中沒有對dispatch方法進行重寫,因此可以採用與"修復weblogic的JAVA反序列化漏洞的多種方法")中“修改weblogic的代碼”部分相同的修復方法。具體步驟略。
優點 | 缺點 |
不需要對SSL證書進行格式轉換;對系統影響小,不需測試對現有系統功能的影響;不需要購買設備;能夠防護從內網發起的JAVA反序列化漏洞攻擊;不會增加服務器的性能開銷 | 存在商業風險,可能給oracle的維保帶來影響 |
6. 結束
無論weblogic服務器開放HTTP服務還是HTTPS服務,都是有可能利用JAVA反序列化漏洞控制服務器的。JAVA反序列化漏洞的影響,應該會持續很長的時間。