<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    【最新漏洞預警】CVE-2022-22965 Spring核心框架Spring4Shell遠程命令執行漏洞原理與修復方式分析

    VSole2022-03-31 22:34:47

    漏洞信息

    Spring是目前全球最受歡迎的Java輕量級開源框架。近日網上爆出Spring核心框架存在RCE漏洞(編號CVE-2022-22965)。在野曝光一段時間后,與近幾年流行的高危漏洞命名方式類似(比如ProxyShell、log4jShell等),這個漏洞被稱為Spring4Shell。3月31日官方終于發布了漏洞信息,并在新版本v5.3.18和v5.2.20中修復了漏洞。(官方不發補丁我也不敢公開發布文章呀!)

    分析后發現漏洞結合了JDK9及以上版本一個新的屬性,成功繞過歷史漏洞CVE-2010-1622修復補丁,同時結合Tomcat容器的一些操作屬性,可以實現GetShell。當然Weblogic、Jetty等其他Java中間件或應用程序也可能構建出完整利用鏈,但從目前研究進度來看,漏洞觸發需要至少滿足以下條件:

    • JDK9或以上版本系列
    • Spring框架或衍生的SpringBoot等框架,版本小于v5.3.18或v5.2.20
    • Spring JavaBean表單參數綁定需要滿足一定條件
    • 部署在Tomcat容器中,且日志記錄功能開啟(默認狀態)

    環境搭建

    新建SpringBoot工程:

    添加實體類`User`:

    添加`LoginController`:

    生成war包并部署到Tomcat容器中啟動。

    JavaBean參數綁定分析

    JavaBean是一種特殊的類,主要用于傳遞數據信息,這種類中的方法主要用于訪問私有的字段,且方法名符合某種命名規則。如果在兩個模塊之間傳遞信息,可以將信息封裝進JavaBean中。比如在`User`類中再添加一個新類`Test`:

    構建如上所示的研究環境,當我們發送如下請求時:

    Spring會將參數用`.`進行分割,前面的參數會自動調用`get***`,最后一個參數會自動調用`set***`,依次執行為:

    ...User->getTest    Test->setT...
    

    通過上面這種鏈式的參數解析規則,我們可以`set***`實現修改Spring框架中某些類的屬性。通過深入分析,發現當在`Controller`的參數前加上注解之類,比如`@RequestBody`,將不會進行鏈式解析,這也是限制適用范圍的其中一個關鍵因素。

    CVE-2010-1622漏洞補丁分析

    Spring歷史上曾經爆出一個漏洞CVE-2010-1622,原理就是基于上面的JavaBean賦值規則。可以通過提交`class.classLoader`參數,最終執行`getClassLoader`函數獲取`ClassLoader`對象,從而可以導致RCE。CVE-2010-1622漏洞補丁位于`CachedIntrospectionResults`:

    CVE-2010-1622補丁通過將`classLoader`加入黑名單,導致無法加入解析屬性列表。

    JDK 9 Module分析

    在JDK9及以上版本的JDK中,`java.lang.Class`類中新增了一個私有變量`module`以及函數`getModule`:

    進入`Module`類,發現存在`loader`變量和函數`getClassLoader`:


    也就是說,通過`Module`可以獲取Web Context上下文環境的`ClassLoader`對象。

    漏洞分析

    通過前面的分析,我們在Tomcat+Spring+JDK11環境中構建研究環境,提交`class.module.classLoader`參數同樣可以獲取`ClassLoader`對象,調試發現在對BeanInfo賦值過程中,`CachedIntrospectionResults`中會加載`class org.apache.catalina.loader.ParallelWebappClassLoader`對象,可以繞過黑名單檢查:

    `ParallelWebappClassLoader`位于Tomcat環境中,獲取`ParallelWebappClassLoader`對象后,就可以在此基礎上繼續尋找可利用鏈。

    可以嘗試采用遞歸方式搜索所有滿足`class.module.classLoader`條件的鏈式調用的屬性,加入一個`help.jsp`文件(腳本參考只考慮int、string與boolean這些基本屬性)。訪問后,可以獲取所有潛在可操控的屬性,結果如下:

    一共找到300個符合條件的屬性可以操控(實際應該更多)。其中的`class.module.classLoader.resources.context.parent.pipeline.first.*`對應于`AccessLogValve`類,主要存放Tomcat日志操作的相關屬性:

    ...class.module.classLoader.resources.context.parent.pipeline.first.directory         //日志保存目錄默認為logsclass.module.classLoader.resources.context.parent.pipeline.first.prefix            //日志文件名前綴默認為localhost_access_logclass.module.classLoader.resources.context.parent.pipeline.first.suffix            //日志文件名后綴默認為.txtclass.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat    //日志文件名日期格式默認為.yyyy-mm-dd...
    

    鏈式調用過程如下:

    getClass()->LoginControllergetModule()->ModulegetClassLoader()->ParallelWebappClassLoadergetResources()->StandardRootgetContext()->StandardContextgetParent()->StandardEnginegetPipeline()->PipelinegetFirst()->AccessLogValve...
    

    默認情況下日志目錄為`logs`,文件名稱為`localhost_access_log.yyy-mm-dd.txt`,可以通過構造請求修改日志存儲路徑、日志文件名稱、后綴名屬性值。

    通過修改日志后綴名、文件名稱、存放位置等屬性,可以寫入jsp的webshell。需要注意的是,由于Tomcat稍微新一點的版本出于安全性考慮,無法直接在URL中攜帶`<`、`{`等特殊字符(否則返回400),我們可以通過`class.module.classLoader.resources.context.parent.pipeline.first.pattern`屬性來修改日志記錄的格式,從而變向寫入webshell。

    參考`AbstractAccessLogValve`類使用說明:

    比如,可以將敏感字符放到HTTP請求頭中(格式:`%{xxx}i`)。最終實現在`webapps`目錄下寫入webshell,名稱為`localhost_access_log123.jsp`:

    修復方式

    在官方沒有發布新版本前,可以通過在WAF中加入對`Class.*`等惡意字符串的過濾,或者在Spring應用程序中新建一個全局類實現對惡意字符串的過濾,同時保證這個類被Spring加載到(推薦在Controller所在的包中添加)。完成類添加后,需對項目進行重新編譯打包,并重新發布項目:

    import org.springframework.core.annotation.Order;import org.springframework.web.bind.WebDataBinder;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.InitBinder;
    @ControllerAdvice@Order(10000)public class a{    @InitBinder    public void setAllowedFields(WebDataBinder dataBinder) {        String[] abd = new String[]{"class.*", "Class.*", "*.class.*", "*.Class.*"};        dataBinder.setDisallowedFields(abd);        }}
    

    3月31日,官方在`v5.3.18`和`v5.2.20`版本中修復了漏洞,我們看下關鍵補丁:


    相比CVE-2010-1622漏洞補丁,新補丁對類型限制更為嚴格,只允許所有類中的`name`屬性合法通過。

    小結

    漏洞通過`class.module.classLoader`在Web Context上下文環境中找到合適的類屬性進行控制從而實現Getshell,理論上漏洞利用鏈不局限于Tomcat,類似Weblogic、Jetty等其他的Java中間件是否可以利用不好下結論,可以嘗試利用`help.jsp`來尋找潛在的利用點,這方面感興趣的小伙伴可以關注公眾號后與本人深入交流。

    漏洞spring框架
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    雖說是 Spring 框架漏洞,但以下包含并不僅 Spring Framework,Spring Boot,還有 Spring Cloud,Spring Data,Spring Security 等。
    Spring框架是一個開放源代碼的J2EE應用程序框架,是針對bean的生命周期進行管理的輕量級容器。Spring可以單獨應用于構筑應用程序,也可以和Struts、Webwork、Tapestry等眾多Web框架組合使用,并且可以與 Swing等桌面應用程序AP組合。 Spring框架主要由七部分組成,分別是 Spring Core、 Spring AOP、 Spring ORM、 Spring
    Spring核心框架存在RCE漏洞.在野曝光一段時間后,官方終于發布漏洞信息CVE-2022-22965,并并修復了漏洞。結合Tomcat屬性可實現RCE。從理論上分析,Weblogic等其他Java中間件或應用程序也可能構建出完整利用鏈。
    雖說是 Spring 框架漏洞,但以下包含并不僅 Spring Framework,Spring Boot,還有 Spring Cloud,Spring Data,Spring Security 等。 CVE-2010-1622 Spring Framework class.classLoader 類遠程代碼執行 影響版本:SpringSource Spring Framework 3.0.0
    2021年11月30日,360漏洞云團隊監測到VMware發布安全公告,修復了一個 Spring AMQP中的拒絕服務漏洞漏洞編號:CVE-2021-22095,漏洞威脅等級:中危。
    Spring framework 是Spring 里面的一個基礎開源框架,其目的是用于簡化 Java 企業級應用的開發難度和開發周期,2022年3月31日,VMware Tanzu發布漏洞報告,Spring Framework存在遠程代碼執行漏洞,在 JDK 9+ 上運行的 Spring MVC 或 Spring WebFlux 應用程序可能容易受到通過數據綁定的遠程代碼執行 (RCE) 的攻擊
    建議相關用戶及時開展安全自查
    360漏洞云近日監測到Spring框架中存在一個嚴重的遠程代碼執行漏洞,該漏洞影響Jdk 9.0以上版本的Spring框架及其衍生框架,包括但不限于Spring Cloud、Spring Boot等。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类