近年來,我們對序列化攻擊產生了濃厚的興趣。就在幾個月前,我們決定投入一點精力研究Apache Dubbo。據我們所知,Dubbo以多種方式對許多程序進行了反序列化處理。自Apache基金會使用Dubbo后,Dubbo在世界各地的用戶數量顯著增加。
據2019年中期新聞稿報道,中國有十幾家企業已經開始使用Dubbo,其中包括阿里巴巴集團、中國人壽、中國電信、當當網、滴滴出行、海爾和中國工商銀行等。該報道指出,Apache宣布將Dubbo提升為Apache頂級項目。
圖2 – Dubbo用戶(圖片來源于Apache Dubbo官網)
我發現Apache Dubbo提供商和用戶使用的版本≤Dubbo 2.7.3,當配置可接受HTTP協議時,允許遠程攻擊者向暴露的服務發送惡意程序,從而導致遠程代碼執行的問題。這是在未經認證的情況下發生的,攻擊者只需知道很少的信息就可以利用此漏洞做文章。具體來說,如果HTTP啟用,在任何Dubbo實例上,攻擊者只需要利用此處所述的漏洞和一個URL就能順利攻破服務系統。本報告附有概念驗證視頻。
攻擊者可以利用此漏洞破解Dubbo提供商的服務(該服務旨在從其消費者獲得遠程連接)。然后攻擊者可以用一個惡意的Dubbo提供商程序將現有Dubbo提供商程序替換掉。接下來,該替換程序可使用類似的惡意對象對消費者作出響應,從而激活遠程代碼執行程序,讓攻擊者攻破整個Dubbo集群。
造成這種漏洞問題的根本原因在于Spring框架中使用了遠程反序列化服務。Spring框架文檔明確建議,用戶切勿使用不可信的數據運用Spring框架。再加上庫(該庫含一個鮮為人知的小工具鏈)過時的問題,導致遠程代碼執行的問題產生。不可信數據反序列化處理的不安全隱患,加上小工具鏈的存在,造成遠程訪問和遠程未經認證的代碼執行無縫對接的隱患產生。
Chris Frohoff和Moritz Bechler的研究和工具(ysoserial和marshalsec)功不可沒。他們將一些代碼用在小工具鏈上,他們的研究為解決這種漏洞問題奠定了基礎。
嚴重級別
Checkmarx認為該漏洞的CVS評分為9.8(嚴重),因為它是一個未經認證的遠程代碼執行漏洞,在Dubbo服務的權限級別提供特權,從而完全破解了該服務的機密性、完整性和可及性。
雖然并非所有Dubbo實例都配置使用HTTP協議,但就配置使用該協議的Dubbo版本(帶有已知漏洞)而言,只要提供很少且隨時可用的信息(即存在漏洞的服務URL),這類系統就非常容易受到攻擊。任何人只要通過注冊表(如Zookeeper)等服務就可以在網上獲得上述服務URL,且該服務URL不被視為秘密或機密內容。
CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H/E:F/RL:U/RC:C/CR:H/IR:H/AR:H
規范
這是怎么回事?
激活遠程HTTP協議的Dubbo應用程序會產生反序列化的不安全問題。如果Apache Dubbo提供商實例啟用了HTTP,攻擊者就可以通過提交一個帶有Java對象的POST請求,完全破解該實例。
Dubbo HTTP實例試圖在Java ObjectStream中對數據進行反序列化處理,而Java ObjectStream包含一組惡意的類(常被稱為小工具鏈),調用該工具鏈會導致系統執行惡意代碼。在這種情況下,有問題的惡意代碼允許攻擊者對系統命令進行任意操作。異常創建期間,在這個小工具鏈上的Dubbo實例中進行內部toString調用時,小工具鏈就會被調用。
重建問題
攻擊者可以將帶有惡意對象的POST請求提交到Apache Dubbo HTTP服務的bean URL,以便執行遠程代碼。在這種情況下,bean是由Spring綁定到指定Dubbo協議端點的接口實現類。該bean連接到一個URL,該bean的請求體包含一個HTTP遠程調用,用于確定適合的bean調用方法和參數的選用。
攻擊者獲得bean的URL之后,他們只需要通過標準POST請求提交一個惡意的小工具鏈即可利用這個漏洞做文章。
如果HTTP服務和協議已經啟用,在具有Dubbo-Remoting-HTTP的vanilla Apache Dubbo范圍內能夠找到允許執行遠程操作系統命令的新小工具鏈。
為概念驗證(PoC)重建受損Dubbo HTTP實例
遵守以下指南:
鎖定易受攻擊的實例
要觸發此漏洞,攻擊者必須識別一個指向Dubbo HTTP bean的URL。URL地址信息通常是公開或無需特權訪問即可獲得的,只要攻擊者通過Zookeeper等Dubbo服務注冊表以及多播就可以在網上獲得該URL地址,無須部署良好的HTTPS傳遞途徑,從而實現中間人攻擊。
觸發漏洞概念驗證
有關運行的概念驗證代碼,參加附件1。請注意,Dubbo實例的IP地址等變量需要在這段代碼中進行修改。
如上所述,攻擊者需要與Dubbo HTTP服務相同的依賴項。在此概念驗證中,com.nqzero:permit-reflect用于序列化期間所需的反射函數,而org.apache.httpcomponents.httpclient則被用于將惡意小工具發送到HTTP服務。為觸發這個漏洞,攻擊者使用Apache Dubbo和JDK的類空間中可用方法設計了新的小工具鏈。
此小工具鏈使用以下組件:
圖3–利用字節碼
如果調用了newTransformer,
HttpInvokerServiceExporter.doReadRemoteInvocation(ObjectInputStream ois)
和java.lang.Runtime.getRuntime().exec(command)之間的反序列化流程就完成了,從而實現遠程代碼執行。
最終小工具鏈的結構如下:
如果該漏洞被觸發,并且惡意代碼被執行(在概念驗證中,服務器上會彈出一個calc.exe實例),就會引發異常。然而,應用程序將繼續按照預期的方式運行,從而穩定地利用給定的小工具鏈。
圖4–概念驗證結果
為什么會發生這種情況?
當在Spring框架上使用HTTP協議創建Dubbo應用程序時,就會出現使用HTTP遠程處理的Apache Dubbo。Dubbo毫無防備地在Spring中調用一個已知存在漏洞的類,并使用極易受攻擊(幾乎沒有防范能力)的ObjectInputStream反序列化用戶輸入。攻擊者可以提供一個有效負載,當反序列化時,該有效負載將觸發一連串的對象和方法調用,如果在反序列化范圍內給定一個易受攻擊的小工具鏈,可能會導致遠程代碼執行,這將在本概念驗證中演示。
易受攻擊的Spring Remoting類是HttpInvokerServiceExporter。來自Spring文檔中:
“警告:請當心不安全的Java反序列化導致的漏洞問題:在反序列化步驟中,被操縱的輸入流會導致服務器上不需要的代碼執行。因此,不要將HTTP調用方端點暴露給不可信的客戶端,而是只在您自己的服務之間公開。一般來說,我們強烈推薦采用任何其他消息格式替代(如JSON)。”
這正是Dubbo HTTP遠程處理所發生的情況。使用Dubbo HTTP遠程處理模塊,公開一個接收以下結構的HTTP請求的HTTP端點:
HttpProtocol處理程序使用HttpInvokerServiceExporter解析傳入的org.apache.dubbo.rpc.protocol.http.HttpRemoteInvocation對象,該對象在內部利用ObjectInputStream對其進行反序列化。HttpRemoteInvocation包含對某個方法的調用,以及該方法的傳遞參數。但是,使用ObjectInputStream,可以傳遞任何任意序列化的Java對象,然后以不安全的方式反序列化這些對象,從而導致不安全的反序列化。
ObjectInputStream本身沒有任何外部類,當它用于反序列化格式錯誤的嵌套對象時,容易受到內存耗盡和堆溢出攻擊。
如果允許代碼或命令執行的代碼范圍內有ObjectInputStream可反序列化小工具鏈,則攻擊者可以利用這一點來創建導致遠程代碼執行的對象。這樣一個小工具鏈被發現和利用。
受污染的代碼流
在Dubbo HTTP服務中,會發生以下情況:
開發所需的先驗知識
利用開放的HTTP端口訪問Dubbo HTTP Remoting服務所需知道的唯一內容就是遠程調用(Remote Invocation)接口的程序包和類的名稱。該信息用于創建URL,后者是序列化惡意對象必須提交的地方,這是標準Spring bean行為。舉例而言,如果遠程接口的程序包名稱為“org.apache.dubbo.demo”,而被遠程處理的接口名稱為“DemoService”,則攻擊者需要將由ObjectOutputStream序列化的對象發布到URL“http://domain:port/org.apache.dubbo.demo.DemoService”上。這些URL信息可以以下各種方法獲得:
執行攻擊不需要額外的信息。
應該注意的是,人們一般不會將URL路徑視為機密信息,但網絡攻擊者可以在所謂的不可知的URL路徑后面隱藏易受攻擊的網絡服務,通過隱蔽性的操作,對服務安全構成威脅。
時間軸和披露信息總結
Checkmarx研究團隊首次發現這個漏洞后,致力于找到能夠再現漏洞攻擊進程的方法。一旦證實攻擊者的漏洞攻擊方法,研究團隊就會負責任地將自己的研究發現告知Apache。
披露時間軸
程序包版本
org.apache.dubbo.dubbo – 2.7.3
org.apache.dubbo.dubbo-remoting-http – 2.7.3
org.springframework.spring-web – 5.1.9.RELEASE
供應商防范
Apache Dubbo團隊通過將FastJSON(含最新版本JSONObject)更新為項目依賴項中的最新版本,解決了這個問題,有效地打破了當前的枷鎖。他們還將HTTP協議使用的反序列化機制進行替換,變更了通信協議,確保這種特定的攻擊無法發揮作用。
結論
Dubbo HTTP Remoting服務容易受到未經認證的遠程代碼執行的攻擊。事實上,攻擊者除了需要知道URL的信息,不需要知道任何先驗知識就可以順利通過該漏洞對該服務進行攻擊。
造成這種漏洞問題的根本原因是系統使用了一個不安全的Spring類,HttpInvokerServiceExporter,用于綁定HTTP服務。該類使用標準的Java ObjectStream,并且沒有白名單類形式的安全機制,卻能讓反序列化允許調用其反序列化過程可能觸發惡意代碼的任意類。這時應該停止使用這個類,采用完善的解決方案替代,將DubboHTTP beans中的預期類列入白名單。
Checkmarx安全研究團隊持續開展這類研究活動旨在讓全球各地的企業都能在軟件安全實踐方面進行必要的變革,以努力提高所有人的整體安全防護級別。了解更多安全研究可以關注Checkmarx微信公眾號和官網。
附件1
附件1A:DubboGadget類
一個用于攻擊Dubbo HTTP實例的類
附件1B: Utils類
實用類,包括實用方法,用于創建惡意小工具鏈的某些部分,并通過簡化反射來公開某些函數。很大程度上,實用類源自Chris Frohoff系列文章中的輔助類和舒適方法——https://github.com/frohoff/ysoserial。此外,makeXStringToStringTrigger源自Moritz Bechler的前期研究,示例參見https://github.com/mbechler/marshalsec
附件1C:用于DubboGadget的pom.xml文件
DubboGadget的Maven依賴項