SpringBoot框架SpEL表达式注入漏洞复现与原理分析
前言
这是2016年的一个洞,利用条件是至少知道一个触发 springboot 默认错误页面的接口及参数名。
影响版本:1.1.0-1.1.12 1.2.0-1.2.7 1.3.0
修复方案:升级版本
环境搭建
下载链接:https://github.com/LandGrey/SpringBootVulExploit/tree/master/repository/springboot-spel-rce
用idea打开之后配置一下,如下图:

然后启动访问出现如下页面,代表搭建成功。

漏洞复现
访问:http://localhost:9091/article?id=${9*9} ,可以发现${9*9}的SpEL表达式进行了解析,随后将该表达式的运行的结果进行了返回,如下图。

现在尝试弹出计算器,访问:http://localhost:9091/article?id=${T(java.lang.Runtime).getRuntime().exec(new String(new byte[]{0x63,0x61,0x6c,0x63}))}
成功弹出,如下图:

调试分析
为什么会出现这情况呢,这是因为springboot返回错误页面的时候提供了详细信息,这些信息包括
错误status("status"->500)、时间戳("timestamp"->"Fri Dec.....")、错误信息("error"->"Internal Server Error")、和用户输入的参数("message"->"test"),然后后端渲染视图时,会解析错误模板中的参数名。然后拿到对应的参数值,通过函数检查参数值中是否存在${},如果存在则去除,然后传入SpEL引擎进行解析。模板内容如下所示:
<html>
<body>
<h1>Whitelabel Error Page</h1>
<p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p>
<div id='created'>${timestamp}</div>
<div>There was an unexpected error (type=${error}, status=${status})</div>
<div>${message}</div>
</body>
</html>
程序会判断模板中每个${}的位置,然后将参数名一个一个取出来后传入spel引擎,解析参数名对应的值。这里就是漏洞的触发点,假如我输入${payload},spel取出来payload后进行解析,然后触发漏洞。触发点如下:

浏览器访问http://localhost:9091/article?id=${T(java.lang.Runtime).getRuntime().exec(new%20String(new%20byte[]{0x63,0x61,0x6c,0x63}))},现在开始调试,首先会将map的值传入,context的rootObject中,之后以this.template和this.resolver为参数调用replacePlaceholders方法,如下图:

this.template的内容就是上文的错误模板,跟进replacePlaceholders方法 ,进入PropertyPlaceholderHelper文件。
继续跟进parseStringValue方法


分析一下代码,首先StringBuilder将strVal转为字符串,并赋值给result,接着判断result中${和}位置,结果为157、168,然后通过substring截取157和168的中间值,并赋值给placeholder,本次的值为"timestamp",然后将placeholder作为第一个参数,再次调用本方法。结果如下图:

strVal的值变为timestamp,所以在indexOf判断时,由于没出现${,所以变为了-1,跳过了while循环,直接执行下边的return result.toString();。
继续跟进,下一步是调用resolvePlaceholder方法,此函数的作用是查找this.context中对应参数的值并返回,如下图:

发现拿到了时间戳"timestamp" -> "Wed Oct 19 00:38:36 CST 2022",然后赋值给propVal,此时不为空,进入下一个if循环,再次调用parseStringValue。
接着进行replace替换,将原来的${timestamp}处的值替换成了 Wed Oct 19 00:38:36 CST 2022,最后return result.toString();返回,如下图:

然后寻找template中的下一个参数位,这次的参数是error,流程与上面基本一样,这里不再细致分析。

接着第三个参数是status,同理

最后是第四个参数message,重点来了,这个值是用户输入的。接着分析,跟进parseStringValue方法

拿到message对应的值,也就是用户输入的payload

赋值给propVal,接着调用parseStringValue
这次调用去除了${}

最后进入resolvePlaceholder,成功执行T(java.lang.Runtime).getRuntime().exec(new String(new byte[]{0x63,0x61,0x6c,0x63})),弹出计算器,分析结束。

参考文章
https://www.cnblogs.com/litlife/p/10183137.html
https://www.cnblogs.com/zpchcbd/p/15536569.html
https://blog.csdn.net/haduwi/article/details/126326511
https://blog.csdn.net/weixin_54902210/article/details/124533353
SpringBoot框架SpEL表达式注入漏洞复现与原理分析的更多相关文章
- SpEL表达式注入漏洞学习和回显poc研究
目录 前言 环境 基础学习和回显实验 语法基础 回显实验 BufferedReader Scanner SpEL漏洞复现 低版本SpringBoot中IllegalStateException CVE ...
- SpringBoot SpEL表达式注入漏洞-分析与复现
目录 0x00前言 0x01触发原因 0x02调试分析 0x03补丁分析 0x04参考文章 影响版本: 1.1.0-1.1.12 1.2.0-1.2.7 1.3.0 修复方案:升至1.3.1或以上版本 ...
- 【Android漏洞复现】StrandHogg漏洞复现及原理分析_Android系统上的维京海盗
文章作者MG1937 CNBLOG博客:ALDYS4 QQ:3496925334 0x00 StrandHogg漏洞详情 StrandHogg漏洞 CVE编号:暂无 [漏洞危害] 近日,Android ...
- nginx CRLF(换行回车)注入漏洞复现
nginx CRLF(换行回车)注入漏洞复现 一.漏洞描述 CRLF是”回车+换行”(\r\n)的简称,其十六进制编码分别为0x0d和0x0a.在HTTP协议中,HTTP header与HTTP Bo ...
- Java框架之MybatisSQL注入漏洞
一.SQL注入漏洞基本原理 在常见的web漏洞中,SQL注入漏洞较为常见,危害也较大.攻击者一旦利用系统中存在的SQL注入漏洞来发起攻击,在条件允许的情况下,不仅可以获取整站数据,还可通过进一步的渗透 ...
- 【漏洞复现】CVE-2022–21661 WordPress核心框架WP_Query SQL注入漏洞原理分析与复现
影响版本 wordpress < 5.8.3 分析 参考:https://blog.csdn.net/qq_46717339/article/details/122431779 在 5.8.3 ...
- Atlassian JIRA服务器模板注入漏洞复现(CVE-2019-11581)
0x00 漏洞描述 Atlassian Jira是澳大利亚Atlassian公司的一套缺陷跟踪管理系统.该系统主要用于对工作中各类问题.缺陷进行跟踪管理. Atlassian Jira Server和 ...
- CVE-2020-15778 OpenSSH命令注入漏洞复现
一.漏洞概要 OpenSSH 8.3p1及之前版本中的scp允许在scp.c远程功能中注入命令,攻击者可利用该漏洞执行任意命令.目前绝大多数linux系统受影响. 参考链接:https://githu ...
- 【漏洞复现】Struts2-045分析(CVE-2017-5638)
如果需要大佬写好的脚本,可以直接去github上面搜 struts2 - 045 一个还比较出名的漏洞,因为涉及到利用Gopher协议反弹shell,所以写篇文章来简单学习下这个漏洞. Struts2 ...
随机推荐
- Apache DolphinScheduler&ShenYu(Incubating) 联合 Meetup,暖春 3 月与你相约!
云霞出海曙,梅柳渡江春. 2022 年的早春在疫情中显得格外生机勃勃,虽然接下来寒流仍有可能造访国内部分地区,但开源的世界,早已热闹非凡! 2022 年 3 月 26 日(星期六), Apache D ...
- 如何成为一名合格的Apache项目Committer,参与Apache开源贡献的正确姿势
近日,孙金城老师在 "Open Source Promotion Plan - Summer 2020" 开源软件供应链点亮计划做了<如何成为一名合格的Apache项目Com ...
- ceph 004 纠删码池 修改参数 cephx认证
复习ceph003 存储池为逻辑概念,存储池可以占用整个集群的所有空间 [root@ceph01 ~]# ceph osd pool create pool1 pool 'pool1' created ...
- mybatis 07: sql标签中 "#{}" 和 "${}" 的作用和比较
"#{}"占位符 作用 传参大部分使用"#{}",在数据库底层使用的是:PreparedStatement预编译处理对象 数据库底层被解析为"?&qu ...
- 急如闪电快如风,彩虹女神跃长空,Go语言高性能Web框架Iris项目实战-初始化项目ep00
在Golang Web编程的世界里,君不言高性能则已,言高性能必称Iris.彩虹女神的名号响彻寰宇.名动江湖,单论一个快字,无人能出其右,就连以简洁轻量著称于世的Gin也难以望其项背,只见彩虹女神Ir ...
- HCIA-Datacom 4.1 实验一:访问控制列表配置实验
实验介绍 访问控制列表ACL(Access Control List)是由一条或多条规则组成的集合.所谓规则,是指描述报文匹配条件的判断语句,这些条件可以是报文的源地址.目的地址.端口号等.ACL本质 ...
- Canvas 非线性图形(一):文本
基础 画布除了绘制图形以外还可以绘制文本,画布中的文本可以设置字体大小.字体格式.对齐方式(横向和纵向对齐方式),并且还可以制作很炫酷的文本,比如渐变文字. 文本有以下三个属性,控制文本的字体大小.字 ...
- 零基础学Java(14)对象构造
对象构造 之前学习了编写简单的构造器,可以定义对象的初始状态.但是,由于对象构造非常重要,所以Java提供了多种编写构造器的机制. 重载 有些类有多个构造器.例如,可以如下构造一个空的StringBu ...
- [CF1536F] Omkar and Akmar(博弈论?组合数学)
题面 [CF1536F] Omkar and Akmar 甲乙轮流在一个有 N N N 个位置的环上放字母(环上每个位置不同),每次可以放一个 A 或 B ,要求不能有相同的字母相邻,轮到某个人时不能 ...
- 内网技巧-通过SAM数据库获得本地用户hash的方法
内网技巧-通过SAM数据库获得本地用户hash的方法 在windows上的C:\Windows\System32\config目录保存着当前用户的密码hash.我们可以使用相关手段获取该hash. 提 ...