作者:r4v3zn@白帽匯安全研究院
本文為作者投稿,Seebug Paper 期待你的分享,凡經采用即有禮品相送!
投稿郵箱:paper@seebug.org
一、背景
通常在滲透的過程中會遇到很多 Weblogic 服務器,但通過 IIOP 協議進行發送序列化惡意代碼包時,會面臨著無法建立通訊請求發送惡意序列化失敗。最近參與了一場在成都舉辦的《FreeTalk 2020 成都站》,有幸分享了關于 Weblogic IIOP 協議 NAT 繞過的幾種方式。
PPT 下載地址:《Weblogic IIOP 協議NAT 網絡繞過》
二、成果演示
Goby 工具中關于 Weblogic 基本都是用了 IIOP 協議繞過的方案,比較有代表性的漏洞為 CVE-2020-2551 漏洞。在演示中,所有的環境均為自搭建,請勿發起網絡攻擊。

內部工具 weblogic-framework 使用了多項核心技術來進行優雅的測試 Weblogic,其中也使用了 IIOP 協議的繞過方案。

三、協議
在開始之前,非常有比較提及一下以下這些協議相關的內容:
-
RMI:遠程方法調用,本質上是 RPC 服務的 JAVA 實現,底層實現是 JRMP 協議,主要場景是分布式系統。
-
CORBA:跨語言(C ++、Java等)的通信體系結構,通常在 IIOP 協議中使用。
-
GIOP:主要提供標準的傳輸語法以及 ORB 通信的信息格式標準。
-
IIOP:CORBA 對象之間交流的協議,GIOP 的實現。
-
RMI-IIOP:解決 RMI 和 CORBA/IIOP 無法同時使用的技術方案。
-
Weblogic IIOP:Weblogic 自實現的 RMI-IIOP。
-
T3:WebLogic Server 中的 RMI 通信使用 T3 協議傳輸 WebLogic Server 和其他 Java 程序,包括客戶端及其他 WebLogic Server 實例之間 數據。
T3 協議本質上 RMI 中傳輸數據使用的協議,但通過上面我們看到 RMI-IIOP 是可以兼容 RMI 和 IIOP 的,所以在 Weblogic 中只要可以通過 T3 序列化惡意代碼的都可以通過 IIOP 協議進行序列化,正是因為這種情況,我進入 Weblogic 第三季度深度貢獻者名單。

四、流程
1、IIOP 序列化攻擊流程

一般 IIOP 序列化攻擊的大致流程主要為首先構建惡意序列化代碼,然后初始化上下文實例,最后通過 bind/rebind 進行發送惡意序列化代碼,下圖為關鍵代碼。

2、IIOP 初始化上下文流程
初始化上下文通過攻擊流程中的 new InitialContext(env) 進行構建,最終的入口點通過 getInitialContext 方法進行構建,最終是進行流入到 InitialContextFactoryImpl.getInitialContext 進行初始化上下文。

在流入 InitialContextFactoryImpl.getInitialContext 之后會通過 obj = ORBHelper.getORBHelper().getORBReference 來進行獲取 NameService,然后將獲取到的 NameService 進行實例化創建上下文實例,提供后續的執行操作。

3、rebind 流程
執行 rebind 流程中,首先會通過 this.getContext 方法進行獲取前面所講的上下對象,然后通過 rebind_any 進行發發送序列化代碼,當前在此之前已經通過經過序列化的了。

在 rebind_any 中,首先會通過 this._request 進行發送 rebind_any 建立 Socket 通訊,最后通過 this._invoke 方法進行執行最終的操作發送序列化代碼。

4、大致流程
所以最終大致的執行流程是如下圖,獲取 NameService,基于獲取的信息進行創建上下文實例(獲取實際連接信息),然后進行發起 request 請求,最后進行執行 rebind_any 操作。

五、環境準備
- Weblogic:12.1.3.0
- 協議:IIOP
- 漏洞編號:CVE-2020-2555
- 內網(Windows):http://10.10.10.173:7001
- NAT 網絡( vulfocus ) : http://118.193.36.37:32769/ 內部 IP: 172.17.0.5(ZoomEye搜索結果)
NAT 網絡構建通過 http://vulfocus.fofa.so/ 進行搭建構造。

六、成因
在后續的調試以及研究中我們所使用的版本為 12.1.3.0 版本,漏洞為 CVE-2020-2555 漏洞,以下為漏洞 POC,以及漏洞執行鏈,在這里不多講該漏洞,有興趣的可以移步漫談 Weblogic CVE-2020-2555。

執行鏈:
ObjectInputStream.readObject()
BadAttributeValueExpException.readObject()
LimitFilter.toString()
ChainedExtractor.extract()
ReflectionExtractor.extract()
Method.invoke()
Class.getMethod()
ReflectionExtractor.extract()
Method.invoke()
Runtime.getRuntime()
ReflectionExtractor.extract()
Method.invoke()
Runtime.exec()
當我們可以與 Weblogic 所處同一網段并且可達的時,可以看到是成功執行系統命令彈出計算器。

通過 Wireshark 進行抓包可以,可以看到一共通訊了 2 次,第一次發送 LocateRequest 類型的 LocateRequest 的通訊操作獲取 NameService,第二次發送 Request 類型的 rebind_any 操作進行發送序列化代碼。

而進行測試公網中的靶機時拋出 Operation time out 異常,具體信息如下圖。

而在 Wireshark 中可以看到,與第一次獲取NameService中的內網 IP、端口進行了 Socket 通信。

而在執行的流程中停留在了 createEndPoint 方法中,所以通信問題大概率是在此方法中引發的。

在 createEndPoint 方法中,最后通過 MuxableSocketIIOP.createConnection 方法進行建立 Socket 通信,此時的通信變為了 Weblogic 運行的內網 IP 和端口。

所以大體的情況為如下圖,問題出現在發起 request 時調用的 createEndPoint 方法中,由于 createEndPoint 無法正常建立 Socket 通信導致后續的操作無法正常秩序。

其實,我們也可以在 Weblogic 啟動日志中也可以看到 Weblogic 關于端口和協議分配的情況,基本分配都是內網網卡的IP和端口同時會進行監聽 0.0.0.0:7001 來處理協議的請求操作,那么現在問題來了,公網中的 Weblogic 服務器 99% 分配的都是內網 IP 和端口。
七、IIOP NAT 繞過方案
由于問題發生在響應的 Weblogic 在獲取 NameService 時,響應的 IP和端口為內網中的端口,導致在后續 createEndPoint 建立 Socket 通信,所以我們可以進行在建立 Socket 通信之前修改為正確的 IP和端口(公網中的IP和端口)。

1、GIOP 協議極簡實現
當我們與服務器所處同一網段時,可以看到一共通訊了 2 次,第一次發送 LocateRequest 類型的 LocateRequest 的通訊操作獲取 NameService,第二次發送 Request 類型的 rebind_any 操作進行發送序列化代碼。

所以我們根據 Wireshark 中的信息,可以進行構建極簡的 GIOP 實現,大體如下:
a.請求 LocateRequest,獲取 NameService 以及獲取 key
b.請求 Request,執行 rebind_any 操作,發送序列化代碼
GIOP 協議
GIOP 協議大致由 Header 和 Message Type 進行構成,在 Header 包含了 Magic、Version、Message Type、Message Size。

Message Type 的類型如下:
| 消息類型 | 始發方 |
|---|---|
| Request | Client |
| Request | Server |
| CancelRequest | Client |
| LocateRequest | Client |
| LocateReply | Server |
| CloseConnection | Server |
| MessageError | Both |
| Fragment | Both |
實現

獲取 NameService 請求代碼實現:

執行 rebind_any 操作代碼實現:

最終效果:

2、Javassist 字節碼庫
Javassist (JAVA programming ASSISTant) 是在 Java 中編輯字節碼的類庫,它使 Java 程序能夠在運行時定義一個新類,并在 JVM 加載時修改類文件。
- Javassist.CtClass 是類文件的抽象表示形式
- Javassist.CtMethod 是類方法的抽象表示形式
讀取類
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get("test.Rectangle");
創建類
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.makeClass("Point");
繼承
cc.setSuperclass(pool.get("test.Point"));
寫入
cc.writeFile();
cc.toClass();
需要注意的是 toClass() 會把當前修改的 Class 加入到當前的 ClassLoader 中。
創建方法
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.makeClass("Point");
CtMethod ctMethod = new CtMethod(CtClass.voidType, "printName", new CtClass[]{}, cc);
修改方法
CtMethod ctMethod = ctClass.getDeclaredMethod("hello");
ctMethod.setBody("System.out.println(\"set body\");");
ctMethod.insertBefore("System.out.println(\"set before\");");
ctMethod.insertAfter("System.out.println(\"set after\");");
通過 Javassist 進行實現時,可以通過修改建立 Socket 通信之前的方法,將 ip、端口替換為正常的 IP 和端口,在這里選取的是 newSocket 方法,在第一個參數為 host,第二個參數為 port。

最終修改的如下圖:

實現
在實現的過程中,僅需要在執行到 newSocket 方法時,將連接到 IP 和端口設置為正確的 IP 和 端口,核心代碼如下圖:

最終效果:

3、源代碼修改

在執行的流程中最終執行到了 createEndPoint 方法中,從執行流程來看主要如下圖所示。

在執行 rebind 方法發送序列化代碼時,可以看到在此時已經變成了 Weblogic 內網中運行的 IP 和 端口,直到程序執行到 createEndPoint 拋出異常。

而執行到 getInvocationIOR 方法時,會調用 IIOPRemoteRef.locateIORForRequest 方法來進行尋找 IOR,并且將尋找到的 IOR 設置為當作當前 IOR 進行返回提供使用。

在進入 locateIORForRequest 方法之后會通過 EndPointManager.findOrCreateEndPoint 來進行尋找或創建結束切點,可以看到此時 IOR 的 host、port 變成了內網中的 IP 和端口。

在進入 EndPointManager.findOrCreateEndPoint 最終會執行到 createEndPoint 方法中來進行建立 Socket 通信,在這里由于是內網的 IP 和端口無法成功建立通信,導致后續的利用也無法繼續進行。

實現
大致的問題點已經確認的清楚的情況下,我們可以通過修改原始代碼的方式來進行實現繞過,大體思路為:
a. 修改 weblogic.corba.j2ee.naming.ContextImpl 類中的 rebind 方法
b. 修改 weblogic.iiop.IIOPRemoteRef 類中 locateIORForRequest 方法的 ior 參數,確保正常調用 findOrCreateEndPoint 創建結束切點
首先修改 weblogic.corba.j2ee.naming.ContextImpl 類中 rebind 方法將正確的連接 IP 和端口加入到系統環境變量中。

最后在 locateIORForRequest 方法讀取系統環境變量中正確的 IP 和端口并且修改 ior 變量中相關的連接信息。使之能夠正常的執行 findOrCreatePoint 方法創建結束切點

最終效果:

八、IIOP NAT 繞過方案總結
- GIOP 協議極簡實現
- 優點:原始 Socket 發包,效率較快
- 缺點:構造難度較高,需要掌握協議相關知識
- Javassist
- 優點:修改難度較低
- 缺點:程序使用完畢之后需要重啟,如果使用動態加載等方案可能導致資源占用率過高
- 源代碼修改
- 優點:原生代碼兼容性較強
- 缺點:修改難度較大
九、參考文獻
- https://blog.csdn.net/weixin_33913377/article/details/94134763
- https://docs.oracle.com/cd/E13211_01/wle/wle42/corba/giop.pdf
- https://www.slideserve.com/milek/13-giop-iiop-ior
- https://www.cnblogs.com/scy251147/p/11100961.html
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1396/
暫無評論