一、漏洞概述
“由於Spring Cloud Function中RoutingFunction類的apply方法將請求頭中的“spring.cloud.function.routing-expression”參數作為Spel表達式進行處理,造成了Spel表達式注入漏洞,攻擊者可利用該漏洞遠程執行任意代碼。”
二、影響范圍
3.0.0.RELEASE <= Spring Cloud Function <= 3.2.2
三、漏洞復現
在漏洞官網GitHub上給出了修復commit
可以看到官網給出的poc代碼如下:
SpringCloud Function會直接將其參數內容直接帶入到SPEL中查詢,造成SPEL漏洞注入。
這里我用https://github.com/jwwam/scfunc項目簡單的搭建環境
該項目是用的2.0.2版本,不在影響范圍內,因此還要修改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.5.5</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.zyq</groupId> <artifactId>scfunc</artifactId> <version>0.0.1-SNAPSHOT</version> <name>scfunc</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>Greenwich.SR2</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-function-context</artifactId> <version>3.1.4</version> </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-web</artifactId> <version>3.1.4</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-deploy-plugin</artifactId> <configuration> <skip>true</skip> </configuration> </plugin> </plugins> </build> </project>
這里構造惡意請求訪問RoutingFunction功能
四、漏洞原理分析
漏洞是出在SpringCloud Function的RoutingFunction功能上,其功能的目的本身就是為了微服務應運而生的,可以直接通過HTTP請求與單個的函數進行交互,同時為spring.cloud.function.definition參數提供您要調用的函數的名稱。
拿之前的scfunc項目舉個例子
我有一個反轉字符串的函數,我如果想調用它,我可以通過如下請求來訪問
POST /functionRouter HTTP/1.1 Host: localhost:8080 spring.cloud.function.definition: reverseString Content-Type: text/plain Content-Length: 3 abc
接下來就系好安全帶,准備開始正文分析了
根據上述所說,漏洞是存在與header頭的spring.cloud.function.routing-expression參數
我們就開始從SpringCloud Function的Controller處理來一步步往下跟入。
在org.springframework.cloud.function.web.mvc.FunctionController#post方法上下斷點
程序會獲取body中的參數,並傳入processRequest方法中
最后進入到org.springframework.cloud.function.context.config.RoutingFunction#route方法中
並將結果帶入到this.functionFromExpression()方法中
最終直接由SpelExpressionParser來解析,導致Spel表達式注入。
其中的this.headerEvalContext變量就是由SimpleEvaluationContext來解析的。
Reference
[1].http://blog.nsfocus.net/spring-cloud-function-spel/
[4].https://blog.csdn.net/zhulier1124/article/details/100133932