漏洞简介
最近爆出的 tomcat session 反序列化漏洞,思路比较明确,但是需要开配置,稍微鸡肋。
PS:这个洞刚出的时候,看到许少发pyq于是看了下,但是因为学校论文和找实习的事拖了俩礼拜没写文章,惨惨() btw,来个厂子收了我罢
环境搭建
有两种调试方法,一种是直接搭建源码调试环境,一种是配置 tomcat 后添加 lib 依赖,分别对应下面两个教程:
- 郑瀚师傅的源码调试: https://www.cnblogs.com/LittleHann/p/17735106.html
- idea 部署 tomcat: https://blog.csdn.net/qq_74312232/article/details/137474027
PS:这里采用法二,第一种方法会有各种问题,包括 build error、缺少 java.lang.xxx 等等,可以解决但是会很麻烦。
法二的大致思路:部署 tomcat-binary ,idea 添加一个 web framework(artifact),然后运行这个 artifact;至于源码调试,直接把 tomcat-binary 的 lib 里的 jar 包全部 add as library 就好,里面还有些小坑,这里详细说一下。
首先下载 tomcat-binary-9.0.98: https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.98/bin/apache-tomcat-9.0.98.zip
然后 idea new 一个 空 maven 项目,然后选中项目根目录,双击shift 输入 add framework
若成功,则会弹出下面的页面,选择 web 框架并添加,这是帮助我们添加一个适配 tomcat 的 web 目录架构。
点击 OK 添加后, 目录下会多出一个web目录,web目录下的index.jsp是我们后续会访问的地方。
注意:还需要将 Web 目录添加到 source root,不然会出现 404 Not Found。
下面配置 tomcat,右上角 add environment,选择添加 tomcat local server,并进行配置,下面的两个路径都是之前下载的 tomcat-binary 的根目录。
注意到右下角有个 Fix,提醒我们添加 artifact,点击 Fix 自动跳转的 Deployment Tab,这里的 Application context 可改可不改,我这里保持原样。
至此 tomcat 就配置完毕了,点击运行应该会去访问创建的index.jsp,出现一个 END 字样。
然后为了能够 debug,需要添加 tomat lib 到 idea 里,把 tomcat-binary 目录下的 lib 复制一份到项目根目录,然后右键 add as library 即可。注意:要利用漏洞的话,还需加一个漏洞依赖,例如 CC3.2.1。
打断点org.apache.catalina.servlets.DefaultServlet#doGet
,访问http://localhost:8080/CVE_2025_24813_war_exploded/123
,成功断下,可调式环境搭建完成。
接下来是开启漏洞所需的配置项,不开配置无法上传 session,所以有点鸡肋。
web.xml
1 | <init-param> |
context.xml
1 | <Manager className="org.apache.catalina.session.PersistentManager"> |
漏洞分析
漏洞本质:利用 PUT 协议上传恶意 Session 到服务器,由于服务器读取 Session 是反序列化读取,导致反序列化漏洞。
影响范围
- 9.0.0.M1 <= tomcat <= 9.0.98
- 10.1.0-M1 <= tomcat <= 10.1.34
- 11.0.0-M1 <= tomcat <= 11.0.2
Exp
step1:上传恶意 session 到服务器
1 | PUT /CVE_2025_24813_war_exploded/Jasper_sec/session HTTP/1.1 |
step2:触发 session 反序列化
1 | GET /CVE_2025_24813_war_exploded/ HTTP/1.1 |
漏洞调试
首先是 Session文件的上传,路由处理在 org.apache.catalina.servlets.DefaultServlet#doPut
,开头就能看到,如果 readonly=true
的话,会直接 send not allowed,所以需要通过配置文件设置 readonly=false
。
然后如果请求里有 Content-Range
,并且符合一定规则,就可以进到 else 逻辑,触发DefaultServlet#executePartialPut
org.apache.catalina.servlets.DefaultServlet#executePartialPut
会把文件上传的 tomcat 设置的 tmp 目录里,文件名是把路由的 "/"
替换成 "."
,所以 /Jasper_sec/session
变成了 .Jasper_sec.session
,实现了 Session 文件的上传。
然后是触发 Session 反序列化,这个也很简单,就是读取 Cookie 的 JSESSIONID 然后做拼接,可以看这个 load 函数,逻辑会很清晰:org.apache.catalina.session.FileStore#load
,包括拼接文件名,然后执行对文件内容反序列化。
函数调用栈
1 | transform:120, InvokerTransformer (org.apache.commons.collections.functors) |