前天发布了《我想问问:你昨晚吃到 Spring 的惊天算夜瓜了吗?》这篇文章,没想到阅读量居然这么高。

这篇文章实在是我那天晚上知道这个“瓜”之后,看到很多技能群都在谈论,大概在 23 点 30 分的时候开始想写一篇,然后卡着零点发。

由于我想着本来着凭借我的手速,写这篇文章 30 分钟够够的吧。

jsp一打开页面就触发我滴个乖乖我复现了Spring的破绽畏惧 Ruby

于是我边写边吃瓜,吃着吃着韶光就来到了第二天零点。

当时我就想:哎,这拖延症也来越严重了...反正都已经到凌晨了,要不打几把欢快斗地主,欢快欢快?昨天把豆子输光了,本日又可以免费领豆子了。

以是....

我又打了几把斗地主。
很快啊,又没有豆子了。

于是开始苦哈哈的开始写文章,一不留神就写到第二天凌晨 1 点 25 分。

为什么我记得这么清楚呢?

由于我写这篇文章的时候还是很愉快的,毕竟吃 Spring 的大瓜,一辈子也吃不了几次。

我看了一下我的腕表记录,在 1 点 25 分之后,我的心率开始低落,以是该当是这个时候写完文章的:

哎,这件事情再次印证了写"大众号的,或者说做自媒体的人的一个“黄金定律”:

一些文章写的时候以为这文章真牛逼,我花了这么多韶光写出来,这玩意一发出去肯定是爆款啊,这都不火,天理难容啊!

结果,真的发出去之后,无人问津。

每每是不经意间写的东西,溘然就火了。

这东西,你找谁说理去?

言归正传

好了,言归正传。

我真的复现了这次 Spring 的漏洞。

昨天晚上我正在家里悄悄卷你们的时候,溘然有人给我发来这样的一个链接:

https://sizeof.cat/post/springcore-rce/

然后只配上了四个字:

于是我赶紧点进去看了一下。

很明显这个文章最开始的时候该当也是和我一样一起吃瓜的。

由于他最开始的描述是用的这样的词汇:

可能、听说、大概...

然后在某个韶光点变成了这样:

大略来说便是:实锤了!

而文章中提到的这个地方是一个 PDF 文件:

这个 PDF 文件便是本文的核心了。

但是,我想先拐个弯让你看看这个地方:

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

这里才是 Spring 关于这个漏洞的官宣。

内容比较多,我就不给大家逐一翻译了。
只是给大家看看这个地方:

这里说了两件事,相称于“辟谣”。

第一个是关于我之前文章中提到的废弃 SerializationUtils 方法。

你看我之前的文章说的还是“疑似瓜”,解释我还是比较严谨的。

官方的博客说:

The deprecation is unrelated to this vulnerability.

弃用与此漏洞无关。

幸好我在之前的文章里面说了:

这不,打脸来的那么快。
但是没紧要,吃瓜嘛,愉快最主要,挨几巴掌,不寒碜。

第二个事情是说这段韶光 Spring Cloud Function 也爆出了一个高危漏洞,但是这个漏洞是在 Spring 漏洞之前爆出来的。

官方的说法是:

It is also unrelated.

这两者之间这也是不干系的。

以是,大家在吃瓜的时候要看准方向,被别一些司机带错路了,假瓜吃的津津有味,自己还不知道。

然后,在我写文章的时候,这个官方博客也在不断的更新:

可以看到在 14:00 更新了这个漏洞报告:

https://tanzu.vmware.com/security/cve-2022-22965

在这个报告里面,再次明确了这个漏洞的先决条件:

必须是 JDK 9+ 的版本。
必须是 Apache Tomcat 作为 Servlet 容器。
必须因此 war 的形式打包。
必须是依赖了 spring-webmvc 或 spring-webflux。

我想第一个条件,就让一大批人放心了。
至少这波,不用加班加点的升级修复了。

可以安心吃瓜。

开始复现

额,这么写到这里了都还没有进入正题呢。

好吧,我想闲扯的基本上也就扯完了,下面开始搞事情。

让我们回到这个地方:

你访问下面这个链接,可以直接拿到这个 pdf:

https://sizeof.cat/post/springcore-rce/files/readme.pdf

打开这个 pdf 之后,你可以看到如果要复现漏洞,哀求条件是这样的:

你仔细思考,实在这些条件都在 Spring 官宣的先决条件内。

先不必纠结于此,紧张记住我框起来的这两个点,然后直接看下面的重点。

在漏洞剖析里面,他提到了一句话,是重中之重:

由于我以为须要使⽤的参数内,存在⼀个 Class 类型的属性。

什么意思呢?

便是假设我们定义一个要求工具,叫做 UserReqDto,是这样定义的:

里面有一个 Class 类型的属性,便是这个意思。

确实,我纵横开拓界这么久,就没有见过要求工具里面哀求传 Class 的。

但是他给出了这样的一个示例:

分别有两个工具,EvalBean 和 CommonBean。

个中 CommonBean 是 EvalBean 的一个属性。

这样的定义就非常的常见了吧,项目里面一抓一大把。

然后还记得我前面框起来的两个点吗?

这啥意思?

上个代码你就看的明明白白的:

这写法便是“Spring 的参数绑定”,这不便是我们常规的写法吗?没有看到任何欠妥的地方呀?

是的,没有看到任何欠妥的地方。

但是,如果你这样的代码对应的运行环境和办法,知足了前面官方提到的先决条件。

那么恭喜你,便是有漏洞的。

你就仔细想想,是不是细思极恐?

那么对应的事理是啥呢?

大佬在 PDF 里面指了个路:

意思便是在前面的示例代码中,要求工具中虽然没有 class 熟习,但是在 Spring 进行参数绑定的时候会凭空多出一个 “class” 属性。

那么为什么会多出来呢?

我不知道,我也没去深入研究。
大概是由于反射的时候获取 bean 信息会处理所有以 get 开头的方法,以是 getClass 方法被映射成了 class 属性。

然后再想一想为什么是 JDK 9+ 往后才有这个问题呢?

我也不知道,但我盲猜一波是由于“模块化”这个东西。

我不知道,我也没去研究。
反正路指给你了,你想深入的话,可以从这条路走。

那么到底怎么发起攻击呢?

PDF 里面也写了。

你只要把代码打个 war 包,然后运行在对应的环境中,并实行下面这五个要求:

就能在项目的 out 文件夹中写入一个 jsp:

写入 jsp 文件啊!

老铁,这可是写入了一个 jsp 文件啊!

我不知道你有没有经历过 jsp 文件写页面的那个时期,我以前写过。

我当年特殊喜好这个东西,由于它支持热支配,修正了 jsp 页面的内容,都不用重启的。

以是,我喜好通过 jsp 页面留下一点方便我对项目进走运维的后门操作。

后门是啥,详细就不详说了。

如果你知道 jsp 的威力,你就能明白这句话的分量是多大:

这可是由别人通过布局特定的要求写入了一个 jsp 文件在你的项目里面啊!

但是我必须要补充一句,如果你也想复现这个漏洞,最关键的是前面提到的“五个要求”。

但是在 pdf 里面,这五个要求的内容实在是不全的,大概缺失落了 30% 的内容。

我不知道为什么,但是我预测是作者故意的。

然后,凭借我超强的悟(瞎)性(猜),我花了一点韶光,补全了这部分的要求。

以是,我本地也写入了这个 jsp 文件:

万事俱备,只须要触发一下了。

怎么触发呢?

jsp 页面还能怎么触发,大略的一比嘛。

直接访问对应链接就可以了:

我能吊起打算器,我就能接管你的机器。

而在这个过程中,掌握台不会有任何输出:

但是还是能处理正常的要求,且打印日志:

潜入细无声,我就问你,怕不怕!

p1n93r

从 PDF 上看,是一个叫做 p1n93r 写的这个 PDF,并且把干系测试代码开源了:

但是在我看到这篇文章并点击这个开源项目的时候,创造已经 404 了:

乃至,p1n93r 也已经 404 了:

然后我搜索了一下这个关键词:

确认这是一个安全大佬。

我的搜索就止步于此了,很明显,他主动删除了干系的项目,乃至主动让自己在 github 上消逝,便是不想引起关注。

这让我想起了和其余一个安全大佬的对话:

对付一个安全大佬来说,静默,便是最好的生存之道。