Web安全性漏洞之:JDK1.5環境下掃描遠端偵錯連接埠導致JVM崩潰【JDWP exit error JVMTI_ERROR_NONE(0)】

來源:互聯網
上載者:User
問題描述:

對運行在JDK 1.5版本下的java應用伺服器進行連接埠掃描,掃描的方式可以用相關掃描軟體,最簡單的是直接用ping/telnet命令,有閑情還可以自己寫一段代碼進行socket串連,掃描時會發現java進程crash,經測試百發百中;查看作業記錄顯示:
ERROR: transport error 202: handshake failed - received >GET / HTTP/1.0< - excepted >JDWP-Handshake< ["transport.c",L41]
JDWP exit error JVMTI_ERROR_NONE(0): could not connect, timeout or fatal error

問題原因:

該故障是JVM遠程debug存在的缺陷,只有在開啟遠程debug連接埠時才會出現;原因是由於接收到不符合JDWP協議的資料包,導致JVM崩潰。
該問題早已確認為JDK的一個bug,具體見6339385:http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6339385 中的描述;
要確認系統中是否存在該漏洞,可以檢查java啟動參數中是否有如下相關配置:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8787
或者-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8787
若存在相關配置,那就說明java啟動了遠端偵錯連接埠,就會存在該漏洞;此時JVM虛擬機器作為調試的服務提供端,通過8787連接埠監聽一個串連,而調試器通過該串連與虛擬機器進行互動。
目前,Windows平台的JVM提供了兩種方式的串連:共用記憶體和 Socket串連,共用記憶體的服務提供端和調試端只能位於同一台機,而Socket串連則支援不同異機調試,即遠端偵錯。
關於jdwp的參數列表詳見官方文檔:http://download-llnw.oracle.com/javase/1.5.0/docs/guide/jpda/conninv.html#Invocation
從官方文檔中摘錄幾個配置案例:
-Xrunjdwp:transport=dt_socket,server=y,address=8000
在8000連接埠監聽Socket串連,掛起VM(suspend預設為y)並且不載入運行主函數直到調試請求到達
-Xrunjdwp:transport=dt_shmem,server=y,suspend=n
選擇一個可用的共用記憶體(因為沒有指定address)並監聽該記憶體串連,同時載入運行主函數,不掛起VM
-Xrunjdwp:transport=dt_socket,address=myhost:8000
串連到myhost:8000提供的調試服務(server=n,以調試用戶端存在),掛起VM並且不載入運行主函數
-Xrunjdwp:transport=dt_shmem,address=mysharedmemory
通過共用記憶體的方式串連到調試服務,掛起VM並且不載入運行主函數
-Xrunjdwp:transport=dt_socket,server=y,address=8000,onthrow=java.io.IOException,launch=/usr/local/bin/debugstub
等待java.io.IOException被拋出,然後掛起VM並監聽8000連接埠串連,在接到調試請求後以命令/usr/local/bin/debugstub dt_socket myhost:8000執行
-Xrunjdwp:transport=dt_shmem,server=y,onuncaught=y,launch=d:/bin/debugstub.exe
等待一個RuntimeException被拋出,然後掛起VM並監聽一個可用的共用記憶體,在接到調試請求後以命令d:/bin/debugstub.exe dt_shmem <address>執行,<address>是可用的共用記憶體

問題解決:

應該說該問題並不算太嚴重,因為一般線上啟動並執行應用都不會開啟遠程Debug模式,各應用伺服器的預設配置也是不開啟的,就算開啟了該debug連接埠也會有防火牆保護,外網訪問不到。
徹底解決該問題的方法有兩種,任選其一即可:
1、在JDK1.5環境下關閉遠端偵錯模式,開發測試環境下無所謂,但線上環境的部署指令碼一定要仔細review才行;
2、升級JDK到1.6b49以上版本,這就要看應用的相容性了,一般來說不會有什麼問題;

再往前試試:深入Java調試體系JPDA(Java Platform Debugger Architecture)

對於Java虛擬機器介面熟悉的人來說,您一定還記得Java提供了兩個介面體系,JVMPI(Java Virtual Machine Profiler Interface)和 JVMDI(Java Virtual Machine Debug Interface),而它們,以及在 Java SE 5 中準備代替它們的 JVMTI(Java Virtual Machine Tool Interface),都是 Java 平台調試體系(Java Platform Debugger Architecture,JPDA)的重要組成部分。 Java SE 自 1.2.2 版就開始推出 Java 平台調試體繫結構(JPDA)工具集,而從 JDK 1.3.x 開始,Java SDK 就提供了對 Java 平台調試體繫結構的直接支援。顧名思義,這個體係為開發人員提供了一整套用於調試 Java 程式的 API,是一套用於開發 Java 調試工具的介面和協議。本質上說,它是我們通向虛擬機器,考察虛擬機器運行態的一個通道,一套工具。理解這一點對於學習 JPDA 非常重要。
換句話說,通過 JPDA 這套介面,我們就可以開發自己的調試工具。通過這些 JPDA 提供的介面和協議,調試器開發人員就能根據特定開發人員的需求,擴充定製 Java 調試應用程式,開發出吸引開發人員使用的調試工具。前面我們提到的 IDE 調試工具都是基於 JPDA 體系開發的,區別僅僅在於它們可能提供了不同的圖形介面、具有一些不同的自訂功能。另外,我們要注意的是,JPDA 是一套標準,任何的 JDK 實現都必須完成這個標準,因此,通過 JPDA 開發出來的調試工具先天具有跨平台、不依賴虛擬機器實現、JDK 版本無關等移植優點,因此大部分的調試工具都是基於這個體系的。

JPDA 組成模組

JPDA 定義了一個完整獨立的體系,它由三個相對獨立的層次共同組成,而且規定了它們三者之間的互動方式,或者說定義了它們通訊的介面。這三個層次由低到高分別是 JAVA 虛擬機器工具介面(JVMTI),Java 調試線協議(JDWP)以及 Java 調試介面(JDI)。這三個模組把調試過程分解成幾個很自然的概念:調試者(debugger)和被調試者(debuggee),以及他們中間的通訊器。被調試者運行於我們想調試的 JAVA 虛擬機器之上,它可以通過 JVMTI 這個標準介面,監控當前虛擬機器的資訊;調試者定義了使用者可使用的調試介面,通過這些介面,使用者可以對被調試虛擬機器發送調試命令,同時調試者接受並顯示調試結果。在調試者和被調試著之間,調試命令和調試結果,都是通過 JDWP 的通訊協議傳輸的。所有的命令被封裝成 JDWP 命令包,通過傳輸層發送給被調試者,被調試者接收到 JDWP 命令包後,解析這個命令並轉化為 JVMTI 的調用,在被調試者上運行。類似的,JVMTI 的運行結果,被格式化成 JDWP 資料包,發送給調試者並返回給 JDI 調用。而調試器開發人員就是通過 JDI 得到資料,發出指令。就展示了三者間的互動過程:

下面就簡單介紹下這三個模組的主要功能:

JAVA 虛擬機器工具介面(JVMTI)

JVMTI(Java Virtual Machine Tool Interface)即指 JAVA 虛擬機器工具介面,它是一套由虛擬機器直接提供的 native 介面,它處於整個 JPDA 體系的最底層,所有調試功能本質上都需要通過 JVMTI 來提供。通過這些介面,開發人員不僅調試在該虛擬機器上啟動並執行 Java 程式,還能查看它們啟動並執行狀態,設定回呼函數,控制某些環境變數,從而最佳化程式效能。我們知道,JVMTI 的前身是 JVMDI 和 JVMPI,它們原來分別被用於提供調試 Java 程式以及 Java 程式調節效能的功能。在 J2SE 5.0 之後 JDK 取代了 JVMDI 和 JVMPI 這兩套介面,JVMDI 在最新的 Java SE 6 中已經不提供支援,而 JVMPI 也計劃在 Java SE 7 後被徹底取代。

Java 調試互動協議(JDWP)

JDWP(Java Debug Wire Protocol)是一個為 Java 調試而設計的一個通訊互動協議,它定義了調試器和被偵錯工具之間傳遞的資訊的格式。在 JPDA 體系中,作為前端(front-end)的調試者(debugger)進程和後端(back-end)的被偵錯工具(debuggee)進程之間的互動資料的格式就是由 JDWP 來描述的,它詳細完整地定義了請求命令、回應資料和錯誤碼,保證了前端和後端的 JVMTI 和 JDI 的通訊通暢。比如在 Sun 公司提供的實現中,它提供了一個名為 jdwp.dll(jdwp.so)的動態連結程式庫檔案,這個動態庫檔案實現了一個 Agent,它會負責解析前端發出的請求或者命令,並將其轉化為 JVMTI 調用,然後將 JVMTI 函數的傳回值封裝成 JDWP 資料發還給後端。
另外,這裡需要注意的是 JDWP 本身並不包括傳輸層的實現,傳輸層需要獨立實現,但是 JDWP 包括了和傳輸層互動的嚴格的定義,就是說,JDWP 協議雖然不規定我們是通過 EMS 還是快遞運送貨物的,但是它規定了我們傳送的貨物的擺放的方式。在 Sun 公司提供的 JDK 中,在傳輸層上,它提供了 socket 方式,以及在 Windows 上的 shared memory 方式。當然,傳輸層本身無非就是本機內處理序間通訊方式和遠端通訊方式,使用者有興趣也可以按 JDWP 的標準自己實現。

Java 調試介面(JDI)

JDI(Java Debug Interface)是三個模組中最高層的介面,在多數的 JDK 中,它是由 Java 語言實現的。 JDI 由針對前端定義的介面組成,通過它,調試工具開發人員就能通過前端虛擬機器上的調試器來遠程操控後端虛擬機器上被偵錯工具的運行,JDI 不僅能協助開發人員格式化 JDWP 資料,而且還能為 JDWP 資料轉送提供隊列、緩衝等最佳化服務。從理論上說,開發人員只需使用 JDWP 和 JVMTI 即可支援跨平台的遠端偵錯,但是直接編寫 JDWP 程式費時費力,而且效率不高。因此基於 Java 的 JDI 層的引入,簡化了操作,提高了開發人員開發偵錯工具的效率。
如下就總結了三個模組的不同點:

Java 調試介面的特點

Java 語言是第一個使用虛擬機器概念的流行的程式設計語言,正是因為虛擬機器的存在,使很多事情變得簡單而輕鬆,掌握了虛擬機器,就掌握了記憶體配置、線程管理、即時最佳化等等運行態。同樣的,Java 調試的本質,就是和虛擬機器打交道,通過操作虛擬機器來達到觀察調試我們自己代碼的目的。這個特點決定了 Java 調試介面和以前其他程式設計語言的巨大區別。
以 C/C++ 的調試為例,目前比較流行的調試工具是 GDB 和微軟的 Visual Studio 內建的 debugger,在這種 debugger 中,首先,我們必須編譯一個“ debug ”模式的程式,這個會比實際的 release 模式程式大很多。其次,在調試過程中,debugger 將會深層接入程式的運行,掌握和控制運行態的一些資訊,並將這些資訊及時返回。這種介入對啟動並執行效率和記憶體佔用都有一定的需求。基於這些需求,這些 Debugger 本身事實上是提供了,或者說,建立和管理了一個運行態,因此他們的程式演算法比較複雜,個頭都比較大。對於遠端的調試,GDB 也沒有很好的預設實現,當然,C/C++ 在這方面也沒有特別大的需求。
而 Java 則不同,由於 Java 的運行態已經被虛擬機器所很好地管理,因此作為 Java 的 Debugger 無需再自己創造一個可控的運行態,而僅僅需要去操作虛擬機器就可以了。 Java 的 JPDA 就是一套為調試和最佳化服務的虛擬機器的操作工具,其中,JVMTI 是整合在虛擬機器中的介面,JDWP 是一個通訊層,而 JDI 是前端為開發人員準備好的工具和運行庫。
從構架上說,我們可以把 JPDA 看作成是一個 C/S 體繫結構的應用,在這個構架下,我們可以方便地通過網路,在任意的地點調試另外一個虛擬機器上的程式,這個就很好地解決了部署和測試的問題,尤其滿足解決了很多網路時代中的開發應用的需求。前端和後端的分離,也方便使用者開發適合於自己的調試工具。
從效率上看,由於 Java 程式本身就是編譯成位元組碼,運行在虛擬機器上的,因此調試前後的程式、記憶體佔用都不會有大變化(僅僅是啟動一個 JDWP 所需要的記憶體),任意程度都可以很好地調試,非常方便。而 JPDA 構架下的幾個組成部分,JDWP 和 JDI 都比較小,主要的工作可以讓虛擬機器自己完成。
從靈活性上,Java 調試工具是建立在強大的虛擬機器上的,因此,很多前沿的應用,比如動態編譯運行,位元組碼的即時替換等等,都可以通過對虛擬機器的改進而得到實現。隨著虛擬機器技術的逐步發展和深入,各種不同種類,不同應用領域中虛擬機器的出現,各種強大的功能的加入,給我們的調試工具也帶來很多新的應用。
總而言之,一個先天的,可控的運行態給 Java 的調試工作,給 Java 調試介面帶來了極大的優勢和便利。通過 JPDA 這個標準,我們可以從虛擬機器中得到我們所需要的資訊,完成我們所希望的操作,更好地開發我們的程式。

 

 

更多關於JPDA的詳細介紹可參考:
JVMTI 和 Agent 實現:http://www.ibm.com/developerworks/cn/java/j-lo-jpda2/index.html
Java 調試介面(JDI):http://www.ibm.com/developerworks/cn/java/j-lo-jpda4/index.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.