前言: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处理流程不同