继 Log4j 2 之后,听闻 Java 再次遭到漏洞攻击,这一次,似乎情况也更为严重,因为受到影响的是 Java 平台的开源全栈应用程序框架和控制反转容器实现——Spring 家族,而且网传漏洞还不止一个。
一直以来,Spring 是编程开发的必选技术之一,此前一位名为 Bogdan N. 的全栈开发者甚至评价道:“学习 Java、学习 Spring 框架,你永远都不会失业。”
可想而知,如果 Spring 城门失火,Java 必定遭殃。不过,Spring RCE 漏洞在网络上炒了两天,虽然有不少安全圈人员纷纷发圈,但更多的还是表示了只是听闻,这也不禁让人质疑,是真有漏洞,还是虚惊一场?
接下来,本文将盘点一下这两天 Spring 的“大”漏洞。
第一个:真的 Spring Cloud Function SPEL RCE
3 月 26 日,据网络安全网站 Cyber Kendra 报道,Spring Cloud Function 官方测试用例曝光了 Spring Cloud Function SPEL(Spring Expression Language)表达式注入漏洞,黑客可利用该漏洞注入 SPEL 表达式来触发远程命令执行。
漏洞发现过程
起初,研究人员在分析 Spring Cloud 函数的 main 分支(https://github.com/spring-cloud/spring-cloud-function/commit/dc5128b80c6c04232a081458f637c81a64fa9b52)时,发现有开发者向其中添加了 SimpleEvaluationContext 类。还使用了 isViaHeadervariable 作为标志,在解析 spring.cloud.function.routing-expression 之前判断的值取自 HTTP header。
spring.cloud.function.routing-expression 的参数存在于访问 Spring Cloud Function 的 HTTP 请求头中,其 SpEL 表达式可以通过 StandardEvaluationContext 注入并执行。这使得攻击者可以利用这个漏洞进行远程命令执行。
Spring Cloud Function 的应用
当前,Spring Cloud Function 被许多科技巨头应用于产品中,包括 AWS Lambda、Azure、Google Cloud Functions、Apache OpenWhisk 以及许多 Serverless 服务提供商。
根据官方文档,Spring Cloud Function 是基于 Spring Boot 的函数计算框架,它可以:
通过函数促进业务逻辑的实现。
将业务逻辑的开发生命周期与任何特定的运行时目标分离,以便使用相同的代码可以作为 Web 端点、流处理器或任务运行。
支持跨 Serverless 提供商的统一编程模型,具备独立运行(本地或在 PaaS 中)的能力。
在 Serverless 上提供程序上启用 Spring Boot 功能(自动配置、依赖注入、指标)。
简而言之,Spring Cloud Function 通过抽象传输细节和基础设施,为开发者保留熟悉的开发工具和开发流程,让开发者专注于实现业务逻辑,从而提高开发效率。
影响
目前,Spring Cloud Function SPEL 漏洞已被归类为严重等级,CVSS(通用安全漏洞评分系统) 得分为 9.0(满分 10)。
不过,开发者也无须太过担心,因为只有 Spring Cloud Function 的某些版本特定配置(3.0.0.RELEASE <= Spring Cloud Function <= 3.2.2)的动态路由受到影响,受影响的版本发布时间在 2019 年 11 月 22 日至 2022 年 2 月 17 日。
此外,官方也针对漏洞发布修复补丁:https://github.com/spring-cloud/spring-cloud-function/commit/0e89ee27b2e76138c16bcba6f4bca906c4f3744f
以及发布了最新的 3.1.7 和 3.2.3 版本:https://github.com/spring-cloud/spring-cloud-function/tags
第二个:网传比 Spring Cloud Function RCE 更为严重的 Spring RCE
相比前者,3 月 29 日晚间,有不少网友爆料的 Spring RCE 漏洞,让开发者圈中人心惶惶。
不过有些不同寻常的是,这个漏洞目前并没有像 Log4j2 事件那样引起的圈内诸多企业大厂的紧急行动,也不像 Spring Cloud Function SPEL 漏洞那样有官方说明,甚至连国外披露漏洞的根源也是来自 QQ 和国内部分网络安全网站。
这也让不少网友猜测,该漏洞应该是国内某个安全机构、安全人员最先发现的。这不,有网友将该漏洞发布到了 GitHub 上(目前已删除,但有网友将该页面保存了下来):
来源:https://archive.ph/DIbrv
根据网传的内容显示:
Spring 框架出现的 RCE 0day 漏洞影响的范围为 JDK 版本号在 9 及以上的、使用了 Spring 框架或衍生框架。
目前,随着该网传漏洞的暗流涌动,国外不少网络安全研究人员和安全公司也发布 Twitter 表示这一漏洞的存在:
他们也将该漏洞称之为 Spring4Shell,猜测是由传递参数的不安全反序列化引起的。
Spring 零日漏洞真的存在?
针对网传的内容,全球领先的安全风险信息解决方案提供商 Rapid7 通过《Spring4Shell: Zero-Day Vulnerability in Spring Framework》一文也对外确认零日漏洞是真实存在的。
其在文章中表示,该漏洞似乎影响了使用 @RequestMapping 注解和 POJO(Plain Old Java Object)参数的函数。与此同时,Rapid7 还通过 Springframework MVC 进行了演示(https://www.rapid7.com/blog/post/2022/03/30/spring4shell-zero-day-vulnerability-in-spring-framework/):
这里有一个控制器 ( HelloWorldController),当它被加载到 Tomcat 中时,它将为 http://name/appname/rapid7 中处理 HTTP 请求。处理请求的函数被称之为 vulnerable,而且还有一个 POJO 参数 HelloWorld。在这里,HelloWorld 被简化了,但如果需要,POJO 可能会变得非常复杂 :
基于此,Rapid7 表示,“如果我们编译该项目,并将其托管在 Tomcat 上,我们就可以用下面的 curl 命令来利用它。请注意,下面使用的有效载荷与研究人员创建的原始概念证明所使用的完全相同。”
这个有效载荷在 Tomcat ROOT 目录下投放了一个受密码保护的 webshell,名为 tomcatwar.jsp,它看起来像这样:
然后,攻击者可以调用命令。下面是一个执行 whoami 以获得 albinolobster 的例子:
通过测试,Rapid7 发现在 OpenJDK 1.8.0_312 上的测试失败了,但 OpenJDK 11.0.14.1 有作用。
临时修复方案
目前由于 Spring 官方尚未发布最新说明,无法确定哪些应用程序使用了有漏洞的功能,这也导致但凡和 Spring 沾点关系的功能,开发者都要问上一句「是否涉及 Spring Core 的 RCE 0day 漏洞」。
不过,据外媒 BleepingComputer 报道,这个漏洞虽然会影响到 JDK 版本号在 9 及以上的、使用了 Spring 框架或衍生框架,但是也有特定的前提条件。
同时,也有不少网友调侃道:
别慌,虽然现在 Java 已经到了 Java 18 版本,但是很多企业仍然停留在 Java 8 版本及以下。
不同的安全漏洞,也让 Java 工程师产生了严重的心理阴影:
对于开发者、企业而言,当前也不用自乱阵脚,不过,为了避免一定的风险,可以做的就是先排查一下自己的 JDK 版本以使用 Spring 框架或衍生框架 的情况,如果版本在 JDK 8 及以下,则不受漏洞的影响。
此外,根据 rapid 7、国内的北京大学计算中心等渠道给出的临时修复方案,大家也可以尝试一波:
在应用中全局搜索@InitBinder 注解,看看方法体内是否调用dataBinder.setDisallowedFields 方法,如果发现此代码片段的引入,则在原来的黑名单中,添加 {"class.*", "Class. *", "*. class.*", "*.Class.*"}。
注:如果此代码片段使用较多,需要每个地方都追加。
在应用系统的项目包下新建以下全局类,并保证这个类被Spring 加载(推荐在Controller 所在的包中添加)。完成类添加后需对项目进行重新编译打包和功能验证测试,并重新发布项目。
import org.springframework.core.annotation.Order;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
@ControllerAdvice
@Order(10000)
public class GlobalControllerAdvice{
@InitBinder
public void setAllowedFields(webdataBinder dataBinder){
String[]abd=new string[]{"class.*","Class.*","*.class.*","*.Class.*"};
dataBinder.setDisallowedFields(abd);
}
}
最后,静待官方消息。
参考资料:
https://www.cyberkendra.com/2022/03/rce-0-day-exploit-found-in-spring-cloud.html
https://its.pku.edu.cn/announce/tz20220330110501.jsp
https://github.com/spring-projects/spring-framework/commit/7f7fb58dd0dae86d22268a4b59ac7c72a6c22529
https://www.bleepingcomputer.com/news/security/new-spring-java-framework-zero-day-allows-remote-code-execution/
https://www.rapid7.com/blog/post/2022/03/30/spring4shell-zero-day-vulnerability-in-spring-framework/
END
《新程序员001-004》全面上市,对话世界级大师,报道中国IT行业创新创造
— 推荐阅读 —
—点这里↓↓↓记得关注标星哦~—
一键三连 「分享」「点赞」「在看」
成就一亿技术人