一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情。
漏洞说明
这次spring的漏洞在哪能看到呢?我们直接上spring官网。早blog模块就能看见spring的官方说明了。
2022年3月30日,Spring框架曝出RCE 0day漏洞,国家信息安全漏洞共享平台(CNVD)已收录了Spring框架远程命令执行漏洞(CNVD-2022-23942),考虑到Spring框架的广泛应用,漏洞被评级为危险。
通过该漏洞可写入webshell以及命令执行。在Spring框架的JDK9版本(及以上版本)中,远程攻击者可在满足特定条件的基础上,通过框架的参数绑定功能获取AccessLogValve对象并诸如恶意字段值,从而触发pipeline机制并写入任意路径下的文件。有的小伙伴不知道这个AccessLogValve对象是啥,其实我们都经常使用。只是没注意:
就在tomcat的server.xml文件中,AccessLogValve就是用来记录容器访问请求的日志处理类。Valve,本意是阀门的意思,AccessLogValve是处理生成访问日志的。其原理就是动态修改这个对象的参数值,之后向容器中写入指定的文件(比如jsp文件)之后再通过写入的文件写入shell脚本命令进行执行。
漏洞条件
-
Apache Tomcat作为Servlet容器;
-
使用JDK9及以上版本的Spring MVC框架;
-
Spring框架以及衍生的框架spring-beans-*.jar文件或者存在 CachedIntrospectionResults.class
影响范围
jdk
JDK 9+
Spring
5.3.0 to 5.3.17
5.2.0 to 5.2.19
更老的版本
尝试复现
我们先尝试一下能否复现,之后在说一下怎么解决:
- 看一下环境
- 构建一个基于maven的web项目,框架用的spring-mvc,就是常规的工程没有什么特殊的。主要是要注意maven打包为war包。并独立部署外部tomcat中,不要直接在idea中进行部署启动。
主要注意协议对应spring的版本:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.10</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.10</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.10</version>
</dependency>
定义一个简单的controller
@Controller
public class IndexController {
@RequestMapping("/test1")
@ResponseBody
public String index(User user) {
user = new User();
user.setAddress("123");
return user.getAddress();
}
}
- 访问对应的路径,注意加上下面的参数。
说明一下以上的参数的含义
class.module.classLoader.resources.context.parent.pipeline.first.pattern=构建文件的内容
class.module.classLoader.resources.context.parent.pipeline.first.suffix=修改tomcat日志文件后缀
class.module.classLoader.resources.context.parent.pipeline.first.directory=写入文件所在的网站根目录
class.module.classLoader.resources.context.parent.pipeline.first.prefix=写入文件名称
class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=文件日期格式(实际构造为空值即可)
- 结果在root根目录就会生成你要写入的jsp文件。
这个文件在root目录下,当然就可以在外面直接进行访问。之后就可以通过这个文件进行写入各种shell命令。
自查漏洞
- 排查是否使用了Spring框架(包括但不限于以下方法)
(1) 排查项目中是否使用了Spring框架指定版本:
可遍历项目文件查找是否包含spring-beans-*.jar
(2) 排查war包中是否存在Spring框架:
检查war包内是否存在spring-beans-*.jar文件,若存在则表示使用spring开发框架;若不存在,则进一步确认是否存在CachedIntrospectionResults.class文件,若存在则表示使用Spring开发框架或衍生框架。
- 排查包含Spring框架的项目使用的JDK版本,如果JDK版本>=9则存在风险。
漏洞修复
spring官方建议最好通过升级spring版本来解决,不过也提供了其他集中修复的方法
- 将spring版本升级到5.3.18和5.2.20或者以上版本
- 升级tomcat
- 降低jdk版本
- 禁止请求时带指定参数
咱们说一下最后一种方案:需要增加controller拦截
@ControllerAdvice
@Order(Ordered.LOWEST_PRECEDENCE)
public class BinderControllerAdvice {
@InitBinder
public void setAllowedFields(WebDataBinder dataBinder) {
String[] denylist = new String[]{"class.*", "Class.*", "*.class.*", "*.Class.*"};
dataBinder.setDisallowedFields(denylist);
}
}
不过spring官方墙裂建议升级spring版本,因为目前版本还可能存在未知的问题。
The preferred response is to update to Spring Framework 5.3.18 and 5.2.20 or greater. If you have done this, then no workarounds are necessary. However, some may be in a position where upgrading is not possible to do quickly. For that reason, we have provided some workarounds below.
漏洞现状
目前spring官方已经对该漏洞修复,现在拉取最新spring的jar包通过上面我的的复现步骤进行试验发现结果:
欢迎关注『IT技术小栈』分享求职、工作、技术干货。