天玄安全实验室 04月05日 22:00
Spring Framework RCE分析(CVE-2022-22965)
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

Spring Framework 在 JDK 9 及以上版本中存在远程代码执行漏洞,攻击者可利用该漏洞写入恶意代码。该漏洞源于框架的参数绑定功能,攻击者通过构造恶意请求,获取 AccessLogValve 对象并写入恶意字段值,从而触发 pipeline 机制,最终实现任意文件写入。文章详细分析了漏洞原理,包括对象绑定机制、属性访问过程以及绕过 CVE-2010-1622 限制的方法,并提供了漏洞验证截图。

💥 漏洞触发条件:该漏洞主要影响使用 JDK 9 及以上版本的 Spring MVC 框架,且框架依赖 spring-beans-*.jar 文件或存在 CachedIntrospectionResults.class。

⚙️ 漏洞原理:Spring 的对象绑定机制(由 org.springframework.beans.BeanWrapperImpl 实现)允许攻击者通过构造特定参数,利用 AccessLogValve 对象进行恶意操作,最终实现文件写入。

🔍 关键绕过:CVE-2010-1622 限制了从 Class 实例直接获取 classLoader,但在 JDK 9 中,通过 java.lang.Module 的 classLoader 属性,该限制被绕过,从而导致漏洞的产生。

🛠️ 攻击流程:攻击者利用 Spring 的参数绑定功能,设置 AccessLogValve 对象的相关属性,例如 directory、prefix、suffix、fileDateFormat 等,最终实现日志文件的写入,从而达到远程代码执行的目的。

原创 p1ay2win 2022-04-01 10:49

3月29日,Spring Framework 存在远程代码执行漏洞,在 JDK 9 及以上版本环境下,远程攻

3月29日,Spring Framework 存在远程代码执行漏洞,在 JDK 9 及以上版本环境下,远程攻击者可利用该漏洞写入恶意代码导 致远程代码执行漏洞。

漏洞描述

作为目前全球最受欢迎的Java轻量级开源框架,在Spring框架的JDK9版本(及以上版本)中,远程攻击者可在满足特定条件的基础上,通过框架的参数绑定功能获取AccessLogValve对象并诸如恶意字段值,从而触发pipeline机制并 写入任意路径下的文件。

目前已知,触发该漏洞需要满足两个基本条件:

    使用JDK9及以上版本的Spring MVC框架
    Spring 框架以及衍生的框架spring-beans-*.jar 文件或者存在CachedIntrospectionResults.class

影响范围

Spring Framework 5.3.X < 5.3.18

Spring Framework 5.2.X < 5.2.20

漏洞分析

Spring中对象绑定是由org.springframework.beans.BeanWrapperImpl实现的。在参数绑定过程中,由其父类AbstractPropertyAccessorsetPropertyValues方法为请求中所有参数对应的bean对象属性赋值。

跟进到setPropertyValue方法,由属性名获取BeanWrapperImpl的方法getPropertyAccessorForPropertyPath返回到的是封装了tomcat日志属性的对象org.apache.catalina.valves.AccessLogValveBeanWrapperImpl

再跟进到到AbstractNestablePropertyAccessor,发现它的逻辑是会用.号分割,递归获取封装对应属性的BeanWrapperImpl直到最后一个属性并返回。

protected AbstractNestablePropertyAccessor getPropertyAccessorForPropertyPath(String propertyPath) {
 int pos = PropertyAccessorUtils.getFirstNestedPropertySeparatorIndex(propertyPath);
 // Handle nested properties recursively.
 if (pos > -1) {
  String nestedProperty = propertyPath.substring(0, pos);
  String nestedPath = propertyPath.substring(pos + 1);
  AbstractNestablePropertyAccessor nestedPa = getNestedPropertyAccessor(nestedProperty);
  return nestedPa.getPropertyAccessorForPropertyPath(nestedPath);
 }
 else {
  return this;
 }
}

最后回到setPropertyValue中,后续用请求参数键值对pvnestedPa封装的AccessLogValve对象中相应的属性赋值。结合以上,可以得出Spring这么一个特性:Spring对象绑定请求参数的路由Mapping,其POJO类所有具有settergetter属性,也包括属性对应类的属性,都可通过请求参数修改。

这时稍加思考会发现,我们的示例类User并没有显示的设置一个class属性,但回看封装了示例类的BeanWrapperImpl对象,nestedPropertyAccessors属性中存在一个封装ClassBeanWrapperImpl对象。

那是因为每个对象都继承于Object类,都存在getClass方法,所以class就是每个对象的嵌套属性,可以被这样神不知鬼不觉的被访问到。

还有细心的同学会发现这个漏洞的利用方式很像Struts2的S2-020,都是用class属性最后控制AccessLogValve类,但差别是Spring中先通过class获取module,再从module获取classLoader。

class.classLoader.resources.context.parent.pipeline.first.directory =logs
class.classLoader.resources.context.parent.pipeline.first.prefix =localhost_access_log
class.classLoader.resources.context.parent.pipeline.first.suffix = .txt
class.classLoader.resources.context.parent.pipeline.first.fileDateFormat =.yyyy-mm-dd

那是因为在CVE-2010-1622后,Spring限制了bean直接从Class实例直接获取classLoader,具体在org.springframework.beans.CachedIntrospectionResults#CachedIntrospectionResults构造方法可以体现。

而在JDK9后出现的java.lang.Module存在一个ClassLoader属性:loader,又存在它的getter方法:getClassLoader,CVE-2010-1622的修复就这么被轻松绕过了。这也是目前的POC只能攻击JDK9的原因。

以下是具体验证截图:

阅读原文

跳转微信打开

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

Spring Framework 远程代码执行 漏洞分析 JDK 9
相关文章