写点什么

漏洞挖掘之 Spring Cloud 注入漏洞

  • 2022 年 4 月 14 日
  • 本文字数:2377 字

    阅读完需:约 8 分钟

漏洞描述

Spring 框架为现代基于 java 的企业应用程序(在任何类型的部署平台上)提供了一个全面的编程和配置模型。


Spring Cloud 中的 serveless 框架 Spring Cloud Function 中的 RoutingFunction 类的 apply 方法将请求头中的“spring.cloud.function.routing-expression”参数作为 Spel 表达式进行处理,造成 Spel 表达式注入,攻击者可通过该漏洞执行任意代码。

利用条件

3.0.0.RELEASE <= Spring Cloud Function <= 3.2.2

环境搭建

在官方网页新建一个 Spring boot 项目(https://start.spring.io/)、使用 idea 启动。



修改 pom.xml 配置文件


<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.5</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>demo</artifactId><version>0.0.1-SNAPSHOT</version><name>demo</name><description>Demo project for Spring Boot</description><properties><java.version>17</java.version><spring-cloud.version>2021.0.1</spring-cloud.version></properties><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-function-context</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-task</artifactId></dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-function-webflux</artifactId></dependency>
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-function-dependencies</artifactId><version>3.2.2</version><type>pom</type></dependency>
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-function-web</artifactId><version>3.2.2</version></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>
<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
复制代码


最后访问 http://127.0.0.1:8080. 出现以下页面表示成功。


【一>所有资源获取<一】1、很多已经买不到的绝版电子书 2、安全大厂内部的培训资料 3、全套工具包 4、100 份 src 源码技术文档 5、网络安全基础入门、Linux、web 安全、攻防方面的视频 6、应急响应笔记 7、 网络安全学习路线 8、ctf 夺旗赛解析 9、WEB 安全入门笔记


漏洞复现

漏洞原理

apply 方法会将 http 头部中的 Spel 表达式进行解析,从而造成 Spel 表达式注入。


查看官方diff




进入 springframework/cloud/function/context/config/RoutingFunction 文件。进入调试模式、将断点添加到 apply()方法。



进入到 apply()方法后、会调用 route() 在该方法中会去判读 input 是否为 message 的实例,function 是否为空、然后进入 else if 去获取头信息、获取 key 值 spring.cloud.function.routing-expression 、在中间会对有无空格做判断。然后继续向下走。



会进入到 springframework/cloud/function/context/config/RoutingFunction/functionFromExpression()方法。



routingExpression 会做为参数传入到 springframework/expression/common/TemplateAwareExpressionParser/parseExpression()方法中。



判读其 context 是否为 none 值 在进入


springframework/expression/spel/standard/SpelExpressionParser/doPareExpression() 会 new 一个 InternalSpelExpressionParser 类调用 doPareExpression() 继续跟进。



在 springframeworl/expression/spel/stand/InternalSpelExpressionParser/doParseExpression()方法中、会在 tokenizer.process()中 对 token 进行 源码与字节码的判断操作、继续向下。



会 new 一个 SpelExpression() 跟进到


springframwork/expression/spel/standard/SpelExpression/SpelExpression()。



SpelExpression()方法中会将将表达式赋值到this.expression继续跟进 return 到 springframework/expression/spel/standard/SpelpressionParser/doParseExpression()、继续 return 到springframework/expression/common/TemplateAwareExpressionPareser/pareExpression()、return springframework/cloud/function/context/config/RoutingFunction/functionFromExpression()



在 functionFromExpression()方法中会进入 MessageUtils.toCaseInsensitiveHeadersStructure()。



调用 MessageStructureWithCaseInsensitiveHeaderKeys(),进入到 putAll()方法 获取 message 中头信息。



最后会进入漏洞触发点。


漏洞测试

Payload 的构造可以参考官方测试用例。



本次利用创建文件测试。使用 payload touch /tmp/xxxxxx.test.test。




用户头像

我是一名网络安全渗透师 2021.06.18 加入

关注我,后续将会带来更多精选作品,需要资料+wx:mengmengji08

评论

发布
暂无评论
漏洞挖掘之Spring Cloud注入漏洞_网络安全_网络安全学海_InfoQ写作平台