电脑疯子技术论坛|电脑极客社区

微信扫一扫 分享朋友圈

已有 1288 人浏览分享

Spring SPEL表达式注入

[复制链接]
1288 0
本帖最后由 zhaorong 于 2021-10-23 14:43 编辑

JAVA SPEL表达式注入

一、SPEL 简介

​Spring 表达式语言(简称 SpEL)是一种强大的表达式语言 支持在运行时查询和操作对象图语言语
法类似Struts2 的OGNL。但提供了额外的功能,最显着的是方法调用和基本的字符串模板功能这
进而也可能导致模板注入。

093939e9ni6zn89dknznso.png.thumb.jpg

虽然还有其他几种可用的 Java 表达式语言 OGNL、MVEL 和 JBoss EL 但创建 Spring 表达式语言的目的是为 Spring社
区提供一种受良好支持的表达式语言。该语言可以在所有产品中使用。它的语言特性由 Spring 组合中项目的需求驱动包
括基于 Eclipse 的 SpringSource 工具套件中代码完成支持的工具需求。也就是说,SpEL 基于与技术无关的 API 它不直
接与 Spring 相关联,可以独立使用。SPEL需要引入一些基础类,例如解析器。大多数 Spring 用户不需要引入该类包只
需要编写表达式字符串然后.Eval()调用。

主要的对象如下:

QQ截图20211023142619.png

二、SPEL 注入介绍

​最早研究SPEL表达式注入在2012年12月14日 danamodio.com 研究Spring框架漏洞时发现SPEL存
在注入风险在2012年。SPEL相对于其他几种表达式语言,使用面相对较窄 但是这些年Spring框架
被广泛推广。SPEL越来越具有研究的价值。

Spring 表达式语言注入(SPEL 注入)发生在攻击者可以部分或全部控制数据到表达式语言输入。SPEL语言可以支持
查询并可以在运行时操作对象图。这可能有些难理解,但联想一下JSP表达式语言,JavaServer Pages 允许使用诸如
${name} 之类的语法来访问 bean 以获取简单变量 。换言之,通过攻击者控制 SPEL 语法/查询并注入未经处理的数
据 他们可以恶意提取敏感信息或在应用程序上下文中运行任意代码。

SpEL使用 #{…} 作为定界符,所有在大括号中的字符都将被认为是 SpEL表达式,我们可以在其中使用运算符变量
以及引用bean,属性和方法如:引用其他对象:#{car},调用其它方法 , 还可以链式操作:#{car.toString()}。
除引用对象,SPEL还有更强大的功能 使用T()运算符会调用类作用域的方法和常量使用T()运算符#{T(java.l
ang.Math)}该T()运算符的结果会返回一个java.lang.Math类对象。

三、SPEL 漏洞样例

​在SQL注入中攻击者通过传递非法变量,修改了SQL语句原定义的查询结构SPEL注入的漏洞
形态更像是命令注入因此SPEL漏洞归为命令注入类。

样例1
  1. @RequestMapping("/me")
  2. public String spel(String iss) {
  3.     SpelExpressionParser parser = new SpelExpressionParser();
  4.     Expression expression = parser.parseExpression(iss);
  5.     return expression.getValue().toString()+"   Done!";
  6. }
复制代码

样例1代码将输入的iss参数作表达式解析的参数 在解析过程中将造成命令执行。
  1. /me?iss={T(java.util.Arrays).toString(T(java.nio.file.Files).list(T(java.
  2. nio.file.Paths).get('d:\i4Tools7')).toArray())}
复制代码

093940z0t39sl6t6m2j05c.png

样例2
  1. RequestMapping("/you")
  2. public String test(String cc) throws IOException {
  3.     SpelExpressionParser parser = new SpelExpressionParser();
  4.     Expression exp = parser.parseExpression("T(java.lang.Runtime).getRuntime()");
  5.     Runtime value = (Runtime) exp.getValue();
  6.     return value.exec(cc).toString();
  7. }
复制代码

在样例2中SPEL执行后返回类对象Object 然后再调用类中方法或属性在SpEL中直接使用
某个类名时(省略包名)此类必须在java.lang 包中。否则需要提供全名。

093940rzfaf2k1dmzqkksz.png.thumb.jpg

四、SPEL 历史漏洞

CVE-2018-1270

Spring框架中的 spring-messaging 模块提供了一种基于WebSocket的STOMP协议实现
STOMP消息代理在处理客户端消息时存在SpEL表达式注入漏洞,攻击者可以通过构造恶
意的消息来实现远程代码执行。

CVE-2018-1275


​由于官方修补漏洞后其发布流程及代码管理上犯低级错误,导致4.3.14-4.3.15版本升级中该漏洞
所涉及文件并未更新 所以在更新的版本中CVE-2018-1270并未修复,漏洞依然存在 进而有
CVE-2018-1275漏洞 在4.3.16版本中再次得到修复。

影响版本

Spring Framework 5.0 to 5.0.4
Spring Framework 4.3 to 4.3.14

环境搭建

https://github.com/spring-guides/gs-messaging-stomp-websocket

22.jpg

POC构造

​篡改前端app.js中Websocket connect函数中,插入恶意selector代码,PoC如下:

var header  = {"selector":"T(java.lang.Runtime).getRuntime().exec('calc.exe')"};

21.jpg

保持JS文件后  回到Web界面上重新Connect,然后Send若干任意字符即可触发服务端执行漏洞。

20.jpg

漏洞成因

​在 package org.springframework.messaging.simp.broker.class 第82行,对header参数处理:

String selector = Sim*.getFirstNativeHeader(this.getSelectorHeaderName(), headers);

expression = this.expressionParser.parseExpression(selector);

当参数传递到org.springframework.messaging.simp.broker#filt

erSubscriptions()执行.getValue()时触发漏洞。

19.jpg

务场景

​Spring Messaging模块用于消息处理,在业务中常和RocketMQ搭配使用。如在代码审计中遇到Rocket
MQ-Spring协同案例,可重点关注项目pom 文件版本依赖org.springframework.boot  判断是否为漏洞
版本若为漏洞版本。再继而跟踪 GreetingController#greeting()。

修复方法

​将pom.xml中的org.springframework.boot设置为2.0.1版本或更新版本。
  1. ...
  2.     <parent>
  3.     <groupId>org.springframework.boot</groupId>
  4.     <artifactId>spring-boot-starter-parent</artifactId>
  5.     <version>2.0.1.RELEASE</version>
  6.     </parent>
  7. ...
复制代码

五、修复

​SimpleEvaluationContext、StandardEvaluationContext 是 SpEL 提供的两个 EvaluationContext
使用 SimpleEvaluationContext 替换 StandardEvaluationContext,可有效防止SpEL滥用。
StandardEvaluationContext - 拥有全套 SpEL 语言功能和配置选项。您可以使用它来指
定默认的根对象并配置每个可用的评估相关策略。
SimpleEvaluationContext - 针对不需要 SpEL 语言语法的全部范围并且应该受到有意限制的表达
式类别它不包括 Java 类型引用,构造函数和 bean 引用。

六、小结

​SPEL表达式较为灵活,其可以很好地适配业务中 经常变化 的部分 这可能是 业务规则 也可能是
不同的数据处理逻辑常见的SPEL实现资源的注入有如:调用各种资源的情况 包含普通文件 网址
配置文件 系统环境变量。

在审计中 可使用关键字加快进展,如org.springframework.expression.spel.standard
expression.getValue(),expression.setValue() 。
在项目中运用Spel技术的开发人员编程水平通常较高 也正是这种巧妙运用。使得漏洞较为隐蔽较难实
现一致性修复。需要安全人员付出足够耐心去寻找查核修复完成情况。

您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

关注

0

粉丝

9021

主题
精彩推荐
热门资讯
网友晒图
图文推荐

Powered by Pcgho! X3.4

© 2008-2022 Pcgho Inc.