[备份]Tomcat JMXProxy利用方式

前言:在介绍该利用方式之前有必要先进行一些说明

(1)不影响默认配置的Tomcat但利用方式前置条件并非罕见

(2)该利用方式本身不属于Tomcat的安全问题,但存在安全风险

(3)该利用方式为利用链中的一环,配合第三方平台未授权访问或弱口令可以直接利用

 

JMX

JMXTomcat无关,在Java官方文档对于JMX的定义如下:

JMX(Java Management Extensions)是一个为应用程序植入管理功能的框架。JMX是一套标准的代理和服务,实际上,用户可以在任何Java应用程序中使用这些代理和服务实现管理。

用人话来说JMX让程序有被管理的功能,例如某Web网站是在24小时不间断运行,那么对网站进行监控是必要的功能;又或者在业务高峰的期间,想对接口进行限流,就必须去修改接口并发的配置值。

借用网上博客一张图:一般JMX会通过Adapter实现Web管理页面,例如ZabbixNagios等工具对于JVM的监控实现,老一些的平台比如JDMKMX4J等。

结合实例来讲,我搭建了一个MX4J的监控平台

进入其中的ClassLoading属性观察:监控到类的属性,并且部分值可以在运行时进行修改

在网上进行搜索可以发现大量类似的JMX管理页面,我们可以实时地修改JVM内部的一些属性

但这种修改大多数情况下是无意义的,顶多由于某些属性为空通过空指针导致拒绝服务这样的鸡肋洞

因此研究如何通过JMX修改变量以实现RCE是比较有意义的研究

 

Manager

Tomcat一直存在一个不是“漏洞”的漏洞:Tomcat Manager导致上传war解压生成webshellRCE

tomcat/conf/tomcat-users.xml配置

访问/manager/html输入用户名和密码,即可在里面上传war进行部署

显然这不归Tomcat负责,应该由用户保证自己的账号和密码安全

Tomcat对于Manager的管理页面采用了HTTP Basic认证,也就是用户名密码拼接后Base64编码

如果想要暴力破解这个身份认证其实是不太可能的,因为Tomcat已经考虑到这个问题:参考LockOutRealm类的代码,默认在输入错误5次后会锁定5分钟。这也是Tomcat官方拒绝该漏洞的原因之一

 

其实值得关心的是:Tomcat并不仅仅支持管理页面,同时支持APIJMXProxy(本文重点)

发现如果API可以未授权访问也会导致严重的安全问题

使用API的方式是:http://{host}:{port}/manager/text/{command}?{parameters}

使用API部署WAR包:

 

JMXProxy

接下来是本文的重点,在Tomcat Manager中还有一种特殊的管理:JMX Proxy Servlet

参考 Tomcat 9.0 官方文档 中的描述,翻译后为:

JMX Proxy Servlet是一个轻量级代理,用于获取和设置Tomcat内部或任何已通过MBean公开的类。它的使用不是非常用户友好,但对于集成命令行脚本以监视和更改Tomcat的内部结构非常有帮助。您可以使用代理做两件事:获取信息和设置信息。要真正了解 JMX Proxy Servlet,您应该对 JMX 有一个大致的了解。如果您不知道 JMX 是什么,那么请准备好被迷惑(不知道怎么解释confused这个词就用迷惑了)

直接阅读这段话可能不能够理解,通过开头对JMX概念的描述,应该问题不大。Tomcat提供了JMXAgent或者说API给用户,而用户一般不是直接手动管理,而是会选择第三方平台进行管理。

参考示例,例如我们需要监控运行时的堆内存使用情况

执行后得到的结果

不仅可以监控JVM属性也可以修改JVM中的一些属性,例如开头JMX篇章中提到的一个场景:

在业务高峰的期间,想对接口进行限流,就必须去修改接口并发的配置值。

JMXProxy中也提供了修改一些变量的方法

参数:

另外支持命令调用,不过这一点我并没有做深入研究(也许一些特殊命令组合存在漏洞?)

总结:

JMXProxy提供TomcatJMX接口给第三方平台分析和管理

用于监控Tomcat内部并且支持部分变量的修改

 

RCE

本节内容是针对TomcatJMXProxy如何实现RCE

换句话来说:哪些JMXProxy支持修改的属性被修改后可以RCE

经过肉眼审计,我发现一个有趣的类(熟悉Spring RCE的师傅应该一眼就能看出来)

AccessLogValve

对应JXMProxy中的描述信息如下,重点关注五个属性:

 

假设以上五个属性可以被设置,那么接下来的RCE之路就很简单了

于是我测试了每一个属性,发现都可以成功修改

 

RCE的思路如下:

 

第一步:

 

这里有一个细节:要求其中的val参数为全部的URL编码

开头和结尾的特殊符号从请求头的ps中获取

 

第二步:

修改日志后缀为:JSP

 

第三步:

修改日志前缀为:shell(当时间格式为空时文件名就是shell.jsp了)

 

第四步:

修改日志存储目录到可解析JSP的目录:webapps/ROOT

 

第五步:

修改日志文件名日期格式为空,使文件全名为shell.jsp

 

第六步:

发送带有ps请求头的请求,成功写入一句话

 

RCE:

 

我将以上发包的过程自动化,成功利用

 

实战

虽说RCE成功但感觉还是欠了些什么:需要有基础认证才可以触发漏洞

于是有必要研究一下实际的利用

 

我在全网进行搜索,发现了很多这样的第三方平台

找到很多可以直接修改AccessLogValve属性的JMX管理平台,于是我用nmap对这些主机进行扫描

检查了某些端口,开着基于JavaWeb服务,99%跑在Tomcat

 

存在这样管理页面的IP地址非常多,初步估计至少有几十个

我并没有做过多的尝试和实战,不过很大的概率可以通过JMX修改日志以写入Webshell达到RCE

总结

正如开头所说,虽然Tomcat官方不认可,但我认为该漏洞的危害大于一些Tomcat曾经的RCE CVE

虽然有限制条件,但在整个漏洞利用链中该限制条件可以绕过