论如何优雅注入 Java 内存马

💡 原文中文,约3000字,阅读约需7分钟。
📝

内容提要

文章探讨Java内存马注入问题,指出传统Servlet和Filter内存马可能因Filter执行顺序被改变而无法连接。建议优先注入Filter类型,并调整其顺序至首位以确保连接。还提及新型WS和Agent内存马,但未深入细节。

🔎

延伸解读

注入优先级:Filter 优于 Servlet

文章指出,传统内存马中 Listener、Filter、Servlet 的优先级理论上依次递减,但 Listener 可能干扰业务,且干净容器中通常不存在,因此实际应优先注入 Filter。Servlet 内存马需考虑已有 Filter 的拦截规则,可能因路径被过滤而无法连接。选择 Filter 类型可减少被拦截的风险,提高连接成功率。

连接失败的可能原因:Filter 顺序被改变

作者通过实验发现,动态注册的 Filter 内存马在后续注册其他 Filter 时,其执行顺序可能被移动,导致原本位于首位的过滤器被排到后面,从而被业务 Filter 拦截,造成无法连接。这解释了部分内存马注入成功却无法访问的现象,提示在注入后需检查并调整 Filter 顺序。

注入后的顺序调整方法

为确保 Filter 内存马能正常连接,文章提供了调整执行顺序的代码示例:通过反射获取 FilterMap 数组,将目标 Filter 与数组首位交换,使其置于最前。该方法兼容 Tomcat 不同版本(如 org.apache.tomcat.util.descriptor.web.FilterMap 和 org.apache.catalina.deploy.FilterMap),但未考虑 RASP 等防御机制。

Q&A

为什么注入的Java内存马有时无法连接?

文章指出,传统Servlet和Filter内存马可能因为Filter执行顺序被改变而无法连接。例如,动态注册的Filter内存马可能被后续注册的Filter挤到后面,导致请求被其他Filter拦截,从而无法访问到内存马。

注入Java内存马时,应该优先选择哪种类型?

文章建议优先注入Filter类型内存马,因为理论上传统内存马的优先级是Listener > Filter > Servlet,但Listener会干扰业务,而Servlet可能被已有Filter拦截。Filter类型相对更可靠,且可以通过调整顺序确保连接。

如何调整Filter内存马的执行顺序以确保连接?

文章提供了一段代码示例,通过反射获取StandardContext的FilterMaps,找到目标Filter的FilterMap,然后将其与第一个FilterMap交换位置,从而将目标Filter的执行顺序调整到第一位。

为什么注入Servlet内存马可能失败?

因为服务中可能存在Filter,如果请求路径被Filter拦截,Servlet内存马就无法被访问。例如,文章中的示例Filter只放行包含'favicon'的路径,如果Servlet内存马路径为'/favicondemo.ico',则会被拦截。

Listener内存马为什么不推荐使用?

因为Listener本身的特点会很大干扰业务的正常运行,而且正常情况下干净的Java Web容器(如Tomcat)可能不存在任何Listener,所以不推荐注入Listener内存马。

文章提到了哪些新型内存马?

文章提到了新型WS内存马和Agent内存马,但未深入细节,仅作为提及。

🏷️

标签

➡️

继续阅读