修復weblogic的JAVA反序列化漏洞的多種方法

wyzsk發表於2020-08-19
作者: z_zz_zzz · 2016/03/08 10:25

0x00 前言


目前oracle還沒有在公開途徑釋出weblogic的JAVA反序列化漏洞的官方補丁,目前看到的修復方法無非兩條:

  1. 使用SerialKiller替換進行序列化操作的ObjectInputStream類;
  2. 在不影響業務的情況下,臨時刪除掉專案裡的 "org/apache/commons/collections/functors/InvokerTransformer.class"檔案。

ObjectInputStream類為JRE的原生類,InvokerTransformer.class為weblogic基礎包中的類,對上述兩個類進行修改或刪除,實在無法保證對業務沒有影響。如果使用上述的修復方式,需要大量的測試工作。且僅僅刪除InvokerTransformer.class檔案,無法保證以後不會發現其他的類存在反序列化漏洞。

因此本文針對weblogic的JAVA序列化漏洞進行了分析,對多個版本的weblogic進行了測試,並提出了更加切實可行的修復方法。

0x01 為什麼選擇weblogic的JAVA反序列化漏洞進行分析


  1. weblogic與websphere為金融行業使用較多的企業級JAVA中介軟體;
  2. weblogic比websphere市場佔有率高;
  3. 利用websphere的JAVA反序列化漏洞時需要訪問8880埠,該埠為websphere的wsadmin服務埠,該埠不應該暴露在公網。如果有websphere伺服器的8880埠在公網可訪問,說明該伺服器的安全價值相對較低;
  4. 利用weblogic的JAVA反序列化漏洞能夠直接控制伺服器,危害較大,且weblogic通常只有一個服務埠,無法透過禁用公網訪問特定埠的方式修復漏洞。

0x02 已知條件


breenmachine的“What Do WebLogic, WebSphere, JBoss, Jenkins, OpenNMS, and Your Application Have in Common? This Vulnerability.”文章中對weblogic的JAVA序列化漏洞進行了分析,讀完這篇文章關於weblogic相關的描述部分後,我們知道了以下情況。

  1. 可透過搜尋程式碼查詢weblogic的jar包中是否包含特定的JAVA類;
  2. 在呼叫weblogic的停止指令碼時,會向weblogic傳送JAVA序列化資料;
  3. 可透過ObjectInputStream.readObject方法解析JAVA序列化資料;
  4. weblogic傳送的T3資料的前幾個位元組為資料長度;
  5. 替換weblogic傳送的T3資料中的某個序列化資料為惡意序列化資料,可以使weblogic執行指定的程式碼。

0x03 漏洞分析


weblogic傳送的JAVA序列化資料抓包分析

根據breenmachine的文章我們知道了,在呼叫weblogic的停止指令碼時,會向weblogic傳送JAVA序列化資料,我們來重複這個過程。

資料包分析工具還是Windows環境的Wireshark比較好用,但Windows環境預設無法在訪問本機監聽的埠時進行抓包。上述問題是可以解決的,也可在Windows機器呼叫其他機器的weblogic停止指令碼並使用Wireshark進行抓包;或者在Linux環境使用tcpdump進行抓包,使用Wireshark分析生成的資料包。

Windows環境如何在訪問本機監聽的埠時進行抓包

該問題可透過以下方法解決:

  1. 增加路由策略,route add 【本機IP,不能使用127.0.0.1】 mask 255.255.255.255 【預設閘道器IP】 metric 1,之後可以使用Wireshark抓包分析。XP測試成功,win7失敗。
  2. 使用RawCap工具,可對127.0.0.1進行抓包,產生的抓包檔案可以使用Wireshark分析。win7測試成功,XP失敗。下載地址為http://www.netresec.com/?page=RawCap

如何在Windows機器呼叫其他機器的weblogic停止指令碼

編輯domain的bin目錄中的stopWebLogic.cmd檔案,找到“ADMIN_URL=t3://[IP]:[埠]”部分,[IP]一般為本機的主機名,[埠]一般為7001。將[IP]與[埠]分別修改為其他weblogic所在機器的IP與weblogic監聽埠。執行修改後的stopWebLogic.cmd指令碼並抓包。

使用Wireshark對資料包進行分析

在完成了針對weblogic停止指令碼呼叫過程的抓包後,使用Wireshark對資料包進行分析。可使用IP或埠等條件進行過濾,只顯示與呼叫weblogic停止指令碼相關的資料包。

已知JAVA序列化資料的前4個位元組為“AC ED 00 05”,使用“tcp contains ac:ed:00:05”條件過濾出包含JAVA序列化資料的資料包,並在第一條資料包點選右鍵選擇“Follow TCP Stream”,如下圖。

pic

使用十六進位制形式檢視資料包,查詢“ac ed 00 05”,可以找到對應的資料,可以確認抓包資料中包含JAVA序列化資料。

pic

取消對"ac ed 00 05"的過濾條件,使用ASCII形式檢視第一個資料包,內容如下。

pic

可以看到當weblogic客戶端向weblogic伺服器傳送序列化資料時,傳送的第一個包為T3協議頭,本文測試時傳送的T3協議頭為“t3 9.2.0\nAS:255\nHL:19\n\n”,第一行為“t3”加weblogic客戶端的版本號。weblogic伺服器的返回資料為“HELO:10.0.2.0.false\nAS:2048\nHL:19\n\n”,第一行為“HELO:”加weblogic伺服器的版本號。weblogic客戶端與伺服器傳送的資料均以“\n\n”結尾。

將Wireshark顯示的資料包轉換為JAVA程式碼

從上文的截圖可以看到資料包中JAVA序列化資料非常長,且包含不可列印字元,無法直接匯出到JAVA程式碼中。

在Wireshark中,客戶端向伺服器傳送的資料顯示為紅色,伺服器向客戶端返回的資料顯示為藍色。

使用C陣列形式檢視第一個資料包,peer0_x陣列為Packet 1,將peer0_x陣列複製為一個C語言形式的陣列,格式如“char peer0_0[] = { 0x01, 0x02 ...};”,將上述資料的“char”修改為“byte”,“0x”替換為“(byte)0x”,可以轉換為能直接在JAVA程式碼中使用的形式,格式如“byte peer0_0[] = {(byte)0x00, (byte)0x02 ...}”。

pic

對JAVA序列化資料進行解析

根據breenmachine的文章我們知道了,可以使用ObjectInputStream.readObject方法解析JAVA序列化資料。

使用ObjectInputStream.readObject方法解析weblogic呼叫停止指令碼時傳送的JAVA序列化資料的結構,程式碼如下。執行下面的程式碼時需要將weblogic.jar新增至JAVA執行的classpath中,否則會丟擲ClassNotFoundException異常。

pic

上述程式碼的執行結果如下。

#!bash
Data Length-Compute: 1711  
Data Length: 1711  
Object found: weblogic.rjvm.ClassTableEntry  
Object found: weblogic.rjvm.ClassTableEntry  
Object found: weblogic.rjvm.ClassTableEntry  
Object found: weblogic.rjvm.ClassTableEntry  
Object found: weblogic.rjvm.JVMID  
Object found: weblogic.rjvm.JVMID  
size: 0 start: 0 end: 234  
size: 1 start: 234 end: 348  
size: 2 start: 348 end: 591  
size: 3 start: 591 end: 986  
size: 4 start: 986 end: 1510  
size: 5 start: 1510 end: 1634  
size: 6 start: 1634 end: 1711  

可以看到weblogic傳送的JAVA序列化資料分為7個部分,第一部分的前四個位元組為整個資料包的長度(1711=0x6AF),第二至七部分均為JAVA序列化資料。

pic

weblogic傳送的JAVA序列化資料格式如下圖。

pic

利用weblogic的JAVA反序列化漏洞

在利用weblogic的JAVA反序列化漏洞時,需要向weblogic傳送兩個資料包。

第一個資料包為T3的協議頭。經測試,使用“t3 9.2.0\nAS:255\nHL:19\n\n”字串作為T3的協議頭髮送給weblogic9、weblogic10g、weblogic11g、weblogic12c均合法。向weblogic傳送了T3協議頭後,weblogic也會返回相應的資料,以“\n\n”結束,具體格式見前文。

第二個資料包為JAVA序列化資料,可採用兩種方式產生。

第一種生成方式為,將前文所述的weblogic傳送的JAVA序列化資料的第二到七部分的JAVA序列化資料的任意一個替換為惡意的序列化資料。

採用第一種方式生成JAVA序列化資料時,資料格式如下圖。

pic

第二種生成方式為,將前文所述的weblogic傳送的JAVA序列化資料的第一部分與惡意的序列化資料進行拼接。

採用第二種方式生成JAVA序列化資料時,資料格式如下圖。

pic

惡意序列化資料的生成過程可參考/papers/?id=13244

當向weblogic傳送上述第一種方式生成的JAVA序列化資料時,weblogic會丟擲如下異常。

#!bash
java.io.EOFException  
at weblogic.utils.io.DataIO.readUnsignedByte(DataIO.java:435)  
at weblogic.utils.io.DataIO.readLength(DataIO.java:828)  
at weblogic.utils.io.ChunkedDataInputStream.readLength(ChunkedDataInputStream.java:150)  
at weblogic.utils.io.ChunkedObjectInputStream.readLength(ChunkedObjectInputStream.java:196)  
at weblogic.rjvm.InboundMsgAbbrev.read(InboundMsgAbbrev.java:37)  
at weblogic.rjvm.MsgAbbrevJVMConnection.readMsgAbbrevs(MsgAbbrevJVMConnection.java:287)  
at weblogic.rjvm.MsgAbbrevInputStream.init(MsgAbbrevInputStream.java:212)  
at weblogic.rjvm.MsgAbbrevJVMConnection.dispatch(MsgAbbrevJVMConnection.java:507)  
at weblogic.rjvm.t3.MuxableSocketT3.dispatch(MuxableSocketT3.java:489)  
at weblogic.socket.BaseAbstractMuxableSocket.dispatch(BaseAbstractMuxableSocket.java:359)  
at weblogic.socket.SocketMuxer.readReadySocketOnce(SocketMuxer.java:970)  
at weblogic.socket.SocketMuxer.readReadySocket(SocketMuxer.java:907)  
at weblogic.socket.NIOSocketMuxer.process(NIOSocketMuxer.java:495)  
at weblogic.socket.NIOSocketMuxer.processSockets(NIOSocketMuxer.java:461)  
at weblogic.socket.SocketReaderRequest.run(SocketReaderRequest.java:30)  
at weblogic.socket.SocketReaderRequest.execute(SocketReaderRequest.java:43)  
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:147)  
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:119)

當向weblogic傳送上述第二種方式生成的JAVA序列化資料時,weblogic會丟擲如下異常。

#!bash
weblogic.rjvm.BubblingAbbrever$BadAbbreviationException: Bad abbreviation value: 'xxx'  
at weblogic.rjvm.BubblingAbbrever.getValue(BubblingAbbrever.java:153)  
at weblogic.rjvm.InboundMsgAbbrev.read(InboundMsgAbbrev.java:48)  
at weblogic.rjvm.MsgAbbrevJVMConnection.readMsgAbbrevs(MsgAbbrevJVMConnection.java:287)  
at weblogic.rjvm.MsgAbbrevInputStream.init(MsgAbbrevInputStream.java:212)  
at weblogic.rjvm.MsgAbbrevJVMConnection.dispatch(MsgAbbrevJVMConnection.java:507)  
at weblogic.rjvm.t3.MuxableSocketT3.dispatch(MuxableSocketT3.java:489)  
at weblogic.socket.BaseAbstractMuxableSocket.dispatch(BaseAbstractMuxableSocket.java:359)  
at weblogic.socket.SocketMuxer.readReadySocketOnce(SocketMuxer.java:970)  
at weblogic.socket.SocketMuxer.readReadySocket(SocketMuxer.java:907)  
at weblogic.socket.NIOSocketMuxer.process(NIOSocketMuxer.java:495)  
at weblogic.socket.NIOSocketMuxer.processSockets(NIOSocketMuxer.java:461)  
at weblogic.socket.SocketReaderRequest.run(SocketReaderRequest.java:30)  
at weblogic.socket.SocketReaderRequest.execute(SocketReaderRequest.java:43)  
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:147)  
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:119)

雖然在利用weblogic的JAVA反序列化漏洞時,weblogic會丟擲上述的異常,但是weblogic已經對惡意的序列化資料執行了readObject方法,漏洞仍然會觸發。

經測試,必須先傳送T3協議頭資料包,再傳送JAVA序列化資料包,才能使weblogic進行JAVA反序列化,進而觸發漏洞。如果只傳送JAVA序列化資料包,不先傳送T3協議頭資料包,無法觸發漏洞。

weblogic的JAVA反序列化漏洞觸發時的呼叫過程

將使用FileOutputStream對一個非法的檔案進行寫操作的程式碼構造為惡意序列化資料,併傳送給weblogic,當weblogic對該序列化資料執行反充列化時,會在漏洞觸發時丟擲異常,透過堆疊資訊可以檢視漏洞觸發時的呼叫過程,如下所示。

#!bash
org.apache.commons.collections.FunctorException: InvokerTransformer: The method 'newInstance' on 'class java.lang.reflect.Constructor' threw an exception  
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:356)  
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)  
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)  
at java.lang.reflect.Method.invoke(Method.java:606)  
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1017)  
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1893)  
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1798)  
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)  
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)  
at weblogic.rjvm.InboundMsgAbbrev.readObject(InboundMsgAbbrev.java:67)  
at weblogic.rjvm.InboundMsgAbbrev.read(InboundMsgAbbrev.java:39)  
at weblogic.rjvm.MsgAbbrevJVMConnection.readMsgAbbrevs(MsgAbbrevJVMConnection.java:287)  
at weblogic.rjvm.MsgAbbrevInputStream.init(MsgAbbrevInputStream.java:212)  
at weblogic.rjvm.MsgAbbrevJVMConnection.dispatch(MsgAbbrevJVMConnection.java:507)  
at weblogic.rjvm.t3.MuxableSocketT3.dispatch(MuxableSocketT3.java:489)  
at weblogic.socket.BaseAbstractMuxableSocket.dispatch(BaseAbstractMuxableSocket.java:359)  
at weblogic.socket.SocketMuxer.readReadySocketOnce(SocketMuxer.java:970)  
at weblogic.socket.SocketMuxer.readReadySocket(SocketMuxer.java:907)  
at weblogic.socket.NIOSocketMuxer.process(NIOSocketMuxer.java:495)  
at weblogic.socket.NIOSocketMuxer.processSockets(NIOSocketMuxer.java:461)  
at weblogic.socket.SocketReaderRequest.run(SocketReaderRequest.java:30)  
at weblogic.socket.SocketReaderRequest.execute(SocketReaderRequest.java:43)  
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:147)  
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:119)

確定weblogic是否使用了Apache Commons Collections元件

breenmachine在文章中寫到可以透過搜尋程式碼的方式查詢weblogic的jar包中是否包含特定的JAVA類。由於特定的JAVA類可能在很多個不同的jar包中均存在,因此該方法無法準確判斷weblogic是否使用了Apache Commons Collections元件特定的JAVA類。

可透過以下方法準確判斷weblogic是否使用了Apache Commons Collections元件特定的JAVA類。

在weblogic中任意安裝一個j2ee應用,在某個jsp中寫入以下程式碼。

#!js
<%
String path = [需要查詢的類的完整類名].class.getResource("").getPath();  
out.println(path);
%>

或以下程式碼。

#!js
<%
String path = [需要查詢的類的完整類名].class.getProtectionDomain().getCodeSource().getLocation().getFile();  
out.println(path);
%>

使用瀏覽器訪問上述jsp檔案,可以看到對應的類所在的jar包的完整路徑。

透過上述方法查詢“org.apache.commons.collections.map.TransformedMap”所在的jar包,示例如下。

pic

不同版本的weblogic對Apache Commons Collections元件的使用

“org.apache.commons.collections.map.TransformedMap”所在的weblogic的jar包資訊如下。

weblogic版本 TransformedMap類所在jar包路徑
9.2
10.2.1(weblogic 10g)、10.3.4(weblogic 11g) weblogic安裝目錄的modules/com.bea.core.apache.commons.collections_3.2.0.jar
12.1.3(weblogic 12c) weblogic安裝目錄的wlserver/modules/features/weblogic.server.merged.jar

由於weblogic 9.2未包含TransformedMap類,因此無法觸發反序列化漏洞,weblogic 10g、weblogic 11g、weblogic 12c均包含TransformedMap類,因此會觸發反序列化漏洞。

0x04 漏洞修復


漏洞修復思路

weblogic的預設服務埠為7001,該埠提供了對HTTP(S)、SNMP、T3等協議的服務。由於weblogic的不同協議均使用一個埠,因此無法透過防火牆限制埠訪問的方式防護JAVA反序列化漏洞。

在絕大多數應用的使用場景中,使用者只需要在公網能夠使用HTTP(S)協議訪問web應用伺服器即可。對於weblogic伺服器,在絕大多數情況下,只需要能夠在公網訪問weblogic提供的HTTP(S)協議的服務即可,並不需要訪問T3協議。

少數情況下,運維人員需要使用weblogic的T3協議:

  • 在weblogic伺服器本機執行weblogic的停止指令碼;
  • 透過WLST對weblogic進行指令碼化配置;
  • 編寫使用T3協議通訊的程式對weblogic進行狀態監控及其他管理功能。

T3協議與HTTP協議均基於TCP協議,T3協議以"t3"開頭,HTTP協議以“GET”、“POST”等開頭,兩者有明顯的區別。

因此可以限定只允許特定伺服器訪問weblogic伺服器的T3協議,能夠修復weblogic的JAVA反序列化漏洞。即使今後發現了weblogic的其他類存在JAVA反序列化漏洞,也能夠防護。

若將weblogic修復為傳送T3協議時要求傳送weblogic的使用者名稱與密碼,也能夠修復weblogic的反序列化問題,但會帶來密碼如何在weblogic客戶端儲存的問題。

無效的漏洞修復方法

首先嚐試將應用部署到非管理Server中,判斷其服務埠是否也提供T3協議的服務。

AdminServer是weblogic預設的管理Server,新增一個名為“Server-test”的非管理Server後,weblogic的伺服器資訊如下。管理Server與非管理Server使用不同的監聽埠,可將j2ee應用部署在非管理Server中,這樣可以使weblogic控制檯與應用使用不同的埠提供服務。

pic

經測試,新增的非管理Server的監聽埠也提供了T3協議的服務,也存在JAVA反序列化漏洞。因此這種修復方式對於JAVA反序列化漏洞無效,但可將weblogic控制檯埠與應用埠分離,可以使用防火牆禁止透過公網訪問weblogic的控制檯。

websphere的服務埠

我們來看另一款使用廣泛的企業級JAVA中介軟體:websphere的服務埠情況。從下圖可以看到,websphere的應用預設HTTP服務埠為9080,應用預設HTTPS服務埠為9443,控制檯預設HTTP服務埠為9060,控制檯預設HTTPS服務埠為9043,接收JAVA序列化資料的埠為8880。因此只要透過防火牆使公網無法訪問websphere伺服器的8880埠,就可以防止透過公網利用websphere的JAVA反序列化漏洞。

pic

網路裝置對資料包的影響

對安全有一定要求的公司,在部署需要向公網使用者提供服務的weblogic伺服器時,可能選擇下圖的部署架構(內網中不同網路區域間的防火牆已省略)。

pic

上述網路裝置對資料包的影響如下。

  1. IPS

    IPS可以更新防護規則,可能有廠家的IPS已經設定了對JAVA反序列化漏洞的防護規則,會阻斷惡意的JAVA序列化資料包。

  2. 防火牆

    這裡的防火牆指傳統防火牆,不是指下一代防火牆,僅關心IP與埠,不關心資料包內容,無法阻斷惡意的JAVA序列化資料包。

  3. WAF

    與IPS一樣,能否阻斷惡意的JAVA序列化資料包決定於防護規則。

  4. web代理

    僅對HTTP協議進行代理轉發,不會對T3協議進行代理轉發。

  5. 負載均衡

    可以指定需要進行負載均衡的協議型別,安全起見應選擇HTTP協議而不是TCP協議,只對HTTP協議進行轉發,不對T3協議進行轉發。

根據以上分析可以看出,web代理和負載均衡能夠穩定保證只轉發HTTP協議的資料,不會轉發T3協議的資料,因此能夠防護JAVA反序列化漏洞。

如果在公網訪問weblogic伺服器的路徑中原本就部署了web代理或負載均衡,就能夠防護從公網發起的JAVA反序列化漏洞攻擊。這也是為什麼較少發現大型公司的weblogic反序列化漏洞的原因,其網路架構決定了weblogic的JAVA反序列化漏洞無法在公網利用。

可行的漏洞修復方法

部署負載均衡裝置

在weblogic伺服器外層部署負載均衡裝置,可以修復JAVA反序列化漏洞。

優點 缺點
對系統影響小,不需測試對現有系統功能的影響 需要購買裝置;無法防護從內網發起的JAVA反序列化漏洞攻擊

部署單獨的web代理

在weblogic伺服器外層部署單獨的web代理,可以修復JAVA反序列化漏洞。

優點 缺點
同上 同上

在weblogic伺服器部署web代理

在weblogic控制檯中修改weblogic的監聽埠,如下圖。

pic

在weblogic所在伺服器安裝web代理應用,如apache、nginx等,使web代理監聽原有的weblogic監聽埠,並將HTTP請求轉發給本機的weblogic,可以修復JAVA反序列化漏洞。

優點 缺點
對系統影響小,不需測試對現有系統功能的影響;不需要購買裝置 無法防護從內網發起的JAVA反序列化漏洞攻擊;會增加伺服器的效能開銷

在weblogic伺服器部署web代理並修改weblogic伺服器的監聽IP

在weblogic控制檯中修改weblogic的監聽埠,並將監聽地址修改為“127.0.0.1”或“localhost”,如下圖。經過上述修改後,只有weblogic伺服器本機才能訪問weblogic服務。

pic

在weblogic所在伺服器安裝web代理應用,如apache、nginx等,使web代理監聽原有的weblogic監聽埠,並將HTTP請求轉發給本機的weblogic,可以修復JAVA反序列化漏洞。web代理的監聽IP需設定為“0.0.0.0”,否則其他伺服器無法訪問。

需要將weblogic停止指令碼中的ADMIN_URL引數中的IP修改為“127.0.0.1”或“localhost”,否則停止指令碼將不可用。

優點 缺點
對系統影響小,不需測試對現有系統功能的影響;不需要購買裝置;能夠防護從內網發起的JAVA反序列化漏洞攻擊 會增加伺服器的效能開銷

修改weblogic的程式碼

weblogic處理T3協議的類為“weblogic.rjvm.t3.MuxableSocketT3”,不同版本的weblogic的該類在不同的jar包中,查詢某個類所在的jar包的方法見前文“確定weblogic是否使用了Apache Commons Collections元件”部分。

使用eclipse或其他IDE建立java工程,建立weblogic.rjvm.t3包,並在其中建立MuxableSocketT3.java檔案。在定位到“weblogic.rjvm.t3.MuxableSocketT3”類所在的weblogic的jar包後,對其進行反編譯,將對應的jar包加入到建立的java工程的classpath中。將原始MuxableSocketT3類的反編譯程式碼複製到建立的java工程的MuxableSocketT3.java中,若其中引入了其他jar包中的類,需要將對應的jar包也加入到java工程的classpath中。

pic

weblogic處理T3協議時會呼叫MuxableSocketT3類的dispatch方法,weblogic 12.1.3的dispatch方法原始程式碼如下。

#!java
public final void dispatch(Chunk list) {
    if (!(this.bootstrapped)) {
        try {
            readBootstrapMessage(list);
            this.bootstrapped = true;
        } catch (IOException ioe) {
            SocketMuxer.getMuxer().deliverHasException(getSocketFilter(),
                    ioe);
        }
    } else
        this.connection.dispatch(list);
}

在該方法中增加限制客戶端IP的處理,若傳送T3協議資料的客戶端IP不是允許的IP,則拒絕連線。增加限制後的dispatch方法程式碼如下。

#!java
public final void dispatch(Chunk list) {
    if (!(this.bootstrapped)) {
        try {

            //add
            String ip = getSocket().getInetAddress().getHostAddress();
            System.out.println("MuxableSocketT3-dispatch-ip: " + ip);
            if(!ip.equals("127.0.0.1") && !ip.equals("0:0:0:0:0:0:0:1"))
                rejectConnection(1, "Illegal IP");
            //add-end

            readBootstrapMessage(list);
            this.bootstrapped = true;
        } catch (IOException ioe) {
            SocketMuxer.getMuxer().deliverHasException(getSocketFilter(),
                    ioe);
        }
    } else
        this.connection.dispatch(list);
}

停止weblogic,將編譯生成的MuxableSocketT3*.class檔案替換至MuxableSocketT3所在的jar包中,啟動weblogic,再次向weblogic傳送T3協議資料包,可以看到如下輸出。

pic

上圖說明上文增加的程式碼已正確執行,對weblogic的正常功能沒有影響,且能夠限制傳送T3資料的客戶端IP,能夠修復反序列化漏洞。

當weblogic處理HTTP協議時,不會呼叫MuxableSocketT3類,因此上述修改不會影響正常的業務功能。

可透過環境變數或配置檔案指定允許傳送T3協議的客戶端IP,在修改後的dispatch方法中讀取,本文的示例僅允許本機傳送T3協議。需要將weblogic停止指令碼中的ADMIN_URL引數中的IP修改為“127.0.0.1”或“localhost”,否則停止指令碼將不可用。

優點 缺點
對系統影響小,不需測試對現有系統功能的影響;不需要購買裝置;能夠防護從內網發起的JAVA反序列化漏洞攻擊;不會增加伺服器的效能開銷 存在商業風險,可能給oracle的維保帶來影響

上述修復方法的最大問題在於可能給oracle維保帶來影響,不過相信沒有與oracle簽訂維保合同的公司也是很多的,如果不擔心相關的問題,倒是可以使用這種修復方法。如果能夠要求oracle提供官方補丁,當然是最好不過了。

本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!

相關文章