Spring rce漏洞分析

admin 2022年4月2日08:58:03评论167 views字数 4876阅读16分15秒阅读模式
一、什么是Bean

实体类通常如下定义,一般一个实体类属性对应一个数据库表的结构,加上set和get方法

public class Student {

private String str;

public String getStr() {
return str;
}

public void setStr(String str) {
this.str = str;
}

@Override
public String toString() {
return "Holle [str=" + str + "]";
}
}

在spring框架中如何实例化呢,spring框架是配置地狱,在其配置文件xml中

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd">


   <!--在Spring中创建对象,在Spring这些都称为bean
  类型 变量名 = new 类型();
  Hello hello = new Hello();
 
  bean = 对象(hello)
  id = 变量名(hello)
  class = new的对象(new Hello();)
  property 相当于给对象中的属性设值,让str="Spring"
   -->
   
   <bean id="hello" class="pojo.Hello">
       <property name="str" value="Spring"/>
   </bean>
</beans>

结论:bean其实是实体类的对象。


二、什么是Spring-mvc依赖注入(DI)

建议bilibili看下狂神的java视频,spring依赖注入

实体类

public class User {
  private int id;
  private String name;
  private int age;
  //构造
  //get/set
  //tostring()
}

处理方法

@Controller
public class ControllerTest2{
@RequestMapping("/user")
public String user(User user){
  System.out.println(user);
  return "hello";
}
}

提交数据 : http://localhost:8080/mvc04/user?name=kuangshen&id=1&age=15

后台输出 : User { id=1, name='kuangshen', age=15 }

当我们提交参数时,Springmvc依靠反射机制给user bean属性赋值

三、payload调试

当传入恶意 http://localhost:8080/mvc04/user?class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp

调用栈如下doDispatch方法是Controller入口函数,BeanWrapperImpl是具体bean参数绑定实现类

setValue:334, BeanWrapperImpl$BeanPropertyHandler (org.springframework.beans)
processLocalProperty:458, AbstractNestablePropertyAccessor (org.springframework.beans)
setPropertyValue:278, AbstractNestablePropertyAccessor (org.springframework.beans)
setPropertyValue:266, AbstractNestablePropertyAccessor (org.springframework.beans)
setPropertyValues:97, AbstractPropertyAccessor (org.springframework.beans)
applyPropertyValues:848, DataBinder (org.springframework.validation)
doBind:744, DataBinder (org.springframework.validation)
doBind:197, WebDataBinder (org.springframework.web.bind)
bind:107, ServletRequestDataBinder (org.springframework.web.bind)
bindRequestParameters:157, ServletModelAttributeMethodProcessor (org.springframework.web.servlet.mvc.method.annotation)
resolveArgument:160, ModelAttributeMethodProcessor (org.springframework.web.method.annotation)
resolveArgument:127, HandlerMethodArgumentResolverComposite (org.springframework.web.method.support)
getMethodArgumentValues:167, InvocableHandlerMethod (org.springframework.web.method.support)
invokeForRequest:134, InvocableHandlerMethod (org.springframework.web.method.support)
invokeAndHandle:104, ServletInvocableHandlerMethod (org.springframework.web.servlet.mvc.method.annotation)
invokeHandlerMethod:892, RequestMappingHandlerAdapter (org.springframework.web.servlet.mvc.method.annotation)
handleInternal:797, RequestMappingHandlerAdapter (org.springframework.web.servlet.mvc.method.annotation)
handle:87, AbstractHandlerMethodAdapter (org.springframework.web.servlet.mvc.method)
doDispatch:1039, DispatcherServlet (org.springframework.web.servlet)
doService:942, DispatcherServlet (org.springframework.web.servlet)
processRequest:1005, FrameworkServlet (org.springframework.web.servlet)
doGet:897, FrameworkServlet (org.springframework.web.servlet)
service:655, HttpServlet (javax.servlet.http)
service:882, FrameworkServlet (org.springframework.web.servlet)
service:764, HttpServlet (javax.servlet.http)
internalDoFilter:231, ApplicationFilterCh

先循环读取传出的key值,如下两张图

Spring rce漏洞分析

Spring rce漏洞分析


下一步,获取value值

Spring rce漏洞分析

以之前的key值作为的Bean属性,去找对应的bean

Spring rce漏洞分析

最终反射调用方法赋值,从反射方法可以看出是日志配置相关的



Spring rce漏洞分析

自查方案

目前exp具体影响不明,因为一个完美的武器级exp需要满足

  1. 必须要能通过class为起始对象获取到引用(深度搜索的起点为class),并且还要有无参get方法

  2. 必须有get/set方法,符合java bean规范。

  3. set方法的值必须为字符串

  4. 该controller必须存在spring的参数绑定。

目前只流传tomcat的exp,不排除其他中间件的exp,不排除dos等其他漏洞的exp。

waf规则

现在我们知道为什么java9可以而java8不可以的原因,所以我们可以断定class.module这串字符串一定出现在exp的请求中,可以重点防御这串字符串

甲方自查手册

  1. 确定线上业务中的controller是否使用了spring的参数绑定技术,如果使用则按照下一条继续排查

  2. jdk版本是否为jdk9以上,jdk8以下天然防御

因为该漏洞的本质是变量覆盖漏洞,但是利用手法通过覆盖tomcat的配置修改tomcat的日志位置到根目录,修改日志的后缀为jsp去getshell。

  1. 如果防止getshell,则重点排查中间件是否为tomcat。

  2. 非tomcat中间件目前来说不一定会被getshell,但是存在被该漏洞影响到线上业务的风险(任意变量覆盖到中间件的其他变量配置,导致dos等其他场景),建议停机修改应用,修复方式如下

注意,目前只有通过应用下线重发布的方式打补丁,并且非spring官方推荐修复,存在一定几率的翻车风险。同时按以下两个步骤进行漏涧的临时修复:

1.在应用中全局搜索@InitBinder注解,看看方法体内是否调用dataBinder.setDisallowedFields方法,如果发现此代码片段的引入,则在原来的黑名单中,添加{"class.","Class. *","*. class.", ".Class."}。(注:如果此代码片段使用较多,需要每个地方都追加)

在应用系统的项目包下新建以下全局类,并保证这个类被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);
}
}

参考:https://mp.weixin.qq.com/s/bG3BCdM-suCZldN7FIpYqw

原文始发于微信公众号(瑞不可当):Spring rce漏洞分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年4月2日08:58:03
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Spring rce漏洞分析http://cn-sec.com/archives/861663.html

发表评论

匿名网友 填写信息