前言

这是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.templatethis.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表达式注入漏洞复现与原理分析的更多相关文章

  1. SpEL表达式注入漏洞学习和回显poc研究

    目录 前言 环境 基础学习和回显实验 语法基础 回显实验 BufferedReader Scanner SpEL漏洞复现 低版本SpringBoot中IllegalStateException CVE ...

  2. 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或以上版本 ...

  3. 【Android漏洞复现】StrandHogg漏洞复现及原理分析_Android系统上的维京海盗

    文章作者MG1937 CNBLOG博客:ALDYS4 QQ:3496925334 0x00 StrandHogg漏洞详情 StrandHogg漏洞 CVE编号:暂无 [漏洞危害] 近日,Android ...

  4. nginx CRLF(换行回车)注入漏洞复现

    nginx CRLF(换行回车)注入漏洞复现 一.漏洞描述 CRLF是”回车+换行”(\r\n)的简称,其十六进制编码分别为0x0d和0x0a.在HTTP协议中,HTTP header与HTTP Bo ...

  5. Java框架之MybatisSQL注入漏洞

    一.SQL注入漏洞基本原理 在常见的web漏洞中,SQL注入漏洞较为常见,危害也较大.攻击者一旦利用系统中存在的SQL注入漏洞来发起攻击,在条件允许的情况下,不仅可以获取整站数据,还可通过进一步的渗透 ...

  6. 【漏洞复现】CVE-2022–21661 WordPress核心框架WP_Query SQL注入漏洞原理分析与复现

    影响版本 wordpress < 5.8.3 分析 参考:https://blog.csdn.net/qq_46717339/article/details/122431779 在 5.8.3 ...

  7. Atlassian JIRA服务器模板注入漏洞复现(CVE-2019-11581)

    0x00 漏洞描述 Atlassian Jira是澳大利亚Atlassian公司的一套缺陷跟踪管理系统.该系统主要用于对工作中各类问题.缺陷进行跟踪管理. Atlassian Jira Server和 ...

  8. CVE-2020-15778 OpenSSH命令注入漏洞复现

    一.漏洞概要 OpenSSH 8.3p1及之前版本中的scp允许在scp.c远程功能中注入命令,攻击者可利用该漏洞执行任意命令.目前绝大多数linux系统受影响. 参考链接:https://githu ...

  9. 【漏洞复现】Struts2-045分析(CVE-2017-5638)

    如果需要大佬写好的脚本,可以直接去github上面搜 struts2 - 045 一个还比较出名的漏洞,因为涉及到利用Gopher协议反弹shell,所以写篇文章来简单学习下这个漏洞. Struts2 ...

随机推荐

  1. 关于javascript中this

    ------------恢复内容开始------------ 1 var number = 5; 2 var obj = { 3 number: 3, 4 fn1: (function () { 5 ...

  2. 技术分享 | innodb_buffer_pool_size为什么无法调低至1GB以内

    前言 innodb_buffer_pool_size可以调大,却不能调小至1GB以内,这是为什么? MySQL 版本:5.7.30 测试环境有台 MySQL 服务器反应很慢,检查系统后发现内存使用量已 ...

  3. 常用类--String

    一.String 1.1 String是不可变对象 String的底层是一个 char类型字符数组 String类是final修饰的,不能被继承,不能改变,但引用可以重新赋值 String采用的编码方 ...

  4. 209. 长度最小的子数组--LeetCode

    来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/minimum-size-subarray-sum 著作权归领扣网络所有.商业转载请联系官方授权,非商业 ...

  5. js运算符和逻辑分支

    运算符 1.拼接运算符:+,加号两边只要有一边出现字符串就是拼接 2.算术运算符  如:2+3: 3.赋值运算符+=,-=,/=,*= 4.关系运算符>,<,==,=== != !== ! ...

  6. anltr 解析MYSQL

    String sql = "select a as c,b as s,'zhange' F, 1/5 as e from t_order"; final MysqlQueryLex ...

  7. python九周周末总结

    python九周周末总结 UDP协议 udp协议的交互模式服务端不需要考虑客户端是否退出,你发多少那么他就会按照你发的东西直接去传输给客户端不存在黏包现象 服务端: import socket ser ...

  8. 2020牛客NOIP赛前集训营-提高组(第二场)- B.包含 (FWT)

    题面 题解 这题就是个快速沃尔什变换的模板题,输入ai时,令s[ai]=1,对s[]做一遍DWT_AND(s)(快速沃尔什正变换,按位与),然后直接访问s[x]完事. #include<map& ...

  9. 第五十一篇:webpack中的loader(二) --less-loader

    好家伙 先扩充一下知识点: 什么是.less文件? 作为一名前端开发的同学,很多时候我们都无法避免地要去写大量的 CSS 代码, 而且耗费的时间还不少,所以学习一种能够提升开发效率的 CSS 预处理器 ...

  10. C语言小游戏:贪吃蛇

    #include <graphics.h> #include <conio.h> #include <stdio.h> #define WIDTH 40 //设置宽 ...