Servlet
0x01 Servlet First Shoot
引入依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>9.0.60</version>
</dependency>自定义Servlet
package servlets;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class MyServlet extends HttpServlet {
@Override
public void init() throws ServletException {
System.out.println("init....");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.write("Hello Servlet");
}
}注册Servlet(web.xml)
访问/test 返回页面Hello Servlet
0x02 Create Servlet Memory Shell
在init处下断点,观察调用栈
org.apache.catalina.core.StandardContext#startInternal

findChildren()把所有Wrapper传入loadOnStartup进行处理
org.apache.catalina.core.StandardContext#loadOnStartup
讲Tomcat架构的时候提到,一个 Wrapper 对应一个 Servlet。负责管理 Servlet ,包括 Servlet 的装载、初始化、执行以及资源回收。
这里的wrapper.load()应该就对应着Servlet的装载
每个Servlet的启动顺序在web.xml中,如果没有声明 load-on-startup 属性(默认为-1),则该Servlet会被动态添加到容器。
wrapper.load() => loadServlet

可以看到这里是通过获取servletClass来装载Servlet
完成装载后,进行初始化,根据请求进行调用,最终销毁
装载:启动服务器时加载Servlet的实例
初始化:web服务器启动时或web服务器接收到请求时,或者两者之间的某个时刻启动。初始化工作由init()方法负责执行完成
调用:即每次调用Servlet的service(),从第一次到以后的多次访问,都是只是调用doGet()或doPost()方法
销毁:停止服务器时调用destroy()方法,销毁实例
Wrapper是findChildren()遍历的来的,去看看findChildren()所在类有无addChild()之类的用于添加Wrapper的方法
org.apache.catalina.core.ContainerBase#addChild

实际上StandardContext重写了父类ContainerBase的addChild方法

先调用父类的addChild,接着进行访问jsp的处理
0x03 POC
Last updated
Was this helpful?